tap: misc fixes
[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/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/dhcp/dhcp_proxy.h>
55 #include <vnet/bonding/node.h>
56 #include <vnet/qos/qos_types.h>
57 #include <vnet/ethernet/ethernet_types_api.h>
58 #include <vnet/ip/ip_types_api.h>
59 #include "vat/json_format.h"
60 #include <vnet/ip/ip_types_api.h>
61 #include <vnet/ethernet/ethernet_types_api.h>
62
63 #include <inttypes.h>
64 #include <sys/stat.h>
65
66 #define vl_typedefs             /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_typedefs
69
70 /* declare message handlers for each api */
71
72 #define vl_endianfun            /* define message structures */
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_endianfun
75
76 /* instantiate all the print functions we know about */
77 #if VPP_API_TEST_BUILTIN == 0
78 #define vl_print(handle, ...)
79 #else
80 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
81 #endif
82 #define vl_printfun
83 #include <vpp/api/vpe_all_api_h.h>
84 #undef vl_printfun
85
86 #define __plugin_msg_base 0
87 #include <vlibapi/vat_helper_macros.h>
88
89 void vl_api_set_elog_main (elog_main_t * m);
90 int vl_api_set_elog_trace_api_messages (int enable);
91
92 #if VPP_API_TEST_BUILTIN == 0
93 #include <netdb.h>
94
95 u32
96 vl (void *p)
97 {
98   return vec_len (p);
99 }
100
101 int
102 vat_socket_connect (vat_main_t * vam)
103 {
104   int rv;
105   vam->socket_client_main = &socket_client_main;
106   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
107                                       "vpp_api_test",
108                                       0 /* default socket rx, tx buffer */ )))
109     return rv;
110   /* vpp expects the client index in network order */
111   vam->my_client_index = htonl (socket_client_main.client_index);
112   return 0;
113 }
114 #else /* vpp built-in case, we don't do sockets... */
115 int
116 vat_socket_connect (vat_main_t * vam)
117 {
118   return 0;
119 }
120
121 int
122 vl_socket_client_read (int wait)
123 {
124   return -1;
125 };
126
127 int
128 vl_socket_client_write ()
129 {
130   return -1;
131 };
132
133 void *
134 vl_socket_client_msg_alloc (int nbytes)
135 {
136   return 0;
137 }
138 #endif
139
140
141 f64
142 vat_time_now (vat_main_t * vam)
143 {
144 #if VPP_API_TEST_BUILTIN
145   return vlib_time_now (vam->vlib_main);
146 #else
147   return clib_time_now (&vam->clib_time);
148 #endif
149 }
150
151 void
152 errmsg (char *fmt, ...)
153 {
154   vat_main_t *vam = &vat_main;
155   va_list va;
156   u8 *s;
157
158   va_start (va, fmt);
159   s = va_format (0, fmt, &va);
160   va_end (va);
161
162   vec_add1 (s, 0);
163
164 #if VPP_API_TEST_BUILTIN
165   vlib_cli_output (vam->vlib_main, (char *) s);
166 #else
167   {
168     if (vam->ifp != stdin)
169       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
170                vam->input_line_number);
171     else
172       fformat (vam->ofp, "%s\n", (char *) s);
173     fflush (vam->ofp);
174   }
175 #endif
176
177   vec_free (s);
178 }
179
180 #if VPP_API_TEST_BUILTIN == 0
181 static uword
182 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
183 {
184   vat_main_t *vam = va_arg (*args, vat_main_t *);
185   u32 *result = va_arg (*args, u32 *);
186   u8 *if_name;
187   uword *p;
188
189   if (!unformat (input, "%s", &if_name))
190     return 0;
191
192   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
193   if (p == 0)
194     return 0;
195   *result = p[0];
196   return 1;
197 }
198
199 static uword
200 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
201 {
202   return 0;
203 }
204
205 /* Parse an IP4 address %d.%d.%d.%d. */
206 uword
207 unformat_ip4_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   unsigned a[4];
211
212   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
213     return 0;
214
215   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
216     return 0;
217
218   result[0] = a[0];
219   result[1] = a[1];
220   result[2] = a[2];
221   result[3] = a[3];
222
223   return 1;
224 }
225
226 uword
227 unformat_ethernet_address (unformat_input_t * input, va_list * args)
228 {
229   u8 *result = va_arg (*args, u8 *);
230   u32 i, a[6];
231
232   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
233                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
234     return 0;
235
236   /* Check range. */
237   for (i = 0; i < 6; i++)
238     if (a[i] >= (1 << 8))
239       return 0;
240
241   for (i = 0; i < 6; i++)
242     result[i] = a[i];
243
244   return 1;
245 }
246
247 /* Returns ethernet type as an int in host byte order. */
248 uword
249 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
250                                         va_list * args)
251 {
252   u16 *result = va_arg (*args, u16 *);
253   int type;
254
255   /* Numeric type. */
256   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
257     {
258       if (type >= (1 << 16))
259         return 0;
260       *result = type;
261       return 1;
262     }
263   return 0;
264 }
265
266 /* Parse an IP6 address. */
267 uword
268 unformat_ip6_address (unformat_input_t * input, va_list * args)
269 {
270   ip6_address_t *result = va_arg (*args, ip6_address_t *);
271   u16 hex_quads[8];
272   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
273   uword c, n_colon, double_colon_index;
274
275   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
276   double_colon_index = ARRAY_LEN (hex_quads);
277   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
278     {
279       hex_digit = 16;
280       if (c >= '0' && c <= '9')
281         hex_digit = c - '0';
282       else if (c >= 'a' && c <= 'f')
283         hex_digit = c + 10 - 'a';
284       else if (c >= 'A' && c <= 'F')
285         hex_digit = c + 10 - 'A';
286       else if (c == ':' && n_colon < 2)
287         n_colon++;
288       else
289         {
290           unformat_put_input (input);
291           break;
292         }
293
294       /* Too many hex quads. */
295       if (n_hex_quads >= ARRAY_LEN (hex_quads))
296         return 0;
297
298       if (hex_digit < 16)
299         {
300           hex_quad = (hex_quad << 4) | hex_digit;
301
302           /* Hex quad must fit in 16 bits. */
303           if (n_hex_digits >= 4)
304             return 0;
305
306           n_colon = 0;
307           n_hex_digits++;
308         }
309
310       /* Save position of :: */
311       if (n_colon == 2)
312         {
313           /* More than one :: ? */
314           if (double_colon_index < ARRAY_LEN (hex_quads))
315             return 0;
316           double_colon_index = n_hex_quads;
317         }
318
319       if (n_colon > 0 && n_hex_digits > 0)
320         {
321           hex_quads[n_hex_quads++] = hex_quad;
322           hex_quad = 0;
323           n_hex_digits = 0;
324         }
325     }
326
327   if (n_hex_digits > 0)
328     hex_quads[n_hex_quads++] = hex_quad;
329
330   {
331     word i;
332
333     /* Expand :: to appropriate number of zero hex quads. */
334     if (double_colon_index < ARRAY_LEN (hex_quads))
335       {
336         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
337
338         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
339           hex_quads[n_zero + i] = hex_quads[i];
340
341         for (i = 0; i < n_zero; i++)
342           hex_quads[double_colon_index + i] = 0;
343
344         n_hex_quads = ARRAY_LEN (hex_quads);
345       }
346
347     /* Too few hex quads given. */
348     if (n_hex_quads < ARRAY_LEN (hex_quads))
349       return 0;
350
351     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
352       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
353
354     return 1;
355   }
356 }
357
358 uword
359 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
360 {
361   u32 *r = va_arg (*args, u32 *);
362
363   if (0);
364 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
365   foreach_ipsec_policy_action
366 #undef _
367     else
368     return 0;
369   return 1;
370 }
371
372 u8 *
373 format_ipsec_crypto_alg (u8 * s, va_list * args)
374 {
375   u32 i = va_arg (*args, u32);
376   u8 *t = 0;
377
378   switch (i)
379     {
380 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
381       foreach_ipsec_crypto_alg
382 #undef _
383     default:
384       return format (s, "unknown");
385     }
386   return format (s, "%s", t);
387 }
388
389 u8 *
390 format_ipsec_integ_alg (u8 * s, va_list * args)
391 {
392   u32 i = va_arg (*args, u32);
393   u8 *t = 0;
394
395   switch (i)
396     {
397 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
398       foreach_ipsec_integ_alg
399 #undef _
400     default:
401       return format (s, "unknown");
402     }
403   return format (s, "%s", t);
404 }
405
406 #else /* VPP_API_TEST_BUILTIN == 1 */
407 static uword
408 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
409 {
410   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
411   vnet_main_t *vnm = vnet_get_main ();
412   u32 *result = va_arg (*args, u32 *);
413
414   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
415 }
416
417 static uword
418 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
419 {
420   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
421   vnet_main_t *vnm = vnet_get_main ();
422   u32 *result = va_arg (*args, u32 *);
423
424   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
425 }
426
427 #endif /* VPP_API_TEST_BUILTIN */
428
429 uword
430 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
431 {
432   u32 *r = va_arg (*args, u32 *);
433
434   if (0);
435 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
436   foreach_ipsec_crypto_alg
437 #undef _
438     else
439     return 0;
440   return 1;
441 }
442
443 uword
444 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
445 {
446   u32 *r = va_arg (*args, u32 *);
447
448   if (0);
449 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
450   foreach_ipsec_integ_alg
451 #undef _
452     else
453     return 0;
454   return 1;
455 }
456
457 static uword
458 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
459 {
460   u8 *r = va_arg (*args, u8 *);
461
462   if (unformat (input, "kbps"))
463     *r = SSE2_QOS_RATE_KBPS;
464   else if (unformat (input, "pps"))
465     *r = SSE2_QOS_RATE_PPS;
466   else
467     return 0;
468   return 1;
469 }
470
471 static uword
472 unformat_policer_round_type (unformat_input_t * input, va_list * args)
473 {
474   u8 *r = va_arg (*args, u8 *);
475
476   if (unformat (input, "closest"))
477     *r = SSE2_QOS_ROUND_TO_CLOSEST;
478   else if (unformat (input, "up"))
479     *r = SSE2_QOS_ROUND_TO_UP;
480   else if (unformat (input, "down"))
481     *r = SSE2_QOS_ROUND_TO_DOWN;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_type (unformat_input_t * input, va_list * args)
489 {
490   u8 *r = va_arg (*args, u8 *);
491
492   if (unformat (input, "1r2c"))
493     *r = SSE2_QOS_POLICER_TYPE_1R2C;
494   else if (unformat (input, "1r3c"))
495     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
496   else if (unformat (input, "2r3c-2698"))
497     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
498   else if (unformat (input, "2r3c-4115"))
499     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
500   else if (unformat (input, "2r3c-mef5cf1"))
501     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
502   else
503     return 0;
504   return 1;
505 }
506
507 static uword
508 unformat_dscp (unformat_input_t * input, va_list * va)
509 {
510   u8 *r = va_arg (*va, u8 *);
511
512   if (0);
513 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
514   foreach_vnet_dscp
515 #undef _
516     else
517     return 0;
518   return 1;
519 }
520
521 static uword
522 unformat_policer_action_type (unformat_input_t * input, va_list * va)
523 {
524   sse2_qos_pol_action_params_st *a
525     = va_arg (*va, sse2_qos_pol_action_params_st *);
526
527   if (unformat (input, "drop"))
528     a->action_type = SSE2_QOS_ACTION_DROP;
529   else if (unformat (input, "transmit"))
530     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
531   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
532     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
533   else
534     return 0;
535   return 1;
536 }
537
538 static uword
539 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
540 {
541   u32 *r = va_arg (*va, u32 *);
542   u32 tid;
543
544   if (unformat (input, "ip4"))
545     tid = POLICER_CLASSIFY_TABLE_IP4;
546   else if (unformat (input, "ip6"))
547     tid = POLICER_CLASSIFY_TABLE_IP6;
548   else if (unformat (input, "l2"))
549     tid = POLICER_CLASSIFY_TABLE_L2;
550   else
551     return 0;
552
553   *r = tid;
554   return 1;
555 }
556
557 static uword
558 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
559 {
560   u32 *r = va_arg (*va, u32 *);
561   u32 tid;
562
563   if (unformat (input, "ip4"))
564     tid = FLOW_CLASSIFY_TABLE_IP4;
565   else if (unformat (input, "ip6"))
566     tid = FLOW_CLASSIFY_TABLE_IP6;
567   else
568     return 0;
569
570   *r = tid;
571   return 1;
572 }
573
574 #if (VPP_API_TEST_BUILTIN==0)
575
576 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
577 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
578 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
579 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
580
581 uword
582 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
583 {
584   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
585   mfib_itf_attribute_t attr;
586
587   old = *iflags;
588   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
589   {
590     if (unformat (input, mfib_itf_flag_long_names[attr]))
591       *iflags |= (1 << attr);
592   }
593   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
594   {
595     if (unformat (input, mfib_itf_flag_names[attr]))
596       *iflags |= (1 << attr);
597   }
598
599   return (old == *iflags ? 0 : 1);
600 }
601
602 uword
603 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
604 {
605   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
606   mfib_entry_attribute_t attr;
607
608   old = *eflags;
609   FOR_EACH_MFIB_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_flag_long_names[attr]))
612       *eflags |= (1 << attr);
613   }
614   FOR_EACH_MFIB_ATTRIBUTE (attr)
615   {
616     if (unformat (input, mfib_flag_names[attr]))
617       *eflags |= (1 << attr);
618   }
619
620   return (old == *eflags ? 0 : 1);
621 }
622
623 u8 *
624 format_ip4_address (u8 * s, va_list * args)
625 {
626   u8 *a = va_arg (*args, u8 *);
627   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
628 }
629
630 u8 *
631 format_ip6_address (u8 * s, va_list * args)
632 {
633   ip6_address_t *a = va_arg (*args, ip6_address_t *);
634   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
635
636   i_max_n_zero = ARRAY_LEN (a->as_u16);
637   max_n_zeros = 0;
638   i_first_zero = i_max_n_zero;
639   n_zeros = 0;
640   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
641     {
642       u32 is_zero = a->as_u16[i] == 0;
643       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
644         {
645           i_first_zero = i;
646           n_zeros = 0;
647         }
648       n_zeros += is_zero;
649       if ((!is_zero && n_zeros > max_n_zeros)
650           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
651         {
652           i_max_n_zero = i_first_zero;
653           max_n_zeros = n_zeros;
654           i_first_zero = ARRAY_LEN (a->as_u16);
655           n_zeros = 0;
656         }
657     }
658
659   last_double_colon = 0;
660   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
661     {
662       if (i == i_max_n_zero && max_n_zeros > 1)
663         {
664           s = format (s, "::");
665           i += max_n_zeros - 1;
666           last_double_colon = 1;
667         }
668       else
669         {
670           s = format (s, "%s%x",
671                       (last_double_colon || i == 0) ? "" : ":",
672                       clib_net_to_host_u16 (a->as_u16[i]));
673           last_double_colon = 0;
674         }
675     }
676
677   return s;
678 }
679
680 /* Format an IP46 address. */
681 u8 *
682 format_ip46_address (u8 * s, va_list * args)
683 {
684   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
685   ip46_type_t type = va_arg (*args, ip46_type_t);
686   int is_ip4 = 1;
687
688   switch (type)
689     {
690     case IP46_TYPE_ANY:
691       is_ip4 = ip46_address_is_ip4 (ip46);
692       break;
693     case IP46_TYPE_IP4:
694       is_ip4 = 1;
695       break;
696     case IP46_TYPE_IP6:
697       is_ip4 = 0;
698       break;
699     }
700
701   return is_ip4 ?
702     format (s, "%U", format_ip4_address, &ip46->ip4) :
703     format (s, "%U", format_ip6_address, &ip46->ip6);
704 }
705
706 u8 *
707 format_ethernet_address (u8 * s, va_list * args)
708 {
709   u8 *a = va_arg (*args, u8 *);
710
711   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
712                  a[0], a[1], a[2], a[3], a[4], a[5]);
713 }
714 #endif
715
716 static void
717 increment_v4_address (vl_api_ip4_address_t * i)
718 {
719   ip4_address_t *a = (ip4_address_t *) i;
720   u32 v;
721
722   v = ntohl (a->as_u32) + 1;
723   a->as_u32 = ntohl (v);
724 }
725
726 static void
727 increment_v6_address (vl_api_ip6_address_t * i)
728 {
729   ip6_address_t *a = (ip6_address_t *) i;
730   u64 v0, v1;
731
732   v0 = clib_net_to_host_u64 (a->as_u64[0]);
733   v1 = clib_net_to_host_u64 (a->as_u64[1]);
734
735   v1 += 1;
736   if (v1 == 0)
737     v0 += 1;
738   a->as_u64[0] = clib_net_to_host_u64 (v0);
739   a->as_u64[1] = clib_net_to_host_u64 (v1);
740 }
741
742 static void
743 increment_address (vl_api_address_t * a)
744 {
745   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
746     increment_v4_address (&a->un.ip4);
747   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
748     increment_v6_address (&a->un.ip6);
749 }
750
751 static void
752 set_ip4_address (vl_api_address_t * a, u32 v)
753 {
754   if (a->af == ADDRESS_IP4)
755     {
756       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
757       i->as_u32 = v;
758     }
759 }
760
761 static void
762 increment_mac_address (u8 * mac)
763 {
764   u64 tmp = *((u64 *) mac);
765   tmp = clib_net_to_host_u64 (tmp);
766   tmp += 1 << 16;               /* skip unused (least significant) octets */
767   tmp = clib_host_to_net_u64 (tmp);
768
769   clib_memcpy (mac, &tmp, 6);
770 }
771
772 static void
773 vat_json_object_add_address (vat_json_node_t * node,
774                              const char *str, const vl_api_address_t * addr)
775 {
776   if (ADDRESS_IP6 == addr->af)
777     {
778       struct in6_addr ip6;
779
780       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
781       vat_json_object_add_ip6 (node, str, ip6);
782     }
783   else
784     {
785       struct in_addr ip4;
786
787       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
788       vat_json_object_add_ip4 (node, str, ip4);
789     }
790 }
791
792 static void
793 vat_json_object_add_prefix (vat_json_node_t * node,
794                             const vl_api_prefix_t * prefix)
795 {
796   vat_json_object_add_uint (node, "len", prefix->len);
797   vat_json_object_add_address (node, "address", &prefix->address);
798 }
799
800 static void vl_api_create_loopback_reply_t_handler
801   (vl_api_create_loopback_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   i32 retval = ntohl (mp->retval);
805
806   vam->retval = retval;
807   vam->regenerate_interface_table = 1;
808   vam->sw_if_index = ntohl (mp->sw_if_index);
809   vam->result_ready = 1;
810 }
811
812 static void vl_api_create_loopback_reply_t_handler_json
813   (vl_api_create_loopback_reply_t * mp)
814 {
815   vat_main_t *vam = &vat_main;
816   vat_json_node_t node;
817
818   vat_json_init_object (&node);
819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
821
822   vat_json_print (vam->ofp, &node);
823   vat_json_free (&node);
824   vam->retval = ntohl (mp->retval);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_create_loopback_instance_reply_t_handler
829   (vl_api_create_loopback_instance_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   i32 retval = ntohl (mp->retval);
833
834   vam->retval = retval;
835   vam->regenerate_interface_table = 1;
836   vam->sw_if_index = ntohl (mp->sw_if_index);
837   vam->result_ready = 1;
838 }
839
840 static void vl_api_create_loopback_instance_reply_t_handler_json
841   (vl_api_create_loopback_instance_reply_t * mp)
842 {
843   vat_main_t *vam = &vat_main;
844   vat_json_node_t node;
845
846   vat_json_init_object (&node);
847   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
848   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
849
850   vat_json_print (vam->ofp, &node);
851   vat_json_free (&node);
852   vam->retval = ntohl (mp->retval);
853   vam->result_ready = 1;
854 }
855
856 static void vl_api_af_packet_create_reply_t_handler
857   (vl_api_af_packet_create_reply_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   i32 retval = ntohl (mp->retval);
861
862   vam->retval = retval;
863   vam->regenerate_interface_table = 1;
864   vam->sw_if_index = ntohl (mp->sw_if_index);
865   vam->result_ready = 1;
866 }
867
868 static void vl_api_af_packet_create_reply_t_handler_json
869   (vl_api_af_packet_create_reply_t * mp)
870 {
871   vat_main_t *vam = &vat_main;
872   vat_json_node_t node;
873
874   vat_json_init_object (&node);
875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
876   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void vl_api_create_vlan_subif_reply_t_handler
886   (vl_api_create_vlan_subif_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->regenerate_interface_table = 1;
893   vam->sw_if_index = ntohl (mp->sw_if_index);
894   vam->result_ready = 1;
895 }
896
897 static void vl_api_create_vlan_subif_reply_t_handler_json
898   (vl_api_create_vlan_subif_reply_t * mp)
899 {
900   vat_main_t *vam = &vat_main;
901   vat_json_node_t node;
902
903   vat_json_init_object (&node);
904   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
905   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
906
907   vat_json_print (vam->ofp, &node);
908   vat_json_free (&node);
909
910   vam->retval = ntohl (mp->retval);
911   vam->result_ready = 1;
912 }
913
914 static void vl_api_create_subif_reply_t_handler
915   (vl_api_create_subif_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   i32 retval = ntohl (mp->retval);
919
920   vam->retval = retval;
921   vam->regenerate_interface_table = 1;
922   vam->sw_if_index = ntohl (mp->sw_if_index);
923   vam->result_ready = 1;
924 }
925
926 static void vl_api_create_subif_reply_t_handler_json
927   (vl_api_create_subif_reply_t * mp)
928 {
929   vat_main_t *vam = &vat_main;
930   vat_json_node_t node;
931
932   vat_json_init_object (&node);
933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
934   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
935
936   vat_json_print (vam->ofp, &node);
937   vat_json_free (&node);
938
939   vam->retval = ntohl (mp->retval);
940   vam->result_ready = 1;
941 }
942
943 static void vl_api_interface_name_renumber_reply_t_handler
944   (vl_api_interface_name_renumber_reply_t * mp)
945 {
946   vat_main_t *vam = &vat_main;
947   i32 retval = ntohl (mp->retval);
948
949   vam->retval = retval;
950   vam->regenerate_interface_table = 1;
951   vam->result_ready = 1;
952 }
953
954 static void vl_api_interface_name_renumber_reply_t_handler_json
955   (vl_api_interface_name_renumber_reply_t * mp)
956 {
957   vat_main_t *vam = &vat_main;
958   vat_json_node_t node;
959
960   vat_json_init_object (&node);
961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
962
963   vat_json_print (vam->ofp, &node);
964   vat_json_free (&node);
965
966   vam->retval = ntohl (mp->retval);
967   vam->result_ready = 1;
968 }
969
970 /*
971  * Special-case: build the interface table, maintain
972  * the next loopback sw_if_index vbl.
973  */
974 static void vl_api_sw_interface_details_t_handler
975   (vl_api_sw_interface_details_t * mp)
976 {
977   vat_main_t *vam = &vat_main;
978   u8 *s = format (0, "%s%c", mp->interface_name, 0);
979
980   hash_set_mem (vam->sw_if_index_by_interface_name, s,
981                 ntohl (mp->sw_if_index));
982
983   /* In sub interface case, fill the sub interface table entry */
984   if (mp->sw_if_index != mp->sup_sw_if_index)
985     {
986       sw_interface_subif_t *sub = NULL;
987
988       vec_add2 (vam->sw_if_subif_table, sub, 1);
989
990       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
991       strncpy ((char *) sub->interface_name, (char *) s,
992                vec_len (sub->interface_name));
993       sub->sw_if_index = ntohl (mp->sw_if_index);
994       sub->sub_id = ntohl (mp->sub_id);
995
996       sub->sub_dot1ad = mp->sub_dot1ad;
997       sub->sub_number_of_tags = mp->sub_number_of_tags;
998       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
999       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1000       sub->sub_exact_match = mp->sub_exact_match;
1001       sub->sub_default = mp->sub_default;
1002       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
1003       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
1004
1005       /* vlan tag rewrite */
1006       sub->vtr_op = ntohl (mp->vtr_op);
1007       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1008       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1009       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1010     }
1011 }
1012
1013 static void vl_api_sw_interface_details_t_handler_json
1014   (vl_api_sw_interface_details_t * mp)
1015 {
1016   vat_main_t *vam = &vat_main;
1017   vat_json_node_t *node = NULL;
1018
1019   if (VAT_JSON_ARRAY != vam->json_tree.type)
1020     {
1021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1022       vat_json_init_array (&vam->json_tree);
1023     }
1024   node = vat_json_array_add (&vam->json_tree);
1025
1026   vat_json_init_object (node);
1027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1028   vat_json_object_add_uint (node, "sup_sw_if_index",
1029                             ntohl (mp->sup_sw_if_index));
1030   vat_json_object_add_uint (node, "l2_address_length",
1031                             ntohl (mp->l2_address_length));
1032   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1033                              sizeof (mp->l2_address));
1034   vat_json_object_add_string_copy (node, "interface_name",
1035                                    mp->interface_name);
1036   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
1037   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
1038   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1039   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1040   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1041   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1042   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1043   vat_json_object_add_uint (node, "sub_number_of_tags",
1044                             mp->sub_number_of_tags);
1045   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1046                             ntohs (mp->sub_outer_vlan_id));
1047   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1048                             ntohs (mp->sub_inner_vlan_id));
1049   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1050   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1051   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1052                             mp->sub_outer_vlan_id_any);
1053   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1054                             mp->sub_inner_vlan_id_any);
1055   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1056   vat_json_object_add_uint (node, "vtr_push_dot1q",
1057                             ntohl (mp->vtr_push_dot1q));
1058   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1059   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1060   if (mp->sub_dot1ah)
1061     {
1062       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1063                                        format (0, "%U",
1064                                                format_ethernet_address,
1065                                                &mp->b_dmac));
1066       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1067                                        format (0, "%U",
1068                                                format_ethernet_address,
1069                                                &mp->b_smac));
1070       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1071       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1072     }
1073 }
1074
1075 #if VPP_API_TEST_BUILTIN == 0
1076 static void vl_api_sw_interface_event_t_handler
1077   (vl_api_sw_interface_event_t * mp)
1078 {
1079   vat_main_t *vam = &vat_main;
1080   if (vam->interface_event_display)
1081     errmsg ("interface flags: sw_if_index %d %s %s",
1082             ntohl (mp->sw_if_index),
1083             mp->admin_up_down ? "admin-up" : "admin-down",
1084             mp->link_up_down ? "link-up" : "link-down");
1085 }
1086 #endif
1087
1088 __clib_unused static void
1089 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1090 {
1091   /* JSON output not supported */
1092 }
1093
1094 static void
1095 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1096 {
1097   vat_main_t *vam = &vat_main;
1098   i32 retval = ntohl (mp->retval);
1099
1100   vam->retval = retval;
1101   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   vat_json_node_t node;
1110   api_main_t *am = &api_main;
1111   void *oldheap;
1112   u8 *reply;
1113
1114   vat_json_init_object (&node);
1115   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1116   vat_json_object_add_uint (&node, "reply_in_shmem",
1117                             ntohl (mp->reply_in_shmem));
1118   /* Toss the shared-memory original... */
1119   pthread_mutex_lock (&am->vlib_rp->mutex);
1120   oldheap = svm_push_data_heap (am->vlib_rp);
1121
1122   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1123   vec_free (reply);
1124
1125   svm_pop_heap (oldheap);
1126   pthread_mutex_unlock (&am->vlib_rp->mutex);
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void
1136 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   i32 retval = ntohl (mp->retval);
1140   u32 length = vl_api_string_len (&mp->reply);
1141
1142   vec_reset_length (vam->cmd_reply);
1143
1144   vam->retval = retval;
1145   if (retval == 0)
1146     {
1147       vec_validate (vam->cmd_reply, length);
1148       clib_memcpy ((char *) (vam->cmd_reply),
1149                    vl_api_from_api_string (&mp->reply), length);
1150       vam->cmd_reply[length] = 0;
1151     }
1152   vam->result_ready = 1;
1153 }
1154
1155 static void
1156 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1157 {
1158   vat_main_t *vam = &vat_main;
1159   vat_json_node_t node;
1160
1161   vec_reset_length (vam->cmd_reply);
1162
1163   vat_json_init_object (&node);
1164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1165   vat_json_object_add_string_copy (&node, "reply",
1166                                    vl_api_from_api_string (&mp->reply));
1167
1168   vat_json_print (vam->ofp, &node);
1169   vat_json_free (&node);
1170
1171   vam->retval = ntohl (mp->retval);
1172   vam->result_ready = 1;
1173 }
1174
1175 static void vl_api_classify_add_del_table_reply_t_handler
1176   (vl_api_classify_add_del_table_reply_t * mp)
1177 {
1178   vat_main_t *vam = &vat_main;
1179   i32 retval = ntohl (mp->retval);
1180   if (vam->async_mode)
1181     {
1182       vam->async_errors += (retval < 0);
1183     }
1184   else
1185     {
1186       vam->retval = retval;
1187       if (retval == 0 &&
1188           ((mp->new_table_index != 0xFFFFFFFF) ||
1189            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1190            (mp->match_n_vectors != 0xFFFFFFFF)))
1191         /*
1192          * Note: this is just barely thread-safe, depends on
1193          * the main thread spinning waiting for an answer...
1194          */
1195         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1196                 ntohl (mp->new_table_index),
1197                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1198       vam->result_ready = 1;
1199     }
1200 }
1201
1202 static void vl_api_classify_add_del_table_reply_t_handler_json
1203   (vl_api_classify_add_del_table_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   vat_json_node_t node;
1207
1208   vat_json_init_object (&node);
1209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1210   vat_json_object_add_uint (&node, "new_table_index",
1211                             ntohl (mp->new_table_index));
1212   vat_json_object_add_uint (&node, "skip_n_vectors",
1213                             ntohl (mp->skip_n_vectors));
1214   vat_json_object_add_uint (&node, "match_n_vectors",
1215                             ntohl (mp->match_n_vectors));
1216
1217   vat_json_print (vam->ofp, &node);
1218   vat_json_free (&node);
1219
1220   vam->retval = ntohl (mp->retval);
1221   vam->result_ready = 1;
1222 }
1223
1224 static void vl_api_get_node_index_reply_t_handler
1225   (vl_api_get_node_index_reply_t * mp)
1226 {
1227   vat_main_t *vam = &vat_main;
1228   i32 retval = ntohl (mp->retval);
1229   if (vam->async_mode)
1230     {
1231       vam->async_errors += (retval < 0);
1232     }
1233   else
1234     {
1235       vam->retval = retval;
1236       if (retval == 0)
1237         errmsg ("node index %d", ntohl (mp->node_index));
1238       vam->result_ready = 1;
1239     }
1240 }
1241
1242 static void vl_api_get_node_index_reply_t_handler_json
1243   (vl_api_get_node_index_reply_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t node;
1247
1248   vat_json_init_object (&node);
1249   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1250   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1251
1252   vat_json_print (vam->ofp, &node);
1253   vat_json_free (&node);
1254
1255   vam->retval = ntohl (mp->retval);
1256   vam->result_ready = 1;
1257 }
1258
1259 static void vl_api_get_next_index_reply_t_handler
1260   (vl_api_get_next_index_reply_t * mp)
1261 {
1262   vat_main_t *vam = &vat_main;
1263   i32 retval = ntohl (mp->retval);
1264   if (vam->async_mode)
1265     {
1266       vam->async_errors += (retval < 0);
1267     }
1268   else
1269     {
1270       vam->retval = retval;
1271       if (retval == 0)
1272         errmsg ("next node index %d", ntohl (mp->next_index));
1273       vam->result_ready = 1;
1274     }
1275 }
1276
1277 static void vl_api_get_next_index_reply_t_handler_json
1278   (vl_api_get_next_index_reply_t * mp)
1279 {
1280   vat_main_t *vam = &vat_main;
1281   vat_json_node_t node;
1282
1283   vat_json_init_object (&node);
1284   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1285   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void vl_api_add_node_next_reply_t_handler
1295   (vl_api_add_node_next_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299   if (vam->async_mode)
1300     {
1301       vam->async_errors += (retval < 0);
1302     }
1303   else
1304     {
1305       vam->retval = retval;
1306       if (retval == 0)
1307         errmsg ("next index %d", ntohl (mp->next_index));
1308       vam->result_ready = 1;
1309     }
1310 }
1311
1312 static void vl_api_add_node_next_reply_t_handler_json
1313   (vl_api_add_node_next_reply_t * mp)
1314 {
1315   vat_main_t *vam = &vat_main;
1316   vat_json_node_t node;
1317
1318   vat_json_init_object (&node);
1319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1320   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1321
1322   vat_json_print (vam->ofp, &node);
1323   vat_json_free (&node);
1324
1325   vam->retval = ntohl (mp->retval);
1326   vam->result_ready = 1;
1327 }
1328
1329 static void vl_api_show_version_reply_t_handler
1330   (vl_api_show_version_reply_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   i32 retval = ntohl (mp->retval);
1334
1335   if (retval >= 0)
1336     {
1337       errmsg ("        program: %s", mp->program);
1338       errmsg ("        version: %s", mp->version);
1339       errmsg ("     build date: %s", mp->build_date);
1340       errmsg ("build directory: %s", mp->build_directory);
1341     }
1342   vam->retval = retval;
1343   vam->result_ready = 1;
1344 }
1345
1346 static void vl_api_show_version_reply_t_handler_json
1347   (vl_api_show_version_reply_t * mp)
1348 {
1349   vat_main_t *vam = &vat_main;
1350   vat_json_node_t node;
1351
1352   vat_json_init_object (&node);
1353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1354   vat_json_object_add_string_copy (&node, "program", mp->program);
1355   vat_json_object_add_string_copy (&node, "version", mp->version);
1356   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1357   vat_json_object_add_string_copy (&node, "build_directory",
1358                                    mp->build_directory);
1359
1360   vat_json_print (vam->ofp, &node);
1361   vat_json_free (&node);
1362
1363   vam->retval = ntohl (mp->retval);
1364   vam->result_ready = 1;
1365 }
1366
1367 static void vl_api_show_threads_reply_t_handler
1368   (vl_api_show_threads_reply_t * mp)
1369 {
1370   vat_main_t *vam = &vat_main;
1371   i32 retval = ntohl (mp->retval);
1372   int i, count = 0;
1373
1374   if (retval >= 0)
1375     count = ntohl (mp->count);
1376
1377   for (i = 0; i < count; i++)
1378     print (vam->ofp,
1379            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1380            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1381            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1382            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1383            ntohl (mp->thread_data[i].cpu_socket));
1384
1385   vam->retval = retval;
1386   vam->result_ready = 1;
1387 }
1388
1389 static void vl_api_show_threads_reply_t_handler_json
1390   (vl_api_show_threads_reply_t * mp)
1391 {
1392   vat_main_t *vam = &vat_main;
1393   vat_json_node_t node;
1394   vl_api_thread_data_t *td;
1395   i32 retval = ntohl (mp->retval);
1396   int i, count = 0;
1397
1398   if (retval >= 0)
1399     count = ntohl (mp->count);
1400
1401   vat_json_init_object (&node);
1402   vat_json_object_add_int (&node, "retval", retval);
1403   vat_json_object_add_uint (&node, "count", count);
1404
1405   for (i = 0; i < count; i++)
1406     {
1407       td = &mp->thread_data[i];
1408       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1409       vat_json_object_add_string_copy (&node, "name", td->name);
1410       vat_json_object_add_string_copy (&node, "type", td->type);
1411       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1412       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1413       vat_json_object_add_int (&node, "core", ntohl (td->id));
1414       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1415     }
1416
1417   vat_json_print (vam->ofp, &node);
1418   vat_json_free (&node);
1419
1420   vam->retval = retval;
1421   vam->result_ready = 1;
1422 }
1423
1424 static int
1425 api_show_threads (vat_main_t * vam)
1426 {
1427   vl_api_show_threads_t *mp;
1428   int ret;
1429
1430   print (vam->ofp,
1431          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1432          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1433
1434   M (SHOW_THREADS, mp);
1435
1436   S (mp);
1437   W (ret);
1438   return ret;
1439 }
1440
1441 static void
1442 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1443 {
1444   u32 sw_if_index = ntohl (mp->sw_if_index);
1445   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1446           mp->mac_ip ? "mac/ip binding" : "address resolution",
1447           ntohl (mp->pid), format_ip4_address, mp->ip,
1448           format_vl_api_mac_address, &mp->mac, sw_if_index);
1449 }
1450
1451 static void
1452 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1453 {
1454   /* JSON output not supported */
1455 }
1456
1457 static void
1458 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1459 {
1460   u32 sw_if_index = ntohl (mp->sw_if_index);
1461   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1462           mp->mac_ip ? "mac/ip binding" : "address resolution",
1463           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1464           format_vl_api_mac_address, mp->mac, sw_if_index);
1465 }
1466
1467 static void
1468 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1469 {
1470   /* JSON output not supported */
1471 }
1472
1473 static void
1474 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1475 {
1476   u32 n_macs = ntohl (mp->n_macs);
1477   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1478           ntohl (mp->pid), mp->client_index, n_macs);
1479   int i;
1480   for (i = 0; i < n_macs; i++)
1481     {
1482       vl_api_mac_entry_t *mac = &mp->mac[i];
1483       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1484               i + 1, ntohl (mac->sw_if_index),
1485               format_ethernet_address, mac->mac_addr, mac->action);
1486       if (i == 1000)
1487         break;
1488     }
1489 }
1490
1491 static void
1492 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1493 {
1494   /* JSON output not supported */
1495 }
1496
1497 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1498 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1499
1500 /*
1501  * Special-case: build the bridge domain table, maintain
1502  * the next bd id vbl.
1503  */
1504 static void vl_api_bridge_domain_details_t_handler
1505   (vl_api_bridge_domain_details_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1509   int i;
1510
1511   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1512          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1513
1514   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1515          ntohl (mp->bd_id), mp->learn, mp->forward,
1516          mp->flood, ntohl (mp->bvi_sw_if_index),
1517          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1518
1519   if (n_sw_ifs)
1520     {
1521       vl_api_bridge_domain_sw_if_t *sw_ifs;
1522       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1523              "Interface Name");
1524
1525       sw_ifs = mp->sw_if_details;
1526       for (i = 0; i < n_sw_ifs; i++)
1527         {
1528           u8 *sw_if_name = 0;
1529           u32 sw_if_index;
1530           hash_pair_t *p;
1531
1532           sw_if_index = ntohl (sw_ifs->sw_if_index);
1533
1534           /* *INDENT-OFF* */
1535           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1536                              ({
1537                                if ((u32) p->value[0] == sw_if_index)
1538                                  {
1539                                    sw_if_name = (u8 *)(p->key);
1540                                    break;
1541                                  }
1542                              }));
1543           /* *INDENT-ON* */
1544           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1545                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1546                  "sw_if_index not found!");
1547
1548           sw_ifs++;
1549         }
1550     }
1551 }
1552
1553 static void vl_api_bridge_domain_details_t_handler_json
1554   (vl_api_bridge_domain_details_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   vat_json_node_t *node, *array = NULL;
1558   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1559
1560   if (VAT_JSON_ARRAY != vam->json_tree.type)
1561     {
1562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1563       vat_json_init_array (&vam->json_tree);
1564     }
1565   node = vat_json_array_add (&vam->json_tree);
1566
1567   vat_json_init_object (node);
1568   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1569   vat_json_object_add_uint (node, "flood", mp->flood);
1570   vat_json_object_add_uint (node, "forward", mp->forward);
1571   vat_json_object_add_uint (node, "learn", mp->learn);
1572   vat_json_object_add_uint (node, "bvi_sw_if_index",
1573                             ntohl (mp->bvi_sw_if_index));
1574   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1575   array = vat_json_object_add (node, "sw_if");
1576   vat_json_init_array (array);
1577
1578
1579
1580   if (n_sw_ifs)
1581     {
1582       vl_api_bridge_domain_sw_if_t *sw_ifs;
1583       int i;
1584
1585       sw_ifs = mp->sw_if_details;
1586       for (i = 0; i < n_sw_ifs; i++)
1587         {
1588           node = vat_json_array_add (array);
1589           vat_json_init_object (node);
1590           vat_json_object_add_uint (node, "sw_if_index",
1591                                     ntohl (sw_ifs->sw_if_index));
1592           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1593           sw_ifs++;
1594         }
1595     }
1596 }
1597
1598 static void vl_api_control_ping_reply_t_handler
1599   (vl_api_control_ping_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   i32 retval = ntohl (mp->retval);
1603   if (vam->async_mode)
1604     {
1605       vam->async_errors += (retval < 0);
1606     }
1607   else
1608     {
1609       vam->retval = retval;
1610       vam->result_ready = 1;
1611     }
1612   if (vam->socket_client_main)
1613     vam->socket_client_main->control_pings_outstanding--;
1614 }
1615
1616 static void vl_api_control_ping_reply_t_handler_json
1617   (vl_api_control_ping_reply_t * mp)
1618 {
1619   vat_main_t *vam = &vat_main;
1620   i32 retval = ntohl (mp->retval);
1621
1622   if (VAT_JSON_NONE != vam->json_tree.type)
1623     {
1624       vat_json_print (vam->ofp, &vam->json_tree);
1625       vat_json_free (&vam->json_tree);
1626       vam->json_tree.type = VAT_JSON_NONE;
1627     }
1628   else
1629     {
1630       /* just print [] */
1631       vat_json_init_array (&vam->json_tree);
1632       vat_json_print (vam->ofp, &vam->json_tree);
1633       vam->json_tree.type = VAT_JSON_NONE;
1634     }
1635
1636   vam->retval = retval;
1637   vam->result_ready = 1;
1638 }
1639
1640 static void
1641   vl_api_bridge_domain_set_mac_age_reply_t_handler
1642   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   i32 retval = ntohl (mp->retval);
1646   if (vam->async_mode)
1647     {
1648       vam->async_errors += (retval < 0);
1649     }
1650   else
1651     {
1652       vam->retval = retval;
1653       vam->result_ready = 1;
1654     }
1655 }
1656
1657 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1658   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   vat_json_node_t node;
1662
1663   vat_json_init_object (&node);
1664   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1665
1666   vat_json_print (vam->ofp, &node);
1667   vat_json_free (&node);
1668
1669   vam->retval = ntohl (mp->retval);
1670   vam->result_ready = 1;
1671 }
1672
1673 static void
1674 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1675 {
1676   vat_main_t *vam = &vat_main;
1677   i32 retval = ntohl (mp->retval);
1678   if (vam->async_mode)
1679     {
1680       vam->async_errors += (retval < 0);
1681     }
1682   else
1683     {
1684       vam->retval = retval;
1685       vam->result_ready = 1;
1686     }
1687 }
1688
1689 static void vl_api_l2_flags_reply_t_handler_json
1690   (vl_api_l2_flags_reply_t * mp)
1691 {
1692   vat_main_t *vam = &vat_main;
1693   vat_json_node_t node;
1694
1695   vat_json_init_object (&node);
1696   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1697   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1698                             ntohl (mp->resulting_feature_bitmap));
1699
1700   vat_json_print (vam->ofp, &node);
1701   vat_json_free (&node);
1702
1703   vam->retval = ntohl (mp->retval);
1704   vam->result_ready = 1;
1705 }
1706
1707 static void vl_api_bridge_flags_reply_t_handler
1708   (vl_api_bridge_flags_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   i32 retval = ntohl (mp->retval);
1712   if (vam->async_mode)
1713     {
1714       vam->async_errors += (retval < 0);
1715     }
1716   else
1717     {
1718       vam->retval = retval;
1719       vam->result_ready = 1;
1720     }
1721 }
1722
1723 static void vl_api_bridge_flags_reply_t_handler_json
1724   (vl_api_bridge_flags_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   vat_json_node_t node;
1728
1729   vat_json_init_object (&node);
1730   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1731   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1732                             ntohl (mp->resulting_feature_bitmap));
1733
1734   vat_json_print (vam->ofp, &node);
1735   vat_json_free (&node);
1736
1737   vam->retval = ntohl (mp->retval);
1738   vam->result_ready = 1;
1739 }
1740
1741 static void
1742 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   i32 retval = ntohl (mp->retval);
1746   if (vam->async_mode)
1747     {
1748       vam->async_errors += (retval < 0);
1749     }
1750   else
1751     {
1752       vam->retval = retval;
1753       vam->sw_if_index = ntohl (mp->sw_if_index);
1754       vam->result_ready = 1;
1755     }
1756
1757 }
1758
1759 static void vl_api_tap_create_v2_reply_t_handler_json
1760   (vl_api_tap_create_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   vat_json_node_t node;
1764
1765   vat_json_init_object (&node);
1766   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1767   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1768
1769   vat_json_print (vam->ofp, &node);
1770   vat_json_free (&node);
1771
1772   vam->retval = ntohl (mp->retval);
1773   vam->result_ready = 1;
1774
1775 }
1776
1777 static void
1778 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1779 {
1780   vat_main_t *vam = &vat_main;
1781   i32 retval = ntohl (mp->retval);
1782   if (vam->async_mode)
1783     {
1784       vam->async_errors += (retval < 0);
1785     }
1786   else
1787     {
1788       vam->retval = retval;
1789       vam->result_ready = 1;
1790     }
1791 }
1792
1793 static void vl_api_tap_delete_v2_reply_t_handler_json
1794   (vl_api_tap_delete_v2_reply_t * mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   vat_json_node_t node;
1798
1799   vat_json_init_object (&node);
1800   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1801
1802   vat_json_print (vam->ofp, &node);
1803   vat_json_free (&node);
1804
1805   vam->retval = ntohl (mp->retval);
1806   vam->result_ready = 1;
1807 }
1808
1809 static void
1810 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1811                                           mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   i32 retval = ntohl (mp->retval);
1815   if (vam->async_mode)
1816     {
1817       vam->async_errors += (retval < 0);
1818     }
1819   else
1820     {
1821       vam->retval = retval;
1822       vam->sw_if_index = ntohl (mp->sw_if_index);
1823       vam->result_ready = 1;
1824     }
1825 }
1826
1827 static void vl_api_virtio_pci_create_reply_t_handler_json
1828   (vl_api_virtio_pci_create_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   vat_json_node_t node;
1832
1833   vat_json_init_object (&node);
1834   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1835   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1836
1837   vat_json_print (vam->ofp, &node);
1838   vat_json_free (&node);
1839
1840   vam->retval = ntohl (mp->retval);
1841   vam->result_ready = 1;
1842
1843 }
1844
1845 static void
1846 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1847                                           mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   i32 retval = ntohl (mp->retval);
1851   if (vam->async_mode)
1852     {
1853       vam->async_errors += (retval < 0);
1854     }
1855   else
1856     {
1857       vam->retval = retval;
1858       vam->result_ready = 1;
1859     }
1860 }
1861
1862 static void vl_api_virtio_pci_delete_reply_t_handler_json
1863   (vl_api_virtio_pci_delete_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   vat_json_node_t node;
1867
1868   vat_json_init_object (&node);
1869   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1870
1871   vat_json_print (vam->ofp, &node);
1872   vat_json_free (&node);
1873
1874   vam->retval = ntohl (mp->retval);
1875   vam->result_ready = 1;
1876 }
1877
1878 static void
1879 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1880 {
1881   vat_main_t *vam = &vat_main;
1882   i32 retval = ntohl (mp->retval);
1883
1884   if (vam->async_mode)
1885     {
1886       vam->async_errors += (retval < 0);
1887     }
1888   else
1889     {
1890       vam->retval = retval;
1891       vam->sw_if_index = ntohl (mp->sw_if_index);
1892       vam->result_ready = 1;
1893     }
1894 }
1895
1896 static void vl_api_bond_create_reply_t_handler_json
1897   (vl_api_bond_create_reply_t * mp)
1898 {
1899   vat_main_t *vam = &vat_main;
1900   vat_json_node_t node;
1901
1902   vat_json_init_object (&node);
1903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1905
1906   vat_json_print (vam->ofp, &node);
1907   vat_json_free (&node);
1908
1909   vam->retval = ntohl (mp->retval);
1910   vam->result_ready = 1;
1911 }
1912
1913 static void
1914 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   i32 retval = ntohl (mp->retval);
1918
1919   if (vam->async_mode)
1920     {
1921       vam->async_errors += (retval < 0);
1922     }
1923   else
1924     {
1925       vam->retval = retval;
1926       vam->result_ready = 1;
1927     }
1928 }
1929
1930 static void vl_api_bond_delete_reply_t_handler_json
1931   (vl_api_bond_delete_reply_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   vat_json_node_t node;
1935
1936   vat_json_init_object (&node);
1937   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1938
1939   vat_json_print (vam->ofp, &node);
1940   vat_json_free (&node);
1941
1942   vam->retval = ntohl (mp->retval);
1943   vam->result_ready = 1;
1944 }
1945
1946 static void
1947 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   i32 retval = ntohl (mp->retval);
1951
1952   if (vam->async_mode)
1953     {
1954       vam->async_errors += (retval < 0);
1955     }
1956   else
1957     {
1958       vam->retval = retval;
1959       vam->result_ready = 1;
1960     }
1961 }
1962
1963 static void vl_api_bond_enslave_reply_t_handler_json
1964   (vl_api_bond_enslave_reply_t * mp)
1965 {
1966   vat_main_t *vam = &vat_main;
1967   vat_json_node_t node;
1968
1969   vat_json_init_object (&node);
1970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1971
1972   vat_json_print (vam->ofp, &node);
1973   vat_json_free (&node);
1974
1975   vam->retval = ntohl (mp->retval);
1976   vam->result_ready = 1;
1977 }
1978
1979 static void
1980 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1981                                           mp)
1982 {
1983   vat_main_t *vam = &vat_main;
1984   i32 retval = ntohl (mp->retval);
1985
1986   if (vam->async_mode)
1987     {
1988       vam->async_errors += (retval < 0);
1989     }
1990   else
1991     {
1992       vam->retval = retval;
1993       vam->result_ready = 1;
1994     }
1995 }
1996
1997 static void vl_api_bond_detach_slave_reply_t_handler_json
1998   (vl_api_bond_detach_slave_reply_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001   vat_json_node_t node;
2002
2003   vat_json_init_object (&node);
2004   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2005
2006   vat_json_print (vam->ofp, &node);
2007   vat_json_free (&node);
2008
2009   vam->retval = ntohl (mp->retval);
2010   vam->result_ready = 1;
2011 }
2012
2013 static void vl_api_sw_interface_bond_details_t_handler
2014   (vl_api_sw_interface_bond_details_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017
2018   print (vam->ofp,
2019          "%-16s %-12d %-12U %-13U %-14u %-14u",
2020          mp->interface_name, ntohl (mp->sw_if_index),
2021          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2022          ntohl (mp->active_slaves), ntohl (mp->slaves));
2023 }
2024
2025 static void vl_api_sw_interface_bond_details_t_handler_json
2026   (vl_api_sw_interface_bond_details_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   vat_json_node_t *node = NULL;
2030
2031   if (VAT_JSON_ARRAY != vam->json_tree.type)
2032     {
2033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2034       vat_json_init_array (&vam->json_tree);
2035     }
2036   node = vat_json_array_add (&vam->json_tree);
2037
2038   vat_json_init_object (node);
2039   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2040   vat_json_object_add_string_copy (node, "interface_name",
2041                                    mp->interface_name);
2042   vat_json_object_add_uint (node, "mode", mp->mode);
2043   vat_json_object_add_uint (node, "load_balance", mp->lb);
2044   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2045   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2046 }
2047
2048 static int
2049 api_sw_interface_bond_dump (vat_main_t * vam)
2050 {
2051   vl_api_sw_interface_bond_dump_t *mp;
2052   vl_api_control_ping_t *mp_ping;
2053   int ret;
2054
2055   print (vam->ofp,
2056          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2057          "interface name", "sw_if_index", "mode", "load balance",
2058          "active slaves", "slaves");
2059
2060   /* Get list of bond interfaces */
2061   M (SW_INTERFACE_BOND_DUMP, mp);
2062   S (mp);
2063
2064   /* Use a control ping for synchronization */
2065   MPING (CONTROL_PING, mp_ping);
2066   S (mp_ping);
2067
2068   W (ret);
2069   return ret;
2070 }
2071
2072 static void vl_api_sw_interface_slave_details_t_handler
2073   (vl_api_sw_interface_slave_details_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076
2077   print (vam->ofp,
2078          "%-25s %-12d %-12d %d", mp->interface_name,
2079          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2080 }
2081
2082 static void vl_api_sw_interface_slave_details_t_handler_json
2083   (vl_api_sw_interface_slave_details_t * mp)
2084 {
2085   vat_main_t *vam = &vat_main;
2086   vat_json_node_t *node = NULL;
2087
2088   if (VAT_JSON_ARRAY != vam->json_tree.type)
2089     {
2090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2091       vat_json_init_array (&vam->json_tree);
2092     }
2093   node = vat_json_array_add (&vam->json_tree);
2094
2095   vat_json_init_object (node);
2096   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2097   vat_json_object_add_string_copy (node, "interface_name",
2098                                    mp->interface_name);
2099   vat_json_object_add_uint (node, "passive", mp->is_passive);
2100   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2101 }
2102
2103 static int
2104 api_sw_interface_slave_dump (vat_main_t * vam)
2105 {
2106   unformat_input_t *i = vam->input;
2107   vl_api_sw_interface_slave_dump_t *mp;
2108   vl_api_control_ping_t *mp_ping;
2109   u32 sw_if_index = ~0;
2110   u8 sw_if_index_set = 0;
2111   int ret;
2112
2113   /* Parse args required to build the message */
2114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2115     {
2116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2117         sw_if_index_set = 1;
2118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2119         sw_if_index_set = 1;
2120       else
2121         break;
2122     }
2123
2124   if (sw_if_index_set == 0)
2125     {
2126       errmsg ("missing vpp interface name. ");
2127       return -99;
2128     }
2129
2130   print (vam->ofp,
2131          "\n%-25s %-12s %-12s %s",
2132          "slave interface name", "sw_if_index", "passive", "long_timeout");
2133
2134   /* Get list of bond interfaces */
2135   M (SW_INTERFACE_SLAVE_DUMP, mp);
2136   mp->sw_if_index = ntohl (sw_if_index);
2137   S (mp);
2138
2139   /* Use a control ping for synchronization */
2140   MPING (CONTROL_PING, mp_ping);
2141   S (mp_ping);
2142
2143   W (ret);
2144   return ret;
2145 }
2146
2147 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2148   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2149 {
2150   vat_main_t *vam = &vat_main;
2151   i32 retval = ntohl (mp->retval);
2152   if (vam->async_mode)
2153     {
2154       vam->async_errors += (retval < 0);
2155     }
2156   else
2157     {
2158       vam->retval = retval;
2159       vam->sw_if_index = ntohl (mp->sw_if_index);
2160       vam->result_ready = 1;
2161     }
2162   vam->regenerate_interface_table = 1;
2163 }
2164
2165 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2166   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   vat_json_node_t node;
2170
2171   vat_json_init_object (&node);
2172   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2173   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2174                             ntohl (mp->sw_if_index));
2175
2176   vat_json_print (vam->ofp, &node);
2177   vat_json_free (&node);
2178
2179   vam->retval = ntohl (mp->retval);
2180   vam->result_ready = 1;
2181 }
2182
2183 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2184   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187   i32 retval = ntohl (mp->retval);
2188   if (vam->async_mode)
2189     {
2190       vam->async_errors += (retval < 0);
2191     }
2192   else
2193     {
2194       vam->retval = retval;
2195       vam->sw_if_index = ntohl (mp->sw_if_index);
2196       vam->result_ready = 1;
2197     }
2198 }
2199
2200 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2201   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2202 {
2203   vat_main_t *vam = &vat_main;
2204   vat_json_node_t node;
2205
2206   vat_json_init_object (&node);
2207   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2208   vat_json_object_add_uint (&node, "sw_if_index", 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_gpe_add_del_fwd_entry_reply_t_handler
2218   (vl_api_gpe_add_del_fwd_entry_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->result_ready = 1;
2230     }
2231 }
2232
2233 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2234   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2235 {
2236   vat_main_t *vam = &vat_main;
2237   vat_json_node_t node;
2238
2239   vat_json_init_object (&node);
2240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2241   vat_json_object_add_uint (&node, "fwd_entry_index",
2242                             clib_net_to_host_u32 (mp->fwd_entry_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 u8 *
2252 format_lisp_transport_protocol (u8 * s, va_list * args)
2253 {
2254   u32 proto = va_arg (*args, u32);
2255
2256   switch (proto)
2257     {
2258     case 1:
2259       return format (s, "udp");
2260     case 2:
2261       return format (s, "api");
2262     default:
2263       return 0;
2264     }
2265   return 0;
2266 }
2267
2268 static void vl_api_one_get_transport_protocol_reply_t_handler
2269   (vl_api_one_get_transport_protocol_reply_t * mp)
2270 {
2271   vat_main_t *vam = &vat_main;
2272   i32 retval = ntohl (mp->retval);
2273   if (vam->async_mode)
2274     {
2275       vam->async_errors += (retval < 0);
2276     }
2277   else
2278     {
2279       u32 proto = mp->protocol;
2280       print (vam->ofp, "Transport protocol: %U",
2281              format_lisp_transport_protocol, proto);
2282       vam->retval = retval;
2283       vam->result_ready = 1;
2284     }
2285 }
2286
2287 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2288   (vl_api_one_get_transport_protocol_reply_t * mp)
2289 {
2290   vat_main_t *vam = &vat_main;
2291   vat_json_node_t node;
2292   u8 *s;
2293
2294   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2295   vec_add1 (s, 0);
2296
2297   vat_json_init_object (&node);
2298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2299   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2300
2301   vec_free (s);
2302   vat_json_print (vam->ofp, &node);
2303   vat_json_free (&node);
2304
2305   vam->retval = ntohl (mp->retval);
2306   vam->result_ready = 1;
2307 }
2308
2309 static void vl_api_one_add_del_locator_set_reply_t_handler
2310   (vl_api_one_add_del_locator_set_reply_t * mp)
2311 {
2312   vat_main_t *vam = &vat_main;
2313   i32 retval = ntohl (mp->retval);
2314   if (vam->async_mode)
2315     {
2316       vam->async_errors += (retval < 0);
2317     }
2318   else
2319     {
2320       vam->retval = retval;
2321       vam->result_ready = 1;
2322     }
2323 }
2324
2325 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2326   (vl_api_one_add_del_locator_set_reply_t * mp)
2327 {
2328   vat_main_t *vam = &vat_main;
2329   vat_json_node_t node;
2330
2331   vat_json_init_object (&node);
2332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2334
2335   vat_json_print (vam->ofp, &node);
2336   vat_json_free (&node);
2337
2338   vam->retval = ntohl (mp->retval);
2339   vam->result_ready = 1;
2340 }
2341
2342 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2343   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2344 {
2345   vat_main_t *vam = &vat_main;
2346   i32 retval = ntohl (mp->retval);
2347   if (vam->async_mode)
2348     {
2349       vam->async_errors += (retval < 0);
2350     }
2351   else
2352     {
2353       vam->retval = retval;
2354       vam->sw_if_index = ntohl (mp->sw_if_index);
2355       vam->result_ready = 1;
2356     }
2357   vam->regenerate_interface_table = 1;
2358 }
2359
2360 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2361   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   vat_json_node_t node;
2365
2366   vat_json_init_object (&node);
2367   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2368   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2369
2370   vat_json_print (vam->ofp, &node);
2371   vat_json_free (&node);
2372
2373   vam->retval = ntohl (mp->retval);
2374   vam->result_ready = 1;
2375 }
2376
2377 static void vl_api_vxlan_offload_rx_reply_t_handler
2378   (vl_api_vxlan_offload_rx_reply_t * mp)
2379 {
2380   vat_main_t *vam = &vat_main;
2381   i32 retval = ntohl (mp->retval);
2382   if (vam->async_mode)
2383     {
2384       vam->async_errors += (retval < 0);
2385     }
2386   else
2387     {
2388       vam->retval = retval;
2389       vam->result_ready = 1;
2390     }
2391 }
2392
2393 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2394   (vl_api_vxlan_offload_rx_reply_t * mp)
2395 {
2396   vat_main_t *vam = &vat_main;
2397   vat_json_node_t node;
2398
2399   vat_json_init_object (&node);
2400   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2401
2402   vat_json_print (vam->ofp, &node);
2403   vat_json_free (&node);
2404
2405   vam->retval = ntohl (mp->retval);
2406   vam->result_ready = 1;
2407 }
2408
2409 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2410   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2411 {
2412   vat_main_t *vam = &vat_main;
2413   i32 retval = ntohl (mp->retval);
2414   if (vam->async_mode)
2415     {
2416       vam->async_errors += (retval < 0);
2417     }
2418   else
2419     {
2420       vam->retval = retval;
2421       vam->sw_if_index = ntohl (mp->sw_if_index);
2422       vam->result_ready = 1;
2423     }
2424 }
2425
2426 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2427   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   vat_json_node_t node;
2431
2432   vat_json_init_object (&node);
2433   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2434   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_vxlan_gpe_add_del_tunnel_reply_t_handler
2444   (vl_api_vxlan_gpe_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   vam->regenerate_interface_table = 1;
2459 }
2460
2461 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2462   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2463 {
2464   vat_main_t *vam = &vat_main;
2465   vat_json_node_t node;
2466
2467   vat_json_init_object (&node);
2468   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2469   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2470
2471   vat_json_print (vam->ofp, &node);
2472   vat_json_free (&node);
2473
2474   vam->retval = ntohl (mp->retval);
2475   vam->result_ready = 1;
2476 }
2477
2478 static void vl_api_gre_tunnel_add_del_reply_t_handler
2479   (vl_api_gre_tunnel_add_del_reply_t * mp)
2480 {
2481   vat_main_t *vam = &vat_main;
2482   i32 retval = ntohl (mp->retval);
2483   if (vam->async_mode)
2484     {
2485       vam->async_errors += (retval < 0);
2486     }
2487   else
2488     {
2489       vam->retval = retval;
2490       vam->sw_if_index = ntohl (mp->sw_if_index);
2491       vam->result_ready = 1;
2492     }
2493 }
2494
2495 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2496   (vl_api_gre_tunnel_add_del_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_create_vhost_user_if_reply_t_handler
2513   (vl_api_create_vhost_user_if_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   vam->regenerate_interface_table = 1;
2528 }
2529
2530 static void vl_api_create_vhost_user_if_reply_t_handler_json
2531   (vl_api_create_vhost_user_if_reply_t * mp)
2532 {
2533   vat_main_t *vam = &vat_main;
2534   vat_json_node_t node;
2535
2536   vat_json_init_object (&node);
2537   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2538   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2539
2540   vat_json_print (vam->ofp, &node);
2541   vat_json_free (&node);
2542
2543   vam->retval = ntohl (mp->retval);
2544   vam->result_ready = 1;
2545 }
2546
2547 static void vl_api_ip_address_details_t_handler
2548   (vl_api_ip_address_details_t * mp)
2549 {
2550   vat_main_t *vam = &vat_main;
2551   static ip_address_details_t empty_ip_address_details = { {0} };
2552   ip_address_details_t *address = NULL;
2553   ip_details_t *current_ip_details = NULL;
2554   ip_details_t *details = NULL;
2555
2556   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2557
2558   if (!details || vam->current_sw_if_index >= vec_len (details)
2559       || !details[vam->current_sw_if_index].present)
2560     {
2561       errmsg ("ip address details arrived but not stored");
2562       errmsg ("ip_dump should be called first");
2563       return;
2564     }
2565
2566   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2567
2568 #define addresses (current_ip_details->addr)
2569
2570   vec_validate_init_empty (addresses, vec_len (addresses),
2571                            empty_ip_address_details);
2572
2573   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2574
2575   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2576   address->prefix_length = mp->prefix.len;
2577 #undef addresses
2578 }
2579
2580 static void vl_api_ip_address_details_t_handler_json
2581   (vl_api_ip_address_details_t * mp)
2582 {
2583   vat_main_t *vam = &vat_main;
2584   vat_json_node_t *node = NULL;
2585
2586   if (VAT_JSON_ARRAY != vam->json_tree.type)
2587     {
2588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2589       vat_json_init_array (&vam->json_tree);
2590     }
2591   node = vat_json_array_add (&vam->json_tree);
2592
2593   vat_json_init_object (node);
2594   vat_json_object_add_prefix (node, &mp->prefix);
2595 }
2596
2597 static void
2598 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2599 {
2600   vat_main_t *vam = &vat_main;
2601   static ip_details_t empty_ip_details = { 0 };
2602   ip_details_t *ip = NULL;
2603   u32 sw_if_index = ~0;
2604
2605   sw_if_index = ntohl (mp->sw_if_index);
2606
2607   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2608                            sw_if_index, empty_ip_details);
2609
2610   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2611                          sw_if_index);
2612
2613   ip->present = 1;
2614 }
2615
2616 static void
2617 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620
2621   if (VAT_JSON_ARRAY != vam->json_tree.type)
2622     {
2623       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2624       vat_json_init_array (&vam->json_tree);
2625     }
2626   vat_json_array_add_uint (&vam->json_tree,
2627                            clib_net_to_host_u32 (mp->sw_if_index));
2628 }
2629
2630 static void
2631 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2632 {
2633   u8 *s, i;
2634
2635   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2636               "host_mac %U router_addr %U",
2637               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2638               mp->lease.hostname,
2639               format_ip4_address, mp->lease.host_address,
2640               format_ethernet_address, mp->lease.host_mac,
2641               format_ip4_address, mp->lease.router_address);
2642
2643   for (i = 0; i < mp->lease.count; i++)
2644     s =
2645       format (s, " domain_server_addr %U", format_ip4_address,
2646               mp->lease.domain_server[i].address);
2647
2648   errmsg ((char *) s);
2649   vec_free (s);
2650 }
2651
2652 static void vl_api_dhcp_compl_event_t_handler_json
2653   (vl_api_dhcp_compl_event_t * mp)
2654 {
2655   /* JSON output not supported */
2656 }
2657
2658 static void vl_api_get_first_msg_id_reply_t_handler
2659   (vl_api_get_first_msg_id_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   i32 retval = ntohl (mp->retval);
2663
2664   if (vam->async_mode)
2665     {
2666       vam->async_errors += (retval < 0);
2667     }
2668   else
2669     {
2670       vam->retval = retval;
2671       vam->result_ready = 1;
2672     }
2673   if (retval >= 0)
2674     {
2675       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2676     }
2677 }
2678
2679 static void vl_api_get_first_msg_id_reply_t_handler_json
2680   (vl_api_get_first_msg_id_reply_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   vat_json_node_t node;
2684
2685   vat_json_init_object (&node);
2686   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2687   vat_json_object_add_uint (&node, "first_msg_id",
2688                             (uint) ntohs (mp->first_msg_id));
2689
2690   vat_json_print (vam->ofp, &node);
2691   vat_json_free (&node);
2692
2693   vam->retval = ntohl (mp->retval);
2694   vam->result_ready = 1;
2695 }
2696
2697 static void vl_api_get_node_graph_reply_t_handler
2698   (vl_api_get_node_graph_reply_t * mp)
2699 {
2700   vat_main_t *vam = &vat_main;
2701   api_main_t *am = &api_main;
2702   i32 retval = ntohl (mp->retval);
2703   u8 *pvt_copy, *reply;
2704   void *oldheap;
2705   vlib_node_t *node;
2706   int i;
2707
2708   if (vam->async_mode)
2709     {
2710       vam->async_errors += (retval < 0);
2711     }
2712   else
2713     {
2714       vam->retval = retval;
2715       vam->result_ready = 1;
2716     }
2717
2718   /* "Should never happen..." */
2719   if (retval != 0)
2720     return;
2721
2722   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2723   pvt_copy = vec_dup (reply);
2724
2725   /* Toss the shared-memory original... */
2726   pthread_mutex_lock (&am->vlib_rp->mutex);
2727   oldheap = svm_push_data_heap (am->vlib_rp);
2728
2729   vec_free (reply);
2730
2731   svm_pop_heap (oldheap);
2732   pthread_mutex_unlock (&am->vlib_rp->mutex);
2733
2734   if (vam->graph_nodes)
2735     {
2736       hash_free (vam->graph_node_index_by_name);
2737
2738       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2739         {
2740           node = vam->graph_nodes[0][i];
2741           vec_free (node->name);
2742           vec_free (node->next_nodes);
2743           vec_free (node);
2744         }
2745       vec_free (vam->graph_nodes[0]);
2746       vec_free (vam->graph_nodes);
2747     }
2748
2749   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2750   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2751   vec_free (pvt_copy);
2752
2753   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2754     {
2755       node = vam->graph_nodes[0][i];
2756       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2757     }
2758 }
2759
2760 static void vl_api_get_node_graph_reply_t_handler_json
2761   (vl_api_get_node_graph_reply_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   api_main_t *am = &api_main;
2765   void *oldheap;
2766   vat_json_node_t node;
2767   u8 *reply;
2768
2769   /* $$$$ make this real? */
2770   vat_json_init_object (&node);
2771   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2772   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2773
2774   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2775
2776   /* Toss the shared-memory original... */
2777   pthread_mutex_lock (&am->vlib_rp->mutex);
2778   oldheap = svm_push_data_heap (am->vlib_rp);
2779
2780   vec_free (reply);
2781
2782   svm_pop_heap (oldheap);
2783   pthread_mutex_unlock (&am->vlib_rp->mutex);
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                   mp->is_ipv6 ? format_ip6_address :
2807                   format_ip4_address,
2808                   mp->ip_address, mp->priority, mp->weight);
2809     }
2810
2811   print (vam->ofp, "%v", s);
2812   vec_free (s);
2813 }
2814
2815 static void
2816 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t *node = NULL;
2820   struct in6_addr ip6;
2821   struct in_addr ip4;
2822
2823   if (VAT_JSON_ARRAY != vam->json_tree.type)
2824     {
2825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2826       vat_json_init_array (&vam->json_tree);
2827     }
2828   node = vat_json_array_add (&vam->json_tree);
2829   vat_json_init_object (node);
2830
2831   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2832   vat_json_object_add_uint (node, "priority", mp->priority);
2833   vat_json_object_add_uint (node, "weight", mp->weight);
2834
2835   if (mp->local)
2836     vat_json_object_add_uint (node, "sw_if_index",
2837                               clib_net_to_host_u32 (mp->sw_if_index));
2838   else
2839     {
2840       if (mp->is_ipv6)
2841         {
2842           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2843           vat_json_object_add_ip6 (node, "address", ip6);
2844         }
2845       else
2846         {
2847           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2848           vat_json_object_add_ip4 (node, "address", ip4);
2849         }
2850     }
2851 }
2852
2853 static void
2854 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2855                                           mp)
2856 {
2857   vat_main_t *vam = &vat_main;
2858   u8 *ls_name = 0;
2859
2860   ls_name = format (0, "%s", mp->ls_name);
2861
2862   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2863          ls_name);
2864   vec_free (ls_name);
2865 }
2866
2867 static void
2868   vl_api_one_locator_set_details_t_handler_json
2869   (vl_api_one_locator_set_details_t * mp)
2870 {
2871   vat_main_t *vam = &vat_main;
2872   vat_json_node_t *node = 0;
2873   u8 *ls_name = 0;
2874
2875   ls_name = format (0, "%s", mp->ls_name);
2876   vec_add1 (ls_name, 0);
2877
2878   if (VAT_JSON_ARRAY != vam->json_tree.type)
2879     {
2880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2881       vat_json_init_array (&vam->json_tree);
2882     }
2883   node = vat_json_array_add (&vam->json_tree);
2884
2885   vat_json_init_object (node);
2886   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2887   vat_json_object_add_uint (node, "ls_index",
2888                             clib_net_to_host_u32 (mp->ls_index));
2889   vec_free (ls_name);
2890 }
2891
2892 typedef struct
2893 {
2894   u32 spi;
2895   u8 si;
2896 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2897
2898 uword
2899 unformat_nsh_address (unformat_input_t * input, va_list * args)
2900 {
2901   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2902   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2903 }
2904
2905 u8 *
2906 format_nsh_address_vat (u8 * s, va_list * args)
2907 {
2908   nsh_t *a = va_arg (*args, nsh_t *);
2909   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2910 }
2911
2912 static u8 *
2913 format_lisp_flat_eid (u8 * s, va_list * args)
2914 {
2915   u32 type = va_arg (*args, u32);
2916   u8 *eid = va_arg (*args, u8 *);
2917   u32 eid_len = va_arg (*args, u32);
2918
2919   switch (type)
2920     {
2921     case 0:
2922       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2923     case 1:
2924       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2925     case 2:
2926       return format (s, "%U", format_ethernet_address, eid);
2927     case 3:
2928       return format (s, "%U", format_nsh_address_vat, eid);
2929     }
2930   return 0;
2931 }
2932
2933 static u8 *
2934 format_lisp_eid_vat (u8 * s, va_list * args)
2935 {
2936   u32 type = va_arg (*args, u32);
2937   u8 *eid = va_arg (*args, u8 *);
2938   u32 eid_len = va_arg (*args, u32);
2939   u8 *seid = va_arg (*args, u8 *);
2940   u32 seid_len = va_arg (*args, u32);
2941   u32 is_src_dst = va_arg (*args, u32);
2942
2943   if (is_src_dst)
2944     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2945
2946   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2947
2948   return s;
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2953 {
2954   vat_main_t *vam = &vat_main;
2955   u8 *s = 0, *eid = 0;
2956
2957   if (~0 == mp->locator_set_index)
2958     s = format (0, "action: %d", mp->action);
2959   else
2960     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2961
2962   eid = format (0, "%U", format_lisp_eid_vat,
2963                 mp->eid_type,
2964                 mp->eid,
2965                 mp->eid_prefix_len,
2966                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2967   vec_add1 (eid, 0);
2968
2969   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2970          clib_net_to_host_u32 (mp->vni),
2971          eid,
2972          mp->is_local ? "local" : "remote",
2973          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2974          clib_net_to_host_u16 (mp->key_id), mp->key);
2975
2976   vec_free (s);
2977   vec_free (eid);
2978 }
2979
2980 static void
2981 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2982                                              * mp)
2983 {
2984   vat_main_t *vam = &vat_main;
2985   vat_json_node_t *node = 0;
2986   u8 *eid = 0;
2987
2988   if (VAT_JSON_ARRAY != vam->json_tree.type)
2989     {
2990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2991       vat_json_init_array (&vam->json_tree);
2992     }
2993   node = vat_json_array_add (&vam->json_tree);
2994
2995   vat_json_init_object (node);
2996   if (~0 == mp->locator_set_index)
2997     vat_json_object_add_uint (node, "action", mp->action);
2998   else
2999     vat_json_object_add_uint (node, "locator_set_index",
3000                               clib_net_to_host_u32 (mp->locator_set_index));
3001
3002   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3003   if (mp->eid_type == 3)
3004     {
3005       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3006       vat_json_init_object (nsh_json);
3007       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3008       vat_json_object_add_uint (nsh_json, "spi",
3009                                 clib_net_to_host_u32 (nsh->spi));
3010       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3011     }
3012   else
3013     {
3014       eid = format (0, "%U", format_lisp_eid_vat,
3015                     mp->eid_type,
3016                     mp->eid,
3017                     mp->eid_prefix_len,
3018                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3019       vec_add1 (eid, 0);
3020       vat_json_object_add_string_copy (node, "eid", eid);
3021       vec_free (eid);
3022     }
3023   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3024   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3025   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3026
3027   if (mp->key_id)
3028     {
3029       vat_json_object_add_uint (node, "key_id",
3030                                 clib_net_to_host_u16 (mp->key_id));
3031       vat_json_object_add_string_copy (node, "key", mp->key);
3032     }
3033 }
3034
3035 static void
3036 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3037 {
3038   vat_main_t *vam = &vat_main;
3039   u8 *seid = 0, *deid = 0;
3040   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3041
3042   deid = format (0, "%U", format_lisp_eid_vat,
3043                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3044
3045   seid = format (0, "%U", format_lisp_eid_vat,
3046                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3047
3048   vec_add1 (deid, 0);
3049   vec_add1 (seid, 0);
3050
3051   if (mp->is_ip4)
3052     format_ip_address_fcn = format_ip4_address;
3053   else
3054     format_ip_address_fcn = format_ip6_address;
3055
3056
3057   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3058          clib_net_to_host_u32 (mp->vni),
3059          seid, deid,
3060          format_ip_address_fcn, mp->lloc,
3061          format_ip_address_fcn, mp->rloc,
3062          clib_net_to_host_u32 (mp->pkt_count),
3063          clib_net_to_host_u32 (mp->bytes));
3064
3065   vec_free (deid);
3066   vec_free (seid);
3067 }
3068
3069 static void
3070 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3071 {
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074   vat_main_t *vam = &vat_main;
3075   vat_json_node_t *node = 0;
3076   u8 *deid = 0, *seid = 0;
3077
3078   if (VAT_JSON_ARRAY != vam->json_tree.type)
3079     {
3080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3081       vat_json_init_array (&vam->json_tree);
3082     }
3083   node = vat_json_array_add (&vam->json_tree);
3084
3085   vat_json_init_object (node);
3086   deid = format (0, "%U", format_lisp_eid_vat,
3087                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3088
3089   seid = format (0, "%U", format_lisp_eid_vat,
3090                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3091
3092   vec_add1 (deid, 0);
3093   vec_add1 (seid, 0);
3094
3095   vat_json_object_add_string_copy (node, "seid", seid);
3096   vat_json_object_add_string_copy (node, "deid", deid);
3097   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3098
3099   if (mp->is_ip4)
3100     {
3101       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3102       vat_json_object_add_ip4 (node, "lloc", ip4);
3103       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3104       vat_json_object_add_ip4 (node, "rloc", ip4);
3105     }
3106   else
3107     {
3108       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3109       vat_json_object_add_ip6 (node, "lloc", ip6);
3110       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3111       vat_json_object_add_ip6 (node, "rloc", ip6);
3112     }
3113   vat_json_object_add_uint (node, "pkt_count",
3114                             clib_net_to_host_u32 (mp->pkt_count));
3115   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3116
3117   vec_free (deid);
3118   vec_free (seid);
3119 }
3120
3121 static void
3122   vl_api_one_eid_table_map_details_t_handler
3123   (vl_api_one_eid_table_map_details_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126
3127   u8 *line = format (0, "%=10d%=10d",
3128                      clib_net_to_host_u32 (mp->vni),
3129                      clib_net_to_host_u32 (mp->dp_table));
3130   print (vam->ofp, "%v", line);
3131   vec_free (line);
3132 }
3133
3134 static void
3135   vl_api_one_eid_table_map_details_t_handler_json
3136   (vl_api_one_eid_table_map_details_t * mp)
3137 {
3138   vat_main_t *vam = &vat_main;
3139   vat_json_node_t *node = NULL;
3140
3141   if (VAT_JSON_ARRAY != vam->json_tree.type)
3142     {
3143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3144       vat_json_init_array (&vam->json_tree);
3145     }
3146   node = vat_json_array_add (&vam->json_tree);
3147   vat_json_init_object (node);
3148   vat_json_object_add_uint (node, "dp_table",
3149                             clib_net_to_host_u32 (mp->dp_table));
3150   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3151 }
3152
3153 static void
3154   vl_api_one_eid_table_vni_details_t_handler
3155   (vl_api_one_eid_table_vni_details_t * mp)
3156 {
3157   vat_main_t *vam = &vat_main;
3158
3159   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3160   print (vam->ofp, "%v", line);
3161   vec_free (line);
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_vni_details_t_handler_json
3166   (vl_api_one_eid_table_vni_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169   vat_json_node_t *node = NULL;
3170
3171   if (VAT_JSON_ARRAY != vam->json_tree.type)
3172     {
3173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3174       vat_json_init_array (&vam->json_tree);
3175     }
3176   node = vat_json_array_add (&vam->json_tree);
3177   vat_json_init_object (node);
3178   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3179 }
3180
3181 static void
3182   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3183   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   int retval = clib_net_to_host_u32 (mp->retval);
3187
3188   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3189   print (vam->ofp, "fallback threshold value: %d", mp->value);
3190
3191   vam->retval = retval;
3192   vam->result_ready = 1;
3193 }
3194
3195 static void
3196   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3197   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   vat_json_node_t _node, *node = &_node;
3201   int retval = clib_net_to_host_u32 (mp->retval);
3202
3203   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3204   vat_json_init_object (node);
3205   vat_json_object_add_uint (node, "value", mp->value);
3206
3207   vat_json_print (vam->ofp, node);
3208   vat_json_free (node);
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_register_state_reply_t_handler
3216   (vl_api_show_one_map_register_state_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   int retval = clib_net_to_host_u32 (mp->retval);
3220
3221   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3222
3223   vam->retval = retval;
3224   vam->result_ready = 1;
3225 }
3226
3227 static void
3228   vl_api_show_one_map_register_state_reply_t_handler_json
3229   (vl_api_show_one_map_register_state_reply_t * mp)
3230 {
3231   vat_main_t *vam = &vat_main;
3232   vat_json_node_t _node, *node = &_node;
3233   int retval = clib_net_to_host_u32 (mp->retval);
3234
3235   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3236
3237   vat_json_init_object (node);
3238   vat_json_object_add_string_copy (node, "state", s);
3239
3240   vat_json_print (vam->ofp, node);
3241   vat_json_free (node);
3242
3243   vam->retval = retval;
3244   vam->result_ready = 1;
3245   vec_free (s);
3246 }
3247
3248 static void
3249   vl_api_show_one_rloc_probe_state_reply_t_handler
3250   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   int retval = clib_net_to_host_u32 (mp->retval);
3254
3255   if (retval)
3256     goto end;
3257
3258   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3259 end:
3260   vam->retval = retval;
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3266   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   vat_json_node_t _node, *node = &_node;
3270   int retval = clib_net_to_host_u32 (mp->retval);
3271
3272   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3273   vat_json_init_object (node);
3274   vat_json_object_add_string_copy (node, "state", s);
3275
3276   vat_json_print (vam->ofp, node);
3277   vat_json_free (node);
3278
3279   vam->retval = retval;
3280   vam->result_ready = 1;
3281   vec_free (s);
3282 }
3283
3284 static void
3285   vl_api_show_one_stats_enable_disable_reply_t_handler
3286   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   int retval = clib_net_to_host_u32 (mp->retval);
3290
3291   if (retval)
3292     goto end;
3293
3294   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3295 end:
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3302   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3309   vat_json_init_object (node);
3310   vat_json_object_add_string_copy (node, "state", s);
3311
3312   vat_json_print (vam->ofp, node);
3313   vat_json_free (node);
3314
3315   vam->retval = retval;
3316   vam->result_ready = 1;
3317   vec_free (s);
3318 }
3319
3320 static void
3321 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3322 {
3323   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3324   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3325   e->vni = clib_net_to_host_u32 (e->vni);
3326 }
3327
3328 static void
3329   gpe_fwd_entries_get_reply_t_net_to_host
3330   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3331 {
3332   u32 i;
3333
3334   mp->count = clib_net_to_host_u32 (mp->count);
3335   for (i = 0; i < mp->count; i++)
3336     {
3337       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3338     }
3339 }
3340
3341 static u8 *
3342 format_gpe_encap_mode (u8 * s, va_list * args)
3343 {
3344   u32 mode = va_arg (*args, u32);
3345
3346   switch (mode)
3347     {
3348     case 0:
3349       return format (s, "lisp");
3350     case 1:
3351       return format (s, "vxlan");
3352     }
3353   return 0;
3354 }
3355
3356 static void
3357   vl_api_gpe_get_encap_mode_reply_t_handler
3358   (vl_api_gpe_get_encap_mode_reply_t * mp)
3359 {
3360   vat_main_t *vam = &vat_main;
3361
3362   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3363   vam->retval = ntohl (mp->retval);
3364   vam->result_ready = 1;
3365 }
3366
3367 static void
3368   vl_api_gpe_get_encap_mode_reply_t_handler_json
3369   (vl_api_gpe_get_encap_mode_reply_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372   vat_json_node_t node;
3373
3374   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3375   vec_add1 (encap_mode, 0);
3376
3377   vat_json_init_object (&node);
3378   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3379
3380   vec_free (encap_mode);
3381   vat_json_print (vam->ofp, &node);
3382   vat_json_free (&node);
3383
3384   vam->retval = ntohl (mp->retval);
3385   vam->result_ready = 1;
3386 }
3387
3388 static void
3389   vl_api_gpe_fwd_entry_path_details_t_handler
3390   (vl_api_gpe_fwd_entry_path_details_t * mp)
3391 {
3392   vat_main_t *vam = &vat_main;
3393   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3394
3395   if (mp->lcl_loc.is_ip4)
3396     format_ip_address_fcn = format_ip4_address;
3397   else
3398     format_ip_address_fcn = format_ip6_address;
3399
3400   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3401          format_ip_address_fcn, &mp->lcl_loc,
3402          format_ip_address_fcn, &mp->rmt_loc);
3403 }
3404
3405 static void
3406 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3407 {
3408   struct in6_addr ip6;
3409   struct in_addr ip4;
3410
3411   if (loc->is_ip4)
3412     {
3413       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3414       vat_json_object_add_ip4 (n, "address", ip4);
3415     }
3416   else
3417     {
3418       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3419       vat_json_object_add_ip6 (n, "address", ip6);
3420     }
3421   vat_json_object_add_uint (n, "weight", loc->weight);
3422 }
3423
3424 static void
3425   vl_api_gpe_fwd_entry_path_details_t_handler_json
3426   (vl_api_gpe_fwd_entry_path_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   vat_json_node_t *node = NULL;
3430   vat_json_node_t *loc_node;
3431
3432   if (VAT_JSON_ARRAY != vam->json_tree.type)
3433     {
3434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3435       vat_json_init_array (&vam->json_tree);
3436     }
3437   node = vat_json_array_add (&vam->json_tree);
3438   vat_json_init_object (node);
3439
3440   loc_node = vat_json_object_add (node, "local_locator");
3441   vat_json_init_object (loc_node);
3442   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3443
3444   loc_node = vat_json_object_add (node, "remote_locator");
3445   vat_json_init_object (loc_node);
3446   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3447 }
3448
3449 static void
3450   vl_api_gpe_fwd_entries_get_reply_t_handler
3451   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3452 {
3453   vat_main_t *vam = &vat_main;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *e;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462
3463   for (i = 0; i < mp->count; i++)
3464     {
3465       e = &mp->entries[i];
3466       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3467              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3468              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3469     }
3470
3471 end:
3472   vam->retval = retval;
3473   vam->result_ready = 1;
3474 }
3475
3476 static void
3477   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3478   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3479 {
3480   u8 *s = 0;
3481   vat_main_t *vam = &vat_main;
3482   vat_json_node_t *e = 0, root;
3483   u32 i;
3484   int retval = clib_net_to_host_u32 (mp->retval);
3485   vl_api_gpe_fwd_entry_t *fwd;
3486
3487   if (retval)
3488     goto end;
3489
3490   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3491   vat_json_init_array (&root);
3492
3493   for (i = 0; i < mp->count; i++)
3494     {
3495       e = vat_json_array_add (&root);
3496       fwd = &mp->entries[i];
3497
3498       vat_json_init_object (e);
3499       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3500       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3501       vat_json_object_add_int (e, "vni", fwd->vni);
3502       vat_json_object_add_int (e, "action", fwd->action);
3503
3504       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3505                   fwd->leid_prefix_len);
3506       vec_add1 (s, 0);
3507       vat_json_object_add_string_copy (e, "leid", s);
3508       vec_free (s);
3509
3510       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3511                   fwd->reid_prefix_len);
3512       vec_add1 (s, 0);
3513       vat_json_object_add_string_copy (e, "reid", s);
3514       vec_free (s);
3515     }
3516
3517   vat_json_print (vam->ofp, &root);
3518   vat_json_free (&root);
3519
3520 end:
3521   vam->retval = retval;
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3527   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533
3534   if (retval)
3535     goto end;
3536
3537   n = clib_net_to_host_u32 (mp->count);
3538
3539   for (i = 0; i < n; i++)
3540     {
3541       r = &mp->entries[i];
3542       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3543              clib_net_to_host_u32 (r->fib_index),
3544              clib_net_to_host_u32 (r->nh_sw_if_index),
3545              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3546     }
3547
3548 end:
3549   vam->retval = retval;
3550   vam->result_ready = 1;
3551 }
3552
3553 static void
3554   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3555   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3556 {
3557   vat_main_t *vam = &vat_main;
3558   vat_json_node_t root, *e;
3559   u32 i, n;
3560   int retval = clib_net_to_host_u32 (mp->retval);
3561   vl_api_gpe_native_fwd_rpath_t *r;
3562   u8 *s;
3563
3564   if (retval)
3565     goto end;
3566
3567   n = clib_net_to_host_u32 (mp->count);
3568   vat_json_init_array (&root);
3569
3570   for (i = 0; i < n; i++)
3571     {
3572       e = vat_json_array_add (&root);
3573       vat_json_init_object (e);
3574       r = &mp->entries[i];
3575       s =
3576         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3577                 r->nh_addr);
3578       vec_add1 (s, 0);
3579       vat_json_object_add_string_copy (e, "ip4", s);
3580       vec_free (s);
3581
3582       vat_json_object_add_uint (e, "fib_index",
3583                                 clib_net_to_host_u32 (r->fib_index));
3584       vat_json_object_add_uint (e, "nh_sw_if_index",
3585                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3586     }
3587
3588   vat_json_print (vam->ofp, &root);
3589   vat_json_free (&root);
3590
3591 end:
3592   vam->retval = retval;
3593   vam->result_ready = 1;
3594 }
3595
3596 static void
3597   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3598   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3599 {
3600   vat_main_t *vam = &vat_main;
3601   u32 i, n;
3602   int retval = clib_net_to_host_u32 (mp->retval);
3603
3604   if (retval)
3605     goto end;
3606
3607   n = clib_net_to_host_u32 (mp->count);
3608
3609   for (i = 0; i < n; i++)
3610     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3611
3612 end:
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3619   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   vat_json_node_t root;
3623   u32 i, n;
3624   int retval = clib_net_to_host_u32 (mp->retval);
3625
3626   if (retval)
3627     goto end;
3628
3629   n = clib_net_to_host_u32 (mp->count);
3630   vat_json_init_array (&root);
3631
3632   for (i = 0; i < n; i++)
3633     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3634
3635   vat_json_print (vam->ofp, &root);
3636   vat_json_free (&root);
3637
3638 end:
3639   vam->retval = retval;
3640   vam->result_ready = 1;
3641 }
3642
3643 static void
3644   vl_api_one_ndp_entries_get_reply_t_handler
3645   (vl_api_one_ndp_entries_get_reply_t * mp)
3646 {
3647   vat_main_t *vam = &vat_main;
3648   u32 i, n;
3649   int retval = clib_net_to_host_u32 (mp->retval);
3650
3651   if (retval)
3652     goto end;
3653
3654   n = clib_net_to_host_u32 (mp->count);
3655
3656   for (i = 0; i < n; i++)
3657     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3658            format_ethernet_address, mp->entries[i].mac);
3659
3660 end:
3661   vam->retval = retval;
3662   vam->result_ready = 1;
3663 }
3664
3665 static void
3666   vl_api_one_ndp_entries_get_reply_t_handler_json
3667   (vl_api_one_ndp_entries_get_reply_t * mp)
3668 {
3669   u8 *s = 0;
3670   vat_main_t *vam = &vat_main;
3671   vat_json_node_t *e = 0, root;
3672   u32 i, n;
3673   int retval = clib_net_to_host_u32 (mp->retval);
3674   vl_api_one_ndp_entry_t *arp_entry;
3675
3676   if (retval)
3677     goto end;
3678
3679   n = clib_net_to_host_u32 (mp->count);
3680   vat_json_init_array (&root);
3681
3682   for (i = 0; i < n; i++)
3683     {
3684       e = vat_json_array_add (&root);
3685       arp_entry = &mp->entries[i];
3686
3687       vat_json_init_object (e);
3688       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3689       vec_add1 (s, 0);
3690
3691       vat_json_object_add_string_copy (e, "mac", s);
3692       vec_free (s);
3693
3694       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3695       vec_add1 (s, 0);
3696       vat_json_object_add_string_copy (e, "ip6", s);
3697       vec_free (s);
3698     }
3699
3700   vat_json_print (vam->ofp, &root);
3701   vat_json_free (&root);
3702
3703 end:
3704   vam->retval = retval;
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_l2_arp_entries_get_reply_t_handler
3710   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715
3716   if (retval)
3717     goto end;
3718
3719   n = clib_net_to_host_u32 (mp->count);
3720
3721   for (i = 0; i < n; i++)
3722     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3723            format_ethernet_address, mp->entries[i].mac);
3724
3725 end:
3726   vam->retval = retval;
3727   vam->result_ready = 1;
3728 }
3729
3730 static void
3731   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3732   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3733 {
3734   u8 *s = 0;
3735   vat_main_t *vam = &vat_main;
3736   vat_json_node_t *e = 0, root;
3737   u32 i, n;
3738   int retval = clib_net_to_host_u32 (mp->retval);
3739   vl_api_one_l2_arp_entry_t *arp_entry;
3740
3741   if (retval)
3742     goto end;
3743
3744   n = clib_net_to_host_u32 (mp->count);
3745   vat_json_init_array (&root);
3746
3747   for (i = 0; i < n; i++)
3748     {
3749       e = vat_json_array_add (&root);
3750       arp_entry = &mp->entries[i];
3751
3752       vat_json_init_object (e);
3753       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3754       vec_add1 (s, 0);
3755
3756       vat_json_object_add_string_copy (e, "mac", s);
3757       vec_free (s);
3758
3759       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3760       vec_add1 (s, 0);
3761       vat_json_object_add_string_copy (e, "ip4", s);
3762       vec_free (s);
3763     }
3764
3765   vat_json_print (vam->ofp, &root);
3766   vat_json_free (&root);
3767
3768 end:
3769   vam->retval = retval;
3770   vam->result_ready = 1;
3771 }
3772
3773 static void
3774 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777   u32 i, n;
3778   int retval = clib_net_to_host_u32 (mp->retval);
3779
3780   if (retval)
3781     goto end;
3782
3783   n = clib_net_to_host_u32 (mp->count);
3784
3785   for (i = 0; i < n; i++)
3786     {
3787       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3788     }
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_ndp_bd_get_reply_t_handler_json
3797   (vl_api_one_ndp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   vat_json_node_t root;
3801   u32 i, n;
3802   int retval = clib_net_to_host_u32 (mp->retval);
3803
3804   if (retval)
3805     goto end;
3806
3807   n = clib_net_to_host_u32 (mp->count);
3808   vat_json_init_array (&root);
3809
3810   for (i = 0; i < n; i++)
3811     {
3812       vat_json_array_add_uint (&root,
3813                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3814     }
3815
3816   vat_json_print (vam->ofp, &root);
3817   vat_json_free (&root);
3818
3819 end:
3820   vam->retval = retval;
3821   vam->result_ready = 1;
3822 }
3823
3824 static void
3825   vl_api_one_l2_arp_bd_get_reply_t_handler
3826   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3827 {
3828   vat_main_t *vam = &vat_main;
3829   u32 i, n;
3830   int retval = clib_net_to_host_u32 (mp->retval);
3831
3832   if (retval)
3833     goto end;
3834
3835   n = clib_net_to_host_u32 (mp->count);
3836
3837   for (i = 0; i < n; i++)
3838     {
3839       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3840     }
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3849   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   vat_json_node_t root;
3853   u32 i, n;
3854   int retval = clib_net_to_host_u32 (mp->retval);
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860   vat_json_init_array (&root);
3861
3862   for (i = 0; i < n; i++)
3863     {
3864       vat_json_array_add_uint (&root,
3865                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3866     }
3867
3868   vat_json_print (vam->ofp, &root);
3869   vat_json_free (&root);
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_one_adjacencies_get_reply_t_handler
3878   (vl_api_one_adjacencies_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889
3890   for (i = 0; i < n; i++)
3891     {
3892       a = &mp->adjacencies[i];
3893       print (vam->ofp, "%U %40U",
3894              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3895              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3896     }
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_one_adjacencies_get_reply_t_handler_json
3905   (vl_api_one_adjacencies_get_reply_t * mp)
3906 {
3907   u8 *s = 0;
3908   vat_main_t *vam = &vat_main;
3909   vat_json_node_t *e = 0, root;
3910   u32 i, n;
3911   int retval = clib_net_to_host_u32 (mp->retval);
3912   vl_api_one_adjacency_t *a;
3913
3914   if (retval)
3915     goto end;
3916
3917   n = clib_net_to_host_u32 (mp->count);
3918   vat_json_init_array (&root);
3919
3920   for (i = 0; i < n; i++)
3921     {
3922       e = vat_json_array_add (&root);
3923       a = &mp->adjacencies[i];
3924
3925       vat_json_init_object (e);
3926       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3927                   a->leid_prefix_len);
3928       vec_add1 (s, 0);
3929       vat_json_object_add_string_copy (e, "leid", s);
3930       vec_free (s);
3931
3932       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3933                   a->reid_prefix_len);
3934       vec_add1 (s, 0);
3935       vat_json_object_add_string_copy (e, "reid", s);
3936       vec_free (s);
3937     }
3938
3939   vat_json_print (vam->ofp, &root);
3940   vat_json_free (&root);
3941
3942 end:
3943   vam->retval = retval;
3944   vam->result_ready = 1;
3945 }
3946
3947 static void
3948 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3949 {
3950   vat_main_t *vam = &vat_main;
3951
3952   print (vam->ofp, "%=20U",
3953          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3954          mp->ip_address);
3955 }
3956
3957 static void
3958   vl_api_one_map_server_details_t_handler_json
3959   (vl_api_one_map_server_details_t * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962   vat_json_node_t *node = NULL;
3963   struct in6_addr ip6;
3964   struct in_addr ip4;
3965
3966   if (VAT_JSON_ARRAY != vam->json_tree.type)
3967     {
3968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3969       vat_json_init_array (&vam->json_tree);
3970     }
3971   node = vat_json_array_add (&vam->json_tree);
3972
3973   vat_json_init_object (node);
3974   if (mp->is_ipv6)
3975     {
3976       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3977       vat_json_object_add_ip6 (node, "map-server", ip6);
3978     }
3979   else
3980     {
3981       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3982       vat_json_object_add_ip4 (node, "map-server", ip4);
3983     }
3984 }
3985
3986 static void
3987 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3988                                            * mp)
3989 {
3990   vat_main_t *vam = &vat_main;
3991
3992   print (vam->ofp, "%=20U",
3993          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3994          mp->ip_address);
3995 }
3996
3997 static void
3998   vl_api_one_map_resolver_details_t_handler_json
3999   (vl_api_one_map_resolver_details_t * mp)
4000 {
4001   vat_main_t *vam = &vat_main;
4002   vat_json_node_t *node = NULL;
4003   struct in6_addr ip6;
4004   struct in_addr ip4;
4005
4006   if (VAT_JSON_ARRAY != vam->json_tree.type)
4007     {
4008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4009       vat_json_init_array (&vam->json_tree);
4010     }
4011   node = vat_json_array_add (&vam->json_tree);
4012
4013   vat_json_init_object (node);
4014   if (mp->is_ipv6)
4015     {
4016       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4017       vat_json_object_add_ip6 (node, "map resolver", ip6);
4018     }
4019   else
4020     {
4021       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4022       vat_json_object_add_ip4 (node, "map resolver", ip4);
4023     }
4024 }
4025
4026 static void
4027 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4028 {
4029   vat_main_t *vam = &vat_main;
4030   i32 retval = ntohl (mp->retval);
4031
4032   if (0 <= retval)
4033     {
4034       print (vam->ofp, "feature: %s\ngpe: %s",
4035              mp->feature_status ? "enabled" : "disabled",
4036              mp->gpe_status ? "enabled" : "disabled");
4037     }
4038
4039   vam->retval = retval;
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_show_one_status_reply_t_handler_json
4045   (vl_api_show_one_status_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   vat_json_node_t node;
4049   u8 *gpe_status = NULL;
4050   u8 *feature_status = NULL;
4051
4052   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4053   feature_status = format (0, "%s",
4054                            mp->feature_status ? "enabled" : "disabled");
4055   vec_add1 (gpe_status, 0);
4056   vec_add1 (feature_status, 0);
4057
4058   vat_json_init_object (&node);
4059   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4060   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4061
4062   vec_free (gpe_status);
4063   vec_free (feature_status);
4064
4065   vat_json_print (vam->ofp, &node);
4066   vat_json_free (&node);
4067
4068   vam->retval = ntohl (mp->retval);
4069   vam->result_ready = 1;
4070 }
4071
4072 static void
4073   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4074   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4075 {
4076   vat_main_t *vam = &vat_main;
4077   i32 retval = ntohl (mp->retval);
4078
4079   if (retval >= 0)
4080     {
4081       print (vam->ofp, "%=20s", mp->locator_set_name);
4082     }
4083
4084   vam->retval = retval;
4085   vam->result_ready = 1;
4086 }
4087
4088 static void
4089   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4090   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   vat_json_node_t *node = NULL;
4094
4095   if (VAT_JSON_ARRAY != vam->json_tree.type)
4096     {
4097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4098       vat_json_init_array (&vam->json_tree);
4099     }
4100   node = vat_json_array_add (&vam->json_tree);
4101
4102   vat_json_init_object (node);
4103   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4104
4105   vat_json_print (vam->ofp, node);
4106   vat_json_free (node);
4107
4108   vam->retval = ntohl (mp->retval);
4109   vam->result_ready = 1;
4110 }
4111
4112 static u8 *
4113 format_lisp_map_request_mode (u8 * s, va_list * args)
4114 {
4115   u32 mode = va_arg (*args, u32);
4116
4117   switch (mode)
4118     {
4119     case 0:
4120       return format (0, "dst-only");
4121     case 1:
4122       return format (0, "src-dst");
4123     }
4124   return 0;
4125 }
4126
4127 static void
4128   vl_api_show_one_map_request_mode_reply_t_handler
4129   (vl_api_show_one_map_request_mode_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   i32 retval = ntohl (mp->retval);
4133
4134   if (0 <= retval)
4135     {
4136       u32 mode = mp->mode;
4137       print (vam->ofp, "map_request_mode: %U",
4138              format_lisp_map_request_mode, mode);
4139     }
4140
4141   vam->retval = retval;
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_show_one_map_request_mode_reply_t_handler_json
4147   (vl_api_show_one_map_request_mode_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   vat_json_node_t node;
4151   u8 *s = 0;
4152   u32 mode;
4153
4154   mode = mp->mode;
4155   s = format (0, "%U", format_lisp_map_request_mode, mode);
4156   vec_add1 (s, 0);
4157
4158   vat_json_init_object (&node);
4159   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4160   vat_json_print (vam->ofp, &node);
4161   vat_json_free (&node);
4162
4163   vec_free (s);
4164   vam->retval = ntohl (mp->retval);
4165   vam->result_ready = 1;
4166 }
4167
4168 static void
4169   vl_api_one_show_xtr_mode_reply_t_handler
4170   (vl_api_one_show_xtr_mode_reply_t * mp)
4171 {
4172   vat_main_t *vam = &vat_main;
4173   i32 retval = ntohl (mp->retval);
4174
4175   if (0 <= retval)
4176     {
4177       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4178     }
4179
4180   vam->retval = retval;
4181   vam->result_ready = 1;
4182 }
4183
4184 static void
4185   vl_api_one_show_xtr_mode_reply_t_handler_json
4186   (vl_api_one_show_xtr_mode_reply_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t node;
4190   u8 *status = 0;
4191
4192   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4193   vec_add1 (status, 0);
4194
4195   vat_json_init_object (&node);
4196   vat_json_object_add_string_copy (&node, "status", status);
4197
4198   vec_free (status);
4199
4200   vat_json_print (vam->ofp, &node);
4201   vat_json_free (&node);
4202
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208   vl_api_one_show_pitr_mode_reply_t_handler
4209   (vl_api_one_show_pitr_mode_reply_t * mp)
4210 {
4211   vat_main_t *vam = &vat_main;
4212   i32 retval = ntohl (mp->retval);
4213
4214   if (0 <= retval)
4215     {
4216       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4217     }
4218
4219   vam->retval = retval;
4220   vam->result_ready = 1;
4221 }
4222
4223 static void
4224   vl_api_one_show_pitr_mode_reply_t_handler_json
4225   (vl_api_one_show_pitr_mode_reply_t * mp)
4226 {
4227   vat_main_t *vam = &vat_main;
4228   vat_json_node_t node;
4229   u8 *status = 0;
4230
4231   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4232   vec_add1 (status, 0);
4233
4234   vat_json_init_object (&node);
4235   vat_json_object_add_string_copy (&node, "status", status);
4236
4237   vec_free (status);
4238
4239   vat_json_print (vam->ofp, &node);
4240   vat_json_free (&node);
4241
4242   vam->retval = ntohl (mp->retval);
4243   vam->result_ready = 1;
4244 }
4245
4246 static void
4247   vl_api_one_show_petr_mode_reply_t_handler
4248   (vl_api_one_show_petr_mode_reply_t * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251   i32 retval = ntohl (mp->retval);
4252
4253   if (0 <= retval)
4254     {
4255       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4256     }
4257
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_one_show_petr_mode_reply_t_handler_json
4264   (vl_api_one_show_petr_mode_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268   u8 *status = 0;
4269
4270   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4271   vec_add1 (status, 0);
4272
4273   vat_json_init_object (&node);
4274   vat_json_object_add_string_copy (&node, "status", status);
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_show_one_use_petr_reply_t_handler
4287   (vl_api_show_one_use_petr_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4295       if (mp->status)
4296         {
4297           print (vam->ofp, "Proxy-ETR address; %U",
4298                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4299                  mp->address);
4300         }
4301     }
4302
4303   vam->retval = retval;
4304   vam->result_ready = 1;
4305 }
4306
4307 static void
4308   vl_api_show_one_use_petr_reply_t_handler_json
4309   (vl_api_show_one_use_petr_reply_t * mp)
4310 {
4311   vat_main_t *vam = &vat_main;
4312   vat_json_node_t node;
4313   u8 *status = 0;
4314   struct in_addr ip4;
4315   struct in6_addr ip6;
4316
4317   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4318   vec_add1 (status, 0);
4319
4320   vat_json_init_object (&node);
4321   vat_json_object_add_string_copy (&node, "status", status);
4322   if (mp->status)
4323     {
4324       if (mp->is_ip4)
4325         {
4326           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4327           vat_json_object_add_ip6 (&node, "address", ip6);
4328         }
4329       else
4330         {
4331           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4332           vat_json_object_add_ip4 (&node, "address", ip4);
4333         }
4334     }
4335
4336   vec_free (status);
4337
4338   vat_json_print (vam->ofp, &node);
4339   vat_json_free (&node);
4340
4341   vam->retval = ntohl (mp->retval);
4342   vam->result_ready = 1;
4343 }
4344
4345 static void
4346   vl_api_show_one_nsh_mapping_reply_t_handler
4347   (vl_api_show_one_nsh_mapping_reply_t * mp)
4348 {
4349   vat_main_t *vam = &vat_main;
4350   i32 retval = ntohl (mp->retval);
4351
4352   if (0 <= retval)
4353     {
4354       print (vam->ofp, "%-20s%-16s",
4355              mp->is_set ? "set" : "not-set",
4356              mp->is_set ? (char *) mp->locator_set_name : "");
4357     }
4358
4359   vam->retval = retval;
4360   vam->result_ready = 1;
4361 }
4362
4363 static void
4364   vl_api_show_one_nsh_mapping_reply_t_handler_json
4365   (vl_api_show_one_nsh_mapping_reply_t * mp)
4366 {
4367   vat_main_t *vam = &vat_main;
4368   vat_json_node_t node;
4369   u8 *status = 0;
4370
4371   status = format (0, "%s", mp->is_set ? "yes" : "no");
4372   vec_add1 (status, 0);
4373
4374   vat_json_init_object (&node);
4375   vat_json_object_add_string_copy (&node, "is_set", status);
4376   if (mp->is_set)
4377     {
4378       vat_json_object_add_string_copy (&node, "locator_set",
4379                                        mp->locator_set_name);
4380     }
4381
4382   vec_free (status);
4383
4384   vat_json_print (vam->ofp, &node);
4385   vat_json_free (&node);
4386
4387   vam->retval = ntohl (mp->retval);
4388   vam->result_ready = 1;
4389 }
4390
4391 static void
4392   vl_api_show_one_map_register_ttl_reply_t_handler
4393   (vl_api_show_one_map_register_ttl_reply_t * mp)
4394 {
4395   vat_main_t *vam = &vat_main;
4396   i32 retval = ntohl (mp->retval);
4397
4398   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4399
4400   if (0 <= retval)
4401     {
4402       print (vam->ofp, "ttl: %u", mp->ttl);
4403     }
4404
4405   vam->retval = retval;
4406   vam->result_ready = 1;
4407 }
4408
4409 static void
4410   vl_api_show_one_map_register_ttl_reply_t_handler_json
4411   (vl_api_show_one_map_register_ttl_reply_t * mp)
4412 {
4413   vat_main_t *vam = &vat_main;
4414   vat_json_node_t node;
4415
4416   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4417   vat_json_init_object (&node);
4418   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4429 {
4430   vat_main_t *vam = &vat_main;
4431   i32 retval = ntohl (mp->retval);
4432
4433   if (0 <= retval)
4434     {
4435       print (vam->ofp, "%-20s%-16s",
4436              mp->status ? "enabled" : "disabled",
4437              mp->status ? (char *) mp->locator_set_name : "");
4438     }
4439
4440   vam->retval = retval;
4441   vam->result_ready = 1;
4442 }
4443
4444 static void
4445 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456   if (mp->status)
4457     {
4458       vat_json_object_add_string_copy (&node, "locator_set",
4459                                        mp->locator_set_name);
4460     }
4461
4462   vec_free (status);
4463
4464   vat_json_print (vam->ofp, &node);
4465   vat_json_free (&node);
4466
4467   vam->retval = ntohl (mp->retval);
4468   vam->result_ready = 1;
4469 }
4470
4471 static u8 *
4472 format_policer_type (u8 * s, va_list * va)
4473 {
4474   u32 i = va_arg (*va, u32);
4475
4476   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4477     s = format (s, "1r2c");
4478   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4479     s = format (s, "1r3c");
4480   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4481     s = format (s, "2r3c-2698");
4482   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4483     s = format (s, "2r3c-4115");
4484   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4485     s = format (s, "2r3c-mef5cf1");
4486   else
4487     s = format (s, "ILLEGAL");
4488   return s;
4489 }
4490
4491 static u8 *
4492 format_policer_rate_type (u8 * s, va_list * va)
4493 {
4494   u32 i = va_arg (*va, u32);
4495
4496   if (i == SSE2_QOS_RATE_KBPS)
4497     s = format (s, "kbps");
4498   else if (i == SSE2_QOS_RATE_PPS)
4499     s = format (s, "pps");
4500   else
4501     s = format (s, "ILLEGAL");
4502   return s;
4503 }
4504
4505 static u8 *
4506 format_policer_round_type (u8 * s, va_list * va)
4507 {
4508   u32 i = va_arg (*va, u32);
4509
4510   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4511     s = format (s, "closest");
4512   else if (i == SSE2_QOS_ROUND_TO_UP)
4513     s = format (s, "up");
4514   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4515     s = format (s, "down");
4516   else
4517     s = format (s, "ILLEGAL");
4518   return s;
4519 }
4520
4521 static u8 *
4522 format_policer_action_type (u8 * s, va_list * va)
4523 {
4524   u32 i = va_arg (*va, u32);
4525
4526   if (i == SSE2_QOS_ACTION_DROP)
4527     s = format (s, "drop");
4528   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4529     s = format (s, "transmit");
4530   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4531     s = format (s, "mark-and-transmit");
4532   else
4533     s = format (s, "ILLEGAL");
4534   return s;
4535 }
4536
4537 static u8 *
4538 format_dscp (u8 * s, va_list * va)
4539 {
4540   u32 i = va_arg (*va, u32);
4541   char *t = 0;
4542
4543   switch (i)
4544     {
4545 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4546       foreach_vnet_dscp
4547 #undef _
4548     default:
4549       return format (s, "ILLEGAL");
4550     }
4551   s = format (s, "%s", t);
4552   return s;
4553 }
4554
4555 static void
4556 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4557 {
4558   vat_main_t *vam = &vat_main;
4559   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4560
4561   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4562     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4563   else
4564     conform_dscp_str = format (0, "");
4565
4566   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4567     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4568   else
4569     exceed_dscp_str = format (0, "");
4570
4571   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4572     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4573   else
4574     violate_dscp_str = format (0, "");
4575
4576   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4577          "rate type %U, round type %U, %s rate, %s color-aware, "
4578          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4579          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4580          "conform action %U%s, exceed action %U%s, violate action %U%s",
4581          mp->name,
4582          format_policer_type, mp->type,
4583          ntohl (mp->cir),
4584          ntohl (mp->eir),
4585          clib_net_to_host_u64 (mp->cb),
4586          clib_net_to_host_u64 (mp->eb),
4587          format_policer_rate_type, mp->rate_type,
4588          format_policer_round_type, mp->round_type,
4589          mp->single_rate ? "single" : "dual",
4590          mp->color_aware ? "is" : "not",
4591          ntohl (mp->cir_tokens_per_period),
4592          ntohl (mp->pir_tokens_per_period),
4593          ntohl (mp->scale),
4594          ntohl (mp->current_limit),
4595          ntohl (mp->current_bucket),
4596          ntohl (mp->extended_limit),
4597          ntohl (mp->extended_bucket),
4598          clib_net_to_host_u64 (mp->last_update_time),
4599          format_policer_action_type, mp->conform_action_type,
4600          conform_dscp_str,
4601          format_policer_action_type, mp->exceed_action_type,
4602          exceed_dscp_str,
4603          format_policer_action_type, mp->violate_action_type,
4604          violate_dscp_str);
4605
4606   vec_free (conform_dscp_str);
4607   vec_free (exceed_dscp_str);
4608   vec_free (violate_dscp_str);
4609 }
4610
4611 static void vl_api_policer_details_t_handler_json
4612   (vl_api_policer_details_t * mp)
4613 {
4614   vat_main_t *vam = &vat_main;
4615   vat_json_node_t *node;
4616   u8 *rate_type_str, *round_type_str, *type_str;
4617   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4618
4619   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4620   round_type_str =
4621     format (0, "%U", format_policer_round_type, mp->round_type);
4622   type_str = format (0, "%U", format_policer_type, mp->type);
4623   conform_action_str = format (0, "%U", format_policer_action_type,
4624                                mp->conform_action_type);
4625   exceed_action_str = format (0, "%U", format_policer_action_type,
4626                               mp->exceed_action_type);
4627   violate_action_str = format (0, "%U", format_policer_action_type,
4628                                mp->violate_action_type);
4629
4630   if (VAT_JSON_ARRAY != vam->json_tree.type)
4631     {
4632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4633       vat_json_init_array (&vam->json_tree);
4634     }
4635   node = vat_json_array_add (&vam->json_tree);
4636
4637   vat_json_init_object (node);
4638   vat_json_object_add_string_copy (node, "name", mp->name);
4639   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4640   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4641   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4642   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4643   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4644   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4645   vat_json_object_add_string_copy (node, "type", type_str);
4646   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4647   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4648   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4649   vat_json_object_add_uint (node, "cir_tokens_per_period",
4650                             ntohl (mp->cir_tokens_per_period));
4651   vat_json_object_add_uint (node, "eir_tokens_per_period",
4652                             ntohl (mp->pir_tokens_per_period));
4653   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4654   vat_json_object_add_uint (node, "current_bucket",
4655                             ntohl (mp->current_bucket));
4656   vat_json_object_add_uint (node, "extended_limit",
4657                             ntohl (mp->extended_limit));
4658   vat_json_object_add_uint (node, "extended_bucket",
4659                             ntohl (mp->extended_bucket));
4660   vat_json_object_add_uint (node, "last_update_time",
4661                             ntohl (mp->last_update_time));
4662   vat_json_object_add_string_copy (node, "conform_action",
4663                                    conform_action_str);
4664   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4665     {
4666       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4667       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4668       vec_free (dscp_str);
4669     }
4670   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4671   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4672     {
4673       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4674       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4675       vec_free (dscp_str);
4676     }
4677   vat_json_object_add_string_copy (node, "violate_action",
4678                                    violate_action_str);
4679   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4680     {
4681       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4682       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4683       vec_free (dscp_str);
4684     }
4685
4686   vec_free (rate_type_str);
4687   vec_free (round_type_str);
4688   vec_free (type_str);
4689   vec_free (conform_action_str);
4690   vec_free (exceed_action_str);
4691   vec_free (violate_action_str);
4692 }
4693
4694 static void
4695 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4696                                            mp)
4697 {
4698   vat_main_t *vam = &vat_main;
4699   int i, count = ntohl (mp->count);
4700
4701   if (count > 0)
4702     print (vam->ofp, "classify table ids (%d) : ", count);
4703   for (i = 0; i < count; i++)
4704     {
4705       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4706       print (vam->ofp, (i < count - 1) ? "," : "");
4707     }
4708   vam->retval = ntohl (mp->retval);
4709   vam->result_ready = 1;
4710 }
4711
4712 static void
4713   vl_api_classify_table_ids_reply_t_handler_json
4714   (vl_api_classify_table_ids_reply_t * mp)
4715 {
4716   vat_main_t *vam = &vat_main;
4717   int i, count = ntohl (mp->count);
4718
4719   if (count > 0)
4720     {
4721       vat_json_node_t node;
4722
4723       vat_json_init_object (&node);
4724       for (i = 0; i < count; i++)
4725         {
4726           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4727         }
4728       vat_json_print (vam->ofp, &node);
4729       vat_json_free (&node);
4730     }
4731   vam->retval = ntohl (mp->retval);
4732   vam->result_ready = 1;
4733 }
4734
4735 static void
4736   vl_api_classify_table_by_interface_reply_t_handler
4737   (vl_api_classify_table_by_interface_reply_t * mp)
4738 {
4739   vat_main_t *vam = &vat_main;
4740   u32 table_id;
4741
4742   table_id = ntohl (mp->l2_table_id);
4743   if (table_id != ~0)
4744     print (vam->ofp, "l2 table id : %d", table_id);
4745   else
4746     print (vam->ofp, "l2 table id : No input ACL tables configured");
4747   table_id = ntohl (mp->ip4_table_id);
4748   if (table_id != ~0)
4749     print (vam->ofp, "ip4 table id : %d", table_id);
4750   else
4751     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4752   table_id = ntohl (mp->ip6_table_id);
4753   if (table_id != ~0)
4754     print (vam->ofp, "ip6 table id : %d", table_id);
4755   else
4756     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4757   vam->retval = ntohl (mp->retval);
4758   vam->result_ready = 1;
4759 }
4760
4761 static void
4762   vl_api_classify_table_by_interface_reply_t_handler_json
4763   (vl_api_classify_table_by_interface_reply_t * mp)
4764 {
4765   vat_main_t *vam = &vat_main;
4766   vat_json_node_t node;
4767
4768   vat_json_init_object (&node);
4769
4770   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4771   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4772   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4773
4774   vat_json_print (vam->ofp, &node);
4775   vat_json_free (&node);
4776
4777   vam->retval = ntohl (mp->retval);
4778   vam->result_ready = 1;
4779 }
4780
4781 static void vl_api_policer_add_del_reply_t_handler
4782   (vl_api_policer_add_del_reply_t * mp)
4783 {
4784   vat_main_t *vam = &vat_main;
4785   i32 retval = ntohl (mp->retval);
4786   if (vam->async_mode)
4787     {
4788       vam->async_errors += (retval < 0);
4789     }
4790   else
4791     {
4792       vam->retval = retval;
4793       vam->result_ready = 1;
4794       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4795         /*
4796          * Note: this is just barely thread-safe, depends on
4797          * the main thread spinning waiting for an answer...
4798          */
4799         errmsg ("policer index %d", ntohl (mp->policer_index));
4800     }
4801 }
4802
4803 static void vl_api_policer_add_del_reply_t_handler_json
4804   (vl_api_policer_add_del_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   vat_json_node_t node;
4808
4809   vat_json_init_object (&node);
4810   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4811   vat_json_object_add_uint (&node, "policer_index",
4812                             ntohl (mp->policer_index));
4813
4814   vat_json_print (vam->ofp, &node);
4815   vat_json_free (&node);
4816
4817   vam->retval = ntohl (mp->retval);
4818   vam->result_ready = 1;
4819 }
4820
4821 /* Format hex dump. */
4822 u8 *
4823 format_hex_bytes (u8 * s, va_list * va)
4824 {
4825   u8 *bytes = va_arg (*va, u8 *);
4826   int n_bytes = va_arg (*va, int);
4827   uword i;
4828
4829   /* Print short or long form depending on byte count. */
4830   uword short_form = n_bytes <= 32;
4831   u32 indent = format_get_indent (s);
4832
4833   if (n_bytes == 0)
4834     return s;
4835
4836   for (i = 0; i < n_bytes; i++)
4837     {
4838       if (!short_form && (i % 32) == 0)
4839         s = format (s, "%08x: ", i);
4840       s = format (s, "%02x", bytes[i]);
4841       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4842         s = format (s, "\n%U", format_white_space, indent);
4843     }
4844
4845   return s;
4846 }
4847
4848 static void
4849 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4850                                             * mp)
4851 {
4852   vat_main_t *vam = &vat_main;
4853   i32 retval = ntohl (mp->retval);
4854   if (retval == 0)
4855     {
4856       print (vam->ofp, "classify table info :");
4857       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4858              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4859              ntohl (mp->miss_next_index));
4860       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4861              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4862              ntohl (mp->match_n_vectors));
4863       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4864              ntohl (mp->mask_length));
4865     }
4866   vam->retval = retval;
4867   vam->result_ready = 1;
4868 }
4869
4870 static void
4871   vl_api_classify_table_info_reply_t_handler_json
4872   (vl_api_classify_table_info_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t node;
4876
4877   i32 retval = ntohl (mp->retval);
4878   if (retval == 0)
4879     {
4880       vat_json_init_object (&node);
4881
4882       vat_json_object_add_int (&node, "sessions",
4883                                ntohl (mp->active_sessions));
4884       vat_json_object_add_int (&node, "nexttbl",
4885                                ntohl (mp->next_table_index));
4886       vat_json_object_add_int (&node, "nextnode",
4887                                ntohl (mp->miss_next_index));
4888       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4889       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4890       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4891       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4892                       ntohl (mp->mask_length), 0);
4893       vat_json_object_add_string_copy (&node, "mask", s);
4894
4895       vat_json_print (vam->ofp, &node);
4896       vat_json_free (&node);
4897     }
4898   vam->retval = ntohl (mp->retval);
4899   vam->result_ready = 1;
4900 }
4901
4902 static void
4903 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4904                                            mp)
4905 {
4906   vat_main_t *vam = &vat_main;
4907
4908   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4909          ntohl (mp->hit_next_index), ntohl (mp->advance),
4910          ntohl (mp->opaque_index));
4911   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4912          ntohl (mp->match_length));
4913 }
4914
4915 static void
4916   vl_api_classify_session_details_t_handler_json
4917   (vl_api_classify_session_details_t * mp)
4918 {
4919   vat_main_t *vam = &vat_main;
4920   vat_json_node_t *node = NULL;
4921
4922   if (VAT_JSON_ARRAY != vam->json_tree.type)
4923     {
4924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4925       vat_json_init_array (&vam->json_tree);
4926     }
4927   node = vat_json_array_add (&vam->json_tree);
4928
4929   vat_json_init_object (node);
4930   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4931   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4932   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4933   u8 *s =
4934     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4935             0);
4936   vat_json_object_add_string_copy (node, "match", s);
4937 }
4938
4939 static void vl_api_pg_create_interface_reply_t_handler
4940   (vl_api_pg_create_interface_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   vam->retval = ntohl (mp->retval);
4945   vam->result_ready = 1;
4946 }
4947
4948 static void vl_api_pg_create_interface_reply_t_handler_json
4949   (vl_api_pg_create_interface_reply_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t node;
4953
4954   i32 retval = ntohl (mp->retval);
4955   if (retval == 0)
4956     {
4957       vat_json_init_object (&node);
4958
4959       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4960
4961       vat_json_print (vam->ofp, &node);
4962       vat_json_free (&node);
4963     }
4964   vam->retval = ntohl (mp->retval);
4965   vam->result_ready = 1;
4966 }
4967
4968 static void vl_api_policer_classify_details_t_handler
4969   (vl_api_policer_classify_details_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972
4973   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4974          ntohl (mp->table_index));
4975 }
4976
4977 static void vl_api_policer_classify_details_t_handler_json
4978   (vl_api_policer_classify_details_t * mp)
4979 {
4980   vat_main_t *vam = &vat_main;
4981   vat_json_node_t *node;
4982
4983   if (VAT_JSON_ARRAY != vam->json_tree.type)
4984     {
4985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4986       vat_json_init_array (&vam->json_tree);
4987     }
4988   node = vat_json_array_add (&vam->json_tree);
4989
4990   vat_json_init_object (node);
4991   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4992   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4993 }
4994
4995 static void vl_api_flow_classify_details_t_handler
4996   (vl_api_flow_classify_details_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999
5000   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5001          ntohl (mp->table_index));
5002 }
5003
5004 static void vl_api_flow_classify_details_t_handler_json
5005   (vl_api_flow_classify_details_t * mp)
5006 {
5007   vat_main_t *vam = &vat_main;
5008   vat_json_node_t *node;
5009
5010   if (VAT_JSON_ARRAY != vam->json_tree.type)
5011     {
5012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5013       vat_json_init_array (&vam->json_tree);
5014     }
5015   node = vat_json_array_add (&vam->json_tree);
5016
5017   vat_json_init_object (node);
5018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5019   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5020 }
5021
5022 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5023 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5024 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5025 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5026 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5028 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5029 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5030 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5031 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5032
5033 /*
5034  * Generate boilerplate reply handlers, which
5035  * dig the return value out of the xxx_reply_t API message,
5036  * stick it into vam->retval, and set vam->result_ready
5037  *
5038  * Could also do this by pointing N message decode slots at
5039  * a single function, but that could break in subtle ways.
5040  */
5041
5042 #define foreach_standard_reply_retval_handler           \
5043 _(sw_interface_set_flags_reply)                         \
5044 _(sw_interface_add_del_address_reply)                   \
5045 _(sw_interface_set_rx_mode_reply)                       \
5046 _(sw_interface_set_rx_placement_reply)                  \
5047 _(sw_interface_set_table_reply)                         \
5048 _(sw_interface_set_mpls_enable_reply)                   \
5049 _(sw_interface_set_vpath_reply)                         \
5050 _(sw_interface_set_vxlan_bypass_reply)                  \
5051 _(sw_interface_set_geneve_bypass_reply)                 \
5052 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5053 _(sw_interface_set_l2_bridge_reply)                     \
5054 _(bridge_domain_add_del_reply)                          \
5055 _(sw_interface_set_l2_xconnect_reply)                   \
5056 _(l2fib_add_del_reply)                                  \
5057 _(l2fib_flush_int_reply)                                \
5058 _(l2fib_flush_bd_reply)                                 \
5059 _(ip_route_add_del_reply)                               \
5060 _(ip_table_add_del_reply)                               \
5061 _(ip_mroute_add_del_reply)                              \
5062 _(mpls_route_add_del_reply)                             \
5063 _(mpls_table_add_del_reply)                             \
5064 _(mpls_ip_bind_unbind_reply)                            \
5065 _(bier_route_add_del_reply)                             \
5066 _(bier_table_add_del_reply)                             \
5067 _(proxy_arp_add_del_reply)                              \
5068 _(proxy_arp_intfc_enable_disable_reply)                 \
5069 _(sw_interface_set_unnumbered_reply)                    \
5070 _(ip_neighbor_add_del_reply)                            \
5071 _(reset_fib_reply)                                      \
5072 _(dhcp_proxy_config_reply)                              \
5073 _(dhcp_proxy_set_vss_reply)                             \
5074 _(dhcp_client_config_reply)                             \
5075 _(set_ip_flow_hash_reply)                               \
5076 _(sw_interface_ip6_enable_disable_reply)                \
5077 _(ip6nd_proxy_add_del_reply)                            \
5078 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5079 _(sw_interface_ip6nd_ra_config_reply)                   \
5080 _(set_arp_neighbor_limit_reply)                         \
5081 _(l2_patch_add_del_reply)                               \
5082 _(sr_mpls_policy_add_reply)                             \
5083 _(sr_mpls_policy_mod_reply)                             \
5084 _(sr_mpls_policy_del_reply)                             \
5085 _(sr_policy_add_reply)                                  \
5086 _(sr_policy_mod_reply)                                  \
5087 _(sr_policy_del_reply)                                  \
5088 _(sr_localsid_add_del_reply)                            \
5089 _(sr_steering_add_del_reply)                            \
5090 _(classify_add_del_session_reply)                       \
5091 _(classify_set_interface_ip_table_reply)                \
5092 _(classify_set_interface_l2_tables_reply)               \
5093 _(l2tpv3_set_tunnel_cookies_reply)                      \
5094 _(l2tpv3_interface_enable_disable_reply)                \
5095 _(l2tpv3_set_lookup_key_reply)                          \
5096 _(l2_fib_clear_table_reply)                             \
5097 _(l2_interface_efp_filter_reply)                        \
5098 _(l2_interface_vlan_tag_rewrite_reply)                  \
5099 _(modify_vhost_user_if_reply)                           \
5100 _(delete_vhost_user_if_reply)                           \
5101 _(ip_probe_neighbor_reply)                              \
5102 _(ip_scan_neighbor_enable_disable_reply)                \
5103 _(want_ip4_arp_events_reply)                            \
5104 _(want_ip6_nd_events_reply)                             \
5105 _(want_l2_macs_events_reply)                            \
5106 _(input_acl_set_interface_reply)                        \
5107 _(ipsec_spd_add_del_reply)                              \
5108 _(ipsec_interface_add_del_spd_reply)                    \
5109 _(ipsec_spd_entry_add_del_reply)                        \
5110 _(ipsec_sad_entry_add_del_reply)                        \
5111 _(ipsec_tunnel_if_add_del_reply)                        \
5112 _(ipsec_tunnel_if_set_sa_reply)                         \
5113 _(delete_loopback_reply)                                \
5114 _(bd_ip_mac_add_del_reply)                              \
5115 _(bd_ip_mac_flush_reply)                                \
5116 _(want_interface_events_reply)                          \
5117 _(cop_interface_enable_disable_reply)                   \
5118 _(cop_whitelist_enable_disable_reply)                   \
5119 _(sw_interface_clear_stats_reply)                       \
5120 _(ioam_enable_reply)                                    \
5121 _(ioam_disable_reply)                                   \
5122 _(one_add_del_locator_reply)                            \
5123 _(one_add_del_local_eid_reply)                          \
5124 _(one_add_del_remote_mapping_reply)                     \
5125 _(one_add_del_adjacency_reply)                          \
5126 _(one_add_del_map_resolver_reply)                       \
5127 _(one_add_del_map_server_reply)                         \
5128 _(one_enable_disable_reply)                             \
5129 _(one_rloc_probe_enable_disable_reply)                  \
5130 _(one_map_register_enable_disable_reply)                \
5131 _(one_map_register_set_ttl_reply)                       \
5132 _(one_set_transport_protocol_reply)                     \
5133 _(one_map_register_fallback_threshold_reply)            \
5134 _(one_pitr_set_locator_set_reply)                       \
5135 _(one_map_request_mode_reply)                           \
5136 _(one_add_del_map_request_itr_rlocs_reply)              \
5137 _(one_eid_table_add_del_map_reply)                      \
5138 _(one_use_petr_reply)                                   \
5139 _(one_stats_enable_disable_reply)                       \
5140 _(one_add_del_l2_arp_entry_reply)                       \
5141 _(one_add_del_ndp_entry_reply)                          \
5142 _(one_stats_flush_reply)                                \
5143 _(one_enable_disable_xtr_mode_reply)                    \
5144 _(one_enable_disable_pitr_mode_reply)                   \
5145 _(one_enable_disable_petr_mode_reply)                   \
5146 _(gpe_enable_disable_reply)                             \
5147 _(gpe_set_encap_mode_reply)                             \
5148 _(gpe_add_del_iface_reply)                              \
5149 _(gpe_add_del_native_fwd_rpath_reply)                   \
5150 _(af_packet_delete_reply)                               \
5151 _(policer_classify_set_interface_reply)                 \
5152 _(netmap_create_reply)                                  \
5153 _(netmap_delete_reply)                                  \
5154 _(set_ipfix_exporter_reply)                             \
5155 _(set_ipfix_classify_stream_reply)                      \
5156 _(ipfix_classify_table_add_del_reply)                   \
5157 _(flow_classify_set_interface_reply)                    \
5158 _(sw_interface_span_enable_disable_reply)               \
5159 _(pg_capture_reply)                                     \
5160 _(pg_enable_disable_reply)                              \
5161 _(ip_source_and_port_range_check_add_del_reply)         \
5162 _(ip_source_and_port_range_check_interface_add_del_reply)\
5163 _(delete_subif_reply)                                   \
5164 _(l2_interface_pbb_tag_rewrite_reply)                   \
5165 _(set_punt_reply)                                       \
5166 _(feature_enable_disable_reply)                         \
5167 _(sw_interface_tag_add_del_reply)                       \
5168 _(hw_interface_set_mtu_reply)                           \
5169 _(p2p_ethernet_add_reply)                               \
5170 _(p2p_ethernet_del_reply)                               \
5171 _(lldp_config_reply)                                    \
5172 _(sw_interface_set_lldp_reply)                          \
5173 _(tcp_configure_src_addresses_reply)                    \
5174 _(session_rule_add_del_reply)                           \
5175 _(ip_container_proxy_add_del_reply)                     \
5176 _(output_acl_set_interface_reply)                       \
5177 _(qos_record_enable_disable_reply)
5178
5179 #define _(n)                                    \
5180     static void vl_api_##n##_t_handler          \
5181     (vl_api_##n##_t * mp)                       \
5182     {                                           \
5183         vat_main_t * vam = &vat_main;           \
5184         i32 retval = ntohl(mp->retval);         \
5185         if (vam->async_mode) {                  \
5186             vam->async_errors += (retval < 0);  \
5187         } else {                                \
5188             vam->retval = retval;               \
5189             vam->result_ready = 1;              \
5190         }                                       \
5191     }
5192 foreach_standard_reply_retval_handler;
5193 #undef _
5194
5195 #define _(n)                                    \
5196     static void vl_api_##n##_t_handler_json     \
5197     (vl_api_##n##_t * mp)                       \
5198     {                                           \
5199         vat_main_t * vam = &vat_main;           \
5200         vat_json_node_t node;                   \
5201         vat_json_init_object(&node);            \
5202         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5203         vat_json_print(vam->ofp, &node);        \
5204         vam->retval = ntohl(mp->retval);        \
5205         vam->result_ready = 1;                  \
5206     }
5207 foreach_standard_reply_retval_handler;
5208 #undef _
5209
5210 /*
5211  * Table of message reply handlers, must include boilerplate handlers
5212  * we just generated
5213  */
5214
5215 #define foreach_vpe_api_reply_msg                                       \
5216 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5217 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5218 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5219 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5220 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5221 _(CLI_REPLY, cli_reply)                                                 \
5222 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5223 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5224   sw_interface_add_del_address_reply)                                   \
5225 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5226 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5227 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5228 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5229 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5230 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5231 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5232 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5233 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5234 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5235   sw_interface_set_l2_xconnect_reply)                                   \
5236 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5237   sw_interface_set_l2_bridge_reply)                                     \
5238 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5239 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5240 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5241 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5242 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5243 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5244 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5245 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5246 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5247 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5248 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5249 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5250 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5251 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5252 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5253 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5254 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5255 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5256 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5257 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5258 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5259 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5260 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5261 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5262 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5263 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5264 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5265 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5266 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5267 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5268   proxy_arp_intfc_enable_disable_reply)                                 \
5269 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5270 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5271   sw_interface_set_unnumbered_reply)                                    \
5272 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5273 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5274 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5275 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5276 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5277 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5278 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5279 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5280 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5281 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5282   sw_interface_ip6_enable_disable_reply)                                \
5283 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5284 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5285 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5286   sw_interface_ip6nd_ra_prefix_reply)                                   \
5287 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5288   sw_interface_ip6nd_ra_config_reply)                                   \
5289 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5290 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5291 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5292 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5293 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5294 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5295 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5296 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5297 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5298 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5299 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5300 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5301 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5302 classify_set_interface_ip_table_reply)                                  \
5303 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5304   classify_set_interface_l2_tables_reply)                               \
5305 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5306 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5307 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5308 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5309 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5310   l2tpv3_interface_enable_disable_reply)                                \
5311 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5312 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5313 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5314 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5315 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5316 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5317 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5318 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5319 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5320 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5321 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5322 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5323 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5324 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5325 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5326 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5327 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5328 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5329 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5330 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5331 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5332 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5333 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5334 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5335 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5336 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5337 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5338 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5339 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5340 _(L2_MACS_EVENT, l2_macs_event)                                         \
5341 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5342 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5343 _(IP_DETAILS, ip_details)                                               \
5344 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5345 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5346 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5347 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5348 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5349 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5350 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5351 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5352 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5353 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5354 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5355 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5356 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5357 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5358 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5359 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5360 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5361 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5362 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5363 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5364 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5365 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5366 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5367 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5368 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5369 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5370 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5371 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5372 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5373   one_map_register_enable_disable_reply)                                \
5374 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5375 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5376 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5377 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5378   one_map_register_fallback_threshold_reply)                            \
5379 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5380   one_rloc_probe_enable_disable_reply)                                  \
5381 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5382 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5383 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5384 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5385 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5386 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5387 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5388 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5389 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5390 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5391 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5392 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5393 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5394 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5395 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5396 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5397   show_one_stats_enable_disable_reply)                                  \
5398 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5399 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5400 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5401 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5402 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5403 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5404 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5405 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5406   one_enable_disable_pitr_mode_reply)                                   \
5407 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5408   one_enable_disable_petr_mode_reply)                                   \
5409 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5410 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5411 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5412 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5413 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5414 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5415 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5416 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5417 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5418 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5419 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5420 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5421   gpe_add_del_native_fwd_rpath_reply)                                   \
5422 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5423   gpe_fwd_entry_path_details)                                           \
5424 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5425 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5426   one_add_del_map_request_itr_rlocs_reply)                              \
5427 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5428   one_get_map_request_itr_rlocs_reply)                                  \
5429 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5430 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5431 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5432 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5433 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5434 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5435   show_one_map_register_state_reply)                                    \
5436 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5437 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5438   show_one_map_register_fallback_threshold_reply)                       \
5439 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5440 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5441 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5442 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5443 _(POLICER_DETAILS, policer_details)                                     \
5444 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5445 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5446 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5447 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5448 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5449 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5450 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5451 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5452 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5453 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5454 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5455 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5456 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5457 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5458 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5459 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5460 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5461 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5462 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5463 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5464 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5465 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5466 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5467 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5468 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5469 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5470  ip_source_and_port_range_check_add_del_reply)                          \
5471 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5472  ip_source_and_port_range_check_interface_add_del_reply)                \
5473 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5474 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5475 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5476 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5477 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5478 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5479 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5480 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5481 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5482 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5483 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5484 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5485 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5486 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5487 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5488 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5489 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5490 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5491 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5492 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5493 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5494 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5495
5496 #define foreach_standalone_reply_msg                                    \
5497 _(SW_INTERFACE_EVENT, sw_interface_event)
5498
5499 typedef struct
5500 {
5501   u8 *name;
5502   u32 value;
5503 } name_sort_t;
5504
5505 #define STR_VTR_OP_CASE(op)     \
5506     case L2_VTR_ ## op:         \
5507         return "" # op;
5508
5509 static const char *
5510 str_vtr_op (u32 vtr_op)
5511 {
5512   switch (vtr_op)
5513     {
5514       STR_VTR_OP_CASE (DISABLED);
5515       STR_VTR_OP_CASE (PUSH_1);
5516       STR_VTR_OP_CASE (PUSH_2);
5517       STR_VTR_OP_CASE (POP_1);
5518       STR_VTR_OP_CASE (POP_2);
5519       STR_VTR_OP_CASE (TRANSLATE_1_1);
5520       STR_VTR_OP_CASE (TRANSLATE_1_2);
5521       STR_VTR_OP_CASE (TRANSLATE_2_1);
5522       STR_VTR_OP_CASE (TRANSLATE_2_2);
5523     }
5524
5525   return "UNKNOWN";
5526 }
5527
5528 static int
5529 dump_sub_interface_table (vat_main_t * vam)
5530 {
5531   const sw_interface_subif_t *sub = NULL;
5532
5533   if (vam->json_output)
5534     {
5535       clib_warning
5536         ("JSON output supported only for VPE API calls and dump_stats_table");
5537       return -99;
5538     }
5539
5540   print (vam->ofp,
5541          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5542          "Interface", "sw_if_index",
5543          "sub id", "dot1ad", "tags", "outer id",
5544          "inner id", "exact", "default", "outer any", "inner any");
5545
5546   vec_foreach (sub, vam->sw_if_subif_table)
5547   {
5548     print (vam->ofp,
5549            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5550            sub->interface_name,
5551            sub->sw_if_index,
5552            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5553            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5554            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5555            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5556     if (sub->vtr_op != L2_VTR_DISABLED)
5557       {
5558         print (vam->ofp,
5559                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5560                "tag1: %d tag2: %d ]",
5561                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5562                sub->vtr_tag1, sub->vtr_tag2);
5563       }
5564   }
5565
5566   return 0;
5567 }
5568
5569 static int
5570 name_sort_cmp (void *a1, void *a2)
5571 {
5572   name_sort_t *n1 = a1;
5573   name_sort_t *n2 = a2;
5574
5575   return strcmp ((char *) n1->name, (char *) n2->name);
5576 }
5577
5578 static int
5579 dump_interface_table (vat_main_t * vam)
5580 {
5581   hash_pair_t *p;
5582   name_sort_t *nses = 0, *ns;
5583
5584   if (vam->json_output)
5585     {
5586       clib_warning
5587         ("JSON output supported only for VPE API calls and dump_stats_table");
5588       return -99;
5589     }
5590
5591   /* *INDENT-OFF* */
5592   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5593   ({
5594     vec_add2 (nses, ns, 1);
5595     ns->name = (u8 *)(p->key);
5596     ns->value = (u32) p->value[0];
5597   }));
5598   /* *INDENT-ON* */
5599
5600   vec_sort_with_function (nses, name_sort_cmp);
5601
5602   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5603   vec_foreach (ns, nses)
5604   {
5605     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5606   }
5607   vec_free (nses);
5608   return 0;
5609 }
5610
5611 static int
5612 dump_ip_table (vat_main_t * vam, int is_ipv6)
5613 {
5614   const ip_details_t *det = NULL;
5615   const ip_address_details_t *address = NULL;
5616   u32 i = ~0;
5617
5618   print (vam->ofp, "%-12s", "sw_if_index");
5619
5620   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5621   {
5622     i++;
5623     if (!det->present)
5624       {
5625         continue;
5626       }
5627     print (vam->ofp, "%-12d", i);
5628     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5629     if (!det->addr)
5630       {
5631         continue;
5632       }
5633     vec_foreach (address, det->addr)
5634     {
5635       print (vam->ofp,
5636              "            %-30U%-13d",
5637              is_ipv6 ? format_ip6_address : format_ip4_address,
5638              address->ip, address->prefix_length);
5639     }
5640   }
5641
5642   return 0;
5643 }
5644
5645 static int
5646 dump_ipv4_table (vat_main_t * vam)
5647 {
5648   if (vam->json_output)
5649     {
5650       clib_warning
5651         ("JSON output supported only for VPE API calls and dump_stats_table");
5652       return -99;
5653     }
5654
5655   return dump_ip_table (vam, 0);
5656 }
5657
5658 static int
5659 dump_ipv6_table (vat_main_t * vam)
5660 {
5661   if (vam->json_output)
5662     {
5663       clib_warning
5664         ("JSON output supported only for VPE API calls and dump_stats_table");
5665       return -99;
5666     }
5667
5668   return dump_ip_table (vam, 1);
5669 }
5670
5671 /*
5672  * Pass CLI buffers directly in the CLI_INBAND API message,
5673  * instead of an additional shared memory area.
5674  */
5675 static int
5676 exec_inband (vat_main_t * vam)
5677 {
5678   vl_api_cli_inband_t *mp;
5679   unformat_input_t *i = vam->input;
5680   int ret;
5681
5682   if (vec_len (i->buffer) == 0)
5683     return -1;
5684
5685   if (vam->exec_mode == 0 && unformat (i, "mode"))
5686     {
5687       vam->exec_mode = 1;
5688       return 0;
5689     }
5690   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5691     {
5692       vam->exec_mode = 0;
5693       return 0;
5694     }
5695
5696   /*
5697    * In order for the CLI command to work, it
5698    * must be a vector ending in \n, not a C-string ending
5699    * in \n\0.
5700    */
5701   u32 len = vec_len (vam->input->buffer);
5702   M2 (CLI_INBAND, mp, len);
5703   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5704
5705   S (mp);
5706   W (ret);
5707   /* json responses may or may not include a useful reply... */
5708   if (vec_len (vam->cmd_reply))
5709     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5710   return ret;
5711 }
5712
5713 int
5714 exec (vat_main_t * vam)
5715 {
5716   return exec_inband (vam);
5717 }
5718
5719 static int
5720 api_create_loopback (vat_main_t * vam)
5721 {
5722   unformat_input_t *i = vam->input;
5723   vl_api_create_loopback_t *mp;
5724   vl_api_create_loopback_instance_t *mp_lbi;
5725   u8 mac_address[6];
5726   u8 mac_set = 0;
5727   u8 is_specified = 0;
5728   u32 user_instance = 0;
5729   int ret;
5730
5731   clib_memset (mac_address, 0, sizeof (mac_address));
5732
5733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5734     {
5735       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5736         mac_set = 1;
5737       if (unformat (i, "instance %d", &user_instance))
5738         is_specified = 1;
5739       else
5740         break;
5741     }
5742
5743   if (is_specified)
5744     {
5745       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5746       mp_lbi->is_specified = is_specified;
5747       if (is_specified)
5748         mp_lbi->user_instance = htonl (user_instance);
5749       if (mac_set)
5750         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5751       S (mp_lbi);
5752     }
5753   else
5754     {
5755       /* Construct the API message */
5756       M (CREATE_LOOPBACK, mp);
5757       if (mac_set)
5758         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5759       S (mp);
5760     }
5761
5762   W (ret);
5763   return ret;
5764 }
5765
5766 static int
5767 api_delete_loopback (vat_main_t * vam)
5768 {
5769   unformat_input_t *i = vam->input;
5770   vl_api_delete_loopback_t *mp;
5771   u32 sw_if_index = ~0;
5772   int ret;
5773
5774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5775     {
5776       if (unformat (i, "sw_if_index %d", &sw_if_index))
5777         ;
5778       else
5779         break;
5780     }
5781
5782   if (sw_if_index == ~0)
5783     {
5784       errmsg ("missing sw_if_index");
5785       return -99;
5786     }
5787
5788   /* Construct the API message */
5789   M (DELETE_LOOPBACK, mp);
5790   mp->sw_if_index = ntohl (sw_if_index);
5791
5792   S (mp);
5793   W (ret);
5794   return ret;
5795 }
5796
5797 static int
5798 api_want_interface_events (vat_main_t * vam)
5799 {
5800   unformat_input_t *i = vam->input;
5801   vl_api_want_interface_events_t *mp;
5802   int enable = -1;
5803   int ret;
5804
5805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5806     {
5807       if (unformat (i, "enable"))
5808         enable = 1;
5809       else if (unformat (i, "disable"))
5810         enable = 0;
5811       else
5812         break;
5813     }
5814
5815   if (enable == -1)
5816     {
5817       errmsg ("missing enable|disable");
5818       return -99;
5819     }
5820
5821   M (WANT_INTERFACE_EVENTS, mp);
5822   mp->enable_disable = enable;
5823
5824   vam->interface_event_display = enable;
5825
5826   S (mp);
5827   W (ret);
5828   return ret;
5829 }
5830
5831
5832 /* Note: non-static, called once to set up the initial intfc table */
5833 int
5834 api_sw_interface_dump (vat_main_t * vam)
5835 {
5836   vl_api_sw_interface_dump_t *mp;
5837   vl_api_control_ping_t *mp_ping;
5838   hash_pair_t *p;
5839   name_sort_t *nses = 0, *ns;
5840   sw_interface_subif_t *sub = NULL;
5841   int ret;
5842
5843   /* Toss the old name table */
5844   /* *INDENT-OFF* */
5845   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5846   ({
5847     vec_add2 (nses, ns, 1);
5848     ns->name = (u8 *)(p->key);
5849     ns->value = (u32) p->value[0];
5850   }));
5851   /* *INDENT-ON* */
5852
5853   hash_free (vam->sw_if_index_by_interface_name);
5854
5855   vec_foreach (ns, nses) vec_free (ns->name);
5856
5857   vec_free (nses);
5858
5859   vec_foreach (sub, vam->sw_if_subif_table)
5860   {
5861     vec_free (sub->interface_name);
5862   }
5863   vec_free (vam->sw_if_subif_table);
5864
5865   /* recreate the interface name hash table */
5866   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5867
5868   /*
5869    * Ask for all interface names. Otherwise, the epic catalog of
5870    * name filters becomes ridiculously long, and vat ends up needing
5871    * to be taught about new interface types.
5872    */
5873   M (SW_INTERFACE_DUMP, mp);
5874   S (mp);
5875
5876   /* Use a control ping for synchronization */
5877   MPING (CONTROL_PING, mp_ping);
5878   S (mp_ping);
5879
5880   W (ret);
5881   return ret;
5882 }
5883
5884 static int
5885 api_sw_interface_set_flags (vat_main_t * vam)
5886 {
5887   unformat_input_t *i = vam->input;
5888   vl_api_sw_interface_set_flags_t *mp;
5889   u32 sw_if_index;
5890   u8 sw_if_index_set = 0;
5891   u8 admin_up = 0;
5892   int ret;
5893
5894   /* Parse args required to build the message */
5895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896     {
5897       if (unformat (i, "admin-up"))
5898         admin_up = 1;
5899       else if (unformat (i, "admin-down"))
5900         admin_up = 0;
5901       else
5902         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5903         sw_if_index_set = 1;
5904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5905         sw_if_index_set = 1;
5906       else
5907         break;
5908     }
5909
5910   if (sw_if_index_set == 0)
5911     {
5912       errmsg ("missing interface name or sw_if_index");
5913       return -99;
5914     }
5915
5916   /* Construct the API message */
5917   M (SW_INTERFACE_SET_FLAGS, mp);
5918   mp->sw_if_index = ntohl (sw_if_index);
5919   mp->admin_up_down = admin_up;
5920
5921   /* send it... */
5922   S (mp);
5923
5924   /* Wait for a reply, return the good/bad news... */
5925   W (ret);
5926   return ret;
5927 }
5928
5929 static int
5930 api_sw_interface_set_rx_mode (vat_main_t * vam)
5931 {
5932   unformat_input_t *i = vam->input;
5933   vl_api_sw_interface_set_rx_mode_t *mp;
5934   u32 sw_if_index;
5935   u8 sw_if_index_set = 0;
5936   int ret;
5937   u8 queue_id_valid = 0;
5938   u32 queue_id;
5939   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5940
5941   /* Parse args required to build the message */
5942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5943     {
5944       if (unformat (i, "queue %d", &queue_id))
5945         queue_id_valid = 1;
5946       else if (unformat (i, "polling"))
5947         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5948       else if (unformat (i, "interrupt"))
5949         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5950       else if (unformat (i, "adaptive"))
5951         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5952       else
5953         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5954         sw_if_index_set = 1;
5955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5956         sw_if_index_set = 1;
5957       else
5958         break;
5959     }
5960
5961   if (sw_if_index_set == 0)
5962     {
5963       errmsg ("missing interface name or sw_if_index");
5964       return -99;
5965     }
5966   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5967     {
5968       errmsg ("missing rx-mode");
5969       return -99;
5970     }
5971
5972   /* Construct the API message */
5973   M (SW_INTERFACE_SET_RX_MODE, mp);
5974   mp->sw_if_index = ntohl (sw_if_index);
5975   mp->mode = mode;
5976   mp->queue_id_valid = queue_id_valid;
5977   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5978
5979   /* send it... */
5980   S (mp);
5981
5982   /* Wait for a reply, return the good/bad news... */
5983   W (ret);
5984   return ret;
5985 }
5986
5987 static int
5988 api_sw_interface_set_rx_placement (vat_main_t * vam)
5989 {
5990   unformat_input_t *i = vam->input;
5991   vl_api_sw_interface_set_rx_placement_t *mp;
5992   u32 sw_if_index;
5993   u8 sw_if_index_set = 0;
5994   int ret;
5995   u8 is_main = 0;
5996   u32 queue_id, thread_index;
5997
5998   /* Parse args required to build the message */
5999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6000     {
6001       if (unformat (i, "queue %d", &queue_id))
6002         ;
6003       else if (unformat (i, "main"))
6004         is_main = 1;
6005       else if (unformat (i, "worker %d", &thread_index))
6006         ;
6007       else
6008         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6009         sw_if_index_set = 1;
6010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6011         sw_if_index_set = 1;
6012       else
6013         break;
6014     }
6015
6016   if (sw_if_index_set == 0)
6017     {
6018       errmsg ("missing interface name or sw_if_index");
6019       return -99;
6020     }
6021
6022   if (is_main)
6023     thread_index = 0;
6024   /* Construct the API message */
6025   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6026   mp->sw_if_index = ntohl (sw_if_index);
6027   mp->worker_id = ntohl (thread_index);
6028   mp->queue_id = ntohl (queue_id);
6029   mp->is_main = is_main;
6030
6031   /* send it... */
6032   S (mp);
6033   /* Wait for a reply, return the good/bad news... */
6034   W (ret);
6035   return ret;
6036 }
6037
6038 static void vl_api_sw_interface_rx_placement_details_t_handler
6039   (vl_api_sw_interface_rx_placement_details_t * mp)
6040 {
6041   vat_main_t *vam = &vat_main;
6042   u32 worker_id = ntohl (mp->worker_id);
6043
6044   print (vam->ofp,
6045          "\n%-11d %-11s %-6d %-5d %-9s",
6046          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6047          worker_id, ntohl (mp->queue_id),
6048          (mp->mode ==
6049           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6050 }
6051
6052 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6053   (vl_api_sw_interface_rx_placement_details_t * mp)
6054 {
6055   vat_main_t *vam = &vat_main;
6056   vat_json_node_t *node = NULL;
6057
6058   if (VAT_JSON_ARRAY != vam->json_tree.type)
6059     {
6060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6061       vat_json_init_array (&vam->json_tree);
6062     }
6063   node = vat_json_array_add (&vam->json_tree);
6064
6065   vat_json_init_object (node);
6066   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6067   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6068   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6069   vat_json_object_add_uint (node, "mode", mp->mode);
6070 }
6071
6072 static int
6073 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6074 {
6075   unformat_input_t *i = vam->input;
6076   vl_api_sw_interface_rx_placement_dump_t *mp;
6077   vl_api_control_ping_t *mp_ping;
6078   int ret;
6079   u32 sw_if_index;
6080   u8 sw_if_index_set = 0;
6081
6082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6083     {
6084       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6085         sw_if_index_set++;
6086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6087         sw_if_index_set++;
6088       else
6089         break;
6090     }
6091
6092   print (vam->ofp,
6093          "\n%-11s %-11s %-6s %-5s %-4s",
6094          "sw_if_index", "main/worker", "thread", "queue", "mode");
6095
6096   /* Dump Interface rx placement */
6097   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6098
6099   if (sw_if_index_set)
6100     mp->sw_if_index = htonl (sw_if_index);
6101   else
6102     mp->sw_if_index = ~0;
6103
6104   S (mp);
6105
6106   /* Use a control ping for synchronization */
6107   MPING (CONTROL_PING, mp_ping);
6108   S (mp_ping);
6109
6110   W (ret);
6111   return ret;
6112 }
6113
6114 static int
6115 api_sw_interface_clear_stats (vat_main_t * vam)
6116 {
6117   unformat_input_t *i = vam->input;
6118   vl_api_sw_interface_clear_stats_t *mp;
6119   u32 sw_if_index;
6120   u8 sw_if_index_set = 0;
6121   int ret;
6122
6123   /* Parse args required to build the message */
6124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125     {
6126       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6127         sw_if_index_set = 1;
6128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6129         sw_if_index_set = 1;
6130       else
6131         break;
6132     }
6133
6134   /* Construct the API message */
6135   M (SW_INTERFACE_CLEAR_STATS, mp);
6136
6137   if (sw_if_index_set == 1)
6138     mp->sw_if_index = ntohl (sw_if_index);
6139   else
6140     mp->sw_if_index = ~0;
6141
6142   /* send it... */
6143   S (mp);
6144
6145   /* Wait for a reply, return the good/bad news... */
6146   W (ret);
6147   return ret;
6148 }
6149
6150 static int
6151 api_sw_interface_add_del_address (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_sw_interface_add_del_address_t *mp;
6155   u32 sw_if_index;
6156   u8 sw_if_index_set = 0;
6157   u8 is_add = 1, del_all = 0;
6158   u32 address_length = 0;
6159   u8 v4_address_set = 0;
6160   u8 v6_address_set = 0;
6161   ip4_address_t v4address;
6162   ip6_address_t v6address;
6163   int ret;
6164
6165   /* Parse args required to build the message */
6166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6167     {
6168       if (unformat (i, "del-all"))
6169         del_all = 1;
6170       else if (unformat (i, "del"))
6171         is_add = 0;
6172       else
6173         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6174         sw_if_index_set = 1;
6175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6176         sw_if_index_set = 1;
6177       else if (unformat (i, "%U/%d",
6178                          unformat_ip4_address, &v4address, &address_length))
6179         v4_address_set = 1;
6180       else if (unformat (i, "%U/%d",
6181                          unformat_ip6_address, &v6address, &address_length))
6182         v6_address_set = 1;
6183       else
6184         break;
6185     }
6186
6187   if (sw_if_index_set == 0)
6188     {
6189       errmsg ("missing interface name or sw_if_index");
6190       return -99;
6191     }
6192   if (v4_address_set && v6_address_set)
6193     {
6194       errmsg ("both v4 and v6 addresses set");
6195       return -99;
6196     }
6197   if (!v4_address_set && !v6_address_set && !del_all)
6198     {
6199       errmsg ("no addresses set");
6200       return -99;
6201     }
6202
6203   /* Construct the API message */
6204   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6205
6206   mp->sw_if_index = ntohl (sw_if_index);
6207   mp->is_add = is_add;
6208   mp->del_all = del_all;
6209   if (v6_address_set)
6210     {
6211       mp->is_ipv6 = 1;
6212       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6213     }
6214   else
6215     {
6216       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6217     }
6218   mp->address_length = address_length;
6219
6220   /* send it... */
6221   S (mp);
6222
6223   /* Wait for a reply, return good/bad news  */
6224   W (ret);
6225   return ret;
6226 }
6227
6228 static int
6229 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6230 {
6231   unformat_input_t *i = vam->input;
6232   vl_api_sw_interface_set_mpls_enable_t *mp;
6233   u32 sw_if_index;
6234   u8 sw_if_index_set = 0;
6235   u8 enable = 1;
6236   int ret;
6237
6238   /* Parse args required to build the message */
6239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6240     {
6241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6242         sw_if_index_set = 1;
6243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6244         sw_if_index_set = 1;
6245       else if (unformat (i, "disable"))
6246         enable = 0;
6247       else if (unformat (i, "dis"))
6248         enable = 0;
6249       else
6250         break;
6251     }
6252
6253   if (sw_if_index_set == 0)
6254     {
6255       errmsg ("missing interface name or sw_if_index");
6256       return -99;
6257     }
6258
6259   /* Construct the API message */
6260   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6261
6262   mp->sw_if_index = ntohl (sw_if_index);
6263   mp->enable = enable;
6264
6265   /* send it... */
6266   S (mp);
6267
6268   /* Wait for a reply... */
6269   W (ret);
6270   return ret;
6271 }
6272
6273 static int
6274 api_sw_interface_set_table (vat_main_t * vam)
6275 {
6276   unformat_input_t *i = vam->input;
6277   vl_api_sw_interface_set_table_t *mp;
6278   u32 sw_if_index, vrf_id = 0;
6279   u8 sw_if_index_set = 0;
6280   u8 is_ipv6 = 0;
6281   int ret;
6282
6283   /* Parse args required to build the message */
6284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6285     {
6286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6287         sw_if_index_set = 1;
6288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "vrf %d", &vrf_id))
6291         ;
6292       else if (unformat (i, "ipv6"))
6293         is_ipv6 = 1;
6294       else
6295         break;
6296     }
6297
6298   if (sw_if_index_set == 0)
6299     {
6300       errmsg ("missing interface name or sw_if_index");
6301       return -99;
6302     }
6303
6304   /* Construct the API message */
6305   M (SW_INTERFACE_SET_TABLE, mp);
6306
6307   mp->sw_if_index = ntohl (sw_if_index);
6308   mp->is_ipv6 = is_ipv6;
6309   mp->vrf_id = ntohl (vrf_id);
6310
6311   /* send it... */
6312   S (mp);
6313
6314   /* Wait for a reply... */
6315   W (ret);
6316   return ret;
6317 }
6318
6319 static void vl_api_sw_interface_get_table_reply_t_handler
6320   (vl_api_sw_interface_get_table_reply_t * mp)
6321 {
6322   vat_main_t *vam = &vat_main;
6323
6324   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6325
6326   vam->retval = ntohl (mp->retval);
6327   vam->result_ready = 1;
6328
6329 }
6330
6331 static void vl_api_sw_interface_get_table_reply_t_handler_json
6332   (vl_api_sw_interface_get_table_reply_t * mp)
6333 {
6334   vat_main_t *vam = &vat_main;
6335   vat_json_node_t node;
6336
6337   vat_json_init_object (&node);
6338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6339   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6340
6341   vat_json_print (vam->ofp, &node);
6342   vat_json_free (&node);
6343
6344   vam->retval = ntohl (mp->retval);
6345   vam->result_ready = 1;
6346 }
6347
6348 static int
6349 api_sw_interface_get_table (vat_main_t * vam)
6350 {
6351   unformat_input_t *i = vam->input;
6352   vl_api_sw_interface_get_table_t *mp;
6353   u32 sw_if_index;
6354   u8 sw_if_index_set = 0;
6355   u8 is_ipv6 = 0;
6356   int ret;
6357
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6361         sw_if_index_set = 1;
6362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6363         sw_if_index_set = 1;
6364       else if (unformat (i, "ipv6"))
6365         is_ipv6 = 1;
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   M (SW_INTERFACE_GET_TABLE, mp);
6377   mp->sw_if_index = htonl (sw_if_index);
6378   mp->is_ipv6 = is_ipv6;
6379
6380   S (mp);
6381   W (ret);
6382   return ret;
6383 }
6384
6385 static int
6386 api_sw_interface_set_vpath (vat_main_t * vam)
6387 {
6388   unformat_input_t *i = vam->input;
6389   vl_api_sw_interface_set_vpath_t *mp;
6390   u32 sw_if_index = 0;
6391   u8 sw_if_index_set = 0;
6392   u8 is_enable = 0;
6393   int ret;
6394
6395   /* Parse args required to build the message */
6396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6397     {
6398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "enable"))
6403         is_enable = 1;
6404       else if (unformat (i, "disable"))
6405         is_enable = 0;
6406       else
6407         break;
6408     }
6409
6410   if (sw_if_index_set == 0)
6411     {
6412       errmsg ("missing interface name or sw_if_index");
6413       return -99;
6414     }
6415
6416   /* Construct the API message */
6417   M (SW_INTERFACE_SET_VPATH, mp);
6418
6419   mp->sw_if_index = ntohl (sw_if_index);
6420   mp->enable = is_enable;
6421
6422   /* send it... */
6423   S (mp);
6424
6425   /* Wait for a reply... */
6426   W (ret);
6427   return ret;
6428 }
6429
6430 static int
6431 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6432 {
6433   unformat_input_t *i = vam->input;
6434   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6435   u32 sw_if_index = 0;
6436   u8 sw_if_index_set = 0;
6437   u8 is_enable = 1;
6438   u8 is_ipv6 = 0;
6439   int ret;
6440
6441   /* Parse args required to build the message */
6442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6443     {
6444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6445         sw_if_index_set = 1;
6446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6447         sw_if_index_set = 1;
6448       else if (unformat (i, "enable"))
6449         is_enable = 1;
6450       else if (unformat (i, "disable"))
6451         is_enable = 0;
6452       else if (unformat (i, "ip4"))
6453         is_ipv6 = 0;
6454       else if (unformat (i, "ip6"))
6455         is_ipv6 = 1;
6456       else
6457         break;
6458     }
6459
6460   if (sw_if_index_set == 0)
6461     {
6462       errmsg ("missing interface name or sw_if_index");
6463       return -99;
6464     }
6465
6466   /* Construct the API message */
6467   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6468
6469   mp->sw_if_index = ntohl (sw_if_index);
6470   mp->enable = is_enable;
6471   mp->is_ipv6 = is_ipv6;
6472
6473   /* send it... */
6474   S (mp);
6475
6476   /* Wait for a reply... */
6477   W (ret);
6478   return ret;
6479 }
6480
6481 static int
6482 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6483 {
6484   unformat_input_t *i = vam->input;
6485   vl_api_sw_interface_set_geneve_bypass_t *mp;
6486   u32 sw_if_index = 0;
6487   u8 sw_if_index_set = 0;
6488   u8 is_enable = 1;
6489   u8 is_ipv6 = 0;
6490   int ret;
6491
6492   /* Parse args required to build the message */
6493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6494     {
6495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6496         sw_if_index_set = 1;
6497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6498         sw_if_index_set = 1;
6499       else if (unformat (i, "enable"))
6500         is_enable = 1;
6501       else if (unformat (i, "disable"))
6502         is_enable = 0;
6503       else if (unformat (i, "ip4"))
6504         is_ipv6 = 0;
6505       else if (unformat (i, "ip6"))
6506         is_ipv6 = 1;
6507       else
6508         break;
6509     }
6510
6511   if (sw_if_index_set == 0)
6512     {
6513       errmsg ("missing interface name or sw_if_index");
6514       return -99;
6515     }
6516
6517   /* Construct the API message */
6518   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6519
6520   mp->sw_if_index = ntohl (sw_if_index);
6521   mp->enable = is_enable;
6522   mp->is_ipv6 = is_ipv6;
6523
6524   /* send it... */
6525   S (mp);
6526
6527   /* Wait for a reply... */
6528   W (ret);
6529   return ret;
6530 }
6531
6532 static int
6533 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6534 {
6535   unformat_input_t *i = vam->input;
6536   vl_api_sw_interface_set_l2_xconnect_t *mp;
6537   u32 rx_sw_if_index;
6538   u8 rx_sw_if_index_set = 0;
6539   u32 tx_sw_if_index;
6540   u8 tx_sw_if_index_set = 0;
6541   u8 enable = 1;
6542   int ret;
6543
6544   /* Parse args required to build the message */
6545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6546     {
6547       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6548         rx_sw_if_index_set = 1;
6549       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6550         tx_sw_if_index_set = 1;
6551       else if (unformat (i, "rx"))
6552         {
6553           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6554             {
6555               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6556                             &rx_sw_if_index))
6557                 rx_sw_if_index_set = 1;
6558             }
6559           else
6560             break;
6561         }
6562       else if (unformat (i, "tx"))
6563         {
6564           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565             {
6566               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6567                             &tx_sw_if_index))
6568                 tx_sw_if_index_set = 1;
6569             }
6570           else
6571             break;
6572         }
6573       else if (unformat (i, "enable"))
6574         enable = 1;
6575       else if (unformat (i, "disable"))
6576         enable = 0;
6577       else
6578         break;
6579     }
6580
6581   if (rx_sw_if_index_set == 0)
6582     {
6583       errmsg ("missing rx interface name or rx_sw_if_index");
6584       return -99;
6585     }
6586
6587   if (enable && (tx_sw_if_index_set == 0))
6588     {
6589       errmsg ("missing tx interface name or tx_sw_if_index");
6590       return -99;
6591     }
6592
6593   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6594
6595   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6596   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6597   mp->enable = enable;
6598
6599   S (mp);
6600   W (ret);
6601   return ret;
6602 }
6603
6604 static int
6605 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6606 {
6607   unformat_input_t *i = vam->input;
6608   vl_api_sw_interface_set_l2_bridge_t *mp;
6609   vl_api_l2_port_type_t port_type;
6610   u32 rx_sw_if_index;
6611   u8 rx_sw_if_index_set = 0;
6612   u32 bd_id;
6613   u8 bd_id_set = 0;
6614   u32 shg = 0;
6615   u8 enable = 1;
6616   int ret;
6617
6618   port_type = L2_API_PORT_TYPE_NORMAL;
6619
6620   /* Parse args required to build the message */
6621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6622     {
6623       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6624         rx_sw_if_index_set = 1;
6625       else if (unformat (i, "bd_id %d", &bd_id))
6626         bd_id_set = 1;
6627       else
6628         if (unformat
6629             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6630         rx_sw_if_index_set = 1;
6631       else if (unformat (i, "shg %d", &shg))
6632         ;
6633       else if (unformat (i, "bvi"))
6634         port_type = L2_API_PORT_TYPE_BVI;
6635       else if (unformat (i, "uu-fwd"))
6636         port_type = L2_API_PORT_TYPE_UU_FWD;
6637       else if (unformat (i, "enable"))
6638         enable = 1;
6639       else if (unformat (i, "disable"))
6640         enable = 0;
6641       else
6642         break;
6643     }
6644
6645   if (rx_sw_if_index_set == 0)
6646     {
6647       errmsg ("missing rx interface name or sw_if_index");
6648       return -99;
6649     }
6650
6651   if (enable && (bd_id_set == 0))
6652     {
6653       errmsg ("missing bridge domain");
6654       return -99;
6655     }
6656
6657   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6658
6659   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6660   mp->bd_id = ntohl (bd_id);
6661   mp->shg = (u8) shg;
6662   mp->port_type = ntohl (port_type);
6663   mp->enable = enable;
6664
6665   S (mp);
6666   W (ret);
6667   return ret;
6668 }
6669
6670 static int
6671 api_bridge_domain_dump (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_bridge_domain_dump_t *mp;
6675   vl_api_control_ping_t *mp_ping;
6676   u32 bd_id = ~0;
6677   int ret;
6678
6679   /* Parse args required to build the message */
6680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6681     {
6682       if (unformat (i, "bd_id %d", &bd_id))
6683         ;
6684       else
6685         break;
6686     }
6687
6688   M (BRIDGE_DOMAIN_DUMP, mp);
6689   mp->bd_id = ntohl (bd_id);
6690   S (mp);
6691
6692   /* Use a control ping for synchronization */
6693   MPING (CONTROL_PING, mp_ping);
6694   S (mp_ping);
6695
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static int
6701 api_bridge_domain_add_del (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_bridge_domain_add_del_t *mp;
6705   u32 bd_id = ~0;
6706   u8 is_add = 1;
6707   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6708   u8 *bd_tag = NULL;
6709   u32 mac_age = 0;
6710   int ret;
6711
6712   /* Parse args required to build the message */
6713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6714     {
6715       if (unformat (i, "bd_id %d", &bd_id))
6716         ;
6717       else if (unformat (i, "flood %d", &flood))
6718         ;
6719       else if (unformat (i, "uu-flood %d", &uu_flood))
6720         ;
6721       else if (unformat (i, "forward %d", &forward))
6722         ;
6723       else if (unformat (i, "learn %d", &learn))
6724         ;
6725       else if (unformat (i, "arp-term %d", &arp_term))
6726         ;
6727       else if (unformat (i, "mac-age %d", &mac_age))
6728         ;
6729       else if (unformat (i, "bd-tag %s", &bd_tag))
6730         ;
6731       else if (unformat (i, "del"))
6732         {
6733           is_add = 0;
6734           flood = uu_flood = forward = learn = 0;
6735         }
6736       else
6737         break;
6738     }
6739
6740   if (bd_id == ~0)
6741     {
6742       errmsg ("missing bridge domain");
6743       ret = -99;
6744       goto done;
6745     }
6746
6747   if (mac_age > 255)
6748     {
6749       errmsg ("mac age must be less than 256 ");
6750       ret = -99;
6751       goto done;
6752     }
6753
6754   if ((bd_tag) && (vec_len (bd_tag) > 63))
6755     {
6756       errmsg ("bd-tag cannot be longer than 63");
6757       ret = -99;
6758       goto done;
6759     }
6760
6761   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6762
6763   mp->bd_id = ntohl (bd_id);
6764   mp->flood = flood;
6765   mp->uu_flood = uu_flood;
6766   mp->forward = forward;
6767   mp->learn = learn;
6768   mp->arp_term = arp_term;
6769   mp->is_add = is_add;
6770   mp->mac_age = (u8) mac_age;
6771   if (bd_tag)
6772     {
6773       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6774       mp->bd_tag[vec_len (bd_tag)] = 0;
6775     }
6776   S (mp);
6777   W (ret);
6778
6779 done:
6780   vec_free (bd_tag);
6781   return ret;
6782 }
6783
6784 static int
6785 api_l2fib_flush_bd (vat_main_t * vam)
6786 {
6787   unformat_input_t *i = vam->input;
6788   vl_api_l2fib_flush_bd_t *mp;
6789   u32 bd_id = ~0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "bd_id %d", &bd_id));
6796       else
6797         break;
6798     }
6799
6800   if (bd_id == ~0)
6801     {
6802       errmsg ("missing bridge domain");
6803       return -99;
6804     }
6805
6806   M (L2FIB_FLUSH_BD, mp);
6807
6808   mp->bd_id = htonl (bd_id);
6809
6810   S (mp);
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_l2fib_flush_int (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_l2fib_flush_int_t *mp;
6820   u32 sw_if_index = ~0;
6821   int ret;
6822
6823   /* Parse args required to build the message */
6824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825     {
6826       if (unformat (i, "sw_if_index %d", &sw_if_index));
6827       else
6828         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6829       else
6830         break;
6831     }
6832
6833   if (sw_if_index == ~0)
6834     {
6835       errmsg ("missing interface name or sw_if_index");
6836       return -99;
6837     }
6838
6839   M (L2FIB_FLUSH_INT, mp);
6840
6841   mp->sw_if_index = ntohl (sw_if_index);
6842
6843   S (mp);
6844   W (ret);
6845   return ret;
6846 }
6847
6848 static int
6849 api_l2fib_add_del (vat_main_t * vam)
6850 {
6851   unformat_input_t *i = vam->input;
6852   vl_api_l2fib_add_del_t *mp;
6853   f64 timeout;
6854   u8 mac[6] = { 0 };
6855   u8 mac_set = 0;
6856   u32 bd_id;
6857   u8 bd_id_set = 0;
6858   u32 sw_if_index = 0;
6859   u8 sw_if_index_set = 0;
6860   u8 is_add = 1;
6861   u8 static_mac = 0;
6862   u8 filter_mac = 0;
6863   u8 bvi_mac = 0;
6864   int count = 1;
6865   f64 before = 0;
6866   int j;
6867
6868   /* Parse args required to build the message */
6869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6870     {
6871       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6872         mac_set = 1;
6873       else if (unformat (i, "bd_id %d", &bd_id))
6874         bd_id_set = 1;
6875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6876         sw_if_index_set = 1;
6877       else if (unformat (i, "sw_if"))
6878         {
6879           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6880             {
6881               if (unformat
6882                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6883                 sw_if_index_set = 1;
6884             }
6885           else
6886             break;
6887         }
6888       else if (unformat (i, "static"))
6889         static_mac = 1;
6890       else if (unformat (i, "filter"))
6891         {
6892           filter_mac = 1;
6893           static_mac = 1;
6894         }
6895       else if (unformat (i, "bvi"))
6896         {
6897           bvi_mac = 1;
6898           static_mac = 1;
6899         }
6900       else if (unformat (i, "del"))
6901         is_add = 0;
6902       else if (unformat (i, "count %d", &count))
6903         ;
6904       else
6905         break;
6906     }
6907
6908   if (mac_set == 0)
6909     {
6910       errmsg ("missing mac address");
6911       return -99;
6912     }
6913
6914   if (bd_id_set == 0)
6915     {
6916       errmsg ("missing bridge domain");
6917       return -99;
6918     }
6919
6920   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6921     {
6922       errmsg ("missing interface name or sw_if_index");
6923       return -99;
6924     }
6925
6926   if (count > 1)
6927     {
6928       /* Turn on async mode */
6929       vam->async_mode = 1;
6930       vam->async_errors = 0;
6931       before = vat_time_now (vam);
6932     }
6933
6934   for (j = 0; j < count; j++)
6935     {
6936       M (L2FIB_ADD_DEL, mp);
6937
6938       clib_memcpy (mp->mac, mac, 6);
6939       mp->bd_id = ntohl (bd_id);
6940       mp->is_add = is_add;
6941       mp->sw_if_index = ntohl (sw_if_index);
6942
6943       if (is_add)
6944         {
6945           mp->static_mac = static_mac;
6946           mp->filter_mac = filter_mac;
6947           mp->bvi_mac = bvi_mac;
6948         }
6949       increment_mac_address (mac);
6950       /* send it... */
6951       S (mp);
6952     }
6953
6954   if (count > 1)
6955     {
6956       vl_api_control_ping_t *mp_ping;
6957       f64 after;
6958
6959       /* Shut off async mode */
6960       vam->async_mode = 0;
6961
6962       MPING (CONTROL_PING, mp_ping);
6963       S (mp_ping);
6964
6965       timeout = vat_time_now (vam) + 1.0;
6966       while (vat_time_now (vam) < timeout)
6967         if (vam->result_ready == 1)
6968           goto out;
6969       vam->retval = -99;
6970
6971     out:
6972       if (vam->retval == -99)
6973         errmsg ("timeout");
6974
6975       if (vam->async_errors > 0)
6976         {
6977           errmsg ("%d asynchronous errors", vam->async_errors);
6978           vam->retval = -98;
6979         }
6980       vam->async_errors = 0;
6981       after = vat_time_now (vam);
6982
6983       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6984              count, after - before, count / (after - before));
6985     }
6986   else
6987     {
6988       int ret;
6989
6990       /* Wait for a reply... */
6991       W (ret);
6992       return ret;
6993     }
6994   /* Return the good/bad news */
6995   return (vam->retval);
6996 }
6997
6998 static int
6999 api_bridge_domain_set_mac_age (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_bridge_domain_set_mac_age_t *mp;
7003   u32 bd_id = ~0;
7004   u32 mac_age = 0;
7005   int ret;
7006
7007   /* Parse args required to build the message */
7008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7009     {
7010       if (unformat (i, "bd_id %d", &bd_id));
7011       else if (unformat (i, "mac-age %d", &mac_age));
7012       else
7013         break;
7014     }
7015
7016   if (bd_id == ~0)
7017     {
7018       errmsg ("missing bridge domain");
7019       return -99;
7020     }
7021
7022   if (mac_age > 255)
7023     {
7024       errmsg ("mac age must be less than 256 ");
7025       return -99;
7026     }
7027
7028   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7029
7030   mp->bd_id = htonl (bd_id);
7031   mp->mac_age = (u8) mac_age;
7032
7033   S (mp);
7034   W (ret);
7035   return ret;
7036 }
7037
7038 static int
7039 api_l2_flags (vat_main_t * vam)
7040 {
7041   unformat_input_t *i = vam->input;
7042   vl_api_l2_flags_t *mp;
7043   u32 sw_if_index;
7044   u32 flags = 0;
7045   u8 sw_if_index_set = 0;
7046   u8 is_set = 0;
7047   int ret;
7048
7049   /* Parse args required to build the message */
7050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7051     {
7052       if (unformat (i, "sw_if_index %d", &sw_if_index))
7053         sw_if_index_set = 1;
7054       else if (unformat (i, "sw_if"))
7055         {
7056           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7057             {
7058               if (unformat
7059                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7060                 sw_if_index_set = 1;
7061             }
7062           else
7063             break;
7064         }
7065       else if (unformat (i, "learn"))
7066         flags |= L2_LEARN;
7067       else if (unformat (i, "forward"))
7068         flags |= L2_FWD;
7069       else if (unformat (i, "flood"))
7070         flags |= L2_FLOOD;
7071       else if (unformat (i, "uu-flood"))
7072         flags |= L2_UU_FLOOD;
7073       else if (unformat (i, "arp-term"))
7074         flags |= L2_ARP_TERM;
7075       else if (unformat (i, "off"))
7076         is_set = 0;
7077       else if (unformat (i, "disable"))
7078         is_set = 0;
7079       else
7080         break;
7081     }
7082
7083   if (sw_if_index_set == 0)
7084     {
7085       errmsg ("missing interface name or sw_if_index");
7086       return -99;
7087     }
7088
7089   M (L2_FLAGS, mp);
7090
7091   mp->sw_if_index = ntohl (sw_if_index);
7092   mp->feature_bitmap = ntohl (flags);
7093   mp->is_set = is_set;
7094
7095   S (mp);
7096   W (ret);
7097   return ret;
7098 }
7099
7100 static int
7101 api_bridge_flags (vat_main_t * vam)
7102 {
7103   unformat_input_t *i = vam->input;
7104   vl_api_bridge_flags_t *mp;
7105   u32 bd_id;
7106   u8 bd_id_set = 0;
7107   u8 is_set = 1;
7108   bd_flags_t flags = 0;
7109   int ret;
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "bd_id %d", &bd_id))
7115         bd_id_set = 1;
7116       else if (unformat (i, "learn"))
7117         flags |= BRIDGE_API_FLAG_LEARN;
7118       else if (unformat (i, "forward"))
7119         flags |= BRIDGE_API_FLAG_FWD;
7120       else if (unformat (i, "flood"))
7121         flags |= BRIDGE_API_FLAG_FLOOD;
7122       else if (unformat (i, "uu-flood"))
7123         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7124       else if (unformat (i, "arp-term"))
7125         flags |= BRIDGE_API_FLAG_ARP_TERM;
7126       else if (unformat (i, "off"))
7127         is_set = 0;
7128       else if (unformat (i, "disable"))
7129         is_set = 0;
7130       else
7131         break;
7132     }
7133
7134   if (bd_id_set == 0)
7135     {
7136       errmsg ("missing bridge domain");
7137       return -99;
7138     }
7139
7140   M (BRIDGE_FLAGS, mp);
7141
7142   mp->bd_id = ntohl (bd_id);
7143   mp->flags = ntohl (flags);
7144   mp->is_set = is_set;
7145
7146   S (mp);
7147   W (ret);
7148   return ret;
7149 }
7150
7151 static int
7152 api_bd_ip_mac_add_del (vat_main_t * vam)
7153 {
7154   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7155   vl_api_mac_address_t mac = { 0 };
7156   unformat_input_t *i = vam->input;
7157   vl_api_bd_ip_mac_add_del_t *mp;
7158   u32 bd_id;
7159   u8 is_add = 1;
7160   u8 bd_id_set = 0;
7161   u8 ip_set = 0;
7162   u8 mac_set = 0;
7163   int ret;
7164
7165
7166   /* Parse args required to build the message */
7167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7168     {
7169       if (unformat (i, "bd_id %d", &bd_id))
7170         {
7171           bd_id_set++;
7172         }
7173       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7174         {
7175           ip_set++;
7176         }
7177       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7178         {
7179           mac_set++;
7180         }
7181       else if (unformat (i, "del"))
7182         is_add = 0;
7183       else
7184         break;
7185     }
7186
7187   if (bd_id_set == 0)
7188     {
7189       errmsg ("missing bridge domain");
7190       return -99;
7191     }
7192   else if (ip_set == 0)
7193     {
7194       errmsg ("missing IP address");
7195       return -99;
7196     }
7197   else if (mac_set == 0)
7198     {
7199       errmsg ("missing MAC address");
7200       return -99;
7201     }
7202
7203   M (BD_IP_MAC_ADD_DEL, mp);
7204
7205   mp->entry.bd_id = ntohl (bd_id);
7206   mp->is_add = is_add;
7207
7208   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7209   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7210
7211   S (mp);
7212   W (ret);
7213   return ret;
7214 }
7215
7216 static int
7217 api_bd_ip_mac_flush (vat_main_t * vam)
7218 {
7219   unformat_input_t *i = vam->input;
7220   vl_api_bd_ip_mac_flush_t *mp;
7221   u32 bd_id;
7222   u8 bd_id_set = 0;
7223   int ret;
7224
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "bd_id %d", &bd_id))
7228         {
7229           bd_id_set++;
7230         }
7231       else
7232         break;
7233     }
7234
7235   if (bd_id_set == 0)
7236     {
7237       errmsg ("missing bridge domain");
7238       return -99;
7239     }
7240
7241   M (BD_IP_MAC_FLUSH, mp);
7242
7243   mp->bd_id = ntohl (bd_id);
7244
7245   S (mp);
7246   W (ret);
7247   return ret;
7248 }
7249
7250 static void vl_api_bd_ip_mac_details_t_handler
7251   (vl_api_bd_ip_mac_details_t * mp)
7252 {
7253   vat_main_t *vam = &vat_main;
7254
7255   print (vam->ofp,
7256          "\n%-5d %U %U",
7257          ntohl (mp->entry.bd_id),
7258          format_vl_api_mac_address, mp->entry.mac,
7259          format_vl_api_address, &mp->entry.ip);
7260 }
7261
7262 static void vl_api_bd_ip_mac_details_t_handler_json
7263   (vl_api_bd_ip_mac_details_t * mp)
7264 {
7265   vat_main_t *vam = &vat_main;
7266   vat_json_node_t *node = NULL;
7267
7268   if (VAT_JSON_ARRAY != vam->json_tree.type)
7269     {
7270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7271       vat_json_init_array (&vam->json_tree);
7272     }
7273   node = vat_json_array_add (&vam->json_tree);
7274
7275   vat_json_init_object (node);
7276   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7277   vat_json_object_add_string_copy (node, "mac_address",
7278                                    format (0, "%U", format_vl_api_mac_address,
7279                                            &mp->entry.mac));
7280   u8 *ip = 0;
7281
7282   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7283   vat_json_object_add_string_copy (node, "ip_address", ip);
7284   vec_free (ip);
7285 }
7286
7287 static int
7288 api_bd_ip_mac_dump (vat_main_t * vam)
7289 {
7290   unformat_input_t *i = vam->input;
7291   vl_api_bd_ip_mac_dump_t *mp;
7292   vl_api_control_ping_t *mp_ping;
7293   int ret;
7294   u32 bd_id;
7295   u8 bd_id_set = 0;
7296
7297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7298     {
7299       if (unformat (i, "bd_id %d", &bd_id))
7300         {
7301           bd_id_set++;
7302         }
7303       else
7304         break;
7305     }
7306
7307   print (vam->ofp,
7308          "\n%-5s %-7s %-20s %-30s",
7309          "bd_id", "is_ipv6", "mac_address", "ip_address");
7310
7311   /* Dump Bridge Domain Ip to Mac entries */
7312   M (BD_IP_MAC_DUMP, mp);
7313
7314   if (bd_id_set)
7315     mp->bd_id = htonl (bd_id);
7316   else
7317     mp->bd_id = ~0;
7318
7319   S (mp);
7320
7321   /* Use a control ping for synchronization */
7322   MPING (CONTROL_PING, mp_ping);
7323   S (mp_ping);
7324
7325   W (ret);
7326   return ret;
7327 }
7328
7329 static int
7330 api_tap_create_v2 (vat_main_t * vam)
7331 {
7332   unformat_input_t *i = vam->input;
7333   vl_api_tap_create_v2_t *mp;
7334 #define TAP_FLAG_GSO (1 << 0)
7335   u8 mac_address[6];
7336   u8 random_mac = 1;
7337   u32 id = ~0;
7338   u8 *host_if_name = 0;
7339   u8 host_if_name_set = 0;
7340   u8 *host_ns = 0;
7341   u8 host_ns_set = 0;
7342   u8 host_mac_addr[6];
7343   u8 host_mac_addr_set = 0;
7344   u8 *host_bridge = 0;
7345   u8 host_bridge_set = 0;
7346   u8 host_ip4_addr_set = 0;
7347   ip4_address_t host_ip4_addr;
7348   ip4_address_t host_ip4_gw;
7349   u8 host_ip4_gw_set = 0;
7350   u32 host_ip4_prefix_len = 0;
7351   u8 host_ip6_addr_set = 0;
7352   ip6_address_t host_ip6_addr;
7353   ip6_address_t host_ip6_gw;
7354   u8 host_ip6_gw_set = 0;
7355   u32 host_ip6_prefix_len = 0;
7356   u8 host_mtu_set = 0;
7357   u32 host_mtu_size = 0;
7358   u32 tap_flags = 0;
7359   int ret;
7360   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7361
7362   clib_memset (mac_address, 0, sizeof (mac_address));
7363
7364   /* Parse args required to build the message */
7365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7366     {
7367       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7368         {
7369           random_mac = 0;
7370         }
7371       else if (unformat (i, "id %u", &id))
7372         ;
7373       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7374         ;
7375       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7376         ;
7377       else if (unformat (i, "host-if-name %s", &host_if_name))
7378         host_if_name_set = 1;
7379       else if (unformat (i, "host-ns %s", &host_ns))
7380         host_ns_set = 1;
7381       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7382                          host_mac_addr))
7383         host_mac_addr_set = 1;
7384       else if (unformat (i, "host-bridge %s", &host_bridge))
7385         host_bridge_set = 1;
7386       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7387                          &host_ip4_addr, &host_ip4_prefix_len))
7388         host_ip4_addr_set = 1;
7389       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7390                          &host_ip6_addr, &host_ip6_prefix_len))
7391         host_ip6_addr_set = 1;
7392       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7393                          &host_ip4_gw))
7394         host_ip4_gw_set = 1;
7395       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7396                          &host_ip6_gw))
7397         host_ip6_gw_set = 1;
7398       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7399         host_mtu_set = 1;
7400       else if (unformat (i, "no-gso"))
7401         tap_flags &= ~TAP_FLAG_GSO;
7402       else if (unformat (i, "gso"))
7403         tap_flags |= TAP_FLAG_GSO;
7404       else
7405         break;
7406     }
7407
7408   if (vec_len (host_if_name) > 63)
7409     {
7410       errmsg ("tap name too long. ");
7411       return -99;
7412     }
7413   if (vec_len (host_ns) > 63)
7414     {
7415       errmsg ("host name space too long. ");
7416       return -99;
7417     }
7418   if (vec_len (host_bridge) > 63)
7419     {
7420       errmsg ("host bridge name too long. ");
7421       return -99;
7422     }
7423   if (host_ip4_prefix_len > 32)
7424     {
7425       errmsg ("host ip4 prefix length not valid. ");
7426       return -99;
7427     }
7428   if (host_ip6_prefix_len > 128)
7429     {
7430       errmsg ("host ip6 prefix length not valid. ");
7431       return -99;
7432     }
7433   if (!is_pow2 (rx_ring_sz))
7434     {
7435       errmsg ("rx ring size must be power of 2. ");
7436       return -99;
7437     }
7438   if (rx_ring_sz > 32768)
7439     {
7440       errmsg ("rx ring size must be 32768 or lower. ");
7441       return -99;
7442     }
7443   if (!is_pow2 (tx_ring_sz))
7444     {
7445       errmsg ("tx ring size must be power of 2. ");
7446       return -99;
7447     }
7448   if (tx_ring_sz > 32768)
7449     {
7450       errmsg ("tx ring size must be 32768 or lower. ");
7451       return -99;
7452     }
7453   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7454     {
7455       errmsg ("host MTU size must be in between 64 and 65355. ");
7456       return -99;
7457     }
7458
7459   /* Construct the API message */
7460   M (TAP_CREATE_V2, mp);
7461
7462   mp->id = ntohl (id);
7463   mp->use_random_mac = random_mac;
7464   mp->rx_ring_sz = ntohs (rx_ring_sz);
7465   mp->tx_ring_sz = ntohs (tx_ring_sz);
7466   mp->host_if_name_set = host_if_name_set;
7467   mp->host_namespace_set = host_ns_set;
7468   mp->host_mac_addr_set = host_mac_addr_set;
7469   mp->host_bridge_set = host_bridge_set;
7470   mp->host_ip4_addr_set = host_ip4_addr_set;
7471   mp->host_ip6_addr_set = host_ip6_addr_set;
7472   mp->host_ip4_gw_set = host_ip4_gw_set;
7473   mp->host_ip6_gw_set = host_ip6_gw_set;
7474   mp->host_mtu_set = host_mtu_set;
7475   mp->host_mtu_size = ntohl (host_mtu_size);
7476   mp->tap_flags = ntohl (tap_flags);
7477
7478   if (random_mac == 0)
7479     clib_memcpy (mp->mac_address, mac_address, 6);
7480   if (host_mac_addr_set)
7481     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7482   if (host_if_name_set)
7483     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7484   if (host_ns_set)
7485     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7486   if (host_bridge_set)
7487     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7488   if (host_ip4_addr_set)
7489     {
7490       clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7491       mp->host_ip4_prefix_len = (u8) host_ip4_prefix_len;
7492     }
7493   if (host_ip6_addr_set)
7494     {
7495       clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7496       mp->host_ip6_prefix_len = (u8) host_ip4_prefix_len;
7497     }
7498   if (host_ip4_gw_set)
7499     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7500   if (host_ip6_gw_set)
7501     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7502
7503   vec_free (host_ns);
7504   vec_free (host_if_name);
7505   vec_free (host_bridge);
7506
7507   /* send it... */
7508   S (mp);
7509
7510   /* Wait for a reply... */
7511   W (ret);
7512   return ret;
7513 }
7514
7515 static int
7516 api_tap_delete_v2 (vat_main_t * vam)
7517 {
7518   unformat_input_t *i = vam->input;
7519   vl_api_tap_delete_v2_t *mp;
7520   u32 sw_if_index = ~0;
7521   u8 sw_if_index_set = 0;
7522   int ret;
7523
7524   /* Parse args required to build the message */
7525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7526     {
7527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7528         sw_if_index_set = 1;
7529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7530         sw_if_index_set = 1;
7531       else
7532         break;
7533     }
7534
7535   if (sw_if_index_set == 0)
7536     {
7537       errmsg ("missing vpp interface name. ");
7538       return -99;
7539     }
7540
7541   /* Construct the API message */
7542   M (TAP_DELETE_V2, mp);
7543
7544   mp->sw_if_index = ntohl (sw_if_index);
7545
7546   /* send it... */
7547   S (mp);
7548
7549   /* Wait for a reply... */
7550   W (ret);
7551   return ret;
7552 }
7553
7554 uword
7555 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7556 {
7557   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7558   u32 x[4];
7559
7560   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7561     return 0;
7562
7563   addr->domain = x[0];
7564   addr->bus = x[1];
7565   addr->slot = x[2];
7566   addr->function = x[3];
7567
7568   return 1;
7569 }
7570
7571 static int
7572 api_virtio_pci_create (vat_main_t * vam)
7573 {
7574   unformat_input_t *i = vam->input;
7575   vl_api_virtio_pci_create_t *mp;
7576   u8 mac_address[6];
7577   u8 random_mac = 1;
7578   u8 gso_enabled = 0;
7579   u32 pci_addr = 0;
7580   u64 features = (u64) ~ (0ULL);
7581   int ret;
7582
7583   clib_memset (mac_address, 0, sizeof (mac_address));
7584
7585   /* Parse args required to build the message */
7586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7587     {
7588       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7589         {
7590           random_mac = 0;
7591         }
7592       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7593         ;
7594       else if (unformat (i, "features 0x%llx", &features))
7595         ;
7596       else if (unformat (i, "gso-enabled"))
7597         gso_enabled = 1;
7598       else
7599         break;
7600     }
7601
7602   if (pci_addr == 0)
7603     {
7604       errmsg ("pci address must be non zero. ");
7605       return -99;
7606     }
7607
7608   /* Construct the API message */
7609   M (VIRTIO_PCI_CREATE, mp);
7610
7611   mp->use_random_mac = random_mac;
7612
7613   mp->pci_addr = htonl (pci_addr);
7614   mp->features = clib_host_to_net_u64 (features);
7615   mp->gso_enabled = gso_enabled;
7616
7617   if (random_mac == 0)
7618     clib_memcpy (mp->mac_address, mac_address, 6);
7619
7620   /* send it... */
7621   S (mp);
7622
7623   /* Wait for a reply... */
7624   W (ret);
7625   return ret;
7626 }
7627
7628 static int
7629 api_virtio_pci_delete (vat_main_t * vam)
7630 {
7631   unformat_input_t *i = vam->input;
7632   vl_api_virtio_pci_delete_t *mp;
7633   u32 sw_if_index = ~0;
7634   u8 sw_if_index_set = 0;
7635   int ret;
7636
7637   /* Parse args required to build the message */
7638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7639     {
7640       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7641         sw_if_index_set = 1;
7642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7643         sw_if_index_set = 1;
7644       else
7645         break;
7646     }
7647
7648   if (sw_if_index_set == 0)
7649     {
7650       errmsg ("missing vpp interface name. ");
7651       return -99;
7652     }
7653
7654   /* Construct the API message */
7655   M (VIRTIO_PCI_DELETE, mp);
7656
7657   mp->sw_if_index = htonl (sw_if_index);
7658
7659   /* send it... */
7660   S (mp);
7661
7662   /* Wait for a reply... */
7663   W (ret);
7664   return ret;
7665 }
7666
7667 static int
7668 api_bond_create (vat_main_t * vam)
7669 {
7670   unformat_input_t *i = vam->input;
7671   vl_api_bond_create_t *mp;
7672   u8 mac_address[6];
7673   u8 custom_mac = 0;
7674   int ret;
7675   u8 mode;
7676   u8 lb;
7677   u8 mode_is_set = 0;
7678   u32 id = ~0;
7679   u8 numa_only = 0;
7680
7681   clib_memset (mac_address, 0, sizeof (mac_address));
7682   lb = BOND_LB_L2;
7683
7684   /* Parse args required to build the message */
7685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7686     {
7687       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7688         mode_is_set = 1;
7689       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7690                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7691         ;
7692       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7693                          mac_address))
7694         custom_mac = 1;
7695       else if (unformat (i, "numa-only"))
7696         numa_only = 1;
7697       else if (unformat (i, "id %u", &id))
7698         ;
7699       else
7700         break;
7701     }
7702
7703   if (mode_is_set == 0)
7704     {
7705       errmsg ("Missing bond mode. ");
7706       return -99;
7707     }
7708
7709   /* Construct the API message */
7710   M (BOND_CREATE, mp);
7711
7712   mp->use_custom_mac = custom_mac;
7713
7714   mp->mode = mode;
7715   mp->lb = lb;
7716   mp->id = htonl (id);
7717   mp->numa_only = numa_only;
7718
7719   if (custom_mac)
7720     clib_memcpy (mp->mac_address, mac_address, 6);
7721
7722   /* send it... */
7723   S (mp);
7724
7725   /* Wait for a reply... */
7726   W (ret);
7727   return ret;
7728 }
7729
7730 static int
7731 api_bond_delete (vat_main_t * vam)
7732 {
7733   unformat_input_t *i = vam->input;
7734   vl_api_bond_delete_t *mp;
7735   u32 sw_if_index = ~0;
7736   u8 sw_if_index_set = 0;
7737   int ret;
7738
7739   /* Parse args required to build the message */
7740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7741     {
7742       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7743         sw_if_index_set = 1;
7744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7745         sw_if_index_set = 1;
7746       else
7747         break;
7748     }
7749
7750   if (sw_if_index_set == 0)
7751     {
7752       errmsg ("missing vpp interface name. ");
7753       return -99;
7754     }
7755
7756   /* Construct the API message */
7757   M (BOND_DELETE, mp);
7758
7759   mp->sw_if_index = ntohl (sw_if_index);
7760
7761   /* send it... */
7762   S (mp);
7763
7764   /* Wait for a reply... */
7765   W (ret);
7766   return ret;
7767 }
7768
7769 static int
7770 api_bond_enslave (vat_main_t * vam)
7771 {
7772   unformat_input_t *i = vam->input;
7773   vl_api_bond_enslave_t *mp;
7774   u32 bond_sw_if_index;
7775   int ret;
7776   u8 is_passive;
7777   u8 is_long_timeout;
7778   u32 bond_sw_if_index_is_set = 0;
7779   u32 sw_if_index;
7780   u8 sw_if_index_is_set = 0;
7781
7782   /* Parse args required to build the message */
7783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7784     {
7785       if (unformat (i, "sw_if_index %d", &sw_if_index))
7786         sw_if_index_is_set = 1;
7787       else if (unformat (i, "bond %u", &bond_sw_if_index))
7788         bond_sw_if_index_is_set = 1;
7789       else if (unformat (i, "passive %d", &is_passive))
7790         ;
7791       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7792         ;
7793       else
7794         break;
7795     }
7796
7797   if (bond_sw_if_index_is_set == 0)
7798     {
7799       errmsg ("Missing bond sw_if_index. ");
7800       return -99;
7801     }
7802   if (sw_if_index_is_set == 0)
7803     {
7804       errmsg ("Missing slave sw_if_index. ");
7805       return -99;
7806     }
7807
7808   /* Construct the API message */
7809   M (BOND_ENSLAVE, mp);
7810
7811   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7812   mp->sw_if_index = ntohl (sw_if_index);
7813   mp->is_long_timeout = is_long_timeout;
7814   mp->is_passive = is_passive;
7815
7816   /* send it... */
7817   S (mp);
7818
7819   /* Wait for a reply... */
7820   W (ret);
7821   return ret;
7822 }
7823
7824 static int
7825 api_bond_detach_slave (vat_main_t * vam)
7826 {
7827   unformat_input_t *i = vam->input;
7828   vl_api_bond_detach_slave_t *mp;
7829   u32 sw_if_index = ~0;
7830   u8 sw_if_index_set = 0;
7831   int ret;
7832
7833   /* Parse args required to build the message */
7834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7835     {
7836       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7837         sw_if_index_set = 1;
7838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7839         sw_if_index_set = 1;
7840       else
7841         break;
7842     }
7843
7844   if (sw_if_index_set == 0)
7845     {
7846       errmsg ("missing vpp interface name. ");
7847       return -99;
7848     }
7849
7850   /* Construct the API message */
7851   M (BOND_DETACH_SLAVE, mp);
7852
7853   mp->sw_if_index = ntohl (sw_if_index);
7854
7855   /* send it... */
7856   S (mp);
7857
7858   /* Wait for a reply... */
7859   W (ret);
7860   return ret;
7861 }
7862
7863 static int
7864 api_ip_table_add_del (vat_main_t * vam)
7865 {
7866   unformat_input_t *i = vam->input;
7867   vl_api_ip_table_add_del_t *mp;
7868   u32 table_id = ~0;
7869   u8 is_ipv6 = 0;
7870   u8 is_add = 1;
7871   int ret = 0;
7872
7873   /* Parse args required to build the message */
7874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7875     {
7876       if (unformat (i, "ipv6"))
7877         is_ipv6 = 1;
7878       else if (unformat (i, "del"))
7879         is_add = 0;
7880       else if (unformat (i, "add"))
7881         is_add = 1;
7882       else if (unformat (i, "table %d", &table_id))
7883         ;
7884       else
7885         {
7886           clib_warning ("parse error '%U'", format_unformat_error, i);
7887           return -99;
7888         }
7889     }
7890
7891   if (~0 == table_id)
7892     {
7893       errmsg ("missing table-ID");
7894       return -99;
7895     }
7896
7897   /* Construct the API message */
7898   M (IP_TABLE_ADD_DEL, mp);
7899
7900   mp->table.table_id = ntohl (table_id);
7901   mp->table.is_ip6 = is_ipv6;
7902   mp->is_add = is_add;
7903
7904   /* send it... */
7905   S (mp);
7906
7907   /* Wait for a reply... */
7908   W (ret);
7909
7910   return ret;
7911 }
7912
7913 uword
7914 unformat_fib_path (unformat_input_t * input, va_list * args)
7915 {
7916   vat_main_t *vam = va_arg (*args, vat_main_t *);
7917   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7918   u32 weight, preference;
7919   mpls_label_t out_label;
7920
7921   clib_memset (path, 0, sizeof (*path));
7922   path->weight = 1;
7923   path->sw_if_index = ~0;
7924   path->rpf_id = ~0;
7925   path->n_labels = 0;
7926
7927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (input, "%U %U",
7930                     unformat_vl_api_ip4_address,
7931                     &path->nh.address.ip4,
7932                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7933         {
7934           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7935         }
7936       else if (unformat (input, "%U %U",
7937                          unformat_vl_api_ip6_address,
7938                          &path->nh.address.ip6,
7939                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7940         {
7941           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7942         }
7943       else if (unformat (input, "weight %u", &weight))
7944         {
7945           path->weight = weight;
7946         }
7947       else if (unformat (input, "preference %u", &preference))
7948         {
7949           path->preference = preference;
7950         }
7951       else if (unformat (input, "%U next-hop-table %d",
7952                          unformat_vl_api_ip4_address,
7953                          &path->nh.address.ip4, &path->table_id))
7954         {
7955           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7956         }
7957       else if (unformat (input, "%U next-hop-table %d",
7958                          unformat_vl_api_ip6_address,
7959                          &path->nh.address.ip6, &path->table_id))
7960         {
7961           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7962         }
7963       else if (unformat (input, "%U",
7964                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7965         {
7966           /*
7967            * the recursive next-hops are by default in the default table
7968            */
7969           path->table_id = 0;
7970           path->sw_if_index = ~0;
7971           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7972         }
7973       else if (unformat (input, "%U",
7974                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7975         {
7976           /*
7977            * the recursive next-hops are by default in the default table
7978            */
7979           path->table_id = 0;
7980           path->sw_if_index = ~0;
7981           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7982         }
7983       else if (unformat (input, "resolve-via-host"))
7984         {
7985           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7986         }
7987       else if (unformat (input, "resolve-via-attached"))
7988         {
7989           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7990         }
7991       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7992         {
7993           path->type = FIB_API_PATH_TYPE_LOCAL;
7994           path->sw_if_index = ~0;
7995           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7996         }
7997       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7998         {
7999           path->type = FIB_API_PATH_TYPE_LOCAL;
8000           path->sw_if_index = ~0;
8001           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8002         }
8003       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8004         ;
8005       else if (unformat (input, "via-label %d", &path->nh.via_label))
8006         {
8007           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8008           path->sw_if_index = ~0;
8009         }
8010       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8011         {
8012           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8013           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8014         }
8015       else if (unformat (input, "local"))
8016         {
8017           path->type = FIB_API_PATH_TYPE_LOCAL;
8018         }
8019       else if (unformat (input, "out-labels"))
8020         {
8021           while (unformat (input, "%d", &out_label))
8022             {
8023               path->label_stack[path->n_labels].label = out_label;
8024               path->label_stack[path->n_labels].is_uniform = 0;
8025               path->label_stack[path->n_labels].ttl = 64;
8026               path->n_labels++;
8027             }
8028         }
8029       else if (unformat (input, "via"))
8030         {
8031           /* new path, back up and return */
8032           unformat_put_input (input);
8033           unformat_put_input (input);
8034           unformat_put_input (input);
8035           unformat_put_input (input);
8036           break;
8037         }
8038       else
8039         {
8040           return (0);
8041         }
8042     }
8043
8044   path->proto = ntohl (path->proto);
8045   path->type = ntohl (path->type);
8046   path->flags = ntohl (path->flags);
8047   path->table_id = ntohl (path->table_id);
8048   path->sw_if_index = ntohl (path->sw_if_index);
8049
8050   return (1);
8051 }
8052
8053 static int
8054 api_ip_route_add_del (vat_main_t * vam)
8055 {
8056   unformat_input_t *i = vam->input;
8057   vl_api_ip_route_add_del_t *mp;
8058   u32 vrf_id = 0;
8059   u8 is_add = 1;
8060   u8 is_multipath = 0;
8061   u8 prefix_set = 0;
8062   u8 path_count = 0;
8063   vl_api_prefix_t pfx = { };
8064   vl_api_fib_path_t paths[8];
8065   int count = 1;
8066   int j;
8067   f64 before = 0;
8068   u32 random_add_del = 0;
8069   u32 *random_vector = 0;
8070   u32 random_seed = 0xdeaddabe;
8071
8072   /* Parse args required to build the message */
8073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8074     {
8075       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8076         prefix_set = 1;
8077       else if (unformat (i, "del"))
8078         is_add = 0;
8079       else if (unformat (i, "add"))
8080         is_add = 1;
8081       else if (unformat (i, "vrf %d", &vrf_id))
8082         ;
8083       else if (unformat (i, "count %d", &count))
8084         ;
8085       else if (unformat (i, "random"))
8086         random_add_del = 1;
8087       else if (unformat (i, "multipath"))
8088         is_multipath = 1;
8089       else if (unformat (i, "seed %d", &random_seed))
8090         ;
8091       else
8092         if (unformat
8093             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8094         {
8095           path_count++;
8096           if (8 == path_count)
8097             {
8098               errmsg ("max 8 paths");
8099               return -99;
8100             }
8101         }
8102       else
8103         {
8104           clib_warning ("parse error '%U'", format_unformat_error, i);
8105           return -99;
8106         }
8107     }
8108
8109   if (!path_count)
8110     {
8111       errmsg ("specify a path; via ...");
8112       return -99;
8113     }
8114   if (prefix_set == 0)
8115     {
8116       errmsg ("missing prefix");
8117       return -99;
8118     }
8119
8120   /* Generate a pile of unique, random routes */
8121   if (random_add_del)
8122     {
8123       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8124       u32 this_random_address;
8125       uword *random_hash;
8126
8127       random_hash = hash_create (count, sizeof (uword));
8128
8129       hash_set (random_hash, i->as_u32, 1);
8130       for (j = 0; j <= count; j++)
8131         {
8132           do
8133             {
8134               this_random_address = random_u32 (&random_seed);
8135               this_random_address =
8136                 clib_host_to_net_u32 (this_random_address);
8137             }
8138           while (hash_get (random_hash, this_random_address));
8139           vec_add1 (random_vector, this_random_address);
8140           hash_set (random_hash, this_random_address, 1);
8141         }
8142       hash_free (random_hash);
8143       set_ip4_address (&pfx.address, random_vector[0]);
8144     }
8145
8146   if (count > 1)
8147     {
8148       /* Turn on async mode */
8149       vam->async_mode = 1;
8150       vam->async_errors = 0;
8151       before = vat_time_now (vam);
8152     }
8153
8154   for (j = 0; j < count; j++)
8155     {
8156       /* Construct the API message */
8157       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8158
8159       mp->is_add = is_add;
8160       mp->is_multipath = is_multipath;
8161
8162       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8163       mp->route.table_id = ntohl (vrf_id);
8164       mp->route.n_paths = path_count;
8165
8166       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8167
8168       if (random_add_del)
8169         set_ip4_address (&pfx.address, random_vector[j + 1]);
8170       else
8171         increment_address (&pfx.address);
8172       /* send it... */
8173       S (mp);
8174       /* If we receive SIGTERM, stop now... */
8175       if (vam->do_exit)
8176         break;
8177     }
8178
8179   /* When testing multiple add/del ops, use a control-ping to sync */
8180   if (count > 1)
8181     {
8182       vl_api_control_ping_t *mp_ping;
8183       f64 after;
8184       f64 timeout;
8185
8186       /* Shut off async mode */
8187       vam->async_mode = 0;
8188
8189       MPING (CONTROL_PING, mp_ping);
8190       S (mp_ping);
8191
8192       timeout = vat_time_now (vam) + 1.0;
8193       while (vat_time_now (vam) < timeout)
8194         if (vam->result_ready == 1)
8195           goto out;
8196       vam->retval = -99;
8197
8198     out:
8199       if (vam->retval == -99)
8200         errmsg ("timeout");
8201
8202       if (vam->async_errors > 0)
8203         {
8204           errmsg ("%d asynchronous errors", vam->async_errors);
8205           vam->retval = -98;
8206         }
8207       vam->async_errors = 0;
8208       after = vat_time_now (vam);
8209
8210       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8211       if (j > 0)
8212         count = j;
8213
8214       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8215              count, after - before, count / (after - before));
8216     }
8217   else
8218     {
8219       int ret;
8220
8221       /* Wait for a reply... */
8222       W (ret);
8223       return ret;
8224     }
8225
8226   /* Return the good/bad news */
8227   return (vam->retval);
8228 }
8229
8230 static int
8231 api_ip_mroute_add_del (vat_main_t * vam)
8232 {
8233   unformat_input_t *i = vam->input;
8234   u8 path_set = 0, prefix_set = 0, is_add = 1;
8235   vl_api_ip_mroute_add_del_t *mp;
8236   mfib_entry_flags_t eflags = 0;
8237   vl_api_mfib_path_t path;
8238   vl_api_mprefix_t pfx = { };
8239   u32 vrf_id = 0;
8240   int ret;
8241
8242   /* Parse args required to build the message */
8243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8244     {
8245       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8246         {
8247           prefix_set = 1;
8248           pfx.grp_address_length = htons (pfx.grp_address_length);
8249         }
8250       else if (unformat (i, "del"))
8251         is_add = 0;
8252       else if (unformat (i, "add"))
8253         is_add = 1;
8254       else if (unformat (i, "vrf %d", &vrf_id))
8255         ;
8256       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8257         path.itf_flags = htonl (path.itf_flags);
8258       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8259         ;
8260       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8261         path_set = 1;
8262       else
8263         {
8264           clib_warning ("parse error '%U'", format_unformat_error, i);
8265           return -99;
8266         }
8267     }
8268
8269   if (prefix_set == 0)
8270     {
8271       errmsg ("missing addresses\n");
8272       return -99;
8273     }
8274   if (path_set == 0)
8275     {
8276       errmsg ("missing path\n");
8277       return -99;
8278     }
8279
8280   /* Construct the API message */
8281   M (IP_MROUTE_ADD_DEL, mp);
8282
8283   mp->is_add = is_add;
8284   mp->is_multipath = 1;
8285
8286   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8287   mp->route.table_id = htonl (vrf_id);
8288   mp->route.n_paths = 1;
8289   mp->route.entry_flags = htonl (eflags);
8290
8291   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8292
8293   /* send it... */
8294   S (mp);
8295   /* Wait for a reply... */
8296   W (ret);
8297   return ret;
8298 }
8299
8300 static int
8301 api_mpls_table_add_del (vat_main_t * vam)
8302 {
8303   unformat_input_t *i = vam->input;
8304   vl_api_mpls_table_add_del_t *mp;
8305   u32 table_id = ~0;
8306   u8 is_add = 1;
8307   int ret = 0;
8308
8309   /* Parse args required to build the message */
8310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8311     {
8312       if (unformat (i, "table %d", &table_id))
8313         ;
8314       else if (unformat (i, "del"))
8315         is_add = 0;
8316       else if (unformat (i, "add"))
8317         is_add = 1;
8318       else
8319         {
8320           clib_warning ("parse error '%U'", format_unformat_error, i);
8321           return -99;
8322         }
8323     }
8324
8325   if (~0 == table_id)
8326     {
8327       errmsg ("missing table-ID");
8328       return -99;
8329     }
8330
8331   /* Construct the API message */
8332   M (MPLS_TABLE_ADD_DEL, mp);
8333
8334   mp->mt_table.mt_table_id = ntohl (table_id);
8335   mp->mt_is_add = is_add;
8336
8337   /* send it... */
8338   S (mp);
8339
8340   /* Wait for a reply... */
8341   W (ret);
8342
8343   return ret;
8344 }
8345
8346 static int
8347 api_mpls_route_add_del (vat_main_t * vam)
8348 {
8349   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8350   mpls_label_t local_label = MPLS_LABEL_INVALID;
8351   unformat_input_t *i = vam->input;
8352   vl_api_mpls_route_add_del_t *mp;
8353   vl_api_fib_path_t paths[8];
8354   int count = 1, j;
8355   f64 before = 0;
8356
8357   /* Parse args required to build the message */
8358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8359     {
8360       if (unformat (i, "%d", &local_label))
8361         ;
8362       else if (unformat (i, "eos"))
8363         is_eos = 1;
8364       else if (unformat (i, "non-eos"))
8365         is_eos = 0;
8366       else if (unformat (i, "del"))
8367         is_add = 0;
8368       else if (unformat (i, "add"))
8369         is_add = 1;
8370       else if (unformat (i, "multipath"))
8371         is_multipath = 1;
8372       else if (unformat (i, "count %d", &count))
8373         ;
8374       else
8375         if (unformat
8376             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8377         {
8378           path_count++;
8379           if (8 == path_count)
8380             {
8381               errmsg ("max 8 paths");
8382               return -99;
8383             }
8384         }
8385       else
8386         {
8387           clib_warning ("parse error '%U'", format_unformat_error, i);
8388           return -99;
8389         }
8390     }
8391
8392   if (!path_count)
8393     {
8394       errmsg ("specify a path; via ...");
8395       return -99;
8396     }
8397
8398   if (MPLS_LABEL_INVALID == local_label)
8399     {
8400       errmsg ("missing label");
8401       return -99;
8402     }
8403
8404   if (count > 1)
8405     {
8406       /* Turn on async mode */
8407       vam->async_mode = 1;
8408       vam->async_errors = 0;
8409       before = vat_time_now (vam);
8410     }
8411
8412   for (j = 0; j < count; j++)
8413     {
8414       /* Construct the API message */
8415       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8416
8417       mp->mr_is_add = is_add;
8418       mp->mr_is_multipath = is_multipath;
8419
8420       mp->mr_route.mr_label = local_label;
8421       mp->mr_route.mr_eos = is_eos;
8422       mp->mr_route.mr_table_id = 0;
8423       mp->mr_route.mr_n_paths = path_count;
8424
8425       clib_memcpy (&mp->mr_route.mr_paths, paths,
8426                    sizeof (paths[0]) * path_count);
8427
8428       local_label++;
8429
8430       /* send it... */
8431       S (mp);
8432       /* If we receive SIGTERM, stop now... */
8433       if (vam->do_exit)
8434         break;
8435     }
8436
8437   /* When testing multiple add/del ops, use a control-ping to sync */
8438   if (count > 1)
8439     {
8440       vl_api_control_ping_t *mp_ping;
8441       f64 after;
8442       f64 timeout;
8443
8444       /* Shut off async mode */
8445       vam->async_mode = 0;
8446
8447       MPING (CONTROL_PING, mp_ping);
8448       S (mp_ping);
8449
8450       timeout = vat_time_now (vam) + 1.0;
8451       while (vat_time_now (vam) < timeout)
8452         if (vam->result_ready == 1)
8453           goto out;
8454       vam->retval = -99;
8455
8456     out:
8457       if (vam->retval == -99)
8458         errmsg ("timeout");
8459
8460       if (vam->async_errors > 0)
8461         {
8462           errmsg ("%d asynchronous errors", vam->async_errors);
8463           vam->retval = -98;
8464         }
8465       vam->async_errors = 0;
8466       after = vat_time_now (vam);
8467
8468       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8469       if (j > 0)
8470         count = j;
8471
8472       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8473              count, after - before, count / (after - before));
8474     }
8475   else
8476     {
8477       int ret;
8478
8479       /* Wait for a reply... */
8480       W (ret);
8481       return ret;
8482     }
8483
8484   /* Return the good/bad news */
8485   return (vam->retval);
8486   return (0);
8487 }
8488
8489 static int
8490 api_mpls_ip_bind_unbind (vat_main_t * vam)
8491 {
8492   unformat_input_t *i = vam->input;
8493   vl_api_mpls_ip_bind_unbind_t *mp;
8494   u32 ip_table_id = 0;
8495   u8 is_bind = 1;
8496   vl_api_prefix_t pfx;
8497   u8 prefix_set = 0;
8498   mpls_label_t local_label = MPLS_LABEL_INVALID;
8499   int ret;
8500
8501   /* Parse args required to build the message */
8502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8503     {
8504       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8505         prefix_set = 1;
8506       else if (unformat (i, "%d", &local_label))
8507         ;
8508       else if (unformat (i, "table-id %d", &ip_table_id))
8509         ;
8510       else if (unformat (i, "unbind"))
8511         is_bind = 0;
8512       else if (unformat (i, "bind"))
8513         is_bind = 1;
8514       else
8515         {
8516           clib_warning ("parse error '%U'", format_unformat_error, i);
8517           return -99;
8518         }
8519     }
8520
8521   if (!prefix_set)
8522     {
8523       errmsg ("IP prefix not set");
8524       return -99;
8525     }
8526
8527   if (MPLS_LABEL_INVALID == local_label)
8528     {
8529       errmsg ("missing label");
8530       return -99;
8531     }
8532
8533   /* Construct the API message */
8534   M (MPLS_IP_BIND_UNBIND, mp);
8535
8536   mp->mb_is_bind = is_bind;
8537   mp->mb_ip_table_id = ntohl (ip_table_id);
8538   mp->mb_mpls_table_id = 0;
8539   mp->mb_label = ntohl (local_label);
8540   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8541
8542   /* send it... */
8543   S (mp);
8544
8545   /* Wait for a reply... */
8546   W (ret);
8547   return ret;
8548   return (0);
8549 }
8550
8551 static int
8552 api_sr_mpls_policy_add (vat_main_t * vam)
8553 {
8554   unformat_input_t *i = vam->input;
8555   vl_api_sr_mpls_policy_add_t *mp;
8556   u32 bsid = 0;
8557   u32 weight = 1;
8558   u8 type = 0;
8559   u8 n_segments = 0;
8560   u32 sid;
8561   u32 *segments = NULL;
8562   int ret;
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "bsid %d", &bsid))
8568         ;
8569       else if (unformat (i, "weight %d", &weight))
8570         ;
8571       else if (unformat (i, "spray"))
8572         type = 1;
8573       else if (unformat (i, "next %d", &sid))
8574         {
8575           n_segments += 1;
8576           vec_add1 (segments, htonl (sid));
8577         }
8578       else
8579         {
8580           clib_warning ("parse error '%U'", format_unformat_error, i);
8581           return -99;
8582         }
8583     }
8584
8585   if (bsid == 0)
8586     {
8587       errmsg ("bsid not set");
8588       return -99;
8589     }
8590
8591   if (n_segments == 0)
8592     {
8593       errmsg ("no sid in segment stack");
8594       return -99;
8595     }
8596
8597   /* Construct the API message */
8598   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8599
8600   mp->bsid = htonl (bsid);
8601   mp->weight = htonl (weight);
8602   mp->type = type;
8603   mp->n_segments = n_segments;
8604   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8605   vec_free (segments);
8606
8607   /* send it... */
8608   S (mp);
8609
8610   /* Wait for a reply... */
8611   W (ret);
8612   return ret;
8613 }
8614
8615 static int
8616 api_sr_mpls_policy_del (vat_main_t * vam)
8617 {
8618   unformat_input_t *i = vam->input;
8619   vl_api_sr_mpls_policy_del_t *mp;
8620   u32 bsid = 0;
8621   int ret;
8622
8623   /* Parse args required to build the message */
8624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8625     {
8626       if (unformat (i, "bsid %d", &bsid))
8627         ;
8628       else
8629         {
8630           clib_warning ("parse error '%U'", format_unformat_error, i);
8631           return -99;
8632         }
8633     }
8634
8635   if (bsid == 0)
8636     {
8637       errmsg ("bsid not set");
8638       return -99;
8639     }
8640
8641   /* Construct the API message */
8642   M (SR_MPLS_POLICY_DEL, mp);
8643
8644   mp->bsid = htonl (bsid);
8645
8646   /* send it... */
8647   S (mp);
8648
8649   /* Wait for a reply... */
8650   W (ret);
8651   return ret;
8652 }
8653
8654 static int
8655 api_bier_table_add_del (vat_main_t * vam)
8656 {
8657   unformat_input_t *i = vam->input;
8658   vl_api_bier_table_add_del_t *mp;
8659   u8 is_add = 1;
8660   u32 set = 0, sub_domain = 0, hdr_len = 3;
8661   mpls_label_t local_label = MPLS_LABEL_INVALID;
8662   int ret;
8663
8664   /* Parse args required to build the message */
8665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8666     {
8667       if (unformat (i, "sub-domain %d", &sub_domain))
8668         ;
8669       else if (unformat (i, "set %d", &set))
8670         ;
8671       else if (unformat (i, "label %d", &local_label))
8672         ;
8673       else if (unformat (i, "hdr-len %d", &hdr_len))
8674         ;
8675       else if (unformat (i, "add"))
8676         is_add = 1;
8677       else if (unformat (i, "del"))
8678         is_add = 0;
8679       else
8680         {
8681           clib_warning ("parse error '%U'", format_unformat_error, i);
8682           return -99;
8683         }
8684     }
8685
8686   if (MPLS_LABEL_INVALID == local_label)
8687     {
8688       errmsg ("missing label\n");
8689       return -99;
8690     }
8691
8692   /* Construct the API message */
8693   M (BIER_TABLE_ADD_DEL, mp);
8694
8695   mp->bt_is_add = is_add;
8696   mp->bt_label = ntohl (local_label);
8697   mp->bt_tbl_id.bt_set = set;
8698   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8699   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8700
8701   /* send it... */
8702   S (mp);
8703
8704   /* Wait for a reply... */
8705   W (ret);
8706
8707   return (ret);
8708 }
8709
8710 static int
8711 api_bier_route_add_del (vat_main_t * vam)
8712 {
8713   unformat_input_t *i = vam->input;
8714   vl_api_bier_route_add_del_t *mp;
8715   u8 is_add = 1;
8716   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8717   ip4_address_t v4_next_hop_address;
8718   ip6_address_t v6_next_hop_address;
8719   u8 next_hop_set = 0;
8720   u8 next_hop_proto_is_ip4 = 1;
8721   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8722   int ret;
8723
8724   /* Parse args required to build the message */
8725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8726     {
8727       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8728         {
8729           next_hop_proto_is_ip4 = 1;
8730           next_hop_set = 1;
8731         }
8732       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8733         {
8734           next_hop_proto_is_ip4 = 0;
8735           next_hop_set = 1;
8736         }
8737       if (unformat (i, "sub-domain %d", &sub_domain))
8738         ;
8739       else if (unformat (i, "set %d", &set))
8740         ;
8741       else if (unformat (i, "hdr-len %d", &hdr_len))
8742         ;
8743       else if (unformat (i, "bp %d", &bp))
8744         ;
8745       else if (unformat (i, "add"))
8746         is_add = 1;
8747       else if (unformat (i, "del"))
8748         is_add = 0;
8749       else if (unformat (i, "out-label %d", &next_hop_out_label))
8750         ;
8751       else
8752         {
8753           clib_warning ("parse error '%U'", format_unformat_error, i);
8754           return -99;
8755         }
8756     }
8757
8758   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8759     {
8760       errmsg ("next hop / label set\n");
8761       return -99;
8762     }
8763   if (0 == bp)
8764     {
8765       errmsg ("bit=position not set\n");
8766       return -99;
8767     }
8768
8769   /* Construct the API message */
8770   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8771
8772   mp->br_is_add = is_add;
8773   mp->br_route.br_tbl_id.bt_set = set;
8774   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8775   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8776   mp->br_route.br_bp = ntohs (bp);
8777   mp->br_route.br_n_paths = 1;
8778   mp->br_route.br_paths[0].n_labels = 1;
8779   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8780   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8781                                     FIB_API_PATH_NH_PROTO_IP4 :
8782                                     FIB_API_PATH_NH_PROTO_IP6);
8783
8784   if (next_hop_proto_is_ip4)
8785     {
8786       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8787                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8788     }
8789   else
8790     {
8791       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8792                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8793     }
8794
8795   /* send it... */
8796   S (mp);
8797
8798   /* Wait for a reply... */
8799   W (ret);
8800
8801   return (ret);
8802 }
8803
8804 static int
8805 api_proxy_arp_add_del (vat_main_t * vam)
8806 {
8807   unformat_input_t *i = vam->input;
8808   vl_api_proxy_arp_add_del_t *mp;
8809   u32 vrf_id = 0;
8810   u8 is_add = 1;
8811   vl_api_ip4_address_t lo, hi;
8812   u8 range_set = 0;
8813   int ret;
8814
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "vrf %d", &vrf_id))
8818         ;
8819       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8820                          unformat_vl_api_ip4_address, &hi))
8821         range_set = 1;
8822       else if (unformat (i, "del"))
8823         is_add = 0;
8824       else
8825         {
8826           clib_warning ("parse error '%U'", format_unformat_error, i);
8827           return -99;
8828         }
8829     }
8830
8831   if (range_set == 0)
8832     {
8833       errmsg ("address range not set");
8834       return -99;
8835     }
8836
8837   M (PROXY_ARP_ADD_DEL, mp);
8838
8839   mp->proxy.table_id = ntohl (vrf_id);
8840   mp->is_add = is_add;
8841   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8842   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8843
8844   S (mp);
8845   W (ret);
8846   return ret;
8847 }
8848
8849 static int
8850 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8851 {
8852   unformat_input_t *i = vam->input;
8853   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8854   u32 sw_if_index;
8855   u8 enable = 1;
8856   u8 sw_if_index_set = 0;
8857   int ret;
8858
8859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8860     {
8861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8862         sw_if_index_set = 1;
8863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8864         sw_if_index_set = 1;
8865       else if (unformat (i, "enable"))
8866         enable = 1;
8867       else if (unformat (i, "disable"))
8868         enable = 0;
8869       else
8870         {
8871           clib_warning ("parse error '%U'", format_unformat_error, i);
8872           return -99;
8873         }
8874     }
8875
8876   if (sw_if_index_set == 0)
8877     {
8878       errmsg ("missing interface name or sw_if_index");
8879       return -99;
8880     }
8881
8882   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8883
8884   mp->sw_if_index = ntohl (sw_if_index);
8885   mp->enable_disable = enable;
8886
8887   S (mp);
8888   W (ret);
8889   return ret;
8890 }
8891
8892 static int
8893 api_mpls_tunnel_add_del (vat_main_t * vam)
8894 {
8895   unformat_input_t *i = vam->input;
8896   vl_api_mpls_tunnel_add_del_t *mp;
8897
8898   vl_api_fib_path_t paths[8];
8899   u32 sw_if_index = ~0;
8900   u8 path_count = 0;
8901   u8 l2_only = 0;
8902   u8 is_add = 1;
8903   int ret;
8904
8905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8906     {
8907       if (unformat (i, "add"))
8908         is_add = 1;
8909       else
8910         if (unformat
8911             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8912         is_add = 0;
8913       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8914         is_add = 0;
8915       else if (unformat (i, "l2-only"))
8916         l2_only = 1;
8917       else
8918         if (unformat
8919             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8920         {
8921           path_count++;
8922           if (8 == path_count)
8923             {
8924               errmsg ("max 8 paths");
8925               return -99;
8926             }
8927         }
8928       else
8929         {
8930           clib_warning ("parse error '%U'", format_unformat_error, i);
8931           return -99;
8932         }
8933     }
8934
8935   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8936
8937   mp->mt_is_add = is_add;
8938   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8939   mp->mt_tunnel.mt_l2_only = l2_only;
8940   mp->mt_tunnel.mt_is_multicast = 0;
8941   mp->mt_tunnel.mt_n_paths = path_count;
8942
8943   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8944                sizeof (paths[0]) * path_count);
8945
8946   S (mp);
8947   W (ret);
8948   return ret;
8949 }
8950
8951 static int
8952 api_sw_interface_set_unnumbered (vat_main_t * vam)
8953 {
8954   unformat_input_t *i = vam->input;
8955   vl_api_sw_interface_set_unnumbered_t *mp;
8956   u32 sw_if_index;
8957   u32 unnum_sw_index = ~0;
8958   u8 is_add = 1;
8959   u8 sw_if_index_set = 0;
8960   int ret;
8961
8962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8963     {
8964       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8965         sw_if_index_set = 1;
8966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8969         ;
8970       else if (unformat (i, "del"))
8971         is_add = 0;
8972       else
8973         {
8974           clib_warning ("parse error '%U'", format_unformat_error, i);
8975           return -99;
8976         }
8977     }
8978
8979   if (sw_if_index_set == 0)
8980     {
8981       errmsg ("missing interface name or sw_if_index");
8982       return -99;
8983     }
8984
8985   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8986
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8989   mp->is_add = is_add;
8990
8991   S (mp);
8992   W (ret);
8993   return ret;
8994 }
8995
8996 static int
8997 api_ip_neighbor_add_del (vat_main_t * vam)
8998 {
8999   vl_api_mac_address_t mac_address;
9000   unformat_input_t *i = vam->input;
9001   vl_api_ip_neighbor_add_del_t *mp;
9002   vl_api_address_t ip_address;
9003   u32 sw_if_index;
9004   u8 sw_if_index_set = 0;
9005   u8 is_add = 1;
9006   u8 mac_set = 0;
9007   u8 address_set = 0;
9008   int ret;
9009   ip_neighbor_flags_t flags;
9010
9011   flags = IP_NEIGHBOR_FLAG_NONE;
9012   clib_memset (&ip_address, 0, sizeof (ip_address));
9013   clib_memset (&mac_address, 0, sizeof (mac_address));
9014
9015   /* Parse args required to build the message */
9016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9017     {
9018       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9019         {
9020           mac_set = 1;
9021         }
9022       else if (unformat (i, "del"))
9023         is_add = 0;
9024       else
9025         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9026         sw_if_index_set = 1;
9027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9028         sw_if_index_set = 1;
9029       else if (unformat (i, "static"))
9030         flags |= IP_NEIGHBOR_FLAG_STATIC;
9031       else if (unformat (i, "no-fib-entry"))
9032         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9033       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9034         address_set = 1;
9035       else
9036         {
9037           clib_warning ("parse error '%U'", format_unformat_error, i);
9038           return -99;
9039         }
9040     }
9041
9042   if (sw_if_index_set == 0)
9043     {
9044       errmsg ("missing interface name or sw_if_index");
9045       return -99;
9046     }
9047   if (!address_set)
9048     {
9049       errmsg ("no address set");
9050       return -99;
9051     }
9052
9053   /* Construct the API message */
9054   M (IP_NEIGHBOR_ADD_DEL, mp);
9055
9056   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9057   mp->is_add = is_add;
9058   mp->neighbor.flags = htonl (flags);
9059   if (mac_set)
9060     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9061                  sizeof (mac_address));
9062   if (address_set)
9063     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9064
9065   /* send it... */
9066   S (mp);
9067
9068   /* Wait for a reply, return good/bad news  */
9069   W (ret);
9070   return ret;
9071 }
9072
9073 static int
9074 api_create_vlan_subif (vat_main_t * vam)
9075 {
9076   unformat_input_t *i = vam->input;
9077   vl_api_create_vlan_subif_t *mp;
9078   u32 sw_if_index;
9079   u8 sw_if_index_set = 0;
9080   u32 vlan_id;
9081   u8 vlan_id_set = 0;
9082   int ret;
9083
9084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9085     {
9086       if (unformat (i, "sw_if_index %d", &sw_if_index))
9087         sw_if_index_set = 1;
9088       else
9089         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9090         sw_if_index_set = 1;
9091       else if (unformat (i, "vlan %d", &vlan_id))
9092         vlan_id_set = 1;
9093       else
9094         {
9095           clib_warning ("parse error '%U'", format_unformat_error, i);
9096           return -99;
9097         }
9098     }
9099
9100   if (sw_if_index_set == 0)
9101     {
9102       errmsg ("missing interface name or sw_if_index");
9103       return -99;
9104     }
9105
9106   if (vlan_id_set == 0)
9107     {
9108       errmsg ("missing vlan_id");
9109       return -99;
9110     }
9111   M (CREATE_VLAN_SUBIF, mp);
9112
9113   mp->sw_if_index = ntohl (sw_if_index);
9114   mp->vlan_id = ntohl (vlan_id);
9115
9116   S (mp);
9117   W (ret);
9118   return ret;
9119 }
9120
9121 #define foreach_create_subif_bit                \
9122 _(no_tags)                                      \
9123 _(one_tag)                                      \
9124 _(two_tags)                                     \
9125 _(dot1ad)                                       \
9126 _(exact_match)                                  \
9127 _(default_sub)                                  \
9128 _(outer_vlan_id_any)                            \
9129 _(inner_vlan_id_any)
9130
9131 static int
9132 api_create_subif (vat_main_t * vam)
9133 {
9134   unformat_input_t *i = vam->input;
9135   vl_api_create_subif_t *mp;
9136   u32 sw_if_index;
9137   u8 sw_if_index_set = 0;
9138   u32 sub_id;
9139   u8 sub_id_set = 0;
9140   u32 no_tags = 0;
9141   u32 one_tag = 0;
9142   u32 two_tags = 0;
9143   u32 dot1ad = 0;
9144   u32 exact_match = 0;
9145   u32 default_sub = 0;
9146   u32 outer_vlan_id_any = 0;
9147   u32 inner_vlan_id_any = 0;
9148   u32 tmp;
9149   u16 outer_vlan_id = 0;
9150   u16 inner_vlan_id = 0;
9151   int ret;
9152
9153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9154     {
9155       if (unformat (i, "sw_if_index %d", &sw_if_index))
9156         sw_if_index_set = 1;
9157       else
9158         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9159         sw_if_index_set = 1;
9160       else if (unformat (i, "sub_id %d", &sub_id))
9161         sub_id_set = 1;
9162       else if (unformat (i, "outer_vlan_id %d", &tmp))
9163         outer_vlan_id = tmp;
9164       else if (unformat (i, "inner_vlan_id %d", &tmp))
9165         inner_vlan_id = tmp;
9166
9167 #define _(a) else if (unformat (i, #a)) a = 1 ;
9168       foreach_create_subif_bit
9169 #undef _
9170         else
9171         {
9172           clib_warning ("parse error '%U'", format_unformat_error, i);
9173           return -99;
9174         }
9175     }
9176
9177   if (sw_if_index_set == 0)
9178     {
9179       errmsg ("missing interface name or sw_if_index");
9180       return -99;
9181     }
9182
9183   if (sub_id_set == 0)
9184     {
9185       errmsg ("missing sub_id");
9186       return -99;
9187     }
9188   M (CREATE_SUBIF, mp);
9189
9190   mp->sw_if_index = ntohl (sw_if_index);
9191   mp->sub_id = ntohl (sub_id);
9192
9193 #define _(a) mp->a = a;
9194   foreach_create_subif_bit;
9195 #undef _
9196
9197   mp->outer_vlan_id = ntohs (outer_vlan_id);
9198   mp->inner_vlan_id = ntohs (inner_vlan_id);
9199
9200   S (mp);
9201   W (ret);
9202   return ret;
9203 }
9204
9205 static int
9206 api_reset_fib (vat_main_t * vam)
9207 {
9208   unformat_input_t *i = vam->input;
9209   vl_api_reset_fib_t *mp;
9210   u32 vrf_id = 0;
9211   u8 is_ipv6 = 0;
9212   u8 vrf_id_set = 0;
9213
9214   int ret;
9215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9216     {
9217       if (unformat (i, "vrf %d", &vrf_id))
9218         vrf_id_set = 1;
9219       else if (unformat (i, "ipv6"))
9220         is_ipv6 = 1;
9221       else
9222         {
9223           clib_warning ("parse error '%U'", format_unformat_error, i);
9224           return -99;
9225         }
9226     }
9227
9228   if (vrf_id_set == 0)
9229     {
9230       errmsg ("missing vrf id");
9231       return -99;
9232     }
9233
9234   M (RESET_FIB, mp);
9235
9236   mp->vrf_id = ntohl (vrf_id);
9237   mp->is_ipv6 = is_ipv6;
9238
9239   S (mp);
9240   W (ret);
9241   return ret;
9242 }
9243
9244 static int
9245 api_dhcp_proxy_config (vat_main_t * vam)
9246 {
9247   unformat_input_t *i = vam->input;
9248   vl_api_dhcp_proxy_config_t *mp;
9249   u32 rx_vrf_id = 0;
9250   u32 server_vrf_id = 0;
9251   u8 is_add = 1;
9252   u8 v4_address_set = 0;
9253   u8 v6_address_set = 0;
9254   ip4_address_t v4address;
9255   ip6_address_t v6address;
9256   u8 v4_src_address_set = 0;
9257   u8 v6_src_address_set = 0;
9258   ip4_address_t v4srcaddress;
9259   ip6_address_t v6srcaddress;
9260   int ret;
9261
9262   /* Parse args required to build the message */
9263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9264     {
9265       if (unformat (i, "del"))
9266         is_add = 0;
9267       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9268         ;
9269       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9270         ;
9271       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9272         v4_address_set = 1;
9273       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9274         v6_address_set = 1;
9275       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9276         v4_src_address_set = 1;
9277       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9278         v6_src_address_set = 1;
9279       else
9280         break;
9281     }
9282
9283   if (v4_address_set && v6_address_set)
9284     {
9285       errmsg ("both v4 and v6 server addresses set");
9286       return -99;
9287     }
9288   if (!v4_address_set && !v6_address_set)
9289     {
9290       errmsg ("no server addresses set");
9291       return -99;
9292     }
9293
9294   if (v4_src_address_set && v6_src_address_set)
9295     {
9296       errmsg ("both v4 and v6  src addresses set");
9297       return -99;
9298     }
9299   if (!v4_src_address_set && !v6_src_address_set)
9300     {
9301       errmsg ("no src addresses set");
9302       return -99;
9303     }
9304
9305   if (!(v4_src_address_set && v4_address_set) &&
9306       !(v6_src_address_set && v6_address_set))
9307     {
9308       errmsg ("no matching server and src addresses set");
9309       return -99;
9310     }
9311
9312   /* Construct the API message */
9313   M (DHCP_PROXY_CONFIG, mp);
9314
9315   mp->is_add = is_add;
9316   mp->rx_vrf_id = ntohl (rx_vrf_id);
9317   mp->server_vrf_id = ntohl (server_vrf_id);
9318   if (v6_address_set)
9319     {
9320       mp->is_ipv6 = 1;
9321       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9322       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9323     }
9324   else
9325     {
9326       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9327       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9328     }
9329
9330   /* send it... */
9331   S (mp);
9332
9333   /* Wait for a reply, return good/bad news  */
9334   W (ret);
9335   return ret;
9336 }
9337
9338 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9339 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9340
9341 static void
9342 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9343 {
9344   vat_main_t *vam = &vat_main;
9345   u32 i, count = mp->count;
9346   vl_api_dhcp_server_t *s;
9347
9348   if (mp->is_ipv6)
9349     print (vam->ofp,
9350            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9351            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9352            ntohl (mp->rx_vrf_id),
9353            format_ip6_address, mp->dhcp_src_address,
9354            mp->vss_type, mp->vss_vpn_ascii_id,
9355            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9356   else
9357     print (vam->ofp,
9358            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9359            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9360            ntohl (mp->rx_vrf_id),
9361            format_ip4_address, mp->dhcp_src_address,
9362            mp->vss_type, mp->vss_vpn_ascii_id,
9363            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9364
9365   for (i = 0; i < count; i++)
9366     {
9367       s = &mp->servers[i];
9368
9369       if (mp->is_ipv6)
9370         print (vam->ofp,
9371                " Server Table-ID %d, Server Address %U",
9372                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9373       else
9374         print (vam->ofp,
9375                " Server Table-ID %d, Server Address %U",
9376                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9377     }
9378 }
9379
9380 static void vl_api_dhcp_proxy_details_t_handler_json
9381   (vl_api_dhcp_proxy_details_t * mp)
9382 {
9383   vat_main_t *vam = &vat_main;
9384   vat_json_node_t *node = NULL;
9385   u32 i, count = mp->count;
9386   struct in_addr ip4;
9387   struct in6_addr ip6;
9388   vl_api_dhcp_server_t *s;
9389
9390   if (VAT_JSON_ARRAY != vam->json_tree.type)
9391     {
9392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9393       vat_json_init_array (&vam->json_tree);
9394     }
9395   node = vat_json_array_add (&vam->json_tree);
9396
9397   vat_json_init_object (node);
9398   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9399   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9400                              sizeof (mp->vss_type));
9401   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9402                                    mp->vss_vpn_ascii_id);
9403   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9404   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9405
9406   if (mp->is_ipv6)
9407     {
9408       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9409       vat_json_object_add_ip6 (node, "src_address", ip6);
9410     }
9411   else
9412     {
9413       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9414       vat_json_object_add_ip4 (node, "src_address", ip4);
9415     }
9416
9417   for (i = 0; i < count; i++)
9418     {
9419       s = &mp->servers[i];
9420
9421       vat_json_object_add_uint (node, "server-table-id",
9422                                 ntohl (s->server_vrf_id));
9423
9424       if (mp->is_ipv6)
9425         {
9426           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9427           vat_json_object_add_ip4 (node, "src_address", ip4);
9428         }
9429       else
9430         {
9431           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9432           vat_json_object_add_ip6 (node, "server_address", ip6);
9433         }
9434     }
9435 }
9436
9437 static int
9438 api_dhcp_proxy_dump (vat_main_t * vam)
9439 {
9440   unformat_input_t *i = vam->input;
9441   vl_api_control_ping_t *mp_ping;
9442   vl_api_dhcp_proxy_dump_t *mp;
9443   u8 is_ipv6 = 0;
9444   int ret;
9445
9446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9447     {
9448       if (unformat (i, "ipv6"))
9449         is_ipv6 = 1;
9450       else
9451         {
9452           clib_warning ("parse error '%U'", format_unformat_error, i);
9453           return -99;
9454         }
9455     }
9456
9457   M (DHCP_PROXY_DUMP, mp);
9458
9459   mp->is_ip6 = is_ipv6;
9460   S (mp);
9461
9462   /* Use a control ping for synchronization */
9463   MPING (CONTROL_PING, mp_ping);
9464   S (mp_ping);
9465
9466   W (ret);
9467   return ret;
9468 }
9469
9470 static int
9471 api_dhcp_proxy_set_vss (vat_main_t * vam)
9472 {
9473   unformat_input_t *i = vam->input;
9474   vl_api_dhcp_proxy_set_vss_t *mp;
9475   u8 is_ipv6 = 0;
9476   u8 is_add = 1;
9477   u32 tbl_id = ~0;
9478   u8 vss_type = VSS_TYPE_DEFAULT;
9479   u8 *vpn_ascii_id = 0;
9480   u32 oui = 0;
9481   u32 fib_id = 0;
9482   int ret;
9483
9484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9485     {
9486       if (unformat (i, "tbl_id %d", &tbl_id))
9487         ;
9488       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9489         vss_type = VSS_TYPE_ASCII;
9490       else if (unformat (i, "fib_id %d", &fib_id))
9491         vss_type = VSS_TYPE_VPN_ID;
9492       else if (unformat (i, "oui %d", &oui))
9493         vss_type = VSS_TYPE_VPN_ID;
9494       else if (unformat (i, "ipv6"))
9495         is_ipv6 = 1;
9496       else if (unformat (i, "del"))
9497         is_add = 0;
9498       else
9499         break;
9500     }
9501
9502   if (tbl_id == ~0)
9503     {
9504       errmsg ("missing tbl_id ");
9505       vec_free (vpn_ascii_id);
9506       return -99;
9507     }
9508
9509   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9510     {
9511       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9512       vec_free (vpn_ascii_id);
9513       return -99;
9514     }
9515
9516   M (DHCP_PROXY_SET_VSS, mp);
9517   mp->tbl_id = ntohl (tbl_id);
9518   mp->vss_type = vss_type;
9519   if (vpn_ascii_id)
9520     {
9521       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9522       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9523     }
9524   mp->vpn_index = ntohl (fib_id);
9525   mp->oui = ntohl (oui);
9526   mp->is_ipv6 = is_ipv6;
9527   mp->is_add = is_add;
9528
9529   S (mp);
9530   W (ret);
9531
9532   vec_free (vpn_ascii_id);
9533   return ret;
9534 }
9535
9536 static int
9537 api_dhcp_client_config (vat_main_t * vam)
9538 {
9539   unformat_input_t *i = vam->input;
9540   vl_api_dhcp_client_config_t *mp;
9541   u32 sw_if_index;
9542   u8 sw_if_index_set = 0;
9543   u8 is_add = 1;
9544   u8 *hostname = 0;
9545   u8 disable_event = 0;
9546   int ret;
9547
9548   /* Parse args required to build the message */
9549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9550     {
9551       if (unformat (i, "del"))
9552         is_add = 0;
9553       else
9554         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "hostname %s", &hostname))
9559         ;
9560       else if (unformat (i, "disable_event"))
9561         disable_event = 1;
9562       else
9563         break;
9564     }
9565
9566   if (sw_if_index_set == 0)
9567     {
9568       errmsg ("missing interface name or sw_if_index");
9569       return -99;
9570     }
9571
9572   if (vec_len (hostname) > 63)
9573     {
9574       errmsg ("hostname too long");
9575     }
9576   vec_add1 (hostname, 0);
9577
9578   /* Construct the API message */
9579   M (DHCP_CLIENT_CONFIG, mp);
9580
9581   mp->is_add = is_add;
9582   mp->client.sw_if_index = htonl (sw_if_index);
9583   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9584   vec_free (hostname);
9585   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9586   mp->client.pid = htonl (getpid ());
9587
9588   /* send it... */
9589   S (mp);
9590
9591   /* Wait for a reply, return good/bad news  */
9592   W (ret);
9593   return ret;
9594 }
9595
9596 static int
9597 api_set_ip_flow_hash (vat_main_t * vam)
9598 {
9599   unformat_input_t *i = vam->input;
9600   vl_api_set_ip_flow_hash_t *mp;
9601   u32 vrf_id = 0;
9602   u8 is_ipv6 = 0;
9603   u8 vrf_id_set = 0;
9604   u8 src = 0;
9605   u8 dst = 0;
9606   u8 sport = 0;
9607   u8 dport = 0;
9608   u8 proto = 0;
9609   u8 reverse = 0;
9610   int ret;
9611
9612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9613     {
9614       if (unformat (i, "vrf %d", &vrf_id))
9615         vrf_id_set = 1;
9616       else if (unformat (i, "ipv6"))
9617         is_ipv6 = 1;
9618       else if (unformat (i, "src"))
9619         src = 1;
9620       else if (unformat (i, "dst"))
9621         dst = 1;
9622       else if (unformat (i, "sport"))
9623         sport = 1;
9624       else if (unformat (i, "dport"))
9625         dport = 1;
9626       else if (unformat (i, "proto"))
9627         proto = 1;
9628       else if (unformat (i, "reverse"))
9629         reverse = 1;
9630
9631       else
9632         {
9633           clib_warning ("parse error '%U'", format_unformat_error, i);
9634           return -99;
9635         }
9636     }
9637
9638   if (vrf_id_set == 0)
9639     {
9640       errmsg ("missing vrf id");
9641       return -99;
9642     }
9643
9644   M (SET_IP_FLOW_HASH, mp);
9645   mp->src = src;
9646   mp->dst = dst;
9647   mp->sport = sport;
9648   mp->dport = dport;
9649   mp->proto = proto;
9650   mp->reverse = reverse;
9651   mp->vrf_id = ntohl (vrf_id);
9652   mp->is_ipv6 = is_ipv6;
9653
9654   S (mp);
9655   W (ret);
9656   return ret;
9657 }
9658
9659 static int
9660 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9661 {
9662   unformat_input_t *i = vam->input;
9663   vl_api_sw_interface_ip6_enable_disable_t *mp;
9664   u32 sw_if_index;
9665   u8 sw_if_index_set = 0;
9666   u8 enable = 0;
9667   int ret;
9668
9669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9670     {
9671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9672         sw_if_index_set = 1;
9673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9674         sw_if_index_set = 1;
9675       else if (unformat (i, "enable"))
9676         enable = 1;
9677       else if (unformat (i, "disable"))
9678         enable = 0;
9679       else
9680         {
9681           clib_warning ("parse error '%U'", format_unformat_error, i);
9682           return -99;
9683         }
9684     }
9685
9686   if (sw_if_index_set == 0)
9687     {
9688       errmsg ("missing interface name or sw_if_index");
9689       return -99;
9690     }
9691
9692   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9693
9694   mp->sw_if_index = ntohl (sw_if_index);
9695   mp->enable = enable;
9696
9697   S (mp);
9698   W (ret);
9699   return ret;
9700 }
9701
9702 static int
9703 api_ip6nd_proxy_add_del (vat_main_t * vam)
9704 {
9705   unformat_input_t *i = vam->input;
9706   vl_api_ip6nd_proxy_add_del_t *mp;
9707   u32 sw_if_index = ~0;
9708   u8 v6_address_set = 0;
9709   vl_api_ip6_address_t v6address;
9710   u8 is_del = 0;
9711   int ret;
9712
9713   /* Parse args required to build the message */
9714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9715     {
9716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9717         ;
9718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9719         ;
9720       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9721         v6_address_set = 1;
9722       if (unformat (i, "del"))
9723         is_del = 1;
9724       else
9725         {
9726           clib_warning ("parse error '%U'", format_unformat_error, i);
9727           return -99;
9728         }
9729     }
9730
9731   if (sw_if_index == ~0)
9732     {
9733       errmsg ("missing interface name or sw_if_index");
9734       return -99;
9735     }
9736   if (!v6_address_set)
9737     {
9738       errmsg ("no address set");
9739       return -99;
9740     }
9741
9742   /* Construct the API message */
9743   M (IP6ND_PROXY_ADD_DEL, mp);
9744
9745   mp->is_del = is_del;
9746   mp->sw_if_index = ntohl (sw_if_index);
9747   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9748
9749   /* send it... */
9750   S (mp);
9751
9752   /* Wait for a reply, return good/bad news  */
9753   W (ret);
9754   return ret;
9755 }
9756
9757 static int
9758 api_ip6nd_proxy_dump (vat_main_t * vam)
9759 {
9760   vl_api_ip6nd_proxy_dump_t *mp;
9761   vl_api_control_ping_t *mp_ping;
9762   int ret;
9763
9764   M (IP6ND_PROXY_DUMP, mp);
9765
9766   S (mp);
9767
9768   /* Use a control ping for synchronization */
9769   MPING (CONTROL_PING, mp_ping);
9770   S (mp_ping);
9771
9772   W (ret);
9773   return ret;
9774 }
9775
9776 static void vl_api_ip6nd_proxy_details_t_handler
9777   (vl_api_ip6nd_proxy_details_t * mp)
9778 {
9779   vat_main_t *vam = &vat_main;
9780
9781   print (vam->ofp, "host %U sw_if_index %d",
9782          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9783 }
9784
9785 static void vl_api_ip6nd_proxy_details_t_handler_json
9786   (vl_api_ip6nd_proxy_details_t * mp)
9787 {
9788   vat_main_t *vam = &vat_main;
9789   struct in6_addr ip6;
9790   vat_json_node_t *node = NULL;
9791
9792   if (VAT_JSON_ARRAY != vam->json_tree.type)
9793     {
9794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9795       vat_json_init_array (&vam->json_tree);
9796     }
9797   node = vat_json_array_add (&vam->json_tree);
9798
9799   vat_json_init_object (node);
9800   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9801
9802   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9803   vat_json_object_add_ip6 (node, "host", ip6);
9804 }
9805
9806 static int
9807 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9808 {
9809   unformat_input_t *i = vam->input;
9810   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9811   u32 sw_if_index;
9812   u8 sw_if_index_set = 0;
9813   u8 v6_address_set = 0;
9814   vl_api_prefix_t pfx;
9815   u8 use_default = 0;
9816   u8 no_advertise = 0;
9817   u8 off_link = 0;
9818   u8 no_autoconfig = 0;
9819   u8 no_onlink = 0;
9820   u8 is_no = 0;
9821   u32 val_lifetime = 0;
9822   u32 pref_lifetime = 0;
9823   int ret;
9824
9825   /* Parse args required to build the message */
9826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9827     {
9828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9829         sw_if_index_set = 1;
9830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9831         sw_if_index_set = 1;
9832       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9833         v6_address_set = 1;
9834       else if (unformat (i, "val_life %d", &val_lifetime))
9835         ;
9836       else if (unformat (i, "pref_life %d", &pref_lifetime))
9837         ;
9838       else if (unformat (i, "def"))
9839         use_default = 1;
9840       else if (unformat (i, "noadv"))
9841         no_advertise = 1;
9842       else if (unformat (i, "offl"))
9843         off_link = 1;
9844       else if (unformat (i, "noauto"))
9845         no_autoconfig = 1;
9846       else if (unformat (i, "nolink"))
9847         no_onlink = 1;
9848       else if (unformat (i, "isno"))
9849         is_no = 1;
9850       else
9851         {
9852           clib_warning ("parse error '%U'", format_unformat_error, i);
9853           return -99;
9854         }
9855     }
9856
9857   if (sw_if_index_set == 0)
9858     {
9859       errmsg ("missing interface name or sw_if_index");
9860       return -99;
9861     }
9862   if (!v6_address_set)
9863     {
9864       errmsg ("no address set");
9865       return -99;
9866     }
9867
9868   /* Construct the API message */
9869   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9870
9871   mp->sw_if_index = ntohl (sw_if_index);
9872   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9873   mp->use_default = use_default;
9874   mp->no_advertise = no_advertise;
9875   mp->off_link = off_link;
9876   mp->no_autoconfig = no_autoconfig;
9877   mp->no_onlink = no_onlink;
9878   mp->is_no = is_no;
9879   mp->val_lifetime = ntohl (val_lifetime);
9880   mp->pref_lifetime = ntohl (pref_lifetime);
9881
9882   /* send it... */
9883   S (mp);
9884
9885   /* Wait for a reply, return good/bad news  */
9886   W (ret);
9887   return ret;
9888 }
9889
9890 static int
9891 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9892 {
9893   unformat_input_t *i = vam->input;
9894   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9895   u32 sw_if_index;
9896   u8 sw_if_index_set = 0;
9897   u8 suppress = 0;
9898   u8 managed = 0;
9899   u8 other = 0;
9900   u8 ll_option = 0;
9901   u8 send_unicast = 0;
9902   u8 cease = 0;
9903   u8 is_no = 0;
9904   u8 default_router = 0;
9905   u32 max_interval = 0;
9906   u32 min_interval = 0;
9907   u32 lifetime = 0;
9908   u32 initial_count = 0;
9909   u32 initial_interval = 0;
9910   int ret;
9911
9912
9913   /* Parse args required to build the message */
9914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9915     {
9916       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9917         sw_if_index_set = 1;
9918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9919         sw_if_index_set = 1;
9920       else if (unformat (i, "maxint %d", &max_interval))
9921         ;
9922       else if (unformat (i, "minint %d", &min_interval))
9923         ;
9924       else if (unformat (i, "life %d", &lifetime))
9925         ;
9926       else if (unformat (i, "count %d", &initial_count))
9927         ;
9928       else if (unformat (i, "interval %d", &initial_interval))
9929         ;
9930       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9931         suppress = 1;
9932       else if (unformat (i, "managed"))
9933         managed = 1;
9934       else if (unformat (i, "other"))
9935         other = 1;
9936       else if (unformat (i, "ll"))
9937         ll_option = 1;
9938       else if (unformat (i, "send"))
9939         send_unicast = 1;
9940       else if (unformat (i, "cease"))
9941         cease = 1;
9942       else if (unformat (i, "isno"))
9943         is_no = 1;
9944       else if (unformat (i, "def"))
9945         default_router = 1;
9946       else
9947         {
9948           clib_warning ("parse error '%U'", format_unformat_error, i);
9949           return -99;
9950         }
9951     }
9952
9953   if (sw_if_index_set == 0)
9954     {
9955       errmsg ("missing interface name or sw_if_index");
9956       return -99;
9957     }
9958
9959   /* Construct the API message */
9960   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9961
9962   mp->sw_if_index = ntohl (sw_if_index);
9963   mp->max_interval = ntohl (max_interval);
9964   mp->min_interval = ntohl (min_interval);
9965   mp->lifetime = ntohl (lifetime);
9966   mp->initial_count = ntohl (initial_count);
9967   mp->initial_interval = ntohl (initial_interval);
9968   mp->suppress = suppress;
9969   mp->managed = managed;
9970   mp->other = other;
9971   mp->ll_option = ll_option;
9972   mp->send_unicast = send_unicast;
9973   mp->cease = cease;
9974   mp->is_no = is_no;
9975   mp->default_router = default_router;
9976
9977   /* send it... */
9978   S (mp);
9979
9980   /* Wait for a reply, return good/bad news  */
9981   W (ret);
9982   return ret;
9983 }
9984
9985 static int
9986 api_set_arp_neighbor_limit (vat_main_t * vam)
9987 {
9988   unformat_input_t *i = vam->input;
9989   vl_api_set_arp_neighbor_limit_t *mp;
9990   u32 arp_nbr_limit;
9991   u8 limit_set = 0;
9992   u8 is_ipv6 = 0;
9993   int ret;
9994
9995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9996     {
9997       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9998         limit_set = 1;
9999       else if (unformat (i, "ipv6"))
10000         is_ipv6 = 1;
10001       else
10002         {
10003           clib_warning ("parse error '%U'", format_unformat_error, i);
10004           return -99;
10005         }
10006     }
10007
10008   if (limit_set == 0)
10009     {
10010       errmsg ("missing limit value");
10011       return -99;
10012     }
10013
10014   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10015
10016   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10017   mp->is_ipv6 = is_ipv6;
10018
10019   S (mp);
10020   W (ret);
10021   return ret;
10022 }
10023
10024 static int
10025 api_l2_patch_add_del (vat_main_t * vam)
10026 {
10027   unformat_input_t *i = vam->input;
10028   vl_api_l2_patch_add_del_t *mp;
10029   u32 rx_sw_if_index;
10030   u8 rx_sw_if_index_set = 0;
10031   u32 tx_sw_if_index;
10032   u8 tx_sw_if_index_set = 0;
10033   u8 is_add = 1;
10034   int ret;
10035
10036   /* Parse args required to build the message */
10037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10038     {
10039       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10040         rx_sw_if_index_set = 1;
10041       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10042         tx_sw_if_index_set = 1;
10043       else if (unformat (i, "rx"))
10044         {
10045           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10046             {
10047               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10048                             &rx_sw_if_index))
10049                 rx_sw_if_index_set = 1;
10050             }
10051           else
10052             break;
10053         }
10054       else if (unformat (i, "tx"))
10055         {
10056           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10057             {
10058               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10059                             &tx_sw_if_index))
10060                 tx_sw_if_index_set = 1;
10061             }
10062           else
10063             break;
10064         }
10065       else if (unformat (i, "del"))
10066         is_add = 0;
10067       else
10068         break;
10069     }
10070
10071   if (rx_sw_if_index_set == 0)
10072     {
10073       errmsg ("missing rx interface name or rx_sw_if_index");
10074       return -99;
10075     }
10076
10077   if (tx_sw_if_index_set == 0)
10078     {
10079       errmsg ("missing tx interface name or tx_sw_if_index");
10080       return -99;
10081     }
10082
10083   M (L2_PATCH_ADD_DEL, mp);
10084
10085   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10086   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10087   mp->is_add = is_add;
10088
10089   S (mp);
10090   W (ret);
10091   return ret;
10092 }
10093
10094 u8 is_del;
10095 u8 localsid_addr[16];
10096 u8 end_psp;
10097 u8 behavior;
10098 u32 sw_if_index;
10099 u32 vlan_index;
10100 u32 fib_table;
10101 u8 nh_addr[16];
10102
10103 static int
10104 api_sr_localsid_add_del (vat_main_t * vam)
10105 {
10106   unformat_input_t *i = vam->input;
10107   vl_api_sr_localsid_add_del_t *mp;
10108
10109   u8 is_del;
10110   ip6_address_t localsid;
10111   u8 end_psp = 0;
10112   u8 behavior = ~0;
10113   u32 sw_if_index;
10114   u32 fib_table = ~(u32) 0;
10115   ip6_address_t nh_addr6;
10116   ip4_address_t nh_addr4;
10117   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10118   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10119
10120   bool nexthop_set = 0;
10121
10122   int ret;
10123
10124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10125     {
10126       if (unformat (i, "del"))
10127         is_del = 1;
10128       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10129       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10130         nexthop_set = 1;
10131       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10132         nexthop_set = 1;
10133       else if (unformat (i, "behavior %u", &behavior));
10134       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10135       else if (unformat (i, "fib-table %u", &fib_table));
10136       else if (unformat (i, "end.psp %u", &behavior));
10137       else
10138         break;
10139     }
10140
10141   M (SR_LOCALSID_ADD_DEL, mp);
10142
10143   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10144   if (nexthop_set)
10145     {
10146       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10147       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10148     }
10149   mp->behavior = behavior;
10150   mp->sw_if_index = ntohl (sw_if_index);
10151   mp->fib_table = ntohl (fib_table);
10152   mp->end_psp = end_psp;
10153   mp->is_del = is_del;
10154
10155   S (mp);
10156   W (ret);
10157   return ret;
10158 }
10159
10160 static int
10161 api_ioam_enable (vat_main_t * vam)
10162 {
10163   unformat_input_t *input = vam->input;
10164   vl_api_ioam_enable_t *mp;
10165   u32 id = 0;
10166   int has_trace_option = 0;
10167   int has_pot_option = 0;
10168   int has_seqno_option = 0;
10169   int has_analyse_option = 0;
10170   int ret;
10171
10172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10173     {
10174       if (unformat (input, "trace"))
10175         has_trace_option = 1;
10176       else if (unformat (input, "pot"))
10177         has_pot_option = 1;
10178       else if (unformat (input, "seqno"))
10179         has_seqno_option = 1;
10180       else if (unformat (input, "analyse"))
10181         has_analyse_option = 1;
10182       else
10183         break;
10184     }
10185   M (IOAM_ENABLE, mp);
10186   mp->id = htons (id);
10187   mp->seqno = has_seqno_option;
10188   mp->analyse = has_analyse_option;
10189   mp->pot_enable = has_pot_option;
10190   mp->trace_enable = has_trace_option;
10191
10192   S (mp);
10193   W (ret);
10194   return ret;
10195 }
10196
10197
10198 static int
10199 api_ioam_disable (vat_main_t * vam)
10200 {
10201   vl_api_ioam_disable_t *mp;
10202   int ret;
10203
10204   M (IOAM_DISABLE, mp);
10205   S (mp);
10206   W (ret);
10207   return ret;
10208 }
10209
10210 #define foreach_tcp_proto_field                 \
10211 _(src_port)                                     \
10212 _(dst_port)
10213
10214 #define foreach_udp_proto_field                 \
10215 _(src_port)                                     \
10216 _(dst_port)
10217
10218 #define foreach_ip4_proto_field                 \
10219 _(src_address)                                  \
10220 _(dst_address)                                  \
10221 _(tos)                                          \
10222 _(length)                                       \
10223 _(fragment_id)                                  \
10224 _(ttl)                                          \
10225 _(protocol)                                     \
10226 _(checksum)
10227
10228 typedef struct
10229 {
10230   u16 src_port, dst_port;
10231 } tcpudp_header_t;
10232
10233 #if VPP_API_TEST_BUILTIN == 0
10234 uword
10235 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10236 {
10237   u8 **maskp = va_arg (*args, u8 **);
10238   u8 *mask = 0;
10239   u8 found_something = 0;
10240   tcp_header_t *tcp;
10241
10242 #define _(a) u8 a=0;
10243   foreach_tcp_proto_field;
10244 #undef _
10245
10246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10247     {
10248       if (0);
10249 #define _(a) else if (unformat (input, #a)) a=1;
10250       foreach_tcp_proto_field
10251 #undef _
10252         else
10253         break;
10254     }
10255
10256 #define _(a) found_something += a;
10257   foreach_tcp_proto_field;
10258 #undef _
10259
10260   if (found_something == 0)
10261     return 0;
10262
10263   vec_validate (mask, sizeof (*tcp) - 1);
10264
10265   tcp = (tcp_header_t *) mask;
10266
10267 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10268   foreach_tcp_proto_field;
10269 #undef _
10270
10271   *maskp = mask;
10272   return 1;
10273 }
10274
10275 uword
10276 unformat_udp_mask (unformat_input_t * input, va_list * args)
10277 {
10278   u8 **maskp = va_arg (*args, u8 **);
10279   u8 *mask = 0;
10280   u8 found_something = 0;
10281   udp_header_t *udp;
10282
10283 #define _(a) u8 a=0;
10284   foreach_udp_proto_field;
10285 #undef _
10286
10287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (0);
10290 #define _(a) else if (unformat (input, #a)) a=1;
10291       foreach_udp_proto_field
10292 #undef _
10293         else
10294         break;
10295     }
10296
10297 #define _(a) found_something += a;
10298   foreach_udp_proto_field;
10299 #undef _
10300
10301   if (found_something == 0)
10302     return 0;
10303
10304   vec_validate (mask, sizeof (*udp) - 1);
10305
10306   udp = (udp_header_t *) mask;
10307
10308 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10309   foreach_udp_proto_field;
10310 #undef _
10311
10312   *maskp = mask;
10313   return 1;
10314 }
10315
10316 uword
10317 unformat_l4_mask (unformat_input_t * input, va_list * args)
10318 {
10319   u8 **maskp = va_arg (*args, u8 **);
10320   u16 src_port = 0, dst_port = 0;
10321   tcpudp_header_t *tcpudp;
10322
10323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10326         return 1;
10327       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10328         return 1;
10329       else if (unformat (input, "src_port"))
10330         src_port = 0xFFFF;
10331       else if (unformat (input, "dst_port"))
10332         dst_port = 0xFFFF;
10333       else
10334         return 0;
10335     }
10336
10337   if (!src_port && !dst_port)
10338     return 0;
10339
10340   u8 *mask = 0;
10341   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10342
10343   tcpudp = (tcpudp_header_t *) mask;
10344   tcpudp->src_port = src_port;
10345   tcpudp->dst_port = dst_port;
10346
10347   *maskp = mask;
10348
10349   return 1;
10350 }
10351
10352 uword
10353 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10354 {
10355   u8 **maskp = va_arg (*args, u8 **);
10356   u8 *mask = 0;
10357   u8 found_something = 0;
10358   ip4_header_t *ip;
10359
10360 #define _(a) u8 a=0;
10361   foreach_ip4_proto_field;
10362 #undef _
10363   u8 version = 0;
10364   u8 hdr_length = 0;
10365
10366
10367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10368     {
10369       if (unformat (input, "version"))
10370         version = 1;
10371       else if (unformat (input, "hdr_length"))
10372         hdr_length = 1;
10373       else if (unformat (input, "src"))
10374         src_address = 1;
10375       else if (unformat (input, "dst"))
10376         dst_address = 1;
10377       else if (unformat (input, "proto"))
10378         protocol = 1;
10379
10380 #define _(a) else if (unformat (input, #a)) a=1;
10381       foreach_ip4_proto_field
10382 #undef _
10383         else
10384         break;
10385     }
10386
10387 #define _(a) found_something += a;
10388   foreach_ip4_proto_field;
10389 #undef _
10390
10391   if (found_something == 0)
10392     return 0;
10393
10394   vec_validate (mask, sizeof (*ip) - 1);
10395
10396   ip = (ip4_header_t *) mask;
10397
10398 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10399   foreach_ip4_proto_field;
10400 #undef _
10401
10402   ip->ip_version_and_header_length = 0;
10403
10404   if (version)
10405     ip->ip_version_and_header_length |= 0xF0;
10406
10407   if (hdr_length)
10408     ip->ip_version_and_header_length |= 0x0F;
10409
10410   *maskp = mask;
10411   return 1;
10412 }
10413
10414 #define foreach_ip6_proto_field                 \
10415 _(src_address)                                  \
10416 _(dst_address)                                  \
10417 _(payload_length)                               \
10418 _(hop_limit)                                    \
10419 _(protocol)
10420
10421 uword
10422 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10423 {
10424   u8 **maskp = va_arg (*args, u8 **);
10425   u8 *mask = 0;
10426   u8 found_something = 0;
10427   ip6_header_t *ip;
10428   u32 ip_version_traffic_class_and_flow_label;
10429
10430 #define _(a) u8 a=0;
10431   foreach_ip6_proto_field;
10432 #undef _
10433   u8 version = 0;
10434   u8 traffic_class = 0;
10435   u8 flow_label = 0;
10436
10437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10438     {
10439       if (unformat (input, "version"))
10440         version = 1;
10441       else if (unformat (input, "traffic-class"))
10442         traffic_class = 1;
10443       else if (unformat (input, "flow-label"))
10444         flow_label = 1;
10445       else if (unformat (input, "src"))
10446         src_address = 1;
10447       else if (unformat (input, "dst"))
10448         dst_address = 1;
10449       else if (unformat (input, "proto"))
10450         protocol = 1;
10451
10452 #define _(a) else if (unformat (input, #a)) a=1;
10453       foreach_ip6_proto_field
10454 #undef _
10455         else
10456         break;
10457     }
10458
10459 #define _(a) found_something += a;
10460   foreach_ip6_proto_field;
10461 #undef _
10462
10463   if (found_something == 0)
10464     return 0;
10465
10466   vec_validate (mask, sizeof (*ip) - 1);
10467
10468   ip = (ip6_header_t *) mask;
10469
10470 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10471   foreach_ip6_proto_field;
10472 #undef _
10473
10474   ip_version_traffic_class_and_flow_label = 0;
10475
10476   if (version)
10477     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10478
10479   if (traffic_class)
10480     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10481
10482   if (flow_label)
10483     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10484
10485   ip->ip_version_traffic_class_and_flow_label =
10486     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10487
10488   *maskp = mask;
10489   return 1;
10490 }
10491
10492 uword
10493 unformat_l3_mask (unformat_input_t * input, va_list * args)
10494 {
10495   u8 **maskp = va_arg (*args, u8 **);
10496
10497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10498     {
10499       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10500         return 1;
10501       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10502         return 1;
10503       else
10504         break;
10505     }
10506   return 0;
10507 }
10508
10509 uword
10510 unformat_l2_mask (unformat_input_t * input, va_list * args)
10511 {
10512   u8 **maskp = va_arg (*args, u8 **);
10513   u8 *mask = 0;
10514   u8 src = 0;
10515   u8 dst = 0;
10516   u8 proto = 0;
10517   u8 tag1 = 0;
10518   u8 tag2 = 0;
10519   u8 ignore_tag1 = 0;
10520   u8 ignore_tag2 = 0;
10521   u8 cos1 = 0;
10522   u8 cos2 = 0;
10523   u8 dot1q = 0;
10524   u8 dot1ad = 0;
10525   int len = 14;
10526
10527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10528     {
10529       if (unformat (input, "src"))
10530         src = 1;
10531       else if (unformat (input, "dst"))
10532         dst = 1;
10533       else if (unformat (input, "proto"))
10534         proto = 1;
10535       else if (unformat (input, "tag1"))
10536         tag1 = 1;
10537       else if (unformat (input, "tag2"))
10538         tag2 = 1;
10539       else if (unformat (input, "ignore-tag1"))
10540         ignore_tag1 = 1;
10541       else if (unformat (input, "ignore-tag2"))
10542         ignore_tag2 = 1;
10543       else if (unformat (input, "cos1"))
10544         cos1 = 1;
10545       else if (unformat (input, "cos2"))
10546         cos2 = 1;
10547       else if (unformat (input, "dot1q"))
10548         dot1q = 1;
10549       else if (unformat (input, "dot1ad"))
10550         dot1ad = 1;
10551       else
10552         break;
10553     }
10554   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10555        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10556     return 0;
10557
10558   if (tag1 || ignore_tag1 || cos1 || dot1q)
10559     len = 18;
10560   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10561     len = 22;
10562
10563   vec_validate (mask, len - 1);
10564
10565   if (dst)
10566     clib_memset (mask, 0xff, 6);
10567
10568   if (src)
10569     clib_memset (mask + 6, 0xff, 6);
10570
10571   if (tag2 || dot1ad)
10572     {
10573       /* inner vlan tag */
10574       if (tag2)
10575         {
10576           mask[19] = 0xff;
10577           mask[18] = 0x0f;
10578         }
10579       if (cos2)
10580         mask[18] |= 0xe0;
10581       if (proto)
10582         mask[21] = mask[20] = 0xff;
10583       if (tag1)
10584         {
10585           mask[15] = 0xff;
10586           mask[14] = 0x0f;
10587         }
10588       if (cos1)
10589         mask[14] |= 0xe0;
10590       *maskp = mask;
10591       return 1;
10592     }
10593   if (tag1 | dot1q)
10594     {
10595       if (tag1)
10596         {
10597           mask[15] = 0xff;
10598           mask[14] = 0x0f;
10599         }
10600       if (cos1)
10601         mask[14] |= 0xe0;
10602       if (proto)
10603         mask[16] = mask[17] = 0xff;
10604
10605       *maskp = mask;
10606       return 1;
10607     }
10608   if (cos2)
10609     mask[18] |= 0xe0;
10610   if (cos1)
10611     mask[14] |= 0xe0;
10612   if (proto)
10613     mask[12] = mask[13] = 0xff;
10614
10615   *maskp = mask;
10616   return 1;
10617 }
10618
10619 uword
10620 unformat_classify_mask (unformat_input_t * input, va_list * args)
10621 {
10622   u8 **maskp = va_arg (*args, u8 **);
10623   u32 *skipp = va_arg (*args, u32 *);
10624   u32 *matchp = va_arg (*args, u32 *);
10625   u32 match;
10626   u8 *mask = 0;
10627   u8 *l2 = 0;
10628   u8 *l3 = 0;
10629   u8 *l4 = 0;
10630   int i;
10631
10632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10633     {
10634       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10635         ;
10636       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10637         ;
10638       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10639         ;
10640       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10641         ;
10642       else
10643         break;
10644     }
10645
10646   if (l4 && !l3)
10647     {
10648       vec_free (mask);
10649       vec_free (l2);
10650       vec_free (l4);
10651       return 0;
10652     }
10653
10654   if (mask || l2 || l3 || l4)
10655     {
10656       if (l2 || l3 || l4)
10657         {
10658           /* "With a free Ethernet header in every package" */
10659           if (l2 == 0)
10660             vec_validate (l2, 13);
10661           mask = l2;
10662           if (vec_len (l3))
10663             {
10664               vec_append (mask, l3);
10665               vec_free (l3);
10666             }
10667           if (vec_len (l4))
10668             {
10669               vec_append (mask, l4);
10670               vec_free (l4);
10671             }
10672         }
10673
10674       /* Scan forward looking for the first significant mask octet */
10675       for (i = 0; i < vec_len (mask); i++)
10676         if (mask[i])
10677           break;
10678
10679       /* compute (skip, match) params */
10680       *skipp = i / sizeof (u32x4);
10681       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10682
10683       /* Pad mask to an even multiple of the vector size */
10684       while (vec_len (mask) % sizeof (u32x4))
10685         vec_add1 (mask, 0);
10686
10687       match = vec_len (mask) / sizeof (u32x4);
10688
10689       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10690         {
10691           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10692           if (*tmp || *(tmp + 1))
10693             break;
10694           match--;
10695         }
10696       if (match == 0)
10697         clib_warning ("BUG: match 0");
10698
10699       _vec_len (mask) = match * sizeof (u32x4);
10700
10701       *matchp = match;
10702       *maskp = mask;
10703
10704       return 1;
10705     }
10706
10707   return 0;
10708 }
10709 #endif /* VPP_API_TEST_BUILTIN */
10710
10711 #define foreach_l2_next                         \
10712 _(drop, DROP)                                   \
10713 _(ethernet, ETHERNET_INPUT)                     \
10714 _(ip4, IP4_INPUT)                               \
10715 _(ip6, IP6_INPUT)
10716
10717 uword
10718 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10719 {
10720   u32 *miss_next_indexp = va_arg (*args, u32 *);
10721   u32 next_index = 0;
10722   u32 tmp;
10723
10724 #define _(n,N) \
10725   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10726   foreach_l2_next;
10727 #undef _
10728
10729   if (unformat (input, "%d", &tmp))
10730     {
10731       next_index = tmp;
10732       goto out;
10733     }
10734
10735   return 0;
10736
10737 out:
10738   *miss_next_indexp = next_index;
10739   return 1;
10740 }
10741
10742 #define foreach_ip_next                         \
10743 _(drop, DROP)                                   \
10744 _(local, LOCAL)                                 \
10745 _(rewrite, REWRITE)
10746
10747 uword
10748 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10749 {
10750   u32 *miss_next_indexp = va_arg (*args, u32 *);
10751   u32 next_index = 0;
10752   u32 tmp;
10753
10754 #define _(n,N) \
10755   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10756   foreach_ip_next;
10757 #undef _
10758
10759   if (unformat (input, "%d", &tmp))
10760     {
10761       next_index = tmp;
10762       goto out;
10763     }
10764
10765   return 0;
10766
10767 out:
10768   *miss_next_indexp = next_index;
10769   return 1;
10770 }
10771
10772 #define foreach_acl_next                        \
10773 _(deny, DENY)
10774
10775 uword
10776 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10777 {
10778   u32 *miss_next_indexp = va_arg (*args, u32 *);
10779   u32 next_index = 0;
10780   u32 tmp;
10781
10782 #define _(n,N) \
10783   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10784   foreach_acl_next;
10785 #undef _
10786
10787   if (unformat (input, "permit"))
10788     {
10789       next_index = ~0;
10790       goto out;
10791     }
10792   else if (unformat (input, "%d", &tmp))
10793     {
10794       next_index = tmp;
10795       goto out;
10796     }
10797
10798   return 0;
10799
10800 out:
10801   *miss_next_indexp = next_index;
10802   return 1;
10803 }
10804
10805 uword
10806 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10807 {
10808   u32 *r = va_arg (*args, u32 *);
10809
10810   if (unformat (input, "conform-color"))
10811     *r = POLICE_CONFORM;
10812   else if (unformat (input, "exceed-color"))
10813     *r = POLICE_EXCEED;
10814   else
10815     return 0;
10816
10817   return 1;
10818 }
10819
10820 static int
10821 api_classify_add_del_table (vat_main_t * vam)
10822 {
10823   unformat_input_t *i = vam->input;
10824   vl_api_classify_add_del_table_t *mp;
10825
10826   u32 nbuckets = 2;
10827   u32 skip = ~0;
10828   u32 match = ~0;
10829   int is_add = 1;
10830   int del_chain = 0;
10831   u32 table_index = ~0;
10832   u32 next_table_index = ~0;
10833   u32 miss_next_index = ~0;
10834   u32 memory_size = 32 << 20;
10835   u8 *mask = 0;
10836   u32 current_data_flag = 0;
10837   int current_data_offset = 0;
10838   int ret;
10839
10840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10841     {
10842       if (unformat (i, "del"))
10843         is_add = 0;
10844       else if (unformat (i, "del-chain"))
10845         {
10846           is_add = 0;
10847           del_chain = 1;
10848         }
10849       else if (unformat (i, "buckets %d", &nbuckets))
10850         ;
10851       else if (unformat (i, "memory_size %d", &memory_size))
10852         ;
10853       else if (unformat (i, "skip %d", &skip))
10854         ;
10855       else if (unformat (i, "match %d", &match))
10856         ;
10857       else if (unformat (i, "table %d", &table_index))
10858         ;
10859       else if (unformat (i, "mask %U", unformat_classify_mask,
10860                          &mask, &skip, &match))
10861         ;
10862       else if (unformat (i, "next-table %d", &next_table_index))
10863         ;
10864       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10865                          &miss_next_index))
10866         ;
10867       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10868                          &miss_next_index))
10869         ;
10870       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10871                          &miss_next_index))
10872         ;
10873       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10874         ;
10875       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10876         ;
10877       else
10878         break;
10879     }
10880
10881   if (is_add && mask == 0)
10882     {
10883       errmsg ("Mask required");
10884       return -99;
10885     }
10886
10887   if (is_add && skip == ~0)
10888     {
10889       errmsg ("skip count required");
10890       return -99;
10891     }
10892
10893   if (is_add && match == ~0)
10894     {
10895       errmsg ("match count required");
10896       return -99;
10897     }
10898
10899   if (!is_add && table_index == ~0)
10900     {
10901       errmsg ("table index required for delete");
10902       return -99;
10903     }
10904
10905   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10906
10907   mp->is_add = is_add;
10908   mp->del_chain = del_chain;
10909   mp->table_index = ntohl (table_index);
10910   mp->nbuckets = ntohl (nbuckets);
10911   mp->memory_size = ntohl (memory_size);
10912   mp->skip_n_vectors = ntohl (skip);
10913   mp->match_n_vectors = ntohl (match);
10914   mp->next_table_index = ntohl (next_table_index);
10915   mp->miss_next_index = ntohl (miss_next_index);
10916   mp->current_data_flag = ntohl (current_data_flag);
10917   mp->current_data_offset = ntohl (current_data_offset);
10918   mp->mask_len = ntohl (vec_len (mask));
10919   clib_memcpy (mp->mask, mask, vec_len (mask));
10920
10921   vec_free (mask);
10922
10923   S (mp);
10924   W (ret);
10925   return ret;
10926 }
10927
10928 #if VPP_API_TEST_BUILTIN == 0
10929 uword
10930 unformat_l4_match (unformat_input_t * input, va_list * args)
10931 {
10932   u8 **matchp = va_arg (*args, u8 **);
10933
10934   u8 *proto_header = 0;
10935   int src_port = 0;
10936   int dst_port = 0;
10937
10938   tcpudp_header_t h;
10939
10940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10941     {
10942       if (unformat (input, "src_port %d", &src_port))
10943         ;
10944       else if (unformat (input, "dst_port %d", &dst_port))
10945         ;
10946       else
10947         return 0;
10948     }
10949
10950   h.src_port = clib_host_to_net_u16 (src_port);
10951   h.dst_port = clib_host_to_net_u16 (dst_port);
10952   vec_validate (proto_header, sizeof (h) - 1);
10953   memcpy (proto_header, &h, sizeof (h));
10954
10955   *matchp = proto_header;
10956
10957   return 1;
10958 }
10959
10960 uword
10961 unformat_ip4_match (unformat_input_t * input, va_list * args)
10962 {
10963   u8 **matchp = va_arg (*args, u8 **);
10964   u8 *match = 0;
10965   ip4_header_t *ip;
10966   int version = 0;
10967   u32 version_val;
10968   int hdr_length = 0;
10969   u32 hdr_length_val;
10970   int src = 0, dst = 0;
10971   ip4_address_t src_val, dst_val;
10972   int proto = 0;
10973   u32 proto_val;
10974   int tos = 0;
10975   u32 tos_val;
10976   int length = 0;
10977   u32 length_val;
10978   int fragment_id = 0;
10979   u32 fragment_id_val;
10980   int ttl = 0;
10981   int ttl_val;
10982   int checksum = 0;
10983   u32 checksum_val;
10984
10985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10986     {
10987       if (unformat (input, "version %d", &version_val))
10988         version = 1;
10989       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10990         hdr_length = 1;
10991       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10992         src = 1;
10993       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10994         dst = 1;
10995       else if (unformat (input, "proto %d", &proto_val))
10996         proto = 1;
10997       else if (unformat (input, "tos %d", &tos_val))
10998         tos = 1;
10999       else if (unformat (input, "length %d", &length_val))
11000         length = 1;
11001       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11002         fragment_id = 1;
11003       else if (unformat (input, "ttl %d", &ttl_val))
11004         ttl = 1;
11005       else if (unformat (input, "checksum %d", &checksum_val))
11006         checksum = 1;
11007       else
11008         break;
11009     }
11010
11011   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11012       + ttl + checksum == 0)
11013     return 0;
11014
11015   /*
11016    * Aligned because we use the real comparison functions
11017    */
11018   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11019
11020   ip = (ip4_header_t *) match;
11021
11022   /* These are realistically matched in practice */
11023   if (src)
11024     ip->src_address.as_u32 = src_val.as_u32;
11025
11026   if (dst)
11027     ip->dst_address.as_u32 = dst_val.as_u32;
11028
11029   if (proto)
11030     ip->protocol = proto_val;
11031
11032
11033   /* These are not, but they're included for completeness */
11034   if (version)
11035     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11036
11037   if (hdr_length)
11038     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11039
11040   if (tos)
11041     ip->tos = tos_val;
11042
11043   if (length)
11044     ip->length = clib_host_to_net_u16 (length_val);
11045
11046   if (ttl)
11047     ip->ttl = ttl_val;
11048
11049   if (checksum)
11050     ip->checksum = clib_host_to_net_u16 (checksum_val);
11051
11052   *matchp = match;
11053   return 1;
11054 }
11055
11056 uword
11057 unformat_ip6_match (unformat_input_t * input, va_list * args)
11058 {
11059   u8 **matchp = va_arg (*args, u8 **);
11060   u8 *match = 0;
11061   ip6_header_t *ip;
11062   int version = 0;
11063   u32 version_val;
11064   u8 traffic_class = 0;
11065   u32 traffic_class_val = 0;
11066   u8 flow_label = 0;
11067   u8 flow_label_val;
11068   int src = 0, dst = 0;
11069   ip6_address_t src_val, dst_val;
11070   int proto = 0;
11071   u32 proto_val;
11072   int payload_length = 0;
11073   u32 payload_length_val;
11074   int hop_limit = 0;
11075   int hop_limit_val;
11076   u32 ip_version_traffic_class_and_flow_label;
11077
11078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11079     {
11080       if (unformat (input, "version %d", &version_val))
11081         version = 1;
11082       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11083         traffic_class = 1;
11084       else if (unformat (input, "flow_label %d", &flow_label_val))
11085         flow_label = 1;
11086       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11087         src = 1;
11088       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11089         dst = 1;
11090       else if (unformat (input, "proto %d", &proto_val))
11091         proto = 1;
11092       else if (unformat (input, "payload_length %d", &payload_length_val))
11093         payload_length = 1;
11094       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11095         hop_limit = 1;
11096       else
11097         break;
11098     }
11099
11100   if (version + traffic_class + flow_label + src + dst + proto +
11101       payload_length + hop_limit == 0)
11102     return 0;
11103
11104   /*
11105    * Aligned because we use the real comparison functions
11106    */
11107   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11108
11109   ip = (ip6_header_t *) match;
11110
11111   if (src)
11112     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11113
11114   if (dst)
11115     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11116
11117   if (proto)
11118     ip->protocol = proto_val;
11119
11120   ip_version_traffic_class_and_flow_label = 0;
11121
11122   if (version)
11123     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11124
11125   if (traffic_class)
11126     ip_version_traffic_class_and_flow_label |=
11127       (traffic_class_val & 0xFF) << 20;
11128
11129   if (flow_label)
11130     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11131
11132   ip->ip_version_traffic_class_and_flow_label =
11133     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11134
11135   if (payload_length)
11136     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11137
11138   if (hop_limit)
11139     ip->hop_limit = hop_limit_val;
11140
11141   *matchp = match;
11142   return 1;
11143 }
11144
11145 uword
11146 unformat_l3_match (unformat_input_t * input, va_list * args)
11147 {
11148   u8 **matchp = va_arg (*args, u8 **);
11149
11150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11151     {
11152       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11153         return 1;
11154       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11155         return 1;
11156       else
11157         break;
11158     }
11159   return 0;
11160 }
11161
11162 uword
11163 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11164 {
11165   u8 *tagp = va_arg (*args, u8 *);
11166   u32 tag;
11167
11168   if (unformat (input, "%d", &tag))
11169     {
11170       tagp[0] = (tag >> 8) & 0x0F;
11171       tagp[1] = tag & 0xFF;
11172       return 1;
11173     }
11174
11175   return 0;
11176 }
11177
11178 uword
11179 unformat_l2_match (unformat_input_t * input, va_list * args)
11180 {
11181   u8 **matchp = va_arg (*args, u8 **);
11182   u8 *match = 0;
11183   u8 src = 0;
11184   u8 src_val[6];
11185   u8 dst = 0;
11186   u8 dst_val[6];
11187   u8 proto = 0;
11188   u16 proto_val;
11189   u8 tag1 = 0;
11190   u8 tag1_val[2];
11191   u8 tag2 = 0;
11192   u8 tag2_val[2];
11193   int len = 14;
11194   u8 ignore_tag1 = 0;
11195   u8 ignore_tag2 = 0;
11196   u8 cos1 = 0;
11197   u8 cos2 = 0;
11198   u32 cos1_val = 0;
11199   u32 cos2_val = 0;
11200
11201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11202     {
11203       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11204         src = 1;
11205       else
11206         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11207         dst = 1;
11208       else if (unformat (input, "proto %U",
11209                          unformat_ethernet_type_host_byte_order, &proto_val))
11210         proto = 1;
11211       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11212         tag1 = 1;
11213       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11214         tag2 = 1;
11215       else if (unformat (input, "ignore-tag1"))
11216         ignore_tag1 = 1;
11217       else if (unformat (input, "ignore-tag2"))
11218         ignore_tag2 = 1;
11219       else if (unformat (input, "cos1 %d", &cos1_val))
11220         cos1 = 1;
11221       else if (unformat (input, "cos2 %d", &cos2_val))
11222         cos2 = 1;
11223       else
11224         break;
11225     }
11226   if ((src + dst + proto + tag1 + tag2 +
11227        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11228     return 0;
11229
11230   if (tag1 || ignore_tag1 || cos1)
11231     len = 18;
11232   if (tag2 || ignore_tag2 || cos2)
11233     len = 22;
11234
11235   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11236
11237   if (dst)
11238     clib_memcpy (match, dst_val, 6);
11239
11240   if (src)
11241     clib_memcpy (match + 6, src_val, 6);
11242
11243   if (tag2)
11244     {
11245       /* inner vlan tag */
11246       match[19] = tag2_val[1];
11247       match[18] = tag2_val[0];
11248       if (cos2)
11249         match[18] |= (cos2_val & 0x7) << 5;
11250       if (proto)
11251         {
11252           match[21] = proto_val & 0xff;
11253           match[20] = proto_val >> 8;
11254         }
11255       if (tag1)
11256         {
11257           match[15] = tag1_val[1];
11258           match[14] = tag1_val[0];
11259         }
11260       if (cos1)
11261         match[14] |= (cos1_val & 0x7) << 5;
11262       *matchp = match;
11263       return 1;
11264     }
11265   if (tag1)
11266     {
11267       match[15] = tag1_val[1];
11268       match[14] = tag1_val[0];
11269       if (proto)
11270         {
11271           match[17] = proto_val & 0xff;
11272           match[16] = proto_val >> 8;
11273         }
11274       if (cos1)
11275         match[14] |= (cos1_val & 0x7) << 5;
11276
11277       *matchp = match;
11278       return 1;
11279     }
11280   if (cos2)
11281     match[18] |= (cos2_val & 0x7) << 5;
11282   if (cos1)
11283     match[14] |= (cos1_val & 0x7) << 5;
11284   if (proto)
11285     {
11286       match[13] = proto_val & 0xff;
11287       match[12] = proto_val >> 8;
11288     }
11289
11290   *matchp = match;
11291   return 1;
11292 }
11293
11294 uword
11295 unformat_qos_source (unformat_input_t * input, va_list * args)
11296 {
11297   int *qs = va_arg (*args, int *);
11298
11299   if (unformat (input, "ip"))
11300     *qs = QOS_SOURCE_IP;
11301   else if (unformat (input, "mpls"))
11302     *qs = QOS_SOURCE_MPLS;
11303   else if (unformat (input, "ext"))
11304     *qs = QOS_SOURCE_EXT;
11305   else if (unformat (input, "vlan"))
11306     *qs = QOS_SOURCE_VLAN;
11307   else
11308     return 0;
11309
11310   return 1;
11311 }
11312 #endif
11313
11314 uword
11315 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11316 {
11317   u8 **matchp = va_arg (*args, u8 **);
11318   u32 skip_n_vectors = va_arg (*args, u32);
11319   u32 match_n_vectors = va_arg (*args, u32);
11320
11321   u8 *match = 0;
11322   u8 *l2 = 0;
11323   u8 *l3 = 0;
11324   u8 *l4 = 0;
11325
11326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11327     {
11328       if (unformat (input, "hex %U", unformat_hex_string, &match))
11329         ;
11330       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11331         ;
11332       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11333         ;
11334       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11335         ;
11336       else
11337         break;
11338     }
11339
11340   if (l4 && !l3)
11341     {
11342       vec_free (match);
11343       vec_free (l2);
11344       vec_free (l4);
11345       return 0;
11346     }
11347
11348   if (match || l2 || l3 || l4)
11349     {
11350       if (l2 || l3 || l4)
11351         {
11352           /* "Win a free Ethernet header in every packet" */
11353           if (l2 == 0)
11354             vec_validate_aligned (l2, 13, sizeof (u32x4));
11355           match = l2;
11356           if (vec_len (l3))
11357             {
11358               vec_append_aligned (match, l3, sizeof (u32x4));
11359               vec_free (l3);
11360             }
11361           if (vec_len (l4))
11362             {
11363               vec_append_aligned (match, l4, sizeof (u32x4));
11364               vec_free (l4);
11365             }
11366         }
11367
11368       /* Make sure the vector is big enough even if key is all 0's */
11369       vec_validate_aligned
11370         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11371          sizeof (u32x4));
11372
11373       /* Set size, include skipped vectors */
11374       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11375
11376       *matchp = match;
11377
11378       return 1;
11379     }
11380
11381   return 0;
11382 }
11383
11384 static int
11385 api_classify_add_del_session (vat_main_t * vam)
11386 {
11387   unformat_input_t *i = vam->input;
11388   vl_api_classify_add_del_session_t *mp;
11389   int is_add = 1;
11390   u32 table_index = ~0;
11391   u32 hit_next_index = ~0;
11392   u32 opaque_index = ~0;
11393   u8 *match = 0;
11394   i32 advance = 0;
11395   u32 skip_n_vectors = 0;
11396   u32 match_n_vectors = 0;
11397   u32 action = 0;
11398   u32 metadata = 0;
11399   int ret;
11400
11401   /*
11402    * Warning: you have to supply skip_n and match_n
11403    * because the API client cant simply look at the classify
11404    * table object.
11405    */
11406
11407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11408     {
11409       if (unformat (i, "del"))
11410         is_add = 0;
11411       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11412                          &hit_next_index))
11413         ;
11414       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11415                          &hit_next_index))
11416         ;
11417       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11418                          &hit_next_index))
11419         ;
11420       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11421         ;
11422       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11423         ;
11424       else if (unformat (i, "opaque-index %d", &opaque_index))
11425         ;
11426       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11427         ;
11428       else if (unformat (i, "match_n %d", &match_n_vectors))
11429         ;
11430       else if (unformat (i, "match %U", api_unformat_classify_match,
11431                          &match, skip_n_vectors, match_n_vectors))
11432         ;
11433       else if (unformat (i, "advance %d", &advance))
11434         ;
11435       else if (unformat (i, "table-index %d", &table_index))
11436         ;
11437       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11438         action = 1;
11439       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11440         action = 2;
11441       else if (unformat (i, "action %d", &action))
11442         ;
11443       else if (unformat (i, "metadata %d", &metadata))
11444         ;
11445       else
11446         break;
11447     }
11448
11449   if (table_index == ~0)
11450     {
11451       errmsg ("Table index required");
11452       return -99;
11453     }
11454
11455   if (is_add && match == 0)
11456     {
11457       errmsg ("Match value required");
11458       return -99;
11459     }
11460
11461   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11462
11463   mp->is_add = is_add;
11464   mp->table_index = ntohl (table_index);
11465   mp->hit_next_index = ntohl (hit_next_index);
11466   mp->opaque_index = ntohl (opaque_index);
11467   mp->advance = ntohl (advance);
11468   mp->action = action;
11469   mp->metadata = ntohl (metadata);
11470   mp->match_len = ntohl (vec_len (match));
11471   clib_memcpy (mp->match, match, vec_len (match));
11472   vec_free (match);
11473
11474   S (mp);
11475   W (ret);
11476   return ret;
11477 }
11478
11479 static int
11480 api_classify_set_interface_ip_table (vat_main_t * vam)
11481 {
11482   unformat_input_t *i = vam->input;
11483   vl_api_classify_set_interface_ip_table_t *mp;
11484   u32 sw_if_index;
11485   int sw_if_index_set;
11486   u32 table_index = ~0;
11487   u8 is_ipv6 = 0;
11488   int ret;
11489
11490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11491     {
11492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11493         sw_if_index_set = 1;
11494       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11495         sw_if_index_set = 1;
11496       else if (unformat (i, "table %d", &table_index))
11497         ;
11498       else
11499         {
11500           clib_warning ("parse error '%U'", format_unformat_error, i);
11501           return -99;
11502         }
11503     }
11504
11505   if (sw_if_index_set == 0)
11506     {
11507       errmsg ("missing interface name or sw_if_index");
11508       return -99;
11509     }
11510
11511
11512   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11513
11514   mp->sw_if_index = ntohl (sw_if_index);
11515   mp->table_index = ntohl (table_index);
11516   mp->is_ipv6 = is_ipv6;
11517
11518   S (mp);
11519   W (ret);
11520   return ret;
11521 }
11522
11523 static int
11524 api_classify_set_interface_l2_tables (vat_main_t * vam)
11525 {
11526   unformat_input_t *i = vam->input;
11527   vl_api_classify_set_interface_l2_tables_t *mp;
11528   u32 sw_if_index;
11529   int sw_if_index_set;
11530   u32 ip4_table_index = ~0;
11531   u32 ip6_table_index = ~0;
11532   u32 other_table_index = ~0;
11533   u32 is_input = 1;
11534   int ret;
11535
11536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11537     {
11538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11539         sw_if_index_set = 1;
11540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11541         sw_if_index_set = 1;
11542       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11543         ;
11544       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11545         ;
11546       else if (unformat (i, "other-table %d", &other_table_index))
11547         ;
11548       else if (unformat (i, "is-input %d", &is_input))
11549         ;
11550       else
11551         {
11552           clib_warning ("parse error '%U'", format_unformat_error, i);
11553           return -99;
11554         }
11555     }
11556
11557   if (sw_if_index_set == 0)
11558     {
11559       errmsg ("missing interface name or sw_if_index");
11560       return -99;
11561     }
11562
11563
11564   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11565
11566   mp->sw_if_index = ntohl (sw_if_index);
11567   mp->ip4_table_index = ntohl (ip4_table_index);
11568   mp->ip6_table_index = ntohl (ip6_table_index);
11569   mp->other_table_index = ntohl (other_table_index);
11570   mp->is_input = (u8) is_input;
11571
11572   S (mp);
11573   W (ret);
11574   return ret;
11575 }
11576
11577 static int
11578 api_set_ipfix_exporter (vat_main_t * vam)
11579 {
11580   unformat_input_t *i = vam->input;
11581   vl_api_set_ipfix_exporter_t *mp;
11582   ip4_address_t collector_address;
11583   u8 collector_address_set = 0;
11584   u32 collector_port = ~0;
11585   ip4_address_t src_address;
11586   u8 src_address_set = 0;
11587   u32 vrf_id = ~0;
11588   u32 path_mtu = ~0;
11589   u32 template_interval = ~0;
11590   u8 udp_checksum = 0;
11591   int ret;
11592
11593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11594     {
11595       if (unformat (i, "collector_address %U", unformat_ip4_address,
11596                     &collector_address))
11597         collector_address_set = 1;
11598       else if (unformat (i, "collector_port %d", &collector_port))
11599         ;
11600       else if (unformat (i, "src_address %U", unformat_ip4_address,
11601                          &src_address))
11602         src_address_set = 1;
11603       else if (unformat (i, "vrf_id %d", &vrf_id))
11604         ;
11605       else if (unformat (i, "path_mtu %d", &path_mtu))
11606         ;
11607       else if (unformat (i, "template_interval %d", &template_interval))
11608         ;
11609       else if (unformat (i, "udp_checksum"))
11610         udp_checksum = 1;
11611       else
11612         break;
11613     }
11614
11615   if (collector_address_set == 0)
11616     {
11617       errmsg ("collector_address required");
11618       return -99;
11619     }
11620
11621   if (src_address_set == 0)
11622     {
11623       errmsg ("src_address required");
11624       return -99;
11625     }
11626
11627   M (SET_IPFIX_EXPORTER, mp);
11628
11629   memcpy (mp->collector_address, collector_address.data,
11630           sizeof (collector_address.data));
11631   mp->collector_port = htons ((u16) collector_port);
11632   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11633   mp->vrf_id = htonl (vrf_id);
11634   mp->path_mtu = htonl (path_mtu);
11635   mp->template_interval = htonl (template_interval);
11636   mp->udp_checksum = udp_checksum;
11637
11638   S (mp);
11639   W (ret);
11640   return ret;
11641 }
11642
11643 static int
11644 api_set_ipfix_classify_stream (vat_main_t * vam)
11645 {
11646   unformat_input_t *i = vam->input;
11647   vl_api_set_ipfix_classify_stream_t *mp;
11648   u32 domain_id = 0;
11649   u32 src_port = UDP_DST_PORT_ipfix;
11650   int ret;
11651
11652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11653     {
11654       if (unformat (i, "domain %d", &domain_id))
11655         ;
11656       else if (unformat (i, "src_port %d", &src_port))
11657         ;
11658       else
11659         {
11660           errmsg ("unknown input `%U'", format_unformat_error, i);
11661           return -99;
11662         }
11663     }
11664
11665   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11666
11667   mp->domain_id = htonl (domain_id);
11668   mp->src_port = htons ((u16) src_port);
11669
11670   S (mp);
11671   W (ret);
11672   return ret;
11673 }
11674
11675 static int
11676 api_ipfix_classify_table_add_del (vat_main_t * vam)
11677 {
11678   unformat_input_t *i = vam->input;
11679   vl_api_ipfix_classify_table_add_del_t *mp;
11680   int is_add = -1;
11681   u32 classify_table_index = ~0;
11682   u8 ip_version = 0;
11683   u8 transport_protocol = 255;
11684   int ret;
11685
11686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (i, "add"))
11689         is_add = 1;
11690       else if (unformat (i, "del"))
11691         is_add = 0;
11692       else if (unformat (i, "table %d", &classify_table_index))
11693         ;
11694       else if (unformat (i, "ip4"))
11695         ip_version = 4;
11696       else if (unformat (i, "ip6"))
11697         ip_version = 6;
11698       else if (unformat (i, "tcp"))
11699         transport_protocol = 6;
11700       else if (unformat (i, "udp"))
11701         transport_protocol = 17;
11702       else
11703         {
11704           errmsg ("unknown input `%U'", format_unformat_error, i);
11705           return -99;
11706         }
11707     }
11708
11709   if (is_add == -1)
11710     {
11711       errmsg ("expecting: add|del");
11712       return -99;
11713     }
11714   if (classify_table_index == ~0)
11715     {
11716       errmsg ("classifier table not specified");
11717       return -99;
11718     }
11719   if (ip_version == 0)
11720     {
11721       errmsg ("IP version not specified");
11722       return -99;
11723     }
11724
11725   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11726
11727   mp->is_add = is_add;
11728   mp->table_id = htonl (classify_table_index);
11729   mp->ip_version = ip_version;
11730   mp->transport_protocol = transport_protocol;
11731
11732   S (mp);
11733   W (ret);
11734   return ret;
11735 }
11736
11737 static int
11738 api_get_node_index (vat_main_t * vam)
11739 {
11740   unformat_input_t *i = vam->input;
11741   vl_api_get_node_index_t *mp;
11742   u8 *name = 0;
11743   int ret;
11744
11745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11746     {
11747       if (unformat (i, "node %s", &name))
11748         ;
11749       else
11750         break;
11751     }
11752   if (name == 0)
11753     {
11754       errmsg ("node name required");
11755       return -99;
11756     }
11757   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11758     {
11759       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11760       return -99;
11761     }
11762
11763   M (GET_NODE_INDEX, mp);
11764   clib_memcpy (mp->node_name, name, vec_len (name));
11765   vec_free (name);
11766
11767   S (mp);
11768   W (ret);
11769   return ret;
11770 }
11771
11772 static int
11773 api_get_next_index (vat_main_t * vam)
11774 {
11775   unformat_input_t *i = vam->input;
11776   vl_api_get_next_index_t *mp;
11777   u8 *node_name = 0, *next_node_name = 0;
11778   int ret;
11779
11780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11781     {
11782       if (unformat (i, "node-name %s", &node_name))
11783         ;
11784       else if (unformat (i, "next-node-name %s", &next_node_name))
11785         break;
11786     }
11787
11788   if (node_name == 0)
11789     {
11790       errmsg ("node name required");
11791       return -99;
11792     }
11793   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11794     {
11795       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11796       return -99;
11797     }
11798
11799   if (next_node_name == 0)
11800     {
11801       errmsg ("next node name required");
11802       return -99;
11803     }
11804   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11805     {
11806       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11807       return -99;
11808     }
11809
11810   M (GET_NEXT_INDEX, mp);
11811   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11812   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11813   vec_free (node_name);
11814   vec_free (next_node_name);
11815
11816   S (mp);
11817   W (ret);
11818   return ret;
11819 }
11820
11821 static int
11822 api_add_node_next (vat_main_t * vam)
11823 {
11824   unformat_input_t *i = vam->input;
11825   vl_api_add_node_next_t *mp;
11826   u8 *name = 0;
11827   u8 *next = 0;
11828   int ret;
11829
11830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11831     {
11832       if (unformat (i, "node %s", &name))
11833         ;
11834       else if (unformat (i, "next %s", &next))
11835         ;
11836       else
11837         break;
11838     }
11839   if (name == 0)
11840     {
11841       errmsg ("node name required");
11842       return -99;
11843     }
11844   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11845     {
11846       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11847       return -99;
11848     }
11849   if (next == 0)
11850     {
11851       errmsg ("next node required");
11852       return -99;
11853     }
11854   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11855     {
11856       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11857       return -99;
11858     }
11859
11860   M (ADD_NODE_NEXT, mp);
11861   clib_memcpy (mp->node_name, name, vec_len (name));
11862   clib_memcpy (mp->next_name, next, vec_len (next));
11863   vec_free (name);
11864   vec_free (next);
11865
11866   S (mp);
11867   W (ret);
11868   return ret;
11869 }
11870
11871 static int
11872 api_l2tpv3_create_tunnel (vat_main_t * vam)
11873 {
11874   unformat_input_t *i = vam->input;
11875   ip6_address_t client_address, our_address;
11876   int client_address_set = 0;
11877   int our_address_set = 0;
11878   u32 local_session_id = 0;
11879   u32 remote_session_id = 0;
11880   u64 local_cookie = 0;
11881   u64 remote_cookie = 0;
11882   u8 l2_sublayer_present = 0;
11883   vl_api_l2tpv3_create_tunnel_t *mp;
11884   int ret;
11885
11886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11887     {
11888       if (unformat (i, "client_address %U", unformat_ip6_address,
11889                     &client_address))
11890         client_address_set = 1;
11891       else if (unformat (i, "our_address %U", unformat_ip6_address,
11892                          &our_address))
11893         our_address_set = 1;
11894       else if (unformat (i, "local_session_id %d", &local_session_id))
11895         ;
11896       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11897         ;
11898       else if (unformat (i, "local_cookie %lld", &local_cookie))
11899         ;
11900       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11901         ;
11902       else if (unformat (i, "l2-sublayer-present"))
11903         l2_sublayer_present = 1;
11904       else
11905         break;
11906     }
11907
11908   if (client_address_set == 0)
11909     {
11910       errmsg ("client_address required");
11911       return -99;
11912     }
11913
11914   if (our_address_set == 0)
11915     {
11916       errmsg ("our_address required");
11917       return -99;
11918     }
11919
11920   M (L2TPV3_CREATE_TUNNEL, mp);
11921
11922   clib_memcpy (mp->client_address, client_address.as_u8,
11923                sizeof (mp->client_address));
11924
11925   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11926
11927   mp->local_session_id = ntohl (local_session_id);
11928   mp->remote_session_id = ntohl (remote_session_id);
11929   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11930   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11931   mp->l2_sublayer_present = l2_sublayer_present;
11932   mp->is_ipv6 = 1;
11933
11934   S (mp);
11935   W (ret);
11936   return ret;
11937 }
11938
11939 static int
11940 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11941 {
11942   unformat_input_t *i = vam->input;
11943   u32 sw_if_index;
11944   u8 sw_if_index_set = 0;
11945   u64 new_local_cookie = 0;
11946   u64 new_remote_cookie = 0;
11947   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11948   int ret;
11949
11950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11951     {
11952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11953         sw_if_index_set = 1;
11954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11955         sw_if_index_set = 1;
11956       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11957         ;
11958       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11959         ;
11960       else
11961         break;
11962     }
11963
11964   if (sw_if_index_set == 0)
11965     {
11966       errmsg ("missing interface name or sw_if_index");
11967       return -99;
11968     }
11969
11970   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11971
11972   mp->sw_if_index = ntohl (sw_if_index);
11973   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11974   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11975
11976   S (mp);
11977   W (ret);
11978   return ret;
11979 }
11980
11981 static int
11982 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11983 {
11984   unformat_input_t *i = vam->input;
11985   vl_api_l2tpv3_interface_enable_disable_t *mp;
11986   u32 sw_if_index;
11987   u8 sw_if_index_set = 0;
11988   u8 enable_disable = 1;
11989   int ret;
11990
11991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11992     {
11993       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11994         sw_if_index_set = 1;
11995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11996         sw_if_index_set = 1;
11997       else if (unformat (i, "enable"))
11998         enable_disable = 1;
11999       else if (unformat (i, "disable"))
12000         enable_disable = 0;
12001       else
12002         break;
12003     }
12004
12005   if (sw_if_index_set == 0)
12006     {
12007       errmsg ("missing interface name or sw_if_index");
12008       return -99;
12009     }
12010
12011   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12012
12013   mp->sw_if_index = ntohl (sw_if_index);
12014   mp->enable_disable = enable_disable;
12015
12016   S (mp);
12017   W (ret);
12018   return ret;
12019 }
12020
12021 static int
12022 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12023 {
12024   unformat_input_t *i = vam->input;
12025   vl_api_l2tpv3_set_lookup_key_t *mp;
12026   u8 key = ~0;
12027   int ret;
12028
12029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12030     {
12031       if (unformat (i, "lookup_v6_src"))
12032         key = L2T_LOOKUP_SRC_ADDRESS;
12033       else if (unformat (i, "lookup_v6_dst"))
12034         key = L2T_LOOKUP_DST_ADDRESS;
12035       else if (unformat (i, "lookup_session_id"))
12036         key = L2T_LOOKUP_SESSION_ID;
12037       else
12038         break;
12039     }
12040
12041   if (key == (u8) ~ 0)
12042     {
12043       errmsg ("l2tp session lookup key unset");
12044       return -99;
12045     }
12046
12047   M (L2TPV3_SET_LOOKUP_KEY, mp);
12048
12049   mp->key = key;
12050
12051   S (mp);
12052   W (ret);
12053   return ret;
12054 }
12055
12056 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12057   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12058 {
12059   vat_main_t *vam = &vat_main;
12060
12061   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12062          format_ip6_address, mp->our_address,
12063          format_ip6_address, mp->client_address,
12064          clib_net_to_host_u32 (mp->sw_if_index));
12065
12066   print (vam->ofp,
12067          "   local cookies %016llx %016llx remote cookie %016llx",
12068          clib_net_to_host_u64 (mp->local_cookie[0]),
12069          clib_net_to_host_u64 (mp->local_cookie[1]),
12070          clib_net_to_host_u64 (mp->remote_cookie));
12071
12072   print (vam->ofp, "   local session-id %d remote session-id %d",
12073          clib_net_to_host_u32 (mp->local_session_id),
12074          clib_net_to_host_u32 (mp->remote_session_id));
12075
12076   print (vam->ofp, "   l2 specific sublayer %s\n",
12077          mp->l2_sublayer_present ? "preset" : "absent");
12078
12079 }
12080
12081 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12082   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12083 {
12084   vat_main_t *vam = &vat_main;
12085   vat_json_node_t *node = NULL;
12086   struct in6_addr addr;
12087
12088   if (VAT_JSON_ARRAY != vam->json_tree.type)
12089     {
12090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12091       vat_json_init_array (&vam->json_tree);
12092     }
12093   node = vat_json_array_add (&vam->json_tree);
12094
12095   vat_json_init_object (node);
12096
12097   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12098   vat_json_object_add_ip6 (node, "our_address", addr);
12099   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12100   vat_json_object_add_ip6 (node, "client_address", addr);
12101
12102   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12103   vat_json_init_array (lc);
12104   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12105   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12106   vat_json_object_add_uint (node, "remote_cookie",
12107                             clib_net_to_host_u64 (mp->remote_cookie));
12108
12109   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12110   vat_json_object_add_uint (node, "local_session_id",
12111                             clib_net_to_host_u32 (mp->local_session_id));
12112   vat_json_object_add_uint (node, "remote_session_id",
12113                             clib_net_to_host_u32 (mp->remote_session_id));
12114   vat_json_object_add_string_copy (node, "l2_sublayer",
12115                                    mp->l2_sublayer_present ? (u8 *) "present"
12116                                    : (u8 *) "absent");
12117 }
12118
12119 static int
12120 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12121 {
12122   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12123   vl_api_control_ping_t *mp_ping;
12124   int ret;
12125
12126   /* Get list of l2tpv3-tunnel interfaces */
12127   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12128   S (mp);
12129
12130   /* Use a control ping for synchronization */
12131   MPING (CONTROL_PING, mp_ping);
12132   S (mp_ping);
12133
12134   W (ret);
12135   return ret;
12136 }
12137
12138
12139 static void vl_api_sw_interface_tap_v2_details_t_handler
12140   (vl_api_sw_interface_tap_v2_details_t * mp)
12141 {
12142   vat_main_t *vam = &vat_main;
12143
12144   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12145                     mp->host_ip4_prefix_len);
12146   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12147                     mp->host_ip6_prefix_len);
12148
12149   print (vam->ofp,
12150          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12151          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12152          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12153          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12154          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12155
12156   vec_free (ip4);
12157   vec_free (ip6);
12158 }
12159
12160 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12161   (vl_api_sw_interface_tap_v2_details_t * mp)
12162 {
12163   vat_main_t *vam = &vat_main;
12164   vat_json_node_t *node = NULL;
12165
12166   if (VAT_JSON_ARRAY != vam->json_tree.type)
12167     {
12168       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12169       vat_json_init_array (&vam->json_tree);
12170     }
12171   node = vat_json_array_add (&vam->json_tree);
12172
12173   vat_json_init_object (node);
12174   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12175   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12176   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12177   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12178   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12179   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12180   vat_json_object_add_string_copy (node, "host_mac_addr",
12181                                    format (0, "%U", format_ethernet_address,
12182                                            &mp->host_mac_addr));
12183   vat_json_object_add_string_copy (node, "host_namespace",
12184                                    mp->host_namespace);
12185   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12186   vat_json_object_add_string_copy (node, "host_ip4_addr",
12187                                    format (0, "%U/%d", format_ip4_address,
12188                                            mp->host_ip4_addr,
12189                                            mp->host_ip4_prefix_len));
12190   vat_json_object_add_string_copy (node, "host_ip6_addr",
12191                                    format (0, "%U/%d", format_ip6_address,
12192                                            mp->host_ip6_addr,
12193                                            mp->host_ip6_prefix_len));
12194
12195 }
12196
12197 static int
12198 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12199 {
12200   vl_api_sw_interface_tap_v2_dump_t *mp;
12201   vl_api_control_ping_t *mp_ping;
12202   int ret;
12203
12204   print (vam->ofp,
12205          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12206          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12207          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12208          "host_ip6_addr");
12209
12210   /* Get list of tap interfaces */
12211   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12212   S (mp);
12213
12214   /* Use a control ping for synchronization */
12215   MPING (CONTROL_PING, mp_ping);
12216   S (mp_ping);
12217
12218   W (ret);
12219   return ret;
12220 }
12221
12222 static void vl_api_sw_interface_virtio_pci_details_t_handler
12223   (vl_api_sw_interface_virtio_pci_details_t * mp)
12224 {
12225   vat_main_t *vam = &vat_main;
12226
12227   typedef union
12228   {
12229     struct
12230     {
12231       u16 domain;
12232       u8 bus;
12233       u8 slot:5;
12234       u8 function:3;
12235     };
12236     u32 as_u32;
12237   } pci_addr_t;
12238   pci_addr_t addr;
12239   addr.as_u32 = ntohl (mp->pci_addr);
12240   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12241                          addr.slot, addr.function);
12242
12243   print (vam->ofp,
12244          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12245          pci_addr, ntohl (mp->sw_if_index),
12246          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12247          format_ethernet_address, mp->mac_addr,
12248          clib_net_to_host_u64 (mp->features));
12249   vec_free (pci_addr);
12250 }
12251
12252 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12253   (vl_api_sw_interface_virtio_pci_details_t * mp)
12254 {
12255   vat_main_t *vam = &vat_main;
12256   vat_json_node_t *node = NULL;
12257
12258   if (VAT_JSON_ARRAY != vam->json_tree.type)
12259     {
12260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12261       vat_json_init_array (&vam->json_tree);
12262     }
12263   node = vat_json_array_add (&vam->json_tree);
12264
12265   vat_json_init_object (node);
12266   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12268   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12269   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12270   vat_json_object_add_uint (node, "features",
12271                             clib_net_to_host_u64 (mp->features));
12272   vat_json_object_add_string_copy (node, "mac_addr",
12273                                    format (0, "%U", format_ethernet_address,
12274                                            &mp->mac_addr));
12275 }
12276
12277 static int
12278 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12279 {
12280   vl_api_sw_interface_virtio_pci_dump_t *mp;
12281   vl_api_control_ping_t *mp_ping;
12282   int ret;
12283
12284   print (vam->ofp,
12285          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12286          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12287          "mac_addr", "features");
12288
12289   /* Get list of tap interfaces */
12290   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12291   S (mp);
12292
12293   /* Use a control ping for synchronization */
12294   MPING (CONTROL_PING, mp_ping);
12295   S (mp_ping);
12296
12297   W (ret);
12298   return ret;
12299 }
12300
12301 static int
12302 api_vxlan_offload_rx (vat_main_t * vam)
12303 {
12304   unformat_input_t *line_input = vam->input;
12305   vl_api_vxlan_offload_rx_t *mp;
12306   u32 hw_if_index = ~0, rx_if_index = ~0;
12307   u8 is_add = 1;
12308   int ret;
12309
12310   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12311     {
12312       if (unformat (line_input, "del"))
12313         is_add = 0;
12314       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12315                          &hw_if_index))
12316         ;
12317       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12318         ;
12319       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12320                          &rx_if_index))
12321         ;
12322       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12323         ;
12324       else
12325         {
12326           errmsg ("parse error '%U'", format_unformat_error, line_input);
12327           return -99;
12328         }
12329     }
12330
12331   if (hw_if_index == ~0)
12332     {
12333       errmsg ("no hw interface");
12334       return -99;
12335     }
12336
12337   if (rx_if_index == ~0)
12338     {
12339       errmsg ("no rx tunnel");
12340       return -99;
12341     }
12342
12343   M (VXLAN_OFFLOAD_RX, mp);
12344
12345   mp->hw_if_index = ntohl (hw_if_index);
12346   mp->sw_if_index = ntohl (rx_if_index);
12347   mp->enable = is_add;
12348
12349   S (mp);
12350   W (ret);
12351   return ret;
12352 }
12353
12354 static uword unformat_vxlan_decap_next
12355   (unformat_input_t * input, va_list * args)
12356 {
12357   u32 *result = va_arg (*args, u32 *);
12358   u32 tmp;
12359
12360   if (unformat (input, "l2"))
12361     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12362   else if (unformat (input, "%d", &tmp))
12363     *result = tmp;
12364   else
12365     return 0;
12366   return 1;
12367 }
12368
12369 static int
12370 api_vxlan_add_del_tunnel (vat_main_t * vam)
12371 {
12372   unformat_input_t *line_input = vam->input;
12373   vl_api_vxlan_add_del_tunnel_t *mp;
12374   ip46_address_t src, dst;
12375   u8 is_add = 1;
12376   u8 ipv4_set = 0, ipv6_set = 0;
12377   u8 src_set = 0;
12378   u8 dst_set = 0;
12379   u8 grp_set = 0;
12380   u32 instance = ~0;
12381   u32 mcast_sw_if_index = ~0;
12382   u32 encap_vrf_id = 0;
12383   u32 decap_next_index = ~0;
12384   u32 vni = 0;
12385   int ret;
12386
12387   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12388   clib_memset (&src, 0, sizeof src);
12389   clib_memset (&dst, 0, sizeof dst);
12390
12391   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12392     {
12393       if (unformat (line_input, "del"))
12394         is_add = 0;
12395       else if (unformat (line_input, "instance %d", &instance))
12396         ;
12397       else
12398         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12399         {
12400           ipv4_set = 1;
12401           src_set = 1;
12402         }
12403       else
12404         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12405         {
12406           ipv4_set = 1;
12407           dst_set = 1;
12408         }
12409       else
12410         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12411         {
12412           ipv6_set = 1;
12413           src_set = 1;
12414         }
12415       else
12416         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12417         {
12418           ipv6_set = 1;
12419           dst_set = 1;
12420         }
12421       else if (unformat (line_input, "group %U %U",
12422                          unformat_ip4_address, &dst.ip4,
12423                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12424         {
12425           grp_set = dst_set = 1;
12426           ipv4_set = 1;
12427         }
12428       else if (unformat (line_input, "group %U",
12429                          unformat_ip4_address, &dst.ip4))
12430         {
12431           grp_set = dst_set = 1;
12432           ipv4_set = 1;
12433         }
12434       else if (unformat (line_input, "group %U %U",
12435                          unformat_ip6_address, &dst.ip6,
12436                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12437         {
12438           grp_set = dst_set = 1;
12439           ipv6_set = 1;
12440         }
12441       else if (unformat (line_input, "group %U",
12442                          unformat_ip6_address, &dst.ip6))
12443         {
12444           grp_set = dst_set = 1;
12445           ipv6_set = 1;
12446         }
12447       else
12448         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12449         ;
12450       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12451         ;
12452       else if (unformat (line_input, "decap-next %U",
12453                          unformat_vxlan_decap_next, &decap_next_index))
12454         ;
12455       else if (unformat (line_input, "vni %d", &vni))
12456         ;
12457       else
12458         {
12459           errmsg ("parse error '%U'", format_unformat_error, line_input);
12460           return -99;
12461         }
12462     }
12463
12464   if (src_set == 0)
12465     {
12466       errmsg ("tunnel src address not specified");
12467       return -99;
12468     }
12469   if (dst_set == 0)
12470     {
12471       errmsg ("tunnel dst address not specified");
12472       return -99;
12473     }
12474
12475   if (grp_set && !ip46_address_is_multicast (&dst))
12476     {
12477       errmsg ("tunnel group address not multicast");
12478       return -99;
12479     }
12480   if (grp_set && mcast_sw_if_index == ~0)
12481     {
12482       errmsg ("tunnel nonexistent multicast device");
12483       return -99;
12484     }
12485   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12486     {
12487       errmsg ("tunnel dst address must be unicast");
12488       return -99;
12489     }
12490
12491
12492   if (ipv4_set && ipv6_set)
12493     {
12494       errmsg ("both IPv4 and IPv6 addresses specified");
12495       return -99;
12496     }
12497
12498   if ((vni == 0) || (vni >> 24))
12499     {
12500       errmsg ("vni not specified or out of range");
12501       return -99;
12502     }
12503
12504   M (VXLAN_ADD_DEL_TUNNEL, mp);
12505
12506   if (ipv6_set)
12507     {
12508       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12509       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12510     }
12511   else
12512     {
12513       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12514       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12515     }
12516
12517   mp->instance = htonl (instance);
12518   mp->encap_vrf_id = ntohl (encap_vrf_id);
12519   mp->decap_next_index = ntohl (decap_next_index);
12520   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12521   mp->vni = ntohl (vni);
12522   mp->is_add = is_add;
12523   mp->is_ipv6 = ipv6_set;
12524
12525   S (mp);
12526   W (ret);
12527   return ret;
12528 }
12529
12530 static void vl_api_vxlan_tunnel_details_t_handler
12531   (vl_api_vxlan_tunnel_details_t * mp)
12532 {
12533   vat_main_t *vam = &vat_main;
12534   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12535   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12536
12537   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12538          ntohl (mp->sw_if_index),
12539          ntohl (mp->instance),
12540          format_ip46_address, &src, IP46_TYPE_ANY,
12541          format_ip46_address, &dst, IP46_TYPE_ANY,
12542          ntohl (mp->encap_vrf_id),
12543          ntohl (mp->decap_next_index), ntohl (mp->vni),
12544          ntohl (mp->mcast_sw_if_index));
12545 }
12546
12547 static void vl_api_vxlan_tunnel_details_t_handler_json
12548   (vl_api_vxlan_tunnel_details_t * mp)
12549 {
12550   vat_main_t *vam = &vat_main;
12551   vat_json_node_t *node = NULL;
12552
12553   if (VAT_JSON_ARRAY != vam->json_tree.type)
12554     {
12555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12556       vat_json_init_array (&vam->json_tree);
12557     }
12558   node = vat_json_array_add (&vam->json_tree);
12559
12560   vat_json_init_object (node);
12561   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12562
12563   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12564
12565   if (mp->is_ipv6)
12566     {
12567       struct in6_addr ip6;
12568
12569       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12570       vat_json_object_add_ip6 (node, "src_address", ip6);
12571       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12572       vat_json_object_add_ip6 (node, "dst_address", ip6);
12573     }
12574   else
12575     {
12576       struct in_addr ip4;
12577
12578       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12579       vat_json_object_add_ip4 (node, "src_address", ip4);
12580       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12581       vat_json_object_add_ip4 (node, "dst_address", ip4);
12582     }
12583   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12584   vat_json_object_add_uint (node, "decap_next_index",
12585                             ntohl (mp->decap_next_index));
12586   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12587   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12588   vat_json_object_add_uint (node, "mcast_sw_if_index",
12589                             ntohl (mp->mcast_sw_if_index));
12590 }
12591
12592 static int
12593 api_vxlan_tunnel_dump (vat_main_t * vam)
12594 {
12595   unformat_input_t *i = vam->input;
12596   vl_api_vxlan_tunnel_dump_t *mp;
12597   vl_api_control_ping_t *mp_ping;
12598   u32 sw_if_index;
12599   u8 sw_if_index_set = 0;
12600   int ret;
12601
12602   /* Parse args required to build the message */
12603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12604     {
12605       if (unformat (i, "sw_if_index %d", &sw_if_index))
12606         sw_if_index_set = 1;
12607       else
12608         break;
12609     }
12610
12611   if (sw_if_index_set == 0)
12612     {
12613       sw_if_index = ~0;
12614     }
12615
12616   if (!vam->json_output)
12617     {
12618       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12619              "sw_if_index", "instance", "src_address", "dst_address",
12620              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12621     }
12622
12623   /* Get list of vxlan-tunnel interfaces */
12624   M (VXLAN_TUNNEL_DUMP, mp);
12625
12626   mp->sw_if_index = htonl (sw_if_index);
12627
12628   S (mp);
12629
12630   /* Use a control ping for synchronization */
12631   MPING (CONTROL_PING, mp_ping);
12632   S (mp_ping);
12633
12634   W (ret);
12635   return ret;
12636 }
12637
12638 static uword unformat_geneve_decap_next
12639   (unformat_input_t * input, va_list * args)
12640 {
12641   u32 *result = va_arg (*args, u32 *);
12642   u32 tmp;
12643
12644   if (unformat (input, "l2"))
12645     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12646   else if (unformat (input, "%d", &tmp))
12647     *result = tmp;
12648   else
12649     return 0;
12650   return 1;
12651 }
12652
12653 static int
12654 api_geneve_add_del_tunnel (vat_main_t * vam)
12655 {
12656   unformat_input_t *line_input = vam->input;
12657   vl_api_geneve_add_del_tunnel_t *mp;
12658   ip46_address_t src, dst;
12659   u8 is_add = 1;
12660   u8 ipv4_set = 0, ipv6_set = 0;
12661   u8 src_set = 0;
12662   u8 dst_set = 0;
12663   u8 grp_set = 0;
12664   u32 mcast_sw_if_index = ~0;
12665   u32 encap_vrf_id = 0;
12666   u32 decap_next_index = ~0;
12667   u32 vni = 0;
12668   int ret;
12669
12670   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12671   clib_memset (&src, 0, sizeof src);
12672   clib_memset (&dst, 0, sizeof dst);
12673
12674   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12675     {
12676       if (unformat (line_input, "del"))
12677         is_add = 0;
12678       else
12679         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12680         {
12681           ipv4_set = 1;
12682           src_set = 1;
12683         }
12684       else
12685         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12686         {
12687           ipv4_set = 1;
12688           dst_set = 1;
12689         }
12690       else
12691         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12692         {
12693           ipv6_set = 1;
12694           src_set = 1;
12695         }
12696       else
12697         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12698         {
12699           ipv6_set = 1;
12700           dst_set = 1;
12701         }
12702       else if (unformat (line_input, "group %U %U",
12703                          unformat_ip4_address, &dst.ip4,
12704                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12705         {
12706           grp_set = dst_set = 1;
12707           ipv4_set = 1;
12708         }
12709       else if (unformat (line_input, "group %U",
12710                          unformat_ip4_address, &dst.ip4))
12711         {
12712           grp_set = dst_set = 1;
12713           ipv4_set = 1;
12714         }
12715       else if (unformat (line_input, "group %U %U",
12716                          unformat_ip6_address, &dst.ip6,
12717                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12718         {
12719           grp_set = dst_set = 1;
12720           ipv6_set = 1;
12721         }
12722       else if (unformat (line_input, "group %U",
12723                          unformat_ip6_address, &dst.ip6))
12724         {
12725           grp_set = dst_set = 1;
12726           ipv6_set = 1;
12727         }
12728       else
12729         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12730         ;
12731       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12732         ;
12733       else if (unformat (line_input, "decap-next %U",
12734                          unformat_geneve_decap_next, &decap_next_index))
12735         ;
12736       else if (unformat (line_input, "vni %d", &vni))
12737         ;
12738       else
12739         {
12740           errmsg ("parse error '%U'", format_unformat_error, line_input);
12741           return -99;
12742         }
12743     }
12744
12745   if (src_set == 0)
12746     {
12747       errmsg ("tunnel src address not specified");
12748       return -99;
12749     }
12750   if (dst_set == 0)
12751     {
12752       errmsg ("tunnel dst address not specified");
12753       return -99;
12754     }
12755
12756   if (grp_set && !ip46_address_is_multicast (&dst))
12757     {
12758       errmsg ("tunnel group address not multicast");
12759       return -99;
12760     }
12761   if (grp_set && mcast_sw_if_index == ~0)
12762     {
12763       errmsg ("tunnel nonexistent multicast device");
12764       return -99;
12765     }
12766   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12767     {
12768       errmsg ("tunnel dst address must be unicast");
12769       return -99;
12770     }
12771
12772
12773   if (ipv4_set && ipv6_set)
12774     {
12775       errmsg ("both IPv4 and IPv6 addresses specified");
12776       return -99;
12777     }
12778
12779   if ((vni == 0) || (vni >> 24))
12780     {
12781       errmsg ("vni not specified or out of range");
12782       return -99;
12783     }
12784
12785   M (GENEVE_ADD_DEL_TUNNEL, mp);
12786
12787   if (ipv6_set)
12788     {
12789       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12790       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12791     }
12792   else
12793     {
12794       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12795       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12796     }
12797   mp->encap_vrf_id = ntohl (encap_vrf_id);
12798   mp->decap_next_index = ntohl (decap_next_index);
12799   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12800   mp->vni = ntohl (vni);
12801   mp->is_add = is_add;
12802   mp->is_ipv6 = ipv6_set;
12803
12804   S (mp);
12805   W (ret);
12806   return ret;
12807 }
12808
12809 static void vl_api_geneve_tunnel_details_t_handler
12810   (vl_api_geneve_tunnel_details_t * mp)
12811 {
12812   vat_main_t *vam = &vat_main;
12813   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12814   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12815
12816   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12817          ntohl (mp->sw_if_index),
12818          format_ip46_address, &src, IP46_TYPE_ANY,
12819          format_ip46_address, &dst, IP46_TYPE_ANY,
12820          ntohl (mp->encap_vrf_id),
12821          ntohl (mp->decap_next_index), ntohl (mp->vni),
12822          ntohl (mp->mcast_sw_if_index));
12823 }
12824
12825 static void vl_api_geneve_tunnel_details_t_handler_json
12826   (vl_api_geneve_tunnel_details_t * mp)
12827 {
12828   vat_main_t *vam = &vat_main;
12829   vat_json_node_t *node = NULL;
12830
12831   if (VAT_JSON_ARRAY != vam->json_tree.type)
12832     {
12833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12834       vat_json_init_array (&vam->json_tree);
12835     }
12836   node = vat_json_array_add (&vam->json_tree);
12837
12838   vat_json_init_object (node);
12839   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12840   if (mp->is_ipv6)
12841     {
12842       struct in6_addr ip6;
12843
12844       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12845       vat_json_object_add_ip6 (node, "src_address", ip6);
12846       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12847       vat_json_object_add_ip6 (node, "dst_address", ip6);
12848     }
12849   else
12850     {
12851       struct in_addr ip4;
12852
12853       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12854       vat_json_object_add_ip4 (node, "src_address", ip4);
12855       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12856       vat_json_object_add_ip4 (node, "dst_address", ip4);
12857     }
12858   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12859   vat_json_object_add_uint (node, "decap_next_index",
12860                             ntohl (mp->decap_next_index));
12861   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12862   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12863   vat_json_object_add_uint (node, "mcast_sw_if_index",
12864                             ntohl (mp->mcast_sw_if_index));
12865 }
12866
12867 static int
12868 api_geneve_tunnel_dump (vat_main_t * vam)
12869 {
12870   unformat_input_t *i = vam->input;
12871   vl_api_geneve_tunnel_dump_t *mp;
12872   vl_api_control_ping_t *mp_ping;
12873   u32 sw_if_index;
12874   u8 sw_if_index_set = 0;
12875   int ret;
12876
12877   /* Parse args required to build the message */
12878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12879     {
12880       if (unformat (i, "sw_if_index %d", &sw_if_index))
12881         sw_if_index_set = 1;
12882       else
12883         break;
12884     }
12885
12886   if (sw_if_index_set == 0)
12887     {
12888       sw_if_index = ~0;
12889     }
12890
12891   if (!vam->json_output)
12892     {
12893       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12894              "sw_if_index", "local_address", "remote_address",
12895              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12896     }
12897
12898   /* Get list of geneve-tunnel interfaces */
12899   M (GENEVE_TUNNEL_DUMP, mp);
12900
12901   mp->sw_if_index = htonl (sw_if_index);
12902
12903   S (mp);
12904
12905   /* Use a control ping for synchronization */
12906   M (CONTROL_PING, mp_ping);
12907   S (mp_ping);
12908
12909   W (ret);
12910   return ret;
12911 }
12912
12913 static int
12914 api_gre_tunnel_add_del (vat_main_t * vam)
12915 {
12916   unformat_input_t *line_input = vam->input;
12917   vl_api_address_t src = { }, dst =
12918   {
12919   };
12920   vl_api_gre_tunnel_add_del_t *mp;
12921   vl_api_gre_tunnel_type_t t_type;
12922   u8 is_add = 1;
12923   u8 src_set = 0;
12924   u8 dst_set = 0;
12925   u32 outer_fib_id = 0;
12926   u32 session_id = 0;
12927   u32 instance = ~0;
12928   int ret;
12929
12930   t_type = GRE_API_TUNNEL_TYPE_L3;
12931
12932   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12933     {
12934       if (unformat (line_input, "del"))
12935         is_add = 0;
12936       else if (unformat (line_input, "instance %d", &instance))
12937         ;
12938       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12939         {
12940           src_set = 1;
12941         }
12942       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12943         {
12944           dst_set = 1;
12945         }
12946       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12947         ;
12948       else if (unformat (line_input, "teb"))
12949         t_type = GRE_API_TUNNEL_TYPE_TEB;
12950       else if (unformat (line_input, "erspan %d", &session_id))
12951         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12952       else
12953         {
12954           errmsg ("parse error '%U'", format_unformat_error, line_input);
12955           return -99;
12956         }
12957     }
12958
12959   if (src_set == 0)
12960     {
12961       errmsg ("tunnel src address not specified");
12962       return -99;
12963     }
12964   if (dst_set == 0)
12965     {
12966       errmsg ("tunnel dst address not specified");
12967       return -99;
12968     }
12969
12970   M (GRE_TUNNEL_ADD_DEL, mp);
12971
12972   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12973   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12974
12975   mp->tunnel.instance = htonl (instance);
12976   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12977   mp->is_add = is_add;
12978   mp->tunnel.session_id = htons ((u16) session_id);
12979   mp->tunnel.type = htonl (t_type);
12980
12981   S (mp);
12982   W (ret);
12983   return ret;
12984 }
12985
12986 static void vl_api_gre_tunnel_details_t_handler
12987   (vl_api_gre_tunnel_details_t * mp)
12988 {
12989   vat_main_t *vam = &vat_main;
12990
12991   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12992          ntohl (mp->tunnel.sw_if_index),
12993          ntohl (mp->tunnel.instance),
12994          format_vl_api_address, &mp->tunnel.src,
12995          format_vl_api_address, &mp->tunnel.dst,
12996          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12997          ntohl (mp->tunnel.session_id));
12998 }
12999
13000 static void vl_api_gre_tunnel_details_t_handler_json
13001   (vl_api_gre_tunnel_details_t * mp)
13002 {
13003   vat_main_t *vam = &vat_main;
13004   vat_json_node_t *node = NULL;
13005
13006   if (VAT_JSON_ARRAY != vam->json_tree.type)
13007     {
13008       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13009       vat_json_init_array (&vam->json_tree);
13010     }
13011   node = vat_json_array_add (&vam->json_tree);
13012
13013   vat_json_init_object (node);
13014   vat_json_object_add_uint (node, "sw_if_index",
13015                             ntohl (mp->tunnel.sw_if_index));
13016   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13017
13018   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13019   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13020   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13021   vat_json_object_add_uint (node, "outer_fib_id",
13022                             ntohl (mp->tunnel.outer_fib_id));
13023   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13024 }
13025
13026 static int
13027 api_gre_tunnel_dump (vat_main_t * vam)
13028 {
13029   unformat_input_t *i = vam->input;
13030   vl_api_gre_tunnel_dump_t *mp;
13031   vl_api_control_ping_t *mp_ping;
13032   u32 sw_if_index;
13033   u8 sw_if_index_set = 0;
13034   int ret;
13035
13036   /* Parse args required to build the message */
13037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13038     {
13039       if (unformat (i, "sw_if_index %d", &sw_if_index))
13040         sw_if_index_set = 1;
13041       else
13042         break;
13043     }
13044
13045   if (sw_if_index_set == 0)
13046     {
13047       sw_if_index = ~0;
13048     }
13049
13050   if (!vam->json_output)
13051     {
13052       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13053              "sw_if_index", "instance", "src_address", "dst_address",
13054              "tunnel_type", "outer_fib_id", "session_id");
13055     }
13056
13057   /* Get list of gre-tunnel interfaces */
13058   M (GRE_TUNNEL_DUMP, mp);
13059
13060   mp->sw_if_index = htonl (sw_if_index);
13061
13062   S (mp);
13063
13064   /* Use a control ping for synchronization */
13065   MPING (CONTROL_PING, mp_ping);
13066   S (mp_ping);
13067
13068   W (ret);
13069   return ret;
13070 }
13071
13072 static int
13073 api_l2_fib_clear_table (vat_main_t * vam)
13074 {
13075 //  unformat_input_t * i = vam->input;
13076   vl_api_l2_fib_clear_table_t *mp;
13077   int ret;
13078
13079   M (L2_FIB_CLEAR_TABLE, mp);
13080
13081   S (mp);
13082   W (ret);
13083   return ret;
13084 }
13085
13086 static int
13087 api_l2_interface_efp_filter (vat_main_t * vam)
13088 {
13089   unformat_input_t *i = vam->input;
13090   vl_api_l2_interface_efp_filter_t *mp;
13091   u32 sw_if_index;
13092   u8 enable = 1;
13093   u8 sw_if_index_set = 0;
13094   int ret;
13095
13096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13097     {
13098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13099         sw_if_index_set = 1;
13100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13101         sw_if_index_set = 1;
13102       else if (unformat (i, "enable"))
13103         enable = 1;
13104       else if (unformat (i, "disable"))
13105         enable = 0;
13106       else
13107         {
13108           clib_warning ("parse error '%U'", format_unformat_error, i);
13109           return -99;
13110         }
13111     }
13112
13113   if (sw_if_index_set == 0)
13114     {
13115       errmsg ("missing sw_if_index");
13116       return -99;
13117     }
13118
13119   M (L2_INTERFACE_EFP_FILTER, mp);
13120
13121   mp->sw_if_index = ntohl (sw_if_index);
13122   mp->enable_disable = enable;
13123
13124   S (mp);
13125   W (ret);
13126   return ret;
13127 }
13128
13129 #define foreach_vtr_op                          \
13130 _("disable",  L2_VTR_DISABLED)                  \
13131 _("push-1",  L2_VTR_PUSH_1)                     \
13132 _("push-2",  L2_VTR_PUSH_2)                     \
13133 _("pop-1",  L2_VTR_POP_1)                       \
13134 _("pop-2",  L2_VTR_POP_2)                       \
13135 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13136 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13137 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13138 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13139
13140 static int
13141 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13142 {
13143   unformat_input_t *i = vam->input;
13144   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13145   u32 sw_if_index;
13146   u8 sw_if_index_set = 0;
13147   u8 vtr_op_set = 0;
13148   u32 vtr_op = 0;
13149   u32 push_dot1q = 1;
13150   u32 tag1 = ~0;
13151   u32 tag2 = ~0;
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, "vtr_op %d", &vtr_op))
13161         vtr_op_set = 1;
13162 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13163       foreach_vtr_op
13164 #undef _
13165         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13166         ;
13167       else if (unformat (i, "tag1 %d", &tag1))
13168         ;
13169       else if (unformat (i, "tag2 %d", &tag2))
13170         ;
13171       else
13172         {
13173           clib_warning ("parse error '%U'", format_unformat_error, i);
13174           return -99;
13175         }
13176     }
13177
13178   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13179     {
13180       errmsg ("missing vtr operation or sw_if_index");
13181       return -99;
13182     }
13183
13184   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13185   mp->sw_if_index = ntohl (sw_if_index);
13186   mp->vtr_op = ntohl (vtr_op);
13187   mp->push_dot1q = ntohl (push_dot1q);
13188   mp->tag1 = ntohl (tag1);
13189   mp->tag2 = ntohl (tag2);
13190
13191   S (mp);
13192   W (ret);
13193   return ret;
13194 }
13195
13196 static int
13197 api_create_vhost_user_if (vat_main_t * vam)
13198 {
13199   unformat_input_t *i = vam->input;
13200   vl_api_create_vhost_user_if_t *mp;
13201   u8 *file_name;
13202   u8 is_server = 0;
13203   u8 file_name_set = 0;
13204   u32 custom_dev_instance = ~0;
13205   u8 hwaddr[6];
13206   u8 use_custom_mac = 0;
13207   u8 disable_mrg_rxbuf = 0;
13208   u8 disable_indirect_desc = 0;
13209   u8 *tag = 0;
13210   u8 enable_gso = 0;
13211   int ret;
13212
13213   /* Shut up coverity */
13214   clib_memset (hwaddr, 0, sizeof (hwaddr));
13215
13216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13217     {
13218       if (unformat (i, "socket %s", &file_name))
13219         {
13220           file_name_set = 1;
13221         }
13222       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13223         ;
13224       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13225         use_custom_mac = 1;
13226       else if (unformat (i, "server"))
13227         is_server = 1;
13228       else if (unformat (i, "disable_mrg_rxbuf"))
13229         disable_mrg_rxbuf = 1;
13230       else if (unformat (i, "disable_indirect_desc"))
13231         disable_indirect_desc = 1;
13232       else if (unformat (i, "gso"))
13233         enable_gso = 1;
13234       else if (unformat (i, "tag %s", &tag))
13235         ;
13236       else
13237         break;
13238     }
13239
13240   if (file_name_set == 0)
13241     {
13242       errmsg ("missing socket file name");
13243       return -99;
13244     }
13245
13246   if (vec_len (file_name) > 255)
13247     {
13248       errmsg ("socket file name too long");
13249       return -99;
13250     }
13251   vec_add1 (file_name, 0);
13252
13253   M (CREATE_VHOST_USER_IF, mp);
13254
13255   mp->is_server = is_server;
13256   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13257   mp->disable_indirect_desc = disable_indirect_desc;
13258   mp->enable_gso = enable_gso;
13259   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13260   vec_free (file_name);
13261   if (custom_dev_instance != ~0)
13262     {
13263       mp->renumber = 1;
13264       mp->custom_dev_instance = ntohl (custom_dev_instance);
13265     }
13266
13267   mp->use_custom_mac = use_custom_mac;
13268   clib_memcpy (mp->mac_address, hwaddr, 6);
13269   if (tag)
13270     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13271   vec_free (tag);
13272
13273   S (mp);
13274   W (ret);
13275   return ret;
13276 }
13277
13278 static int
13279 api_modify_vhost_user_if (vat_main_t * vam)
13280 {
13281   unformat_input_t *i = vam->input;
13282   vl_api_modify_vhost_user_if_t *mp;
13283   u8 *file_name;
13284   u8 is_server = 0;
13285   u8 file_name_set = 0;
13286   u32 custom_dev_instance = ~0;
13287   u8 sw_if_index_set = 0;
13288   u32 sw_if_index = (u32) ~ 0;
13289   u8 enable_gso = 0;
13290   int ret;
13291
13292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13293     {
13294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13295         sw_if_index_set = 1;
13296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13297         sw_if_index_set = 1;
13298       else if (unformat (i, "socket %s", &file_name))
13299         {
13300           file_name_set = 1;
13301         }
13302       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13303         ;
13304       else if (unformat (i, "server"))
13305         is_server = 1;
13306       else if (unformat (i, "gso"))
13307         enable_gso = 1;
13308       else
13309         break;
13310     }
13311
13312   if (sw_if_index_set == 0)
13313     {
13314       errmsg ("missing sw_if_index or interface name");
13315       return -99;
13316     }
13317
13318   if (file_name_set == 0)
13319     {
13320       errmsg ("missing socket file name");
13321       return -99;
13322     }
13323
13324   if (vec_len (file_name) > 255)
13325     {
13326       errmsg ("socket file name too long");
13327       return -99;
13328     }
13329   vec_add1 (file_name, 0);
13330
13331   M (MODIFY_VHOST_USER_IF, mp);
13332
13333   mp->sw_if_index = ntohl (sw_if_index);
13334   mp->is_server = is_server;
13335   mp->enable_gso = enable_gso;
13336   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13337   vec_free (file_name);
13338   if (custom_dev_instance != ~0)
13339     {
13340       mp->renumber = 1;
13341       mp->custom_dev_instance = ntohl (custom_dev_instance);
13342     }
13343
13344   S (mp);
13345   W (ret);
13346   return ret;
13347 }
13348
13349 static int
13350 api_delete_vhost_user_if (vat_main_t * vam)
13351 {
13352   unformat_input_t *i = vam->input;
13353   vl_api_delete_vhost_user_if_t *mp;
13354   u32 sw_if_index = ~0;
13355   u8 sw_if_index_set = 0;
13356   int ret;
13357
13358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13359     {
13360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13361         sw_if_index_set = 1;
13362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13363         sw_if_index_set = 1;
13364       else
13365         break;
13366     }
13367
13368   if (sw_if_index_set == 0)
13369     {
13370       errmsg ("missing sw_if_index or interface name");
13371       return -99;
13372     }
13373
13374
13375   M (DELETE_VHOST_USER_IF, mp);
13376
13377   mp->sw_if_index = ntohl (sw_if_index);
13378
13379   S (mp);
13380   W (ret);
13381   return ret;
13382 }
13383
13384 static void vl_api_sw_interface_vhost_user_details_t_handler
13385   (vl_api_sw_interface_vhost_user_details_t * mp)
13386 {
13387   vat_main_t *vam = &vat_main;
13388
13389   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13390          (char *) mp->interface_name,
13391          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13392          clib_net_to_host_u64 (mp->features), mp->is_server,
13393          ntohl (mp->num_regions), (char *) mp->sock_filename);
13394   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13395 }
13396
13397 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13398   (vl_api_sw_interface_vhost_user_details_t * mp)
13399 {
13400   vat_main_t *vam = &vat_main;
13401   vat_json_node_t *node = NULL;
13402
13403   if (VAT_JSON_ARRAY != vam->json_tree.type)
13404     {
13405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13406       vat_json_init_array (&vam->json_tree);
13407     }
13408   node = vat_json_array_add (&vam->json_tree);
13409
13410   vat_json_init_object (node);
13411   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13412   vat_json_object_add_string_copy (node, "interface_name",
13413                                    mp->interface_name);
13414   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13415                             ntohl (mp->virtio_net_hdr_sz));
13416   vat_json_object_add_uint (node, "features",
13417                             clib_net_to_host_u64 (mp->features));
13418   vat_json_object_add_uint (node, "is_server", mp->is_server);
13419   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13420   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13421   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13422 }
13423
13424 static int
13425 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13426 {
13427   vl_api_sw_interface_vhost_user_dump_t *mp;
13428   vl_api_control_ping_t *mp_ping;
13429   int ret;
13430   print (vam->ofp,
13431          "Interface name            idx hdr_sz features server regions filename");
13432
13433   /* Get list of vhost-user interfaces */
13434   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13435   S (mp);
13436
13437   /* Use a control ping for synchronization */
13438   MPING (CONTROL_PING, mp_ping);
13439   S (mp_ping);
13440
13441   W (ret);
13442   return ret;
13443 }
13444
13445 static int
13446 api_show_version (vat_main_t * vam)
13447 {
13448   vl_api_show_version_t *mp;
13449   int ret;
13450
13451   M (SHOW_VERSION, mp);
13452
13453   S (mp);
13454   W (ret);
13455   return ret;
13456 }
13457
13458
13459 static int
13460 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13461 {
13462   unformat_input_t *line_input = vam->input;
13463   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13464   ip4_address_t local4, remote4;
13465   ip6_address_t local6, remote6;
13466   u8 is_add = 1;
13467   u8 ipv4_set = 0, ipv6_set = 0;
13468   u8 local_set = 0;
13469   u8 remote_set = 0;
13470   u8 grp_set = 0;
13471   u32 mcast_sw_if_index = ~0;
13472   u32 encap_vrf_id = 0;
13473   u32 decap_vrf_id = 0;
13474   u8 protocol = ~0;
13475   u32 vni;
13476   u8 vni_set = 0;
13477   int ret;
13478
13479   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13480   clib_memset (&local4, 0, sizeof local4);
13481   clib_memset (&remote4, 0, sizeof remote4);
13482   clib_memset (&local6, 0, sizeof local6);
13483   clib_memset (&remote6, 0, sizeof remote6);
13484
13485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13486     {
13487       if (unformat (line_input, "del"))
13488         is_add = 0;
13489       else if (unformat (line_input, "local %U",
13490                          unformat_ip4_address, &local4))
13491         {
13492           local_set = 1;
13493           ipv4_set = 1;
13494         }
13495       else if (unformat (line_input, "remote %U",
13496                          unformat_ip4_address, &remote4))
13497         {
13498           remote_set = 1;
13499           ipv4_set = 1;
13500         }
13501       else if (unformat (line_input, "local %U",
13502                          unformat_ip6_address, &local6))
13503         {
13504           local_set = 1;
13505           ipv6_set = 1;
13506         }
13507       else if (unformat (line_input, "remote %U",
13508                          unformat_ip6_address, &remote6))
13509         {
13510           remote_set = 1;
13511           ipv6_set = 1;
13512         }
13513       else if (unformat (line_input, "group %U %U",
13514                          unformat_ip4_address, &remote4,
13515                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13516         {
13517           grp_set = remote_set = 1;
13518           ipv4_set = 1;
13519         }
13520       else if (unformat (line_input, "group %U",
13521                          unformat_ip4_address, &remote4))
13522         {
13523           grp_set = remote_set = 1;
13524           ipv4_set = 1;
13525         }
13526       else if (unformat (line_input, "group %U %U",
13527                          unformat_ip6_address, &remote6,
13528                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13529         {
13530           grp_set = remote_set = 1;
13531           ipv6_set = 1;
13532         }
13533       else if (unformat (line_input, "group %U",
13534                          unformat_ip6_address, &remote6))
13535         {
13536           grp_set = remote_set = 1;
13537           ipv6_set = 1;
13538         }
13539       else
13540         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13541         ;
13542       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13543         ;
13544       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13545         ;
13546       else if (unformat (line_input, "vni %d", &vni))
13547         vni_set = 1;
13548       else if (unformat (line_input, "next-ip4"))
13549         protocol = 1;
13550       else if (unformat (line_input, "next-ip6"))
13551         protocol = 2;
13552       else if (unformat (line_input, "next-ethernet"))
13553         protocol = 3;
13554       else if (unformat (line_input, "next-nsh"))
13555         protocol = 4;
13556       else
13557         {
13558           errmsg ("parse error '%U'", format_unformat_error, line_input);
13559           return -99;
13560         }
13561     }
13562
13563   if (local_set == 0)
13564     {
13565       errmsg ("tunnel local address not specified");
13566       return -99;
13567     }
13568   if (remote_set == 0)
13569     {
13570       errmsg ("tunnel remote address not specified");
13571       return -99;
13572     }
13573   if (grp_set && mcast_sw_if_index == ~0)
13574     {
13575       errmsg ("tunnel nonexistent multicast device");
13576       return -99;
13577     }
13578   if (ipv4_set && ipv6_set)
13579     {
13580       errmsg ("both IPv4 and IPv6 addresses specified");
13581       return -99;
13582     }
13583
13584   if (vni_set == 0)
13585     {
13586       errmsg ("vni not specified");
13587       return -99;
13588     }
13589
13590   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13591
13592
13593   if (ipv6_set)
13594     {
13595       clib_memcpy (&mp->local, &local6, sizeof (local6));
13596       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13597     }
13598   else
13599     {
13600       clib_memcpy (&mp->local, &local4, sizeof (local4));
13601       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13602     }
13603
13604   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13605   mp->encap_vrf_id = ntohl (encap_vrf_id);
13606   mp->decap_vrf_id = ntohl (decap_vrf_id);
13607   mp->protocol = protocol;
13608   mp->vni = ntohl (vni);
13609   mp->is_add = is_add;
13610   mp->is_ipv6 = ipv6_set;
13611
13612   S (mp);
13613   W (ret);
13614   return ret;
13615 }
13616
13617 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13618   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13619 {
13620   vat_main_t *vam = &vat_main;
13621   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13622   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13623
13624   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13625          ntohl (mp->sw_if_index),
13626          format_ip46_address, &local, IP46_TYPE_ANY,
13627          format_ip46_address, &remote, IP46_TYPE_ANY,
13628          ntohl (mp->vni), mp->protocol,
13629          ntohl (mp->mcast_sw_if_index),
13630          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13631 }
13632
13633
13634 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13635   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13636 {
13637   vat_main_t *vam = &vat_main;
13638   vat_json_node_t *node = NULL;
13639   struct in_addr ip4;
13640   struct in6_addr ip6;
13641
13642   if (VAT_JSON_ARRAY != vam->json_tree.type)
13643     {
13644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13645       vat_json_init_array (&vam->json_tree);
13646     }
13647   node = vat_json_array_add (&vam->json_tree);
13648
13649   vat_json_init_object (node);
13650   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13651   if (mp->is_ipv6)
13652     {
13653       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13654       vat_json_object_add_ip6 (node, "local", ip6);
13655       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13656       vat_json_object_add_ip6 (node, "remote", ip6);
13657     }
13658   else
13659     {
13660       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13661       vat_json_object_add_ip4 (node, "local", ip4);
13662       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13663       vat_json_object_add_ip4 (node, "remote", ip4);
13664     }
13665   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13666   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13667   vat_json_object_add_uint (node, "mcast_sw_if_index",
13668                             ntohl (mp->mcast_sw_if_index));
13669   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13670   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13671   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13672 }
13673
13674 static int
13675 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13676 {
13677   unformat_input_t *i = vam->input;
13678   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13679   vl_api_control_ping_t *mp_ping;
13680   u32 sw_if_index;
13681   u8 sw_if_index_set = 0;
13682   int ret;
13683
13684   /* Parse args required to build the message */
13685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13686     {
13687       if (unformat (i, "sw_if_index %d", &sw_if_index))
13688         sw_if_index_set = 1;
13689       else
13690         break;
13691     }
13692
13693   if (sw_if_index_set == 0)
13694     {
13695       sw_if_index = ~0;
13696     }
13697
13698   if (!vam->json_output)
13699     {
13700       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13701              "sw_if_index", "local", "remote", "vni",
13702              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13703     }
13704
13705   /* Get list of vxlan-tunnel interfaces */
13706   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13707
13708   mp->sw_if_index = htonl (sw_if_index);
13709
13710   S (mp);
13711
13712   /* Use a control ping for synchronization */
13713   MPING (CONTROL_PING, mp_ping);
13714   S (mp_ping);
13715
13716   W (ret);
13717   return ret;
13718 }
13719
13720 static void vl_api_l2_fib_table_details_t_handler
13721   (vl_api_l2_fib_table_details_t * mp)
13722 {
13723   vat_main_t *vam = &vat_main;
13724
13725   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13726          "       %d       %d     %d",
13727          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13728          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13729          mp->bvi_mac);
13730 }
13731
13732 static void vl_api_l2_fib_table_details_t_handler_json
13733   (vl_api_l2_fib_table_details_t * mp)
13734 {
13735   vat_main_t *vam = &vat_main;
13736   vat_json_node_t *node = NULL;
13737
13738   if (VAT_JSON_ARRAY != vam->json_tree.type)
13739     {
13740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13741       vat_json_init_array (&vam->json_tree);
13742     }
13743   node = vat_json_array_add (&vam->json_tree);
13744
13745   vat_json_init_object (node);
13746   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13747   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13748   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13749   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13750   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13751   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13752 }
13753
13754 static int
13755 api_l2_fib_table_dump (vat_main_t * vam)
13756 {
13757   unformat_input_t *i = vam->input;
13758   vl_api_l2_fib_table_dump_t *mp;
13759   vl_api_control_ping_t *mp_ping;
13760   u32 bd_id;
13761   u8 bd_id_set = 0;
13762   int ret;
13763
13764   /* Parse args required to build the message */
13765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13766     {
13767       if (unformat (i, "bd_id %d", &bd_id))
13768         bd_id_set = 1;
13769       else
13770         break;
13771     }
13772
13773   if (bd_id_set == 0)
13774     {
13775       errmsg ("missing bridge domain");
13776       return -99;
13777     }
13778
13779   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13780
13781   /* Get list of l2 fib entries */
13782   M (L2_FIB_TABLE_DUMP, mp);
13783
13784   mp->bd_id = ntohl (bd_id);
13785   S (mp);
13786
13787   /* Use a control ping for synchronization */
13788   MPING (CONTROL_PING, mp_ping);
13789   S (mp_ping);
13790
13791   W (ret);
13792   return ret;
13793 }
13794
13795
13796 static int
13797 api_interface_name_renumber (vat_main_t * vam)
13798 {
13799   unformat_input_t *line_input = vam->input;
13800   vl_api_interface_name_renumber_t *mp;
13801   u32 sw_if_index = ~0;
13802   u32 new_show_dev_instance = ~0;
13803   int ret;
13804
13805   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13806     {
13807       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13808                     &sw_if_index))
13809         ;
13810       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13811         ;
13812       else if (unformat (line_input, "new_show_dev_instance %d",
13813                          &new_show_dev_instance))
13814         ;
13815       else
13816         break;
13817     }
13818
13819   if (sw_if_index == ~0)
13820     {
13821       errmsg ("missing interface name or sw_if_index");
13822       return -99;
13823     }
13824
13825   if (new_show_dev_instance == ~0)
13826     {
13827       errmsg ("missing new_show_dev_instance");
13828       return -99;
13829     }
13830
13831   M (INTERFACE_NAME_RENUMBER, mp);
13832
13833   mp->sw_if_index = ntohl (sw_if_index);
13834   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13835
13836   S (mp);
13837   W (ret);
13838   return ret;
13839 }
13840
13841 static int
13842 api_ip_probe_neighbor (vat_main_t * vam)
13843 {
13844   unformat_input_t *i = vam->input;
13845   vl_api_ip_probe_neighbor_t *mp;
13846   vl_api_address_t dst_adr = { };
13847   u8 int_set = 0;
13848   u8 adr_set = 0;
13849   u32 sw_if_index;
13850   int ret;
13851
13852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13853     {
13854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13855         int_set = 1;
13856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13857         int_set = 1;
13858       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13859         adr_set = 1;
13860       else
13861         break;
13862     }
13863
13864   if (int_set == 0)
13865     {
13866       errmsg ("missing interface");
13867       return -99;
13868     }
13869
13870   if (adr_set == 0)
13871     {
13872       errmsg ("missing addresses");
13873       return -99;
13874     }
13875
13876   M (IP_PROBE_NEIGHBOR, mp);
13877
13878   mp->sw_if_index = ntohl (sw_if_index);
13879   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13880
13881   S (mp);
13882   W (ret);
13883   return ret;
13884 }
13885
13886 static int
13887 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13888 {
13889   unformat_input_t *i = vam->input;
13890   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13891   u8 mode = IP_SCAN_V46_NEIGHBORS;
13892   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13893   int ret;
13894
13895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13896     {
13897       if (unformat (i, "ip4"))
13898         mode = IP_SCAN_V4_NEIGHBORS;
13899       else if (unformat (i, "ip6"))
13900         mode = IP_SCAN_V6_NEIGHBORS;
13901       if (unformat (i, "both"))
13902         mode = IP_SCAN_V46_NEIGHBORS;
13903       else if (unformat (i, "disable"))
13904         mode = IP_SCAN_DISABLED;
13905       else if (unformat (i, "interval %d", &interval))
13906         ;
13907       else if (unformat (i, "max-time %d", &time))
13908         ;
13909       else if (unformat (i, "max-update %d", &update))
13910         ;
13911       else if (unformat (i, "delay %d", &delay))
13912         ;
13913       else if (unformat (i, "stale %d", &stale))
13914         ;
13915       else
13916         break;
13917     }
13918
13919   if (interval > 255)
13920     {
13921       errmsg ("interval cannot exceed 255 minutes.");
13922       return -99;
13923     }
13924   if (time > 255)
13925     {
13926       errmsg ("max-time cannot exceed 255 usec.");
13927       return -99;
13928     }
13929   if (update > 255)
13930     {
13931       errmsg ("max-update cannot exceed 255.");
13932       return -99;
13933     }
13934   if (delay > 255)
13935     {
13936       errmsg ("delay cannot exceed 255 msec.");
13937       return -99;
13938     }
13939   if (stale > 255)
13940     {
13941       errmsg ("stale cannot exceed 255 minutes.");
13942       return -99;
13943     }
13944
13945   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13946   mp->mode = mode;
13947   mp->scan_interval = interval;
13948   mp->max_proc_time = time;
13949   mp->max_update = update;
13950   mp->scan_int_delay = delay;
13951   mp->stale_threshold = stale;
13952
13953   S (mp);
13954   W (ret);
13955   return ret;
13956 }
13957
13958 static int
13959 api_want_ip4_arp_events (vat_main_t * vam)
13960 {
13961   unformat_input_t *line_input = vam->input;
13962   vl_api_want_ip4_arp_events_t *mp;
13963   ip4_address_t address;
13964   int address_set = 0;
13965   u32 enable_disable = 1;
13966   int ret;
13967
13968   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13969     {
13970       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13971         address_set = 1;
13972       else if (unformat (line_input, "del"))
13973         enable_disable = 0;
13974       else
13975         break;
13976     }
13977
13978   if (address_set == 0)
13979     {
13980       errmsg ("missing addresses");
13981       return -99;
13982     }
13983
13984   M (WANT_IP4_ARP_EVENTS, mp);
13985   mp->enable_disable = enable_disable;
13986   mp->pid = htonl (getpid ());
13987   clib_memcpy (mp->ip, &address, sizeof (address));
13988
13989   S (mp);
13990   W (ret);
13991   return ret;
13992 }
13993
13994 static int
13995 api_want_ip6_nd_events (vat_main_t * vam)
13996 {
13997   unformat_input_t *line_input = vam->input;
13998   vl_api_want_ip6_nd_events_t *mp;
13999   vl_api_ip6_address_t address;
14000   int address_set = 0;
14001   u32 enable_disable = 1;
14002   int ret;
14003
14004   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14005     {
14006       if (unformat
14007           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14008         address_set = 1;
14009       else if (unformat (line_input, "del"))
14010         enable_disable = 0;
14011       else
14012         break;
14013     }
14014
14015   if (address_set == 0)
14016     {
14017       errmsg ("missing addresses");
14018       return -99;
14019     }
14020
14021   M (WANT_IP6_ND_EVENTS, mp);
14022   mp->enable_disable = enable_disable;
14023   mp->pid = htonl (getpid ());
14024   clib_memcpy (&mp->ip, &address, sizeof (address));
14025
14026   S (mp);
14027   W (ret);
14028   return ret;
14029 }
14030
14031 static int
14032 api_want_l2_macs_events (vat_main_t * vam)
14033 {
14034   unformat_input_t *line_input = vam->input;
14035   vl_api_want_l2_macs_events_t *mp;
14036   u8 enable_disable = 1;
14037   u32 scan_delay = 0;
14038   u32 max_macs_in_event = 0;
14039   u32 learn_limit = 0;
14040   int ret;
14041
14042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14043     {
14044       if (unformat (line_input, "learn-limit %d", &learn_limit))
14045         ;
14046       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14047         ;
14048       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14049         ;
14050       else if (unformat (line_input, "disable"))
14051         enable_disable = 0;
14052       else
14053         break;
14054     }
14055
14056   M (WANT_L2_MACS_EVENTS, mp);
14057   mp->enable_disable = enable_disable;
14058   mp->pid = htonl (getpid ());
14059   mp->learn_limit = htonl (learn_limit);
14060   mp->scan_delay = (u8) scan_delay;
14061   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14062   S (mp);
14063   W (ret);
14064   return ret;
14065 }
14066
14067 static int
14068 api_input_acl_set_interface (vat_main_t * vam)
14069 {
14070   unformat_input_t *i = vam->input;
14071   vl_api_input_acl_set_interface_t *mp;
14072   u32 sw_if_index;
14073   int sw_if_index_set;
14074   u32 ip4_table_index = ~0;
14075   u32 ip6_table_index = ~0;
14076   u32 l2_table_index = ~0;
14077   u8 is_add = 1;
14078   int ret;
14079
14080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14083         sw_if_index_set = 1;
14084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14085         sw_if_index_set = 1;
14086       else if (unformat (i, "del"))
14087         is_add = 0;
14088       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14089         ;
14090       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14091         ;
14092       else if (unformat (i, "l2-table %d", &l2_table_index))
14093         ;
14094       else
14095         {
14096           clib_warning ("parse error '%U'", format_unformat_error, i);
14097           return -99;
14098         }
14099     }
14100
14101   if (sw_if_index_set == 0)
14102     {
14103       errmsg ("missing interface name or sw_if_index");
14104       return -99;
14105     }
14106
14107   M (INPUT_ACL_SET_INTERFACE, mp);
14108
14109   mp->sw_if_index = ntohl (sw_if_index);
14110   mp->ip4_table_index = ntohl (ip4_table_index);
14111   mp->ip6_table_index = ntohl (ip6_table_index);
14112   mp->l2_table_index = ntohl (l2_table_index);
14113   mp->is_add = is_add;
14114
14115   S (mp);
14116   W (ret);
14117   return ret;
14118 }
14119
14120 static int
14121 api_output_acl_set_interface (vat_main_t * vam)
14122 {
14123   unformat_input_t *i = vam->input;
14124   vl_api_output_acl_set_interface_t *mp;
14125   u32 sw_if_index;
14126   int sw_if_index_set;
14127   u32 ip4_table_index = ~0;
14128   u32 ip6_table_index = ~0;
14129   u32 l2_table_index = ~0;
14130   u8 is_add = 1;
14131   int ret;
14132
14133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14134     {
14135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14136         sw_if_index_set = 1;
14137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14138         sw_if_index_set = 1;
14139       else if (unformat (i, "del"))
14140         is_add = 0;
14141       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14142         ;
14143       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14144         ;
14145       else if (unformat (i, "l2-table %d", &l2_table_index))
14146         ;
14147       else
14148         {
14149           clib_warning ("parse error '%U'", format_unformat_error, i);
14150           return -99;
14151         }
14152     }
14153
14154   if (sw_if_index_set == 0)
14155     {
14156       errmsg ("missing interface name or sw_if_index");
14157       return -99;
14158     }
14159
14160   M (OUTPUT_ACL_SET_INTERFACE, mp);
14161
14162   mp->sw_if_index = ntohl (sw_if_index);
14163   mp->ip4_table_index = ntohl (ip4_table_index);
14164   mp->ip6_table_index = ntohl (ip6_table_index);
14165   mp->l2_table_index = ntohl (l2_table_index);
14166   mp->is_add = is_add;
14167
14168   S (mp);
14169   W (ret);
14170   return ret;
14171 }
14172
14173 static int
14174 api_ip_address_dump (vat_main_t * vam)
14175 {
14176   unformat_input_t *i = vam->input;
14177   vl_api_ip_address_dump_t *mp;
14178   vl_api_control_ping_t *mp_ping;
14179   u32 sw_if_index = ~0;
14180   u8 sw_if_index_set = 0;
14181   u8 ipv4_set = 0;
14182   u8 ipv6_set = 0;
14183   int ret;
14184
14185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14186     {
14187       if (unformat (i, "sw_if_index %d", &sw_if_index))
14188         sw_if_index_set = 1;
14189       else
14190         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14191         sw_if_index_set = 1;
14192       else if (unformat (i, "ipv4"))
14193         ipv4_set = 1;
14194       else if (unformat (i, "ipv6"))
14195         ipv6_set = 1;
14196       else
14197         break;
14198     }
14199
14200   if (ipv4_set && ipv6_set)
14201     {
14202       errmsg ("ipv4 and ipv6 flags cannot be both set");
14203       return -99;
14204     }
14205
14206   if ((!ipv4_set) && (!ipv6_set))
14207     {
14208       errmsg ("no ipv4 nor ipv6 flag set");
14209       return -99;
14210     }
14211
14212   if (sw_if_index_set == 0)
14213     {
14214       errmsg ("missing interface name or sw_if_index");
14215       return -99;
14216     }
14217
14218   vam->current_sw_if_index = sw_if_index;
14219   vam->is_ipv6 = ipv6_set;
14220
14221   M (IP_ADDRESS_DUMP, mp);
14222   mp->sw_if_index = ntohl (sw_if_index);
14223   mp->is_ipv6 = ipv6_set;
14224   S (mp);
14225
14226   /* Use a control ping for synchronization */
14227   MPING (CONTROL_PING, mp_ping);
14228   S (mp_ping);
14229
14230   W (ret);
14231   return ret;
14232 }
14233
14234 static int
14235 api_ip_dump (vat_main_t * vam)
14236 {
14237   vl_api_ip_dump_t *mp;
14238   vl_api_control_ping_t *mp_ping;
14239   unformat_input_t *in = vam->input;
14240   int ipv4_set = 0;
14241   int ipv6_set = 0;
14242   int is_ipv6;
14243   int i;
14244   int ret;
14245
14246   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14247     {
14248       if (unformat (in, "ipv4"))
14249         ipv4_set = 1;
14250       else if (unformat (in, "ipv6"))
14251         ipv6_set = 1;
14252       else
14253         break;
14254     }
14255
14256   if (ipv4_set && ipv6_set)
14257     {
14258       errmsg ("ipv4 and ipv6 flags cannot be both set");
14259       return -99;
14260     }
14261
14262   if ((!ipv4_set) && (!ipv6_set))
14263     {
14264       errmsg ("no ipv4 nor ipv6 flag set");
14265       return -99;
14266     }
14267
14268   is_ipv6 = ipv6_set;
14269   vam->is_ipv6 = is_ipv6;
14270
14271   /* free old data */
14272   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14273     {
14274       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14275     }
14276   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14277
14278   M (IP_DUMP, mp);
14279   mp->is_ipv6 = ipv6_set;
14280   S (mp);
14281
14282   /* Use a control ping for synchronization */
14283   MPING (CONTROL_PING, mp_ping);
14284   S (mp_ping);
14285
14286   W (ret);
14287   return ret;
14288 }
14289
14290 static int
14291 api_ipsec_spd_add_del (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_ipsec_spd_add_del_t *mp;
14295   u32 spd_id = ~0;
14296   u8 is_add = 1;
14297   int ret;
14298
14299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14300     {
14301       if (unformat (i, "spd_id %d", &spd_id))
14302         ;
14303       else if (unformat (i, "del"))
14304         is_add = 0;
14305       else
14306         {
14307           clib_warning ("parse error '%U'", format_unformat_error, i);
14308           return -99;
14309         }
14310     }
14311   if (spd_id == ~0)
14312     {
14313       errmsg ("spd_id must be set");
14314       return -99;
14315     }
14316
14317   M (IPSEC_SPD_ADD_DEL, mp);
14318
14319   mp->spd_id = ntohl (spd_id);
14320   mp->is_add = is_add;
14321
14322   S (mp);
14323   W (ret);
14324   return ret;
14325 }
14326
14327 static int
14328 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14329 {
14330   unformat_input_t *i = vam->input;
14331   vl_api_ipsec_interface_add_del_spd_t *mp;
14332   u32 sw_if_index;
14333   u8 sw_if_index_set = 0;
14334   u32 spd_id = (u32) ~ 0;
14335   u8 is_add = 1;
14336   int ret;
14337
14338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14339     {
14340       if (unformat (i, "del"))
14341         is_add = 0;
14342       else if (unformat (i, "spd_id %d", &spd_id))
14343         ;
14344       else
14345         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14346         sw_if_index_set = 1;
14347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14348         sw_if_index_set = 1;
14349       else
14350         {
14351           clib_warning ("parse error '%U'", format_unformat_error, i);
14352           return -99;
14353         }
14354
14355     }
14356
14357   if (spd_id == (u32) ~ 0)
14358     {
14359       errmsg ("spd_id must be set");
14360       return -99;
14361     }
14362
14363   if (sw_if_index_set == 0)
14364     {
14365       errmsg ("missing interface name or sw_if_index");
14366       return -99;
14367     }
14368
14369   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14370
14371   mp->spd_id = ntohl (spd_id);
14372   mp->sw_if_index = ntohl (sw_if_index);
14373   mp->is_add = is_add;
14374
14375   S (mp);
14376   W (ret);
14377   return ret;
14378 }
14379
14380 static int
14381 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_ipsec_spd_entry_add_del_t *mp;
14385   u8 is_add = 1, is_outbound = 0;
14386   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14387   i32 priority = 0;
14388   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14389   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14390   vl_api_address_t laddr_start = { }, laddr_stop =
14391   {
14392   }, raddr_start =
14393   {
14394   }, raddr_stop =
14395   {
14396   };
14397   int ret;
14398
14399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14400     {
14401       if (unformat (i, "del"))
14402         is_add = 0;
14403       if (unformat (i, "outbound"))
14404         is_outbound = 1;
14405       if (unformat (i, "inbound"))
14406         is_outbound = 0;
14407       else if (unformat (i, "spd_id %d", &spd_id))
14408         ;
14409       else if (unformat (i, "sa_id %d", &sa_id))
14410         ;
14411       else if (unformat (i, "priority %d", &priority))
14412         ;
14413       else if (unformat (i, "protocol %d", &protocol))
14414         ;
14415       else if (unformat (i, "lport_start %d", &lport_start))
14416         ;
14417       else if (unformat (i, "lport_stop %d", &lport_stop))
14418         ;
14419       else if (unformat (i, "rport_start %d", &rport_start))
14420         ;
14421       else if (unformat (i, "rport_stop %d", &rport_stop))
14422         ;
14423       else if (unformat (i, "laddr_start %U",
14424                          unformat_vl_api_address, &laddr_start))
14425         ;
14426       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14427                          &laddr_stop))
14428         ;
14429       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14430                          &raddr_start))
14431         ;
14432       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14433                          &raddr_stop))
14434         ;
14435       else
14436         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14437         {
14438           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14439             {
14440               clib_warning ("unsupported action: 'resolve'");
14441               return -99;
14442             }
14443         }
14444       else
14445         {
14446           clib_warning ("parse error '%U'", format_unformat_error, i);
14447           return -99;
14448         }
14449
14450     }
14451
14452   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14453
14454   mp->is_add = is_add;
14455
14456   mp->entry.spd_id = ntohl (spd_id);
14457   mp->entry.priority = ntohl (priority);
14458   mp->entry.is_outbound = is_outbound;
14459
14460   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14461                sizeof (vl_api_address_t));
14462   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14463                sizeof (vl_api_address_t));
14464   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14465                sizeof (vl_api_address_t));
14466   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14467                sizeof (vl_api_address_t));
14468
14469   mp->entry.protocol = (u8) protocol;
14470   mp->entry.local_port_start = ntohs ((u16) lport_start);
14471   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14472   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14473   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14474   mp->entry.policy = (u8) policy;
14475   mp->entry.sa_id = ntohl (sa_id);
14476
14477   S (mp);
14478   W (ret);
14479   return ret;
14480 }
14481
14482 static int
14483 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14484 {
14485   unformat_input_t *i = vam->input;
14486   vl_api_ipsec_sad_entry_add_del_t *mp;
14487   u32 sad_id = 0, spi = 0;
14488   u8 *ck = 0, *ik = 0;
14489   u8 is_add = 1;
14490
14491   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14492   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14493   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14494   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14495   vl_api_address_t tun_src, tun_dst;
14496   int ret;
14497
14498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14499     {
14500       if (unformat (i, "del"))
14501         is_add = 0;
14502       else if (unformat (i, "sad_id %d", &sad_id))
14503         ;
14504       else if (unformat (i, "spi %d", &spi))
14505         ;
14506       else if (unformat (i, "esp"))
14507         protocol = IPSEC_API_PROTO_ESP;
14508       else
14509         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14510         {
14511           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14512           if (ADDRESS_IP6 == tun_src.af)
14513             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14514         }
14515       else
14516         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14517         {
14518           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14519           if (ADDRESS_IP6 == tun_src.af)
14520             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14521         }
14522       else
14523         if (unformat (i, "crypto_alg %U",
14524                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14525         ;
14526       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14527         ;
14528       else if (unformat (i, "integ_alg %U",
14529                          unformat_ipsec_api_integ_alg, &integ_alg))
14530         ;
14531       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14532         ;
14533       else
14534         {
14535           clib_warning ("parse error '%U'", format_unformat_error, i);
14536           return -99;
14537         }
14538
14539     }
14540
14541   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14542
14543   mp->is_add = is_add;
14544   mp->entry.sad_id = ntohl (sad_id);
14545   mp->entry.protocol = protocol;
14546   mp->entry.spi = ntohl (spi);
14547   mp->entry.flags = flags;
14548
14549   mp->entry.crypto_algorithm = crypto_alg;
14550   mp->entry.integrity_algorithm = integ_alg;
14551   mp->entry.crypto_key.length = vec_len (ck);
14552   mp->entry.integrity_key.length = vec_len (ik);
14553
14554   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14555     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14556
14557   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14558     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14559
14560   if (ck)
14561     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14562   if (ik)
14563     clib_memcpy (mp->entry.integrity_key.data, ik,
14564                  mp->entry.integrity_key.length);
14565
14566   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14567     {
14568       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14569                    sizeof (mp->entry.tunnel_src));
14570       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14571                    sizeof (mp->entry.tunnel_dst));
14572     }
14573
14574   S (mp);
14575   W (ret);
14576   return ret;
14577 }
14578
14579 static int
14580 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14581 {
14582   unformat_input_t *i = vam->input;
14583   vl_api_ipsec_tunnel_if_add_del_t *mp;
14584   u32 local_spi = 0, remote_spi = 0;
14585   u32 crypto_alg = 0, integ_alg = 0;
14586   u8 *lck = NULL, *rck = NULL;
14587   u8 *lik = NULL, *rik = NULL;
14588   vl_api_address_t local_ip = { 0 };
14589   vl_api_address_t remote_ip = { 0 };
14590   f64 before = 0;
14591   u8 is_add = 1;
14592   u8 esn = 0;
14593   u8 anti_replay = 0;
14594   u8 renumber = 0;
14595   u32 instance = ~0;
14596   u32 count = 1, jj;
14597   int ret = -1;
14598
14599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14600     {
14601       if (unformat (i, "del"))
14602         is_add = 0;
14603       else if (unformat (i, "esn"))
14604         esn = 1;
14605       else if (unformat (i, "anti-replay"))
14606         anti_replay = 1;
14607       else if (unformat (i, "count %d", &count))
14608         ;
14609       else if (unformat (i, "local_spi %d", &local_spi))
14610         ;
14611       else if (unformat (i, "remote_spi %d", &remote_spi))
14612         ;
14613       else
14614         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14615         ;
14616       else
14617         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14618         ;
14619       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14620         ;
14621       else
14622         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14623         ;
14624       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14625         ;
14626       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14627         ;
14628       else
14629         if (unformat
14630             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14631         {
14632           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14633             {
14634               errmsg ("unsupported crypto-alg: '%U'\n",
14635                       format_ipsec_crypto_alg, crypto_alg);
14636               return -99;
14637             }
14638         }
14639       else
14640         if (unformat
14641             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14642         {
14643           if (integ_alg >= IPSEC_INTEG_N_ALG)
14644             {
14645               errmsg ("unsupported integ-alg: '%U'\n",
14646                       format_ipsec_integ_alg, integ_alg);
14647               return -99;
14648             }
14649         }
14650       else if (unformat (i, "instance %u", &instance))
14651         renumber = 1;
14652       else
14653         {
14654           errmsg ("parse error '%U'\n", format_unformat_error, i);
14655           return -99;
14656         }
14657     }
14658
14659   if (count > 1)
14660     {
14661       /* Turn on async mode */
14662       vam->async_mode = 1;
14663       vam->async_errors = 0;
14664       before = vat_time_now (vam);
14665     }
14666
14667   for (jj = 0; jj < count; jj++)
14668     {
14669       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14670
14671       mp->is_add = is_add;
14672       mp->esn = esn;
14673       mp->anti_replay = anti_replay;
14674
14675       if (jj > 0)
14676         increment_address (&remote_ip);
14677
14678       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14679       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14680
14681       mp->local_spi = htonl (local_spi + jj);
14682       mp->remote_spi = htonl (remote_spi + jj);
14683       mp->crypto_alg = (u8) crypto_alg;
14684
14685       mp->local_crypto_key_len = 0;
14686       if (lck)
14687         {
14688           mp->local_crypto_key_len = vec_len (lck);
14689           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14690             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14691           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14692         }
14693
14694       mp->remote_crypto_key_len = 0;
14695       if (rck)
14696         {
14697           mp->remote_crypto_key_len = vec_len (rck);
14698           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14699             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14700           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14701         }
14702
14703       mp->integ_alg = (u8) integ_alg;
14704
14705       mp->local_integ_key_len = 0;
14706       if (lik)
14707         {
14708           mp->local_integ_key_len = vec_len (lik);
14709           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14710             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14711           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14712         }
14713
14714       mp->remote_integ_key_len = 0;
14715       if (rik)
14716         {
14717           mp->remote_integ_key_len = vec_len (rik);
14718           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14719             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14720           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14721         }
14722
14723       if (renumber)
14724         {
14725           mp->renumber = renumber;
14726           mp->show_instance = ntohl (instance);
14727         }
14728       S (mp);
14729     }
14730
14731   /* When testing multiple add/del ops, use a control-ping to sync */
14732   if (count > 1)
14733     {
14734       vl_api_control_ping_t *mp_ping;
14735       f64 after;
14736       f64 timeout;
14737
14738       /* Shut off async mode */
14739       vam->async_mode = 0;
14740
14741       MPING (CONTROL_PING, mp_ping);
14742       S (mp_ping);
14743
14744       timeout = vat_time_now (vam) + 1.0;
14745       while (vat_time_now (vam) < timeout)
14746         if (vam->result_ready == 1)
14747           goto out;
14748       vam->retval = -99;
14749
14750     out:
14751       if (vam->retval == -99)
14752         errmsg ("timeout");
14753
14754       if (vam->async_errors > 0)
14755         {
14756           errmsg ("%d asynchronous errors", vam->async_errors);
14757           vam->retval = -98;
14758         }
14759       vam->async_errors = 0;
14760       after = vat_time_now (vam);
14761
14762       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14763       if (jj > 0)
14764         count = jj;
14765
14766       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14767              count, after - before, count / (after - before));
14768     }
14769   else
14770     {
14771       /* Wait for a reply... */
14772       W (ret);
14773       return ret;
14774     }
14775
14776   return ret;
14777 }
14778
14779 static void
14780 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14781 {
14782   vat_main_t *vam = &vat_main;
14783
14784   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14785          "crypto_key %U integ_alg %u integ_key %U flags %x "
14786          "tunnel_src_addr %U tunnel_dst_addr %U "
14787          "salt %u seq_outbound %lu last_seq_inbound %lu "
14788          "replay_window %lu\n",
14789          ntohl (mp->entry.sad_id),
14790          ntohl (mp->sw_if_index),
14791          ntohl (mp->entry.spi),
14792          ntohl (mp->entry.protocol),
14793          ntohl (mp->entry.crypto_algorithm),
14794          format_hex_bytes, mp->entry.crypto_key.data,
14795          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14796          format_hex_bytes, mp->entry.integrity_key.data,
14797          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14798          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14799          &mp->entry.tunnel_dst, ntohl (mp->salt),
14800          clib_net_to_host_u64 (mp->seq_outbound),
14801          clib_net_to_host_u64 (mp->last_seq_inbound),
14802          clib_net_to_host_u64 (mp->replay_window));
14803 }
14804
14805 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14806 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14807
14808 static void vl_api_ipsec_sa_details_t_handler_json
14809   (vl_api_ipsec_sa_details_t * mp)
14810 {
14811   vat_main_t *vam = &vat_main;
14812   vat_json_node_t *node = NULL;
14813   vl_api_ipsec_sad_flags_t flags;
14814
14815   if (VAT_JSON_ARRAY != vam->json_tree.type)
14816     {
14817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14818       vat_json_init_array (&vam->json_tree);
14819     }
14820   node = vat_json_array_add (&vam->json_tree);
14821
14822   vat_json_init_object (node);
14823   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14825   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14826   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14827   vat_json_object_add_uint (node, "crypto_alg",
14828                             ntohl (mp->entry.crypto_algorithm));
14829   vat_json_object_add_uint (node, "integ_alg",
14830                             ntohl (mp->entry.integrity_algorithm));
14831   flags = ntohl (mp->entry.flags);
14832   vat_json_object_add_uint (node, "use_esn",
14833                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14834   vat_json_object_add_uint (node, "use_anti_replay",
14835                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14836   vat_json_object_add_uint (node, "is_tunnel",
14837                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14838   vat_json_object_add_uint (node, "is_tunnel_ip6",
14839                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14840   vat_json_object_add_uint (node, "udp_encap",
14841                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14842   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14843                              mp->entry.crypto_key.length);
14844   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14845                              mp->entry.integrity_key.length);
14846   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14847   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14848   vat_json_object_add_uint (node, "replay_window",
14849                             clib_net_to_host_u64 (mp->replay_window));
14850 }
14851
14852 static int
14853 api_ipsec_sa_dump (vat_main_t * vam)
14854 {
14855   unformat_input_t *i = vam->input;
14856   vl_api_ipsec_sa_dump_t *mp;
14857   vl_api_control_ping_t *mp_ping;
14858   u32 sa_id = ~0;
14859   int ret;
14860
14861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14862     {
14863       if (unformat (i, "sa_id %d", &sa_id))
14864         ;
14865       else
14866         {
14867           clib_warning ("parse error '%U'", format_unformat_error, i);
14868           return -99;
14869         }
14870     }
14871
14872   M (IPSEC_SA_DUMP, mp);
14873
14874   mp->sa_id = ntohl (sa_id);
14875
14876   S (mp);
14877
14878   /* Use a control ping for synchronization */
14879   M (CONTROL_PING, mp_ping);
14880   S (mp_ping);
14881
14882   W (ret);
14883   return ret;
14884 }
14885
14886 static int
14887 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14888 {
14889   unformat_input_t *i = vam->input;
14890   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14891   u32 sw_if_index = ~0;
14892   u32 sa_id = ~0;
14893   u8 is_outbound = (u8) ~ 0;
14894   int ret;
14895
14896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14897     {
14898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14899         ;
14900       else if (unformat (i, "sa_id %d", &sa_id))
14901         ;
14902       else if (unformat (i, "outbound"))
14903         is_outbound = 1;
14904       else if (unformat (i, "inbound"))
14905         is_outbound = 0;
14906       else
14907         {
14908           clib_warning ("parse error '%U'", format_unformat_error, i);
14909           return -99;
14910         }
14911     }
14912
14913   if (sw_if_index == ~0)
14914     {
14915       errmsg ("interface must be specified");
14916       return -99;
14917     }
14918
14919   if (sa_id == ~0)
14920     {
14921       errmsg ("SA ID must be specified");
14922       return -99;
14923     }
14924
14925   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14926
14927   mp->sw_if_index = htonl (sw_if_index);
14928   mp->sa_id = htonl (sa_id);
14929   mp->is_outbound = is_outbound;
14930
14931   S (mp);
14932   W (ret);
14933
14934   return ret;
14935 }
14936
14937 static int
14938 api_get_first_msg_id (vat_main_t * vam)
14939 {
14940   vl_api_get_first_msg_id_t *mp;
14941   unformat_input_t *i = vam->input;
14942   u8 *name;
14943   u8 name_set = 0;
14944   int ret;
14945
14946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14947     {
14948       if (unformat (i, "client %s", &name))
14949         name_set = 1;
14950       else
14951         break;
14952     }
14953
14954   if (name_set == 0)
14955     {
14956       errmsg ("missing client name");
14957       return -99;
14958     }
14959   vec_add1 (name, 0);
14960
14961   if (vec_len (name) > 63)
14962     {
14963       errmsg ("client name too long");
14964       return -99;
14965     }
14966
14967   M (GET_FIRST_MSG_ID, mp);
14968   clib_memcpy (mp->name, name, vec_len (name));
14969   S (mp);
14970   W (ret);
14971   return ret;
14972 }
14973
14974 static int
14975 api_cop_interface_enable_disable (vat_main_t * vam)
14976 {
14977   unformat_input_t *line_input = vam->input;
14978   vl_api_cop_interface_enable_disable_t *mp;
14979   u32 sw_if_index = ~0;
14980   u8 enable_disable = 1;
14981   int ret;
14982
14983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (line_input, "disable"))
14986         enable_disable = 0;
14987       if (unformat (line_input, "enable"))
14988         enable_disable = 1;
14989       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14990                          vam, &sw_if_index))
14991         ;
14992       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14993         ;
14994       else
14995         break;
14996     }
14997
14998   if (sw_if_index == ~0)
14999     {
15000       errmsg ("missing interface name or sw_if_index");
15001       return -99;
15002     }
15003
15004   /* Construct the API message */
15005   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15006   mp->sw_if_index = ntohl (sw_if_index);
15007   mp->enable_disable = enable_disable;
15008
15009   /* send it... */
15010   S (mp);
15011   /* Wait for the reply */
15012   W (ret);
15013   return ret;
15014 }
15015
15016 static int
15017 api_cop_whitelist_enable_disable (vat_main_t * vam)
15018 {
15019   unformat_input_t *line_input = vam->input;
15020   vl_api_cop_whitelist_enable_disable_t *mp;
15021   u32 sw_if_index = ~0;
15022   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15023   u32 fib_id = 0;
15024   int ret;
15025
15026   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15027     {
15028       if (unformat (line_input, "ip4"))
15029         ip4 = 1;
15030       else if (unformat (line_input, "ip6"))
15031         ip6 = 1;
15032       else if (unformat (line_input, "default"))
15033         default_cop = 1;
15034       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15035                          vam, &sw_if_index))
15036         ;
15037       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15038         ;
15039       else if (unformat (line_input, "fib-id %d", &fib_id))
15040         ;
15041       else
15042         break;
15043     }
15044
15045   if (sw_if_index == ~0)
15046     {
15047       errmsg ("missing interface name or sw_if_index");
15048       return -99;
15049     }
15050
15051   /* Construct the API message */
15052   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15053   mp->sw_if_index = ntohl (sw_if_index);
15054   mp->fib_id = ntohl (fib_id);
15055   mp->ip4 = ip4;
15056   mp->ip6 = ip6;
15057   mp->default_cop = default_cop;
15058
15059   /* send it... */
15060   S (mp);
15061   /* Wait for the reply */
15062   W (ret);
15063   return ret;
15064 }
15065
15066 static int
15067 api_get_node_graph (vat_main_t * vam)
15068 {
15069   vl_api_get_node_graph_t *mp;
15070   int ret;
15071
15072   M (GET_NODE_GRAPH, mp);
15073
15074   /* send it... */
15075   S (mp);
15076   /* Wait for the reply */
15077   W (ret);
15078   return ret;
15079 }
15080
15081 /* *INDENT-OFF* */
15082 /** Used for parsing LISP eids */
15083 typedef CLIB_PACKED(struct{
15084   u8 addr[16];   /**< eid address */
15085   u32 len;       /**< prefix length if IP */
15086   u8 type;      /**< type of eid */
15087 }) lisp_eid_vat_t;
15088 /* *INDENT-ON* */
15089
15090 static uword
15091 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15092 {
15093   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15094
15095   clib_memset (a, 0, sizeof (a[0]));
15096
15097   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15098     {
15099       a->type = 0;              /* ipv4 type */
15100     }
15101   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15102     {
15103       a->type = 1;              /* ipv6 type */
15104     }
15105   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15106     {
15107       a->type = 2;              /* mac type */
15108     }
15109   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15110     {
15111       a->type = 3;              /* NSH type */
15112       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15113       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15114     }
15115   else
15116     {
15117       return 0;
15118     }
15119
15120   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15121     {
15122       return 0;
15123     }
15124
15125   return 1;
15126 }
15127
15128 static int
15129 lisp_eid_size_vat (u8 type)
15130 {
15131   switch (type)
15132     {
15133     case 0:
15134       return 4;
15135     case 1:
15136       return 16;
15137     case 2:
15138       return 6;
15139     case 3:
15140       return 5;
15141     }
15142   return 0;
15143 }
15144
15145 static void
15146 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15147 {
15148   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15149 }
15150
15151 static int
15152 api_one_add_del_locator_set (vat_main_t * vam)
15153 {
15154   unformat_input_t *input = vam->input;
15155   vl_api_one_add_del_locator_set_t *mp;
15156   u8 is_add = 1;
15157   u8 *locator_set_name = NULL;
15158   u8 locator_set_name_set = 0;
15159   vl_api_local_locator_t locator, *locators = 0;
15160   u32 sw_if_index, priority, weight;
15161   u32 data_len = 0;
15162
15163   int ret;
15164   /* Parse args required to build the message */
15165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15166     {
15167       if (unformat (input, "del"))
15168         {
15169           is_add = 0;
15170         }
15171       else if (unformat (input, "locator-set %s", &locator_set_name))
15172         {
15173           locator_set_name_set = 1;
15174         }
15175       else if (unformat (input, "sw_if_index %u p %u w %u",
15176                          &sw_if_index, &priority, &weight))
15177         {
15178           locator.sw_if_index = htonl (sw_if_index);
15179           locator.priority = priority;
15180           locator.weight = weight;
15181           vec_add1 (locators, locator);
15182         }
15183       else
15184         if (unformat
15185             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15186              &sw_if_index, &priority, &weight))
15187         {
15188           locator.sw_if_index = htonl (sw_if_index);
15189           locator.priority = priority;
15190           locator.weight = weight;
15191           vec_add1 (locators, locator);
15192         }
15193       else
15194         break;
15195     }
15196
15197   if (locator_set_name_set == 0)
15198     {
15199       errmsg ("missing locator-set name");
15200       vec_free (locators);
15201       return -99;
15202     }
15203
15204   if (vec_len (locator_set_name) > 64)
15205     {
15206       errmsg ("locator-set name too long");
15207       vec_free (locator_set_name);
15208       vec_free (locators);
15209       return -99;
15210     }
15211   vec_add1 (locator_set_name, 0);
15212
15213   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15214
15215   /* Construct the API message */
15216   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15217
15218   mp->is_add = is_add;
15219   clib_memcpy (mp->locator_set_name, locator_set_name,
15220                vec_len (locator_set_name));
15221   vec_free (locator_set_name);
15222
15223   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15224   if (locators)
15225     clib_memcpy (mp->locators, locators, data_len);
15226   vec_free (locators);
15227
15228   /* send it... */
15229   S (mp);
15230
15231   /* Wait for a reply... */
15232   W (ret);
15233   return ret;
15234 }
15235
15236 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15237
15238 static int
15239 api_one_add_del_locator (vat_main_t * vam)
15240 {
15241   unformat_input_t *input = vam->input;
15242   vl_api_one_add_del_locator_t *mp;
15243   u32 tmp_if_index = ~0;
15244   u32 sw_if_index = ~0;
15245   u8 sw_if_index_set = 0;
15246   u8 sw_if_index_if_name_set = 0;
15247   u32 priority = ~0;
15248   u8 priority_set = 0;
15249   u32 weight = ~0;
15250   u8 weight_set = 0;
15251   u8 is_add = 1;
15252   u8 *locator_set_name = NULL;
15253   u8 locator_set_name_set = 0;
15254   int ret;
15255
15256   /* Parse args required to build the message */
15257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15258     {
15259       if (unformat (input, "del"))
15260         {
15261           is_add = 0;
15262         }
15263       else if (unformat (input, "locator-set %s", &locator_set_name))
15264         {
15265           locator_set_name_set = 1;
15266         }
15267       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15268                          &tmp_if_index))
15269         {
15270           sw_if_index_if_name_set = 1;
15271           sw_if_index = tmp_if_index;
15272         }
15273       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15274         {
15275           sw_if_index_set = 1;
15276           sw_if_index = tmp_if_index;
15277         }
15278       else if (unformat (input, "p %d", &priority))
15279         {
15280           priority_set = 1;
15281         }
15282       else if (unformat (input, "w %d", &weight))
15283         {
15284           weight_set = 1;
15285         }
15286       else
15287         break;
15288     }
15289
15290   if (locator_set_name_set == 0)
15291     {
15292       errmsg ("missing locator-set name");
15293       return -99;
15294     }
15295
15296   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15297     {
15298       errmsg ("missing sw_if_index");
15299       vec_free (locator_set_name);
15300       return -99;
15301     }
15302
15303   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15304     {
15305       errmsg ("cannot use both params interface name and sw_if_index");
15306       vec_free (locator_set_name);
15307       return -99;
15308     }
15309
15310   if (priority_set == 0)
15311     {
15312       errmsg ("missing locator-set priority");
15313       vec_free (locator_set_name);
15314       return -99;
15315     }
15316
15317   if (weight_set == 0)
15318     {
15319       errmsg ("missing locator-set weight");
15320       vec_free (locator_set_name);
15321       return -99;
15322     }
15323
15324   if (vec_len (locator_set_name) > 64)
15325     {
15326       errmsg ("locator-set name too long");
15327       vec_free (locator_set_name);
15328       return -99;
15329     }
15330   vec_add1 (locator_set_name, 0);
15331
15332   /* Construct the API message */
15333   M (ONE_ADD_DEL_LOCATOR, mp);
15334
15335   mp->is_add = is_add;
15336   mp->sw_if_index = ntohl (sw_if_index);
15337   mp->priority = priority;
15338   mp->weight = weight;
15339   clib_memcpy (mp->locator_set_name, locator_set_name,
15340                vec_len (locator_set_name));
15341   vec_free (locator_set_name);
15342
15343   /* send it... */
15344   S (mp);
15345
15346   /* Wait for a reply... */
15347   W (ret);
15348   return ret;
15349 }
15350
15351 #define api_lisp_add_del_locator api_one_add_del_locator
15352
15353 uword
15354 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15355 {
15356   u32 *key_id = va_arg (*args, u32 *);
15357   u8 *s = 0;
15358
15359   if (unformat (input, "%s", &s))
15360     {
15361       if (!strcmp ((char *) s, "sha1"))
15362         key_id[0] = HMAC_SHA_1_96;
15363       else if (!strcmp ((char *) s, "sha256"))
15364         key_id[0] = HMAC_SHA_256_128;
15365       else
15366         {
15367           clib_warning ("invalid key_id: '%s'", s);
15368           key_id[0] = HMAC_NO_KEY;
15369         }
15370     }
15371   else
15372     return 0;
15373
15374   vec_free (s);
15375   return 1;
15376 }
15377
15378 static int
15379 api_one_add_del_local_eid (vat_main_t * vam)
15380 {
15381   unformat_input_t *input = vam->input;
15382   vl_api_one_add_del_local_eid_t *mp;
15383   u8 is_add = 1;
15384   u8 eid_set = 0;
15385   lisp_eid_vat_t _eid, *eid = &_eid;
15386   u8 *locator_set_name = 0;
15387   u8 locator_set_name_set = 0;
15388   u32 vni = 0;
15389   u16 key_id = 0;
15390   u8 *key = 0;
15391   int ret;
15392
15393   /* Parse args required to build the message */
15394   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15395     {
15396       if (unformat (input, "del"))
15397         {
15398           is_add = 0;
15399         }
15400       else if (unformat (input, "vni %d", &vni))
15401         {
15402           ;
15403         }
15404       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15405         {
15406           eid_set = 1;
15407         }
15408       else if (unformat (input, "locator-set %s", &locator_set_name))
15409         {
15410           locator_set_name_set = 1;
15411         }
15412       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15413         ;
15414       else if (unformat (input, "secret-key %_%v%_", &key))
15415         ;
15416       else
15417         break;
15418     }
15419
15420   if (locator_set_name_set == 0)
15421     {
15422       errmsg ("missing locator-set name");
15423       return -99;
15424     }
15425
15426   if (0 == eid_set)
15427     {
15428       errmsg ("EID address not set!");
15429       vec_free (locator_set_name);
15430       return -99;
15431     }
15432
15433   if (key && (0 == key_id))
15434     {
15435       errmsg ("invalid key_id!");
15436       return -99;
15437     }
15438
15439   if (vec_len (key) > 64)
15440     {
15441       errmsg ("key too long");
15442       vec_free (key);
15443       return -99;
15444     }
15445
15446   if (vec_len (locator_set_name) > 64)
15447     {
15448       errmsg ("locator-set name too long");
15449       vec_free (locator_set_name);
15450       return -99;
15451     }
15452   vec_add1 (locator_set_name, 0);
15453
15454   /* Construct the API message */
15455   M (ONE_ADD_DEL_LOCAL_EID, mp);
15456
15457   mp->is_add = is_add;
15458   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15459   mp->eid_type = eid->type;
15460   mp->prefix_len = eid->len;
15461   mp->vni = clib_host_to_net_u32 (vni);
15462   mp->key_id = clib_host_to_net_u16 (key_id);
15463   clib_memcpy (mp->locator_set_name, locator_set_name,
15464                vec_len (locator_set_name));
15465   clib_memcpy (mp->key, key, vec_len (key));
15466
15467   vec_free (locator_set_name);
15468   vec_free (key);
15469
15470   /* send it... */
15471   S (mp);
15472
15473   /* Wait for a reply... */
15474   W (ret);
15475   return ret;
15476 }
15477
15478 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15479
15480 static int
15481 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15482 {
15483   u32 dp_table = 0, vni = 0;;
15484   unformat_input_t *input = vam->input;
15485   vl_api_gpe_add_del_fwd_entry_t *mp;
15486   u8 is_add = 1;
15487   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15488   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15489   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15490   u32 action = ~0, w;
15491   ip4_address_t rmt_rloc4, lcl_rloc4;
15492   ip6_address_t rmt_rloc6, lcl_rloc6;
15493   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15494   int ret;
15495
15496   clib_memset (&rloc, 0, sizeof (rloc));
15497
15498   /* Parse args required to build the message */
15499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15500     {
15501       if (unformat (input, "del"))
15502         is_add = 0;
15503       else if (unformat (input, "add"))
15504         is_add = 1;
15505       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15506         {
15507           rmt_eid_set = 1;
15508         }
15509       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15510         {
15511           lcl_eid_set = 1;
15512         }
15513       else if (unformat (input, "vrf %d", &dp_table))
15514         ;
15515       else if (unformat (input, "bd %d", &dp_table))
15516         ;
15517       else if (unformat (input, "vni %d", &vni))
15518         ;
15519       else if (unformat (input, "w %d", &w))
15520         {
15521           if (!curr_rloc)
15522             {
15523               errmsg ("No RLOC configured for setting priority/weight!");
15524               return -99;
15525             }
15526           curr_rloc->weight = w;
15527         }
15528       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15529                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15530         {
15531           rloc.is_ip4 = 1;
15532
15533           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15534           rloc.weight = 0;
15535           vec_add1 (lcl_locs, rloc);
15536
15537           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15538           vec_add1 (rmt_locs, rloc);
15539           /* weight saved in rmt loc */
15540           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15541         }
15542       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15543                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15544         {
15545           rloc.is_ip4 = 0;
15546           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15547           rloc.weight = 0;
15548           vec_add1 (lcl_locs, rloc);
15549
15550           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15551           vec_add1 (rmt_locs, rloc);
15552           /* weight saved in rmt loc */
15553           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15554         }
15555       else if (unformat (input, "action %d", &action))
15556         {
15557           ;
15558         }
15559       else
15560         {
15561           clib_warning ("parse error '%U'", format_unformat_error, input);
15562           return -99;
15563         }
15564     }
15565
15566   if (!rmt_eid_set)
15567     {
15568       errmsg ("remote eid addresses not set");
15569       return -99;
15570     }
15571
15572   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15573     {
15574       errmsg ("eid types don't match");
15575       return -99;
15576     }
15577
15578   if (0 == rmt_locs && (u32) ~ 0 == action)
15579     {
15580       errmsg ("action not set for negative mapping");
15581       return -99;
15582     }
15583
15584   /* Construct the API message */
15585   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15586       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15587
15588   mp->is_add = is_add;
15589   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15590   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15591   mp->eid_type = rmt_eid->type;
15592   mp->dp_table = clib_host_to_net_u32 (dp_table);
15593   mp->vni = clib_host_to_net_u32 (vni);
15594   mp->rmt_len = rmt_eid->len;
15595   mp->lcl_len = lcl_eid->len;
15596   mp->action = action;
15597
15598   if (0 != rmt_locs && 0 != lcl_locs)
15599     {
15600       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15601       clib_memcpy (mp->locs, lcl_locs,
15602                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15603
15604       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15605       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15606                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15607     }
15608   vec_free (lcl_locs);
15609   vec_free (rmt_locs);
15610
15611   /* send it... */
15612   S (mp);
15613
15614   /* Wait for a reply... */
15615   W (ret);
15616   return ret;
15617 }
15618
15619 static int
15620 api_one_add_del_map_server (vat_main_t * vam)
15621 {
15622   unformat_input_t *input = vam->input;
15623   vl_api_one_add_del_map_server_t *mp;
15624   u8 is_add = 1;
15625   u8 ipv4_set = 0;
15626   u8 ipv6_set = 0;
15627   ip4_address_t ipv4;
15628   ip6_address_t ipv6;
15629   int ret;
15630
15631   /* Parse args required to build the message */
15632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15633     {
15634       if (unformat (input, "del"))
15635         {
15636           is_add = 0;
15637         }
15638       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15639         {
15640           ipv4_set = 1;
15641         }
15642       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15643         {
15644           ipv6_set = 1;
15645         }
15646       else
15647         break;
15648     }
15649
15650   if (ipv4_set && ipv6_set)
15651     {
15652       errmsg ("both eid v4 and v6 addresses set");
15653       return -99;
15654     }
15655
15656   if (!ipv4_set && !ipv6_set)
15657     {
15658       errmsg ("eid addresses not set");
15659       return -99;
15660     }
15661
15662   /* Construct the API message */
15663   M (ONE_ADD_DEL_MAP_SERVER, mp);
15664
15665   mp->is_add = is_add;
15666   if (ipv6_set)
15667     {
15668       mp->is_ipv6 = 1;
15669       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15670     }
15671   else
15672     {
15673       mp->is_ipv6 = 0;
15674       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15675     }
15676
15677   /* send it... */
15678   S (mp);
15679
15680   /* Wait for a reply... */
15681   W (ret);
15682   return ret;
15683 }
15684
15685 #define api_lisp_add_del_map_server api_one_add_del_map_server
15686
15687 static int
15688 api_one_add_del_map_resolver (vat_main_t * vam)
15689 {
15690   unformat_input_t *input = vam->input;
15691   vl_api_one_add_del_map_resolver_t *mp;
15692   u8 is_add = 1;
15693   u8 ipv4_set = 0;
15694   u8 ipv6_set = 0;
15695   ip4_address_t ipv4;
15696   ip6_address_t ipv6;
15697   int ret;
15698
15699   /* Parse args required to build the message */
15700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15701     {
15702       if (unformat (input, "del"))
15703         {
15704           is_add = 0;
15705         }
15706       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15707         {
15708           ipv4_set = 1;
15709         }
15710       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15711         {
15712           ipv6_set = 1;
15713         }
15714       else
15715         break;
15716     }
15717
15718   if (ipv4_set && ipv6_set)
15719     {
15720       errmsg ("both eid v4 and v6 addresses set");
15721       return -99;
15722     }
15723
15724   if (!ipv4_set && !ipv6_set)
15725     {
15726       errmsg ("eid addresses not set");
15727       return -99;
15728     }
15729
15730   /* Construct the API message */
15731   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15732
15733   mp->is_add = is_add;
15734   if (ipv6_set)
15735     {
15736       mp->is_ipv6 = 1;
15737       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15738     }
15739   else
15740     {
15741       mp->is_ipv6 = 0;
15742       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15743     }
15744
15745   /* send it... */
15746   S (mp);
15747
15748   /* Wait for a reply... */
15749   W (ret);
15750   return ret;
15751 }
15752
15753 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15754
15755 static int
15756 api_lisp_gpe_enable_disable (vat_main_t * vam)
15757 {
15758   unformat_input_t *input = vam->input;
15759   vl_api_gpe_enable_disable_t *mp;
15760   u8 is_set = 0;
15761   u8 is_en = 1;
15762   int ret;
15763
15764   /* Parse args required to build the message */
15765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15766     {
15767       if (unformat (input, "enable"))
15768         {
15769           is_set = 1;
15770           is_en = 1;
15771         }
15772       else if (unformat (input, "disable"))
15773         {
15774           is_set = 1;
15775           is_en = 0;
15776         }
15777       else
15778         break;
15779     }
15780
15781   if (is_set == 0)
15782     {
15783       errmsg ("Value not set");
15784       return -99;
15785     }
15786
15787   /* Construct the API message */
15788   M (GPE_ENABLE_DISABLE, mp);
15789
15790   mp->is_en = is_en;
15791
15792   /* send it... */
15793   S (mp);
15794
15795   /* Wait for a reply... */
15796   W (ret);
15797   return ret;
15798 }
15799
15800 static int
15801 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15802 {
15803   unformat_input_t *input = vam->input;
15804   vl_api_one_rloc_probe_enable_disable_t *mp;
15805   u8 is_set = 0;
15806   u8 is_en = 0;
15807   int ret;
15808
15809   /* Parse args required to build the message */
15810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15811     {
15812       if (unformat (input, "enable"))
15813         {
15814           is_set = 1;
15815           is_en = 1;
15816         }
15817       else if (unformat (input, "disable"))
15818         is_set = 1;
15819       else
15820         break;
15821     }
15822
15823   if (!is_set)
15824     {
15825       errmsg ("Value not set");
15826       return -99;
15827     }
15828
15829   /* Construct the API message */
15830   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15831
15832   mp->is_enabled = is_en;
15833
15834   /* send it... */
15835   S (mp);
15836
15837   /* Wait for a reply... */
15838   W (ret);
15839   return ret;
15840 }
15841
15842 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15843
15844 static int
15845 api_one_map_register_enable_disable (vat_main_t * vam)
15846 {
15847   unformat_input_t *input = vam->input;
15848   vl_api_one_map_register_enable_disable_t *mp;
15849   u8 is_set = 0;
15850   u8 is_en = 0;
15851   int ret;
15852
15853   /* Parse args required to build the message */
15854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15855     {
15856       if (unformat (input, "enable"))
15857         {
15858           is_set = 1;
15859           is_en = 1;
15860         }
15861       else if (unformat (input, "disable"))
15862         is_set = 1;
15863       else
15864         break;
15865     }
15866
15867   if (!is_set)
15868     {
15869       errmsg ("Value not set");
15870       return -99;
15871     }
15872
15873   /* Construct the API message */
15874   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15875
15876   mp->is_enabled = is_en;
15877
15878   /* send it... */
15879   S (mp);
15880
15881   /* Wait for a reply... */
15882   W (ret);
15883   return ret;
15884 }
15885
15886 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15887
15888 static int
15889 api_one_enable_disable (vat_main_t * vam)
15890 {
15891   unformat_input_t *input = vam->input;
15892   vl_api_one_enable_disable_t *mp;
15893   u8 is_set = 0;
15894   u8 is_en = 0;
15895   int ret;
15896
15897   /* Parse args required to build the message */
15898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15899     {
15900       if (unformat (input, "enable"))
15901         {
15902           is_set = 1;
15903           is_en = 1;
15904         }
15905       else if (unformat (input, "disable"))
15906         {
15907           is_set = 1;
15908         }
15909       else
15910         break;
15911     }
15912
15913   if (!is_set)
15914     {
15915       errmsg ("Value not set");
15916       return -99;
15917     }
15918
15919   /* Construct the API message */
15920   M (ONE_ENABLE_DISABLE, mp);
15921
15922   mp->is_en = is_en;
15923
15924   /* send it... */
15925   S (mp);
15926
15927   /* Wait for a reply... */
15928   W (ret);
15929   return ret;
15930 }
15931
15932 #define api_lisp_enable_disable api_one_enable_disable
15933
15934 static int
15935 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15936 {
15937   unformat_input_t *input = vam->input;
15938   vl_api_one_enable_disable_xtr_mode_t *mp;
15939   u8 is_set = 0;
15940   u8 is_en = 0;
15941   int ret;
15942
15943   /* Parse args required to build the message */
15944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15945     {
15946       if (unformat (input, "enable"))
15947         {
15948           is_set = 1;
15949           is_en = 1;
15950         }
15951       else if (unformat (input, "disable"))
15952         {
15953           is_set = 1;
15954         }
15955       else
15956         break;
15957     }
15958
15959   if (!is_set)
15960     {
15961       errmsg ("Value not set");
15962       return -99;
15963     }
15964
15965   /* Construct the API message */
15966   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15967
15968   mp->is_en = is_en;
15969
15970   /* send it... */
15971   S (mp);
15972
15973   /* Wait for a reply... */
15974   W (ret);
15975   return ret;
15976 }
15977
15978 static int
15979 api_one_show_xtr_mode (vat_main_t * vam)
15980 {
15981   vl_api_one_show_xtr_mode_t *mp;
15982   int ret;
15983
15984   /* Construct the API message */
15985   M (ONE_SHOW_XTR_MODE, mp);
15986
15987   /* send it... */
15988   S (mp);
15989
15990   /* Wait for a reply... */
15991   W (ret);
15992   return ret;
15993 }
15994
15995 static int
15996 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15997 {
15998   unformat_input_t *input = vam->input;
15999   vl_api_one_enable_disable_pitr_mode_t *mp;
16000   u8 is_set = 0;
16001   u8 is_en = 0;
16002   int ret;
16003
16004   /* Parse args required to build the message */
16005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16006     {
16007       if (unformat (input, "enable"))
16008         {
16009           is_set = 1;
16010           is_en = 1;
16011         }
16012       else if (unformat (input, "disable"))
16013         {
16014           is_set = 1;
16015         }
16016       else
16017         break;
16018     }
16019
16020   if (!is_set)
16021     {
16022       errmsg ("Value not set");
16023       return -99;
16024     }
16025
16026   /* Construct the API message */
16027   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16028
16029   mp->is_en = is_en;
16030
16031   /* send it... */
16032   S (mp);
16033
16034   /* Wait for a reply... */
16035   W (ret);
16036   return ret;
16037 }
16038
16039 static int
16040 api_one_show_pitr_mode (vat_main_t * vam)
16041 {
16042   vl_api_one_show_pitr_mode_t *mp;
16043   int ret;
16044
16045   /* Construct the API message */
16046   M (ONE_SHOW_PITR_MODE, mp);
16047
16048   /* send it... */
16049   S (mp);
16050
16051   /* Wait for a reply... */
16052   W (ret);
16053   return ret;
16054 }
16055
16056 static int
16057 api_one_enable_disable_petr_mode (vat_main_t * vam)
16058 {
16059   unformat_input_t *input = vam->input;
16060   vl_api_one_enable_disable_petr_mode_t *mp;
16061   u8 is_set = 0;
16062   u8 is_en = 0;
16063   int ret;
16064
16065   /* Parse args required to build the message */
16066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16067     {
16068       if (unformat (input, "enable"))
16069         {
16070           is_set = 1;
16071           is_en = 1;
16072         }
16073       else if (unformat (input, "disable"))
16074         {
16075           is_set = 1;
16076         }
16077       else
16078         break;
16079     }
16080
16081   if (!is_set)
16082     {
16083       errmsg ("Value not set");
16084       return -99;
16085     }
16086
16087   /* Construct the API message */
16088   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16089
16090   mp->is_en = is_en;
16091
16092   /* send it... */
16093   S (mp);
16094
16095   /* Wait for a reply... */
16096   W (ret);
16097   return ret;
16098 }
16099
16100 static int
16101 api_one_show_petr_mode (vat_main_t * vam)
16102 {
16103   vl_api_one_show_petr_mode_t *mp;
16104   int ret;
16105
16106   /* Construct the API message */
16107   M (ONE_SHOW_PETR_MODE, mp);
16108
16109   /* send it... */
16110   S (mp);
16111
16112   /* Wait for a reply... */
16113   W (ret);
16114   return ret;
16115 }
16116
16117 static int
16118 api_show_one_map_register_state (vat_main_t * vam)
16119 {
16120   vl_api_show_one_map_register_state_t *mp;
16121   int ret;
16122
16123   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16124
16125   /* send */
16126   S (mp);
16127
16128   /* wait for reply */
16129   W (ret);
16130   return ret;
16131 }
16132
16133 #define api_show_lisp_map_register_state api_show_one_map_register_state
16134
16135 static int
16136 api_show_one_rloc_probe_state (vat_main_t * vam)
16137 {
16138   vl_api_show_one_rloc_probe_state_t *mp;
16139   int ret;
16140
16141   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16142
16143   /* send */
16144   S (mp);
16145
16146   /* wait for reply */
16147   W (ret);
16148   return ret;
16149 }
16150
16151 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16152
16153 static int
16154 api_one_add_del_ndp_entry (vat_main_t * vam)
16155 {
16156   vl_api_one_add_del_ndp_entry_t *mp;
16157   unformat_input_t *input = vam->input;
16158   u8 is_add = 1;
16159   u8 mac_set = 0;
16160   u8 bd_set = 0;
16161   u8 ip_set = 0;
16162   u8 mac[6] = { 0, };
16163   u8 ip6[16] = { 0, };
16164   u32 bd = ~0;
16165   int ret;
16166
16167   /* Parse args required to build the message */
16168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16169     {
16170       if (unformat (input, "del"))
16171         is_add = 0;
16172       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16173         mac_set = 1;
16174       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16175         ip_set = 1;
16176       else if (unformat (input, "bd %d", &bd))
16177         bd_set = 1;
16178       else
16179         {
16180           errmsg ("parse error '%U'", format_unformat_error, input);
16181           return -99;
16182         }
16183     }
16184
16185   if (!bd_set || !ip_set || (!mac_set && is_add))
16186     {
16187       errmsg ("Missing BD, IP or MAC!");
16188       return -99;
16189     }
16190
16191   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16192   mp->is_add = is_add;
16193   clib_memcpy (mp->mac, mac, 6);
16194   mp->bd = clib_host_to_net_u32 (bd);
16195   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16196
16197   /* send */
16198   S (mp);
16199
16200   /* wait for reply */
16201   W (ret);
16202   return ret;
16203 }
16204
16205 static int
16206 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16207 {
16208   vl_api_one_add_del_l2_arp_entry_t *mp;
16209   unformat_input_t *input = vam->input;
16210   u8 is_add = 1;
16211   u8 mac_set = 0;
16212   u8 bd_set = 0;
16213   u8 ip_set = 0;
16214   u8 mac[6] = { 0, };
16215   u32 ip4 = 0, bd = ~0;
16216   int ret;
16217
16218   /* Parse args required to build the message */
16219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16220     {
16221       if (unformat (input, "del"))
16222         is_add = 0;
16223       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16224         mac_set = 1;
16225       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16226         ip_set = 1;
16227       else if (unformat (input, "bd %d", &bd))
16228         bd_set = 1;
16229       else
16230         {
16231           errmsg ("parse error '%U'", format_unformat_error, input);
16232           return -99;
16233         }
16234     }
16235
16236   if (!bd_set || !ip_set || (!mac_set && is_add))
16237     {
16238       errmsg ("Missing BD, IP or MAC!");
16239       return -99;
16240     }
16241
16242   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16243   mp->is_add = is_add;
16244   clib_memcpy (mp->mac, mac, 6);
16245   mp->bd = clib_host_to_net_u32 (bd);
16246   mp->ip4 = ip4;
16247
16248   /* send */
16249   S (mp);
16250
16251   /* wait for reply */
16252   W (ret);
16253   return ret;
16254 }
16255
16256 static int
16257 api_one_ndp_bd_get (vat_main_t * vam)
16258 {
16259   vl_api_one_ndp_bd_get_t *mp;
16260   int ret;
16261
16262   M (ONE_NDP_BD_GET, mp);
16263
16264   /* send */
16265   S (mp);
16266
16267   /* wait for reply */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 static int
16273 api_one_ndp_entries_get (vat_main_t * vam)
16274 {
16275   vl_api_one_ndp_entries_get_t *mp;
16276   unformat_input_t *input = vam->input;
16277   u8 bd_set = 0;
16278   u32 bd = ~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, "bd %d", &bd))
16285         bd_set = 1;
16286       else
16287         {
16288           errmsg ("parse error '%U'", format_unformat_error, input);
16289           return -99;
16290         }
16291     }
16292
16293   if (!bd_set)
16294     {
16295       errmsg ("Expected bridge domain!");
16296       return -99;
16297     }
16298
16299   M (ONE_NDP_ENTRIES_GET, mp);
16300   mp->bd = clib_host_to_net_u32 (bd);
16301
16302   /* send */
16303   S (mp);
16304
16305   /* wait for reply */
16306   W (ret);
16307   return ret;
16308 }
16309
16310 static int
16311 api_one_l2_arp_bd_get (vat_main_t * vam)
16312 {
16313   vl_api_one_l2_arp_bd_get_t *mp;
16314   int ret;
16315
16316   M (ONE_L2_ARP_BD_GET, mp);
16317
16318   /* send */
16319   S (mp);
16320
16321   /* wait for reply */
16322   W (ret);
16323   return ret;
16324 }
16325
16326 static int
16327 api_one_l2_arp_entries_get (vat_main_t * vam)
16328 {
16329   vl_api_one_l2_arp_entries_get_t *mp;
16330   unformat_input_t *input = vam->input;
16331   u8 bd_set = 0;
16332   u32 bd = ~0;
16333   int ret;
16334
16335   /* Parse args required to build the message */
16336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16337     {
16338       if (unformat (input, "bd %d", &bd))
16339         bd_set = 1;
16340       else
16341         {
16342           errmsg ("parse error '%U'", format_unformat_error, input);
16343           return -99;
16344         }
16345     }
16346
16347   if (!bd_set)
16348     {
16349       errmsg ("Expected bridge domain!");
16350       return -99;
16351     }
16352
16353   M (ONE_L2_ARP_ENTRIES_GET, mp);
16354   mp->bd = clib_host_to_net_u32 (bd);
16355
16356   /* send */
16357   S (mp);
16358
16359   /* wait for reply */
16360   W (ret);
16361   return ret;
16362 }
16363
16364 static int
16365 api_one_stats_enable_disable (vat_main_t * vam)
16366 {
16367   vl_api_one_stats_enable_disable_t *mp;
16368   unformat_input_t *input = vam->input;
16369   u8 is_set = 0;
16370   u8 is_en = 0;
16371   int ret;
16372
16373   /* Parse args required to build the message */
16374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16375     {
16376       if (unformat (input, "enable"))
16377         {
16378           is_set = 1;
16379           is_en = 1;
16380         }
16381       else if (unformat (input, "disable"))
16382         {
16383           is_set = 1;
16384         }
16385       else
16386         break;
16387     }
16388
16389   if (!is_set)
16390     {
16391       errmsg ("Value not set");
16392       return -99;
16393     }
16394
16395   M (ONE_STATS_ENABLE_DISABLE, mp);
16396   mp->is_en = is_en;
16397
16398   /* send */
16399   S (mp);
16400
16401   /* wait for reply */
16402   W (ret);
16403   return ret;
16404 }
16405
16406 static int
16407 api_show_one_stats_enable_disable (vat_main_t * vam)
16408 {
16409   vl_api_show_one_stats_enable_disable_t *mp;
16410   int ret;
16411
16412   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16413
16414   /* send */
16415   S (mp);
16416
16417   /* wait for reply */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 static int
16423 api_show_one_map_request_mode (vat_main_t * vam)
16424 {
16425   vl_api_show_one_map_request_mode_t *mp;
16426   int ret;
16427
16428   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16429
16430   /* send */
16431   S (mp);
16432
16433   /* wait for reply */
16434   W (ret);
16435   return ret;
16436 }
16437
16438 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16439
16440 static int
16441 api_one_map_request_mode (vat_main_t * vam)
16442 {
16443   unformat_input_t *input = vam->input;
16444   vl_api_one_map_request_mode_t *mp;
16445   u8 mode = 0;
16446   int ret;
16447
16448   /* Parse args required to build the message */
16449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16450     {
16451       if (unformat (input, "dst-only"))
16452         mode = 0;
16453       else if (unformat (input, "src-dst"))
16454         mode = 1;
16455       else
16456         {
16457           errmsg ("parse error '%U'", format_unformat_error, input);
16458           return -99;
16459         }
16460     }
16461
16462   M (ONE_MAP_REQUEST_MODE, mp);
16463
16464   mp->mode = mode;
16465
16466   /* send */
16467   S (mp);
16468
16469   /* wait for reply */
16470   W (ret);
16471   return ret;
16472 }
16473
16474 #define api_lisp_map_request_mode api_one_map_request_mode
16475
16476 /**
16477  * Enable/disable ONE proxy ITR.
16478  *
16479  * @param vam vpp API test context
16480  * @return return code
16481  */
16482 static int
16483 api_one_pitr_set_locator_set (vat_main_t * vam)
16484 {
16485   u8 ls_name_set = 0;
16486   unformat_input_t *input = vam->input;
16487   vl_api_one_pitr_set_locator_set_t *mp;
16488   u8 is_add = 1;
16489   u8 *ls_name = 0;
16490   int ret;
16491
16492   /* Parse args required to build the message */
16493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16494     {
16495       if (unformat (input, "del"))
16496         is_add = 0;
16497       else if (unformat (input, "locator-set %s", &ls_name))
16498         ls_name_set = 1;
16499       else
16500         {
16501           errmsg ("parse error '%U'", format_unformat_error, input);
16502           return -99;
16503         }
16504     }
16505
16506   if (!ls_name_set)
16507     {
16508       errmsg ("locator-set name not set!");
16509       return -99;
16510     }
16511
16512   M (ONE_PITR_SET_LOCATOR_SET, mp);
16513
16514   mp->is_add = is_add;
16515   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16516   vec_free (ls_name);
16517
16518   /* send */
16519   S (mp);
16520
16521   /* wait for reply */
16522   W (ret);
16523   return ret;
16524 }
16525
16526 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16527
16528 static int
16529 api_one_nsh_set_locator_set (vat_main_t * vam)
16530 {
16531   u8 ls_name_set = 0;
16532   unformat_input_t *input = vam->input;
16533   vl_api_one_nsh_set_locator_set_t *mp;
16534   u8 is_add = 1;
16535   u8 *ls_name = 0;
16536   int ret;
16537
16538   /* Parse args required to build the message */
16539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16540     {
16541       if (unformat (input, "del"))
16542         is_add = 0;
16543       else if (unformat (input, "ls %s", &ls_name))
16544         ls_name_set = 1;
16545       else
16546         {
16547           errmsg ("parse error '%U'", format_unformat_error, input);
16548           return -99;
16549         }
16550     }
16551
16552   if (!ls_name_set && is_add)
16553     {
16554       errmsg ("locator-set name not set!");
16555       return -99;
16556     }
16557
16558   M (ONE_NSH_SET_LOCATOR_SET, mp);
16559
16560   mp->is_add = is_add;
16561   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16562   vec_free (ls_name);
16563
16564   /* send */
16565   S (mp);
16566
16567   /* wait for reply */
16568   W (ret);
16569   return ret;
16570 }
16571
16572 static int
16573 api_show_one_pitr (vat_main_t * vam)
16574 {
16575   vl_api_show_one_pitr_t *mp;
16576   int ret;
16577
16578   if (!vam->json_output)
16579     {
16580       print (vam->ofp, "%=20s", "lisp status:");
16581     }
16582
16583   M (SHOW_ONE_PITR, mp);
16584   /* send it... */
16585   S (mp);
16586
16587   /* Wait for a reply... */
16588   W (ret);
16589   return ret;
16590 }
16591
16592 #define api_show_lisp_pitr api_show_one_pitr
16593
16594 static int
16595 api_one_use_petr (vat_main_t * vam)
16596 {
16597   unformat_input_t *input = vam->input;
16598   vl_api_one_use_petr_t *mp;
16599   u8 is_add = 0;
16600   ip_address_t ip;
16601   int ret;
16602
16603   clib_memset (&ip, 0, sizeof (ip));
16604
16605   /* Parse args required to build the message */
16606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (input, "disable"))
16609         is_add = 0;
16610       else
16611         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16612         {
16613           is_add = 1;
16614           ip_addr_version (&ip) = AF_IP4;
16615         }
16616       else
16617         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16618         {
16619           is_add = 1;
16620           ip_addr_version (&ip) = AF_IP6;
16621         }
16622       else
16623         {
16624           errmsg ("parse error '%U'", format_unformat_error, input);
16625           return -99;
16626         }
16627     }
16628
16629   M (ONE_USE_PETR, mp);
16630
16631   mp->is_add = is_add;
16632   if (is_add)
16633     {
16634       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
16635       if (mp->is_ip4)
16636         clib_memcpy (mp->address, &ip, 4);
16637       else
16638         clib_memcpy (mp->address, &ip, 16);
16639     }
16640
16641   /* send */
16642   S (mp);
16643
16644   /* wait for reply */
16645   W (ret);
16646   return ret;
16647 }
16648
16649 #define api_lisp_use_petr api_one_use_petr
16650
16651 static int
16652 api_show_one_nsh_mapping (vat_main_t * vam)
16653 {
16654   vl_api_show_one_use_petr_t *mp;
16655   int ret;
16656
16657   if (!vam->json_output)
16658     {
16659       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16660     }
16661
16662   M (SHOW_ONE_NSH_MAPPING, mp);
16663   /* send it... */
16664   S (mp);
16665
16666   /* Wait for a reply... */
16667   W (ret);
16668   return ret;
16669 }
16670
16671 static int
16672 api_show_one_use_petr (vat_main_t * vam)
16673 {
16674   vl_api_show_one_use_petr_t *mp;
16675   int ret;
16676
16677   if (!vam->json_output)
16678     {
16679       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16680     }
16681
16682   M (SHOW_ONE_USE_PETR, mp);
16683   /* send it... */
16684   S (mp);
16685
16686   /* Wait for a reply... */
16687   W (ret);
16688   return ret;
16689 }
16690
16691 #define api_show_lisp_use_petr api_show_one_use_petr
16692
16693 /**
16694  * Add/delete mapping between vni and vrf
16695  */
16696 static int
16697 api_one_eid_table_add_del_map (vat_main_t * vam)
16698 {
16699   unformat_input_t *input = vam->input;
16700   vl_api_one_eid_table_add_del_map_t *mp;
16701   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16702   u32 vni, vrf, bd_index;
16703   int ret;
16704
16705   /* Parse args required to build the message */
16706   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16707     {
16708       if (unformat (input, "del"))
16709         is_add = 0;
16710       else if (unformat (input, "vrf %d", &vrf))
16711         vrf_set = 1;
16712       else if (unformat (input, "bd_index %d", &bd_index))
16713         bd_index_set = 1;
16714       else if (unformat (input, "vni %d", &vni))
16715         vni_set = 1;
16716       else
16717         break;
16718     }
16719
16720   if (!vni_set || (!vrf_set && !bd_index_set))
16721     {
16722       errmsg ("missing arguments!");
16723       return -99;
16724     }
16725
16726   if (vrf_set && bd_index_set)
16727     {
16728       errmsg ("error: both vrf and bd entered!");
16729       return -99;
16730     }
16731
16732   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16733
16734   mp->is_add = is_add;
16735   mp->vni = htonl (vni);
16736   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16737   mp->is_l2 = bd_index_set;
16738
16739   /* send */
16740   S (mp);
16741
16742   /* wait for reply */
16743   W (ret);
16744   return ret;
16745 }
16746
16747 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16748
16749 uword
16750 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16751 {
16752   u32 *action = va_arg (*args, u32 *);
16753   u8 *s = 0;
16754
16755   if (unformat (input, "%s", &s))
16756     {
16757       if (!strcmp ((char *) s, "no-action"))
16758         action[0] = 0;
16759       else if (!strcmp ((char *) s, "natively-forward"))
16760         action[0] = 1;
16761       else if (!strcmp ((char *) s, "send-map-request"))
16762         action[0] = 2;
16763       else if (!strcmp ((char *) s, "drop"))
16764         action[0] = 3;
16765       else
16766         {
16767           clib_warning ("invalid action: '%s'", s);
16768           action[0] = 3;
16769         }
16770     }
16771   else
16772     return 0;
16773
16774   vec_free (s);
16775   return 1;
16776 }
16777
16778 /**
16779  * Add/del remote mapping to/from ONE control plane
16780  *
16781  * @param vam vpp API test context
16782  * @return return code
16783  */
16784 static int
16785 api_one_add_del_remote_mapping (vat_main_t * vam)
16786 {
16787   unformat_input_t *input = vam->input;
16788   vl_api_one_add_del_remote_mapping_t *mp;
16789   u32 vni = 0;
16790   lisp_eid_vat_t _eid, *eid = &_eid;
16791   lisp_eid_vat_t _seid, *seid = &_seid;
16792   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16793   u32 action = ~0, p, w, data_len;
16794   ip4_address_t rloc4;
16795   ip6_address_t rloc6;
16796   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16797   int ret;
16798
16799   clib_memset (&rloc, 0, sizeof (rloc));
16800
16801   /* Parse args required to build the message */
16802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16803     {
16804       if (unformat (input, "del-all"))
16805         {
16806           del_all = 1;
16807         }
16808       else if (unformat (input, "del"))
16809         {
16810           is_add = 0;
16811         }
16812       else if (unformat (input, "add"))
16813         {
16814           is_add = 1;
16815         }
16816       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16817         {
16818           eid_set = 1;
16819         }
16820       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16821         {
16822           seid_set = 1;
16823         }
16824       else if (unformat (input, "vni %d", &vni))
16825         {
16826           ;
16827         }
16828       else if (unformat (input, "p %d w %d", &p, &w))
16829         {
16830           if (!curr_rloc)
16831             {
16832               errmsg ("No RLOC configured for setting priority/weight!");
16833               return -99;
16834             }
16835           curr_rloc->priority = p;
16836           curr_rloc->weight = w;
16837         }
16838       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16839         {
16840           rloc.is_ip4 = 1;
16841           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16842           vec_add1 (rlocs, rloc);
16843           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16844         }
16845       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16846         {
16847           rloc.is_ip4 = 0;
16848           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16849           vec_add1 (rlocs, rloc);
16850           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16851         }
16852       else if (unformat (input, "action %U",
16853                          unformat_negative_mapping_action, &action))
16854         {
16855           ;
16856         }
16857       else
16858         {
16859           clib_warning ("parse error '%U'", format_unformat_error, input);
16860           return -99;
16861         }
16862     }
16863
16864   if (0 == eid_set)
16865     {
16866       errmsg ("missing params!");
16867       return -99;
16868     }
16869
16870   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16871     {
16872       errmsg ("no action set for negative map-reply!");
16873       return -99;
16874     }
16875
16876   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16877
16878   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16879   mp->is_add = is_add;
16880   mp->vni = htonl (vni);
16881   mp->action = (u8) action;
16882   mp->is_src_dst = seid_set;
16883   mp->eid_len = eid->len;
16884   mp->seid_len = seid->len;
16885   mp->del_all = del_all;
16886   mp->eid_type = eid->type;
16887   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16888   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16889
16890   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16891   clib_memcpy (mp->rlocs, rlocs, data_len);
16892   vec_free (rlocs);
16893
16894   /* send it... */
16895   S (mp);
16896
16897   /* Wait for a reply... */
16898   W (ret);
16899   return ret;
16900 }
16901
16902 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16903
16904 /**
16905  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16906  * forwarding entries in data-plane accordingly.
16907  *
16908  * @param vam vpp API test context
16909  * @return return code
16910  */
16911 static int
16912 api_one_add_del_adjacency (vat_main_t * vam)
16913 {
16914   unformat_input_t *input = vam->input;
16915   vl_api_one_add_del_adjacency_t *mp;
16916   u32 vni = 0;
16917   ip4_address_t leid4, reid4;
16918   ip6_address_t leid6, reid6;
16919   u8 reid_mac[6] = { 0 };
16920   u8 leid_mac[6] = { 0 };
16921   u8 reid_type, leid_type;
16922   u32 leid_len = 0, reid_len = 0, len;
16923   u8 is_add = 1;
16924   int ret;
16925
16926   leid_type = reid_type = (u8) ~ 0;
16927
16928   /* Parse args required to build the message */
16929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16930     {
16931       if (unformat (input, "del"))
16932         {
16933           is_add = 0;
16934         }
16935       else if (unformat (input, "add"))
16936         {
16937           is_add = 1;
16938         }
16939       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16940                          &reid4, &len))
16941         {
16942           reid_type = 0;        /* ipv4 */
16943           reid_len = len;
16944         }
16945       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16946                          &reid6, &len))
16947         {
16948           reid_type = 1;        /* ipv6 */
16949           reid_len = len;
16950         }
16951       else if (unformat (input, "reid %U", unformat_ethernet_address,
16952                          reid_mac))
16953         {
16954           reid_type = 2;        /* mac */
16955         }
16956       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16957                          &leid4, &len))
16958         {
16959           leid_type = 0;        /* ipv4 */
16960           leid_len = len;
16961         }
16962       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16963                          &leid6, &len))
16964         {
16965           leid_type = 1;        /* ipv6 */
16966           leid_len = len;
16967         }
16968       else if (unformat (input, "leid %U", unformat_ethernet_address,
16969                          leid_mac))
16970         {
16971           leid_type = 2;        /* mac */
16972         }
16973       else if (unformat (input, "vni %d", &vni))
16974         {
16975           ;
16976         }
16977       else
16978         {
16979           errmsg ("parse error '%U'", format_unformat_error, input);
16980           return -99;
16981         }
16982     }
16983
16984   if ((u8) ~ 0 == reid_type)
16985     {
16986       errmsg ("missing params!");
16987       return -99;
16988     }
16989
16990   if (leid_type != reid_type)
16991     {
16992       errmsg ("remote and local EIDs are of different types!");
16993       return -99;
16994     }
16995
16996   M (ONE_ADD_DEL_ADJACENCY, mp);
16997   mp->is_add = is_add;
16998   mp->vni = htonl (vni);
16999   mp->leid_len = leid_len;
17000   mp->reid_len = reid_len;
17001   mp->eid_type = reid_type;
17002
17003   switch (mp->eid_type)
17004     {
17005     case 0:
17006       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17007       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17008       break;
17009     case 1:
17010       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17011       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17012       break;
17013     case 2:
17014       clib_memcpy (mp->leid, leid_mac, 6);
17015       clib_memcpy (mp->reid, reid_mac, 6);
17016       break;
17017     default:
17018       errmsg ("unknown EID type %d!", mp->eid_type);
17019       return 0;
17020     }
17021
17022   /* send it... */
17023   S (mp);
17024
17025   /* Wait for a reply... */
17026   W (ret);
17027   return ret;
17028 }
17029
17030 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17031
17032 uword
17033 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17034 {
17035   u32 *mode = va_arg (*args, u32 *);
17036
17037   if (unformat (input, "lisp"))
17038     *mode = 0;
17039   else if (unformat (input, "vxlan"))
17040     *mode = 1;
17041   else
17042     return 0;
17043
17044   return 1;
17045 }
17046
17047 static int
17048 api_gpe_get_encap_mode (vat_main_t * vam)
17049 {
17050   vl_api_gpe_get_encap_mode_t *mp;
17051   int ret;
17052
17053   /* Construct the API message */
17054   M (GPE_GET_ENCAP_MODE, mp);
17055
17056   /* send it... */
17057   S (mp);
17058
17059   /* Wait for a reply... */
17060   W (ret);
17061   return ret;
17062 }
17063
17064 static int
17065 api_gpe_set_encap_mode (vat_main_t * vam)
17066 {
17067   unformat_input_t *input = vam->input;
17068   vl_api_gpe_set_encap_mode_t *mp;
17069   int ret;
17070   u32 mode = 0;
17071
17072   /* Parse args required to build the message */
17073   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17074     {
17075       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17076         ;
17077       else
17078         break;
17079     }
17080
17081   /* Construct the API message */
17082   M (GPE_SET_ENCAP_MODE, mp);
17083
17084   mp->mode = mode;
17085
17086   /* send it... */
17087   S (mp);
17088
17089   /* Wait for a reply... */
17090   W (ret);
17091   return ret;
17092 }
17093
17094 static int
17095 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17096 {
17097   unformat_input_t *input = vam->input;
17098   vl_api_gpe_add_del_iface_t *mp;
17099   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17100   u32 dp_table = 0, vni = 0;
17101   int ret;
17102
17103   /* Parse args required to build the message */
17104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17105     {
17106       if (unformat (input, "up"))
17107         {
17108           action_set = 1;
17109           is_add = 1;
17110         }
17111       else if (unformat (input, "down"))
17112         {
17113           action_set = 1;
17114           is_add = 0;
17115         }
17116       else if (unformat (input, "table_id %d", &dp_table))
17117         {
17118           dp_table_set = 1;
17119         }
17120       else if (unformat (input, "bd_id %d", &dp_table))
17121         {
17122           dp_table_set = 1;
17123           is_l2 = 1;
17124         }
17125       else if (unformat (input, "vni %d", &vni))
17126         {
17127           vni_set = 1;
17128         }
17129       else
17130         break;
17131     }
17132
17133   if (action_set == 0)
17134     {
17135       errmsg ("Action not set");
17136       return -99;
17137     }
17138   if (dp_table_set == 0 || vni_set == 0)
17139     {
17140       errmsg ("vni and dp_table must be set");
17141       return -99;
17142     }
17143
17144   /* Construct the API message */
17145   M (GPE_ADD_DEL_IFACE, mp);
17146
17147   mp->is_add = is_add;
17148   mp->dp_table = clib_host_to_net_u32 (dp_table);
17149   mp->is_l2 = is_l2;
17150   mp->vni = clib_host_to_net_u32 (vni);
17151
17152   /* send it... */
17153   S (mp);
17154
17155   /* Wait for a reply... */
17156   W (ret);
17157   return ret;
17158 }
17159
17160 static int
17161 api_one_map_register_fallback_threshold (vat_main_t * vam)
17162 {
17163   unformat_input_t *input = vam->input;
17164   vl_api_one_map_register_fallback_threshold_t *mp;
17165   u32 value = 0;
17166   u8 is_set = 0;
17167   int ret;
17168
17169   /* Parse args required to build the message */
17170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17171     {
17172       if (unformat (input, "%u", &value))
17173         is_set = 1;
17174       else
17175         {
17176           clib_warning ("parse error '%U'", format_unformat_error, input);
17177           return -99;
17178         }
17179     }
17180
17181   if (!is_set)
17182     {
17183       errmsg ("fallback threshold value is missing!");
17184       return -99;
17185     }
17186
17187   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17188   mp->value = clib_host_to_net_u32 (value);
17189
17190   /* send it... */
17191   S (mp);
17192
17193   /* Wait for a reply... */
17194   W (ret);
17195   return ret;
17196 }
17197
17198 static int
17199 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17200 {
17201   vl_api_show_one_map_register_fallback_threshold_t *mp;
17202   int ret;
17203
17204   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17205
17206   /* send it... */
17207   S (mp);
17208
17209   /* Wait for a reply... */
17210   W (ret);
17211   return ret;
17212 }
17213
17214 uword
17215 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17216 {
17217   u32 *proto = va_arg (*args, u32 *);
17218
17219   if (unformat (input, "udp"))
17220     *proto = 1;
17221   else if (unformat (input, "api"))
17222     *proto = 2;
17223   else
17224     return 0;
17225
17226   return 1;
17227 }
17228
17229 static int
17230 api_one_set_transport_protocol (vat_main_t * vam)
17231 {
17232   unformat_input_t *input = vam->input;
17233   vl_api_one_set_transport_protocol_t *mp;
17234   u8 is_set = 0;
17235   u32 protocol = 0;
17236   int ret;
17237
17238   /* Parse args required to build the message */
17239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17240     {
17241       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17242         is_set = 1;
17243       else
17244         {
17245           clib_warning ("parse error '%U'", format_unformat_error, input);
17246           return -99;
17247         }
17248     }
17249
17250   if (!is_set)
17251     {
17252       errmsg ("Transport protocol missing!");
17253       return -99;
17254     }
17255
17256   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17257   mp->protocol = (u8) protocol;
17258
17259   /* send it... */
17260   S (mp);
17261
17262   /* Wait for a reply... */
17263   W (ret);
17264   return ret;
17265 }
17266
17267 static int
17268 api_one_get_transport_protocol (vat_main_t * vam)
17269 {
17270   vl_api_one_get_transport_protocol_t *mp;
17271   int ret;
17272
17273   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17274
17275   /* send it... */
17276   S (mp);
17277
17278   /* Wait for a reply... */
17279   W (ret);
17280   return ret;
17281 }
17282
17283 static int
17284 api_one_map_register_set_ttl (vat_main_t * vam)
17285 {
17286   unformat_input_t *input = vam->input;
17287   vl_api_one_map_register_set_ttl_t *mp;
17288   u32 ttl = 0;
17289   u8 is_set = 0;
17290   int ret;
17291
17292   /* Parse args required to build the message */
17293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17294     {
17295       if (unformat (input, "%u", &ttl))
17296         is_set = 1;
17297       else
17298         {
17299           clib_warning ("parse error '%U'", format_unformat_error, input);
17300           return -99;
17301         }
17302     }
17303
17304   if (!is_set)
17305     {
17306       errmsg ("TTL value missing!");
17307       return -99;
17308     }
17309
17310   M (ONE_MAP_REGISTER_SET_TTL, mp);
17311   mp->ttl = clib_host_to_net_u32 (ttl);
17312
17313   /* send it... */
17314   S (mp);
17315
17316   /* Wait for a reply... */
17317   W (ret);
17318   return ret;
17319 }
17320
17321 static int
17322 api_show_one_map_register_ttl (vat_main_t * vam)
17323 {
17324   vl_api_show_one_map_register_ttl_t *mp;
17325   int ret;
17326
17327   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17328
17329   /* send it... */
17330   S (mp);
17331
17332   /* Wait for a reply... */
17333   W (ret);
17334   return ret;
17335 }
17336
17337 /**
17338  * Add/del map request itr rlocs from ONE control plane and updates
17339  *
17340  * @param vam vpp API test context
17341  * @return return code
17342  */
17343 static int
17344 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17345 {
17346   unformat_input_t *input = vam->input;
17347   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17348   u8 *locator_set_name = 0;
17349   u8 locator_set_name_set = 0;
17350   u8 is_add = 1;
17351   int ret;
17352
17353   /* Parse args required to build the message */
17354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17355     {
17356       if (unformat (input, "del"))
17357         {
17358           is_add = 0;
17359         }
17360       else if (unformat (input, "%_%v%_", &locator_set_name))
17361         {
17362           locator_set_name_set = 1;
17363         }
17364       else
17365         {
17366           clib_warning ("parse error '%U'", format_unformat_error, input);
17367           return -99;
17368         }
17369     }
17370
17371   if (is_add && !locator_set_name_set)
17372     {
17373       errmsg ("itr-rloc is not set!");
17374       return -99;
17375     }
17376
17377   if (is_add && vec_len (locator_set_name) > 64)
17378     {
17379       errmsg ("itr-rloc locator-set name too long");
17380       vec_free (locator_set_name);
17381       return -99;
17382     }
17383
17384   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17385   mp->is_add = is_add;
17386   if (is_add)
17387     {
17388       clib_memcpy (mp->locator_set_name, locator_set_name,
17389                    vec_len (locator_set_name));
17390     }
17391   else
17392     {
17393       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17394     }
17395   vec_free (locator_set_name);
17396
17397   /* send it... */
17398   S (mp);
17399
17400   /* Wait for a reply... */
17401   W (ret);
17402   return ret;
17403 }
17404
17405 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17406
17407 static int
17408 api_one_locator_dump (vat_main_t * vam)
17409 {
17410   unformat_input_t *input = vam->input;
17411   vl_api_one_locator_dump_t *mp;
17412   vl_api_control_ping_t *mp_ping;
17413   u8 is_index_set = 0, is_name_set = 0;
17414   u8 *ls_name = 0;
17415   u32 ls_index = ~0;
17416   int ret;
17417
17418   /* Parse args required to build the message */
17419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17420     {
17421       if (unformat (input, "ls_name %_%v%_", &ls_name))
17422         {
17423           is_name_set = 1;
17424         }
17425       else if (unformat (input, "ls_index %d", &ls_index))
17426         {
17427           is_index_set = 1;
17428         }
17429       else
17430         {
17431           errmsg ("parse error '%U'", format_unformat_error, input);
17432           return -99;
17433         }
17434     }
17435
17436   if (!is_index_set && !is_name_set)
17437     {
17438       errmsg ("error: expected one of index or name!");
17439       return -99;
17440     }
17441
17442   if (is_index_set && is_name_set)
17443     {
17444       errmsg ("error: only one param expected!");
17445       return -99;
17446     }
17447
17448   if (vec_len (ls_name) > 62)
17449     {
17450       errmsg ("error: locator set name too long!");
17451       return -99;
17452     }
17453
17454   if (!vam->json_output)
17455     {
17456       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17457     }
17458
17459   M (ONE_LOCATOR_DUMP, mp);
17460   mp->is_index_set = is_index_set;
17461
17462   if (is_index_set)
17463     mp->ls_index = clib_host_to_net_u32 (ls_index);
17464   else
17465     {
17466       vec_add1 (ls_name, 0);
17467       strncpy ((char *) mp->ls_name, (char *) ls_name,
17468                sizeof (mp->ls_name) - 1);
17469     }
17470
17471   /* send it... */
17472   S (mp);
17473
17474   /* Use a control ping for synchronization */
17475   MPING (CONTROL_PING, mp_ping);
17476   S (mp_ping);
17477
17478   /* Wait for a reply... */
17479   W (ret);
17480   return ret;
17481 }
17482
17483 #define api_lisp_locator_dump api_one_locator_dump
17484
17485 static int
17486 api_one_locator_set_dump (vat_main_t * vam)
17487 {
17488   vl_api_one_locator_set_dump_t *mp;
17489   vl_api_control_ping_t *mp_ping;
17490   unformat_input_t *input = vam->input;
17491   u8 filter = 0;
17492   int ret;
17493
17494   /* Parse args required to build the message */
17495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17496     {
17497       if (unformat (input, "local"))
17498         {
17499           filter = 1;
17500         }
17501       else if (unformat (input, "remote"))
17502         {
17503           filter = 2;
17504         }
17505       else
17506         {
17507           errmsg ("parse error '%U'", format_unformat_error, input);
17508           return -99;
17509         }
17510     }
17511
17512   if (!vam->json_output)
17513     {
17514       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17515     }
17516
17517   M (ONE_LOCATOR_SET_DUMP, mp);
17518
17519   mp->filter = filter;
17520
17521   /* send it... */
17522   S (mp);
17523
17524   /* Use a control ping for synchronization */
17525   MPING (CONTROL_PING, mp_ping);
17526   S (mp_ping);
17527
17528   /* Wait for a reply... */
17529   W (ret);
17530   return ret;
17531 }
17532
17533 #define api_lisp_locator_set_dump api_one_locator_set_dump
17534
17535 static int
17536 api_one_eid_table_map_dump (vat_main_t * vam)
17537 {
17538   u8 is_l2 = 0;
17539   u8 mode_set = 0;
17540   unformat_input_t *input = vam->input;
17541   vl_api_one_eid_table_map_dump_t *mp;
17542   vl_api_control_ping_t *mp_ping;
17543   int ret;
17544
17545   /* Parse args required to build the message */
17546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17547     {
17548       if (unformat (input, "l2"))
17549         {
17550           is_l2 = 1;
17551           mode_set = 1;
17552         }
17553       else if (unformat (input, "l3"))
17554         {
17555           is_l2 = 0;
17556           mode_set = 1;
17557         }
17558       else
17559         {
17560           errmsg ("parse error '%U'", format_unformat_error, input);
17561           return -99;
17562         }
17563     }
17564
17565   if (!mode_set)
17566     {
17567       errmsg ("expected one of 'l2' or 'l3' parameter!");
17568       return -99;
17569     }
17570
17571   if (!vam->json_output)
17572     {
17573       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17574     }
17575
17576   M (ONE_EID_TABLE_MAP_DUMP, mp);
17577   mp->is_l2 = is_l2;
17578
17579   /* send it... */
17580   S (mp);
17581
17582   /* Use a control ping for synchronization */
17583   MPING (CONTROL_PING, mp_ping);
17584   S (mp_ping);
17585
17586   /* Wait for a reply... */
17587   W (ret);
17588   return ret;
17589 }
17590
17591 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17592
17593 static int
17594 api_one_eid_table_vni_dump (vat_main_t * vam)
17595 {
17596   vl_api_one_eid_table_vni_dump_t *mp;
17597   vl_api_control_ping_t *mp_ping;
17598   int ret;
17599
17600   if (!vam->json_output)
17601     {
17602       print (vam->ofp, "VNI");
17603     }
17604
17605   M (ONE_EID_TABLE_VNI_DUMP, mp);
17606
17607   /* send it... */
17608   S (mp);
17609
17610   /* Use a control ping for synchronization */
17611   MPING (CONTROL_PING, mp_ping);
17612   S (mp_ping);
17613
17614   /* Wait for a reply... */
17615   W (ret);
17616   return ret;
17617 }
17618
17619 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17620
17621 static int
17622 api_one_eid_table_dump (vat_main_t * vam)
17623 {
17624   unformat_input_t *i = vam->input;
17625   vl_api_one_eid_table_dump_t *mp;
17626   vl_api_control_ping_t *mp_ping;
17627   struct in_addr ip4;
17628   struct in6_addr ip6;
17629   u8 mac[6];
17630   u8 eid_type = ~0, eid_set = 0;
17631   u32 prefix_length = ~0, t, vni = 0;
17632   u8 filter = 0;
17633   int ret;
17634   lisp_nsh_api_t nsh;
17635
17636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17637     {
17638       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17639         {
17640           eid_set = 1;
17641           eid_type = 0;
17642           prefix_length = t;
17643         }
17644       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17645         {
17646           eid_set = 1;
17647           eid_type = 1;
17648           prefix_length = t;
17649         }
17650       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17651         {
17652           eid_set = 1;
17653           eid_type = 2;
17654         }
17655       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17656         {
17657           eid_set = 1;
17658           eid_type = 3;
17659         }
17660       else if (unformat (i, "vni %d", &t))
17661         {
17662           vni = t;
17663         }
17664       else if (unformat (i, "local"))
17665         {
17666           filter = 1;
17667         }
17668       else if (unformat (i, "remote"))
17669         {
17670           filter = 2;
17671         }
17672       else
17673         {
17674           errmsg ("parse error '%U'", format_unformat_error, i);
17675           return -99;
17676         }
17677     }
17678
17679   if (!vam->json_output)
17680     {
17681       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17682              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17683     }
17684
17685   M (ONE_EID_TABLE_DUMP, mp);
17686
17687   mp->filter = filter;
17688   if (eid_set)
17689     {
17690       mp->eid_set = 1;
17691       mp->vni = htonl (vni);
17692       mp->eid_type = eid_type;
17693       switch (eid_type)
17694         {
17695         case 0:
17696           mp->prefix_length = prefix_length;
17697           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17698           break;
17699         case 1:
17700           mp->prefix_length = prefix_length;
17701           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17702           break;
17703         case 2:
17704           clib_memcpy (mp->eid, mac, sizeof (mac));
17705           break;
17706         case 3:
17707           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17708           break;
17709         default:
17710           errmsg ("unknown EID type %d!", eid_type);
17711           return -99;
17712         }
17713     }
17714
17715   /* send it... */
17716   S (mp);
17717
17718   /* Use a control ping for synchronization */
17719   MPING (CONTROL_PING, mp_ping);
17720   S (mp_ping);
17721
17722   /* Wait for a reply... */
17723   W (ret);
17724   return ret;
17725 }
17726
17727 #define api_lisp_eid_table_dump api_one_eid_table_dump
17728
17729 static int
17730 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17731 {
17732   unformat_input_t *i = vam->input;
17733   vl_api_gpe_fwd_entries_get_t *mp;
17734   u8 vni_set = 0;
17735   u32 vni = ~0;
17736   int ret;
17737
17738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17739     {
17740       if (unformat (i, "vni %d", &vni))
17741         {
17742           vni_set = 1;
17743         }
17744       else
17745         {
17746           errmsg ("parse error '%U'", format_unformat_error, i);
17747           return -99;
17748         }
17749     }
17750
17751   if (!vni_set)
17752     {
17753       errmsg ("vni not set!");
17754       return -99;
17755     }
17756
17757   if (!vam->json_output)
17758     {
17759       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17760              "leid", "reid");
17761     }
17762
17763   M (GPE_FWD_ENTRIES_GET, mp);
17764   mp->vni = clib_host_to_net_u32 (vni);
17765
17766   /* send it... */
17767   S (mp);
17768
17769   /* Wait for a reply... */
17770   W (ret);
17771   return ret;
17772 }
17773
17774 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17775 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17776 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17777 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17778 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17779 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17780 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17781 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17782
17783 static int
17784 api_one_adjacencies_get (vat_main_t * vam)
17785 {
17786   unformat_input_t *i = vam->input;
17787   vl_api_one_adjacencies_get_t *mp;
17788   u8 vni_set = 0;
17789   u32 vni = ~0;
17790   int ret;
17791
17792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17793     {
17794       if (unformat (i, "vni %d", &vni))
17795         {
17796           vni_set = 1;
17797         }
17798       else
17799         {
17800           errmsg ("parse error '%U'", format_unformat_error, i);
17801           return -99;
17802         }
17803     }
17804
17805   if (!vni_set)
17806     {
17807       errmsg ("vni not set!");
17808       return -99;
17809     }
17810
17811   if (!vam->json_output)
17812     {
17813       print (vam->ofp, "%s %40s", "leid", "reid");
17814     }
17815
17816   M (ONE_ADJACENCIES_GET, mp);
17817   mp->vni = clib_host_to_net_u32 (vni);
17818
17819   /* send it... */
17820   S (mp);
17821
17822   /* Wait for a reply... */
17823   W (ret);
17824   return ret;
17825 }
17826
17827 #define api_lisp_adjacencies_get api_one_adjacencies_get
17828
17829 static int
17830 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17831 {
17832   unformat_input_t *i = vam->input;
17833   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17834   int ret;
17835   u8 ip_family_set = 0, is_ip4 = 1;
17836
17837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17838     {
17839       if (unformat (i, "ip4"))
17840         {
17841           ip_family_set = 1;
17842           is_ip4 = 1;
17843         }
17844       else if (unformat (i, "ip6"))
17845         {
17846           ip_family_set = 1;
17847           is_ip4 = 0;
17848         }
17849       else
17850         {
17851           errmsg ("parse error '%U'", format_unformat_error, i);
17852           return -99;
17853         }
17854     }
17855
17856   if (!ip_family_set)
17857     {
17858       errmsg ("ip family not set!");
17859       return -99;
17860     }
17861
17862   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17863   mp->is_ip4 = is_ip4;
17864
17865   /* send it... */
17866   S (mp);
17867
17868   /* Wait for a reply... */
17869   W (ret);
17870   return ret;
17871 }
17872
17873 static int
17874 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17875 {
17876   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17877   int ret;
17878
17879   if (!vam->json_output)
17880     {
17881       print (vam->ofp, "VNIs");
17882     }
17883
17884   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17885
17886   /* send it... */
17887   S (mp);
17888
17889   /* Wait for a reply... */
17890   W (ret);
17891   return ret;
17892 }
17893
17894 static int
17895 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17896 {
17897   unformat_input_t *i = vam->input;
17898   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17899   int ret = 0;
17900   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17901   struct in_addr ip4;
17902   struct in6_addr ip6;
17903   u32 table_id = 0, nh_sw_if_index = ~0;
17904
17905   clib_memset (&ip4, 0, sizeof (ip4));
17906   clib_memset (&ip6, 0, sizeof (ip6));
17907
17908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17909     {
17910       if (unformat (i, "del"))
17911         is_add = 0;
17912       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17913                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17914         {
17915           ip_set = 1;
17916           is_ip4 = 1;
17917         }
17918       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17919                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17920         {
17921           ip_set = 1;
17922           is_ip4 = 0;
17923         }
17924       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17925         {
17926           ip_set = 1;
17927           is_ip4 = 1;
17928           nh_sw_if_index = ~0;
17929         }
17930       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17931         {
17932           ip_set = 1;
17933           is_ip4 = 0;
17934           nh_sw_if_index = ~0;
17935         }
17936       else if (unformat (i, "table %d", &table_id))
17937         ;
17938       else
17939         {
17940           errmsg ("parse error '%U'", format_unformat_error, i);
17941           return -99;
17942         }
17943     }
17944
17945   if (!ip_set)
17946     {
17947       errmsg ("nh addr not set!");
17948       return -99;
17949     }
17950
17951   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17952   mp->is_add = is_add;
17953   mp->table_id = clib_host_to_net_u32 (table_id);
17954   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17955   mp->is_ip4 = is_ip4;
17956   if (is_ip4)
17957     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17958   else
17959     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17960
17961   /* send it... */
17962   S (mp);
17963
17964   /* Wait for a reply... */
17965   W (ret);
17966   return ret;
17967 }
17968
17969 static int
17970 api_one_map_server_dump (vat_main_t * vam)
17971 {
17972   vl_api_one_map_server_dump_t *mp;
17973   vl_api_control_ping_t *mp_ping;
17974   int ret;
17975
17976   if (!vam->json_output)
17977     {
17978       print (vam->ofp, "%=20s", "Map server");
17979     }
17980
17981   M (ONE_MAP_SERVER_DUMP, mp);
17982   /* send it... */
17983   S (mp);
17984
17985   /* Use a control ping for synchronization */
17986   MPING (CONTROL_PING, mp_ping);
17987   S (mp_ping);
17988
17989   /* Wait for a reply... */
17990   W (ret);
17991   return ret;
17992 }
17993
17994 #define api_lisp_map_server_dump api_one_map_server_dump
17995
17996 static int
17997 api_one_map_resolver_dump (vat_main_t * vam)
17998 {
17999   vl_api_one_map_resolver_dump_t *mp;
18000   vl_api_control_ping_t *mp_ping;
18001   int ret;
18002
18003   if (!vam->json_output)
18004     {
18005       print (vam->ofp, "%=20s", "Map resolver");
18006     }
18007
18008   M (ONE_MAP_RESOLVER_DUMP, mp);
18009   /* send it... */
18010   S (mp);
18011
18012   /* Use a control ping for synchronization */
18013   MPING (CONTROL_PING, mp_ping);
18014   S (mp_ping);
18015
18016   /* Wait for a reply... */
18017   W (ret);
18018   return ret;
18019 }
18020
18021 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18022
18023 static int
18024 api_one_stats_flush (vat_main_t * vam)
18025 {
18026   vl_api_one_stats_flush_t *mp;
18027   int ret = 0;
18028
18029   M (ONE_STATS_FLUSH, mp);
18030   S (mp);
18031   W (ret);
18032   return ret;
18033 }
18034
18035 static int
18036 api_one_stats_dump (vat_main_t * vam)
18037 {
18038   vl_api_one_stats_dump_t *mp;
18039   vl_api_control_ping_t *mp_ping;
18040   int ret;
18041
18042   M (ONE_STATS_DUMP, mp);
18043   /* send it... */
18044   S (mp);
18045
18046   /* Use a control ping for synchronization */
18047   MPING (CONTROL_PING, mp_ping);
18048   S (mp_ping);
18049
18050   /* Wait for a reply... */
18051   W (ret);
18052   return ret;
18053 }
18054
18055 static int
18056 api_show_one_status (vat_main_t * vam)
18057 {
18058   vl_api_show_one_status_t *mp;
18059   int ret;
18060
18061   if (!vam->json_output)
18062     {
18063       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18064     }
18065
18066   M (SHOW_ONE_STATUS, mp);
18067   /* send it... */
18068   S (mp);
18069   /* Wait for a reply... */
18070   W (ret);
18071   return ret;
18072 }
18073
18074 #define api_show_lisp_status api_show_one_status
18075
18076 static int
18077 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18078 {
18079   vl_api_gpe_fwd_entry_path_dump_t *mp;
18080   vl_api_control_ping_t *mp_ping;
18081   unformat_input_t *i = vam->input;
18082   u32 fwd_entry_index = ~0;
18083   int ret;
18084
18085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (i, "index %d", &fwd_entry_index))
18088         ;
18089       else
18090         break;
18091     }
18092
18093   if (~0 == fwd_entry_index)
18094     {
18095       errmsg ("no index specified!");
18096       return -99;
18097     }
18098
18099   if (!vam->json_output)
18100     {
18101       print (vam->ofp, "first line");
18102     }
18103
18104   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18105
18106   /* send it... */
18107   S (mp);
18108   /* Use a control ping for synchronization */
18109   MPING (CONTROL_PING, mp_ping);
18110   S (mp_ping);
18111
18112   /* Wait for a reply... */
18113   W (ret);
18114   return ret;
18115 }
18116
18117 static int
18118 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18119 {
18120   vl_api_one_get_map_request_itr_rlocs_t *mp;
18121   int ret;
18122
18123   if (!vam->json_output)
18124     {
18125       print (vam->ofp, "%=20s", "itr-rlocs:");
18126     }
18127
18128   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18129   /* send it... */
18130   S (mp);
18131   /* Wait for a reply... */
18132   W (ret);
18133   return ret;
18134 }
18135
18136 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18137
18138 static int
18139 api_af_packet_create (vat_main_t * vam)
18140 {
18141   unformat_input_t *i = vam->input;
18142   vl_api_af_packet_create_t *mp;
18143   u8 *host_if_name = 0;
18144   u8 hw_addr[6];
18145   u8 random_hw_addr = 1;
18146   int ret;
18147
18148   clib_memset (hw_addr, 0, sizeof (hw_addr));
18149
18150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18151     {
18152       if (unformat (i, "name %s", &host_if_name))
18153         vec_add1 (host_if_name, 0);
18154       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18155         random_hw_addr = 0;
18156       else
18157         break;
18158     }
18159
18160   if (!vec_len (host_if_name))
18161     {
18162       errmsg ("host-interface name must be specified");
18163       return -99;
18164     }
18165
18166   if (vec_len (host_if_name) > 64)
18167     {
18168       errmsg ("host-interface name too long");
18169       return -99;
18170     }
18171
18172   M (AF_PACKET_CREATE, mp);
18173
18174   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18175   clib_memcpy (mp->hw_addr, hw_addr, 6);
18176   mp->use_random_hw_addr = random_hw_addr;
18177   vec_free (host_if_name);
18178
18179   S (mp);
18180
18181   /* *INDENT-OFF* */
18182   W2 (ret,
18183       ({
18184         if (ret == 0)
18185           fprintf (vam->ofp ? vam->ofp : stderr,
18186                    " new sw_if_index = %d\n", vam->sw_if_index);
18187       }));
18188   /* *INDENT-ON* */
18189   return ret;
18190 }
18191
18192 static int
18193 api_af_packet_delete (vat_main_t * vam)
18194 {
18195   unformat_input_t *i = vam->input;
18196   vl_api_af_packet_delete_t *mp;
18197   u8 *host_if_name = 0;
18198   int ret;
18199
18200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18201     {
18202       if (unformat (i, "name %s", &host_if_name))
18203         vec_add1 (host_if_name, 0);
18204       else
18205         break;
18206     }
18207
18208   if (!vec_len (host_if_name))
18209     {
18210       errmsg ("host-interface name must be specified");
18211       return -99;
18212     }
18213
18214   if (vec_len (host_if_name) > 64)
18215     {
18216       errmsg ("host-interface name too long");
18217       return -99;
18218     }
18219
18220   M (AF_PACKET_DELETE, mp);
18221
18222   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18223   vec_free (host_if_name);
18224
18225   S (mp);
18226   W (ret);
18227   return ret;
18228 }
18229
18230 static void vl_api_af_packet_details_t_handler
18231   (vl_api_af_packet_details_t * mp)
18232 {
18233   vat_main_t *vam = &vat_main;
18234
18235   print (vam->ofp, "%-16s %d",
18236          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18237 }
18238
18239 static void vl_api_af_packet_details_t_handler_json
18240   (vl_api_af_packet_details_t * mp)
18241 {
18242   vat_main_t *vam = &vat_main;
18243   vat_json_node_t *node = NULL;
18244
18245   if (VAT_JSON_ARRAY != vam->json_tree.type)
18246     {
18247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18248       vat_json_init_array (&vam->json_tree);
18249     }
18250   node = vat_json_array_add (&vam->json_tree);
18251
18252   vat_json_init_object (node);
18253   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18254   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18255 }
18256
18257 static int
18258 api_af_packet_dump (vat_main_t * vam)
18259 {
18260   vl_api_af_packet_dump_t *mp;
18261   vl_api_control_ping_t *mp_ping;
18262   int ret;
18263
18264   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18265   /* Get list of tap interfaces */
18266   M (AF_PACKET_DUMP, mp);
18267   S (mp);
18268
18269   /* Use a control ping for synchronization */
18270   MPING (CONTROL_PING, mp_ping);
18271   S (mp_ping);
18272
18273   W (ret);
18274   return ret;
18275 }
18276
18277 static int
18278 api_policer_add_del (vat_main_t * vam)
18279 {
18280   unformat_input_t *i = vam->input;
18281   vl_api_policer_add_del_t *mp;
18282   u8 is_add = 1;
18283   u8 *name = 0;
18284   u32 cir = 0;
18285   u32 eir = 0;
18286   u64 cb = 0;
18287   u64 eb = 0;
18288   u8 rate_type = 0;
18289   u8 round_type = 0;
18290   u8 type = 0;
18291   u8 color_aware = 0;
18292   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18293   int ret;
18294
18295   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18296   conform_action.dscp = 0;
18297   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18298   exceed_action.dscp = 0;
18299   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18300   violate_action.dscp = 0;
18301
18302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18303     {
18304       if (unformat (i, "del"))
18305         is_add = 0;
18306       else if (unformat (i, "name %s", &name))
18307         vec_add1 (name, 0);
18308       else if (unformat (i, "cir %u", &cir))
18309         ;
18310       else if (unformat (i, "eir %u", &eir))
18311         ;
18312       else if (unformat (i, "cb %u", &cb))
18313         ;
18314       else if (unformat (i, "eb %u", &eb))
18315         ;
18316       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18317                          &rate_type))
18318         ;
18319       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18320                          &round_type))
18321         ;
18322       else if (unformat (i, "type %U", unformat_policer_type, &type))
18323         ;
18324       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18325                          &conform_action))
18326         ;
18327       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18328                          &exceed_action))
18329         ;
18330       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18331                          &violate_action))
18332         ;
18333       else if (unformat (i, "color-aware"))
18334         color_aware = 1;
18335       else
18336         break;
18337     }
18338
18339   if (!vec_len (name))
18340     {
18341       errmsg ("policer name must be specified");
18342       return -99;
18343     }
18344
18345   if (vec_len (name) > 64)
18346     {
18347       errmsg ("policer name too long");
18348       return -99;
18349     }
18350
18351   M (POLICER_ADD_DEL, mp);
18352
18353   clib_memcpy (mp->name, name, vec_len (name));
18354   vec_free (name);
18355   mp->is_add = is_add;
18356   mp->cir = ntohl (cir);
18357   mp->eir = ntohl (eir);
18358   mp->cb = clib_net_to_host_u64 (cb);
18359   mp->eb = clib_net_to_host_u64 (eb);
18360   mp->rate_type = rate_type;
18361   mp->round_type = round_type;
18362   mp->type = type;
18363   mp->conform_action_type = conform_action.action_type;
18364   mp->conform_dscp = conform_action.dscp;
18365   mp->exceed_action_type = exceed_action.action_type;
18366   mp->exceed_dscp = exceed_action.dscp;
18367   mp->violate_action_type = violate_action.action_type;
18368   mp->violate_dscp = violate_action.dscp;
18369   mp->color_aware = color_aware;
18370
18371   S (mp);
18372   W (ret);
18373   return ret;
18374 }
18375
18376 static int
18377 api_policer_dump (vat_main_t * vam)
18378 {
18379   unformat_input_t *i = vam->input;
18380   vl_api_policer_dump_t *mp;
18381   vl_api_control_ping_t *mp_ping;
18382   u8 *match_name = 0;
18383   u8 match_name_valid = 0;
18384   int ret;
18385
18386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18387     {
18388       if (unformat (i, "name %s", &match_name))
18389         {
18390           vec_add1 (match_name, 0);
18391           match_name_valid = 1;
18392         }
18393       else
18394         break;
18395     }
18396
18397   M (POLICER_DUMP, mp);
18398   mp->match_name_valid = match_name_valid;
18399   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18400   vec_free (match_name);
18401   /* send it... */
18402   S (mp);
18403
18404   /* Use a control ping for synchronization */
18405   MPING (CONTROL_PING, mp_ping);
18406   S (mp_ping);
18407
18408   /* Wait for a reply... */
18409   W (ret);
18410   return ret;
18411 }
18412
18413 static int
18414 api_policer_classify_set_interface (vat_main_t * vam)
18415 {
18416   unformat_input_t *i = vam->input;
18417   vl_api_policer_classify_set_interface_t *mp;
18418   u32 sw_if_index;
18419   int sw_if_index_set;
18420   u32 ip4_table_index = ~0;
18421   u32 ip6_table_index = ~0;
18422   u32 l2_table_index = ~0;
18423   u8 is_add = 1;
18424   int ret;
18425
18426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18427     {
18428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18429         sw_if_index_set = 1;
18430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18431         sw_if_index_set = 1;
18432       else if (unformat (i, "del"))
18433         is_add = 0;
18434       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18435         ;
18436       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18437         ;
18438       else if (unformat (i, "l2-table %d", &l2_table_index))
18439         ;
18440       else
18441         {
18442           clib_warning ("parse error '%U'", format_unformat_error, i);
18443           return -99;
18444         }
18445     }
18446
18447   if (sw_if_index_set == 0)
18448     {
18449       errmsg ("missing interface name or sw_if_index");
18450       return -99;
18451     }
18452
18453   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18454
18455   mp->sw_if_index = ntohl (sw_if_index);
18456   mp->ip4_table_index = ntohl (ip4_table_index);
18457   mp->ip6_table_index = ntohl (ip6_table_index);
18458   mp->l2_table_index = ntohl (l2_table_index);
18459   mp->is_add = is_add;
18460
18461   S (mp);
18462   W (ret);
18463   return ret;
18464 }
18465
18466 static int
18467 api_policer_classify_dump (vat_main_t * vam)
18468 {
18469   unformat_input_t *i = vam->input;
18470   vl_api_policer_classify_dump_t *mp;
18471   vl_api_control_ping_t *mp_ping;
18472   u8 type = POLICER_CLASSIFY_N_TABLES;
18473   int ret;
18474
18475   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18476     ;
18477   else
18478     {
18479       errmsg ("classify table type must be specified");
18480       return -99;
18481     }
18482
18483   if (!vam->json_output)
18484     {
18485       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18486     }
18487
18488   M (POLICER_CLASSIFY_DUMP, mp);
18489   mp->type = type;
18490   /* send it... */
18491   S (mp);
18492
18493   /* Use a control ping for synchronization */
18494   MPING (CONTROL_PING, mp_ping);
18495   S (mp_ping);
18496
18497   /* Wait for a reply... */
18498   W (ret);
18499   return ret;
18500 }
18501
18502 static int
18503 api_netmap_create (vat_main_t * vam)
18504 {
18505   unformat_input_t *i = vam->input;
18506   vl_api_netmap_create_t *mp;
18507   u8 *if_name = 0;
18508   u8 hw_addr[6];
18509   u8 random_hw_addr = 1;
18510   u8 is_pipe = 0;
18511   u8 is_master = 0;
18512   int ret;
18513
18514   clib_memset (hw_addr, 0, sizeof (hw_addr));
18515
18516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18517     {
18518       if (unformat (i, "name %s", &if_name))
18519         vec_add1 (if_name, 0);
18520       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18521         random_hw_addr = 0;
18522       else if (unformat (i, "pipe"))
18523         is_pipe = 1;
18524       else if (unformat (i, "master"))
18525         is_master = 1;
18526       else if (unformat (i, "slave"))
18527         is_master = 0;
18528       else
18529         break;
18530     }
18531
18532   if (!vec_len (if_name))
18533     {
18534       errmsg ("interface name must be specified");
18535       return -99;
18536     }
18537
18538   if (vec_len (if_name) > 64)
18539     {
18540       errmsg ("interface name too long");
18541       return -99;
18542     }
18543
18544   M (NETMAP_CREATE, mp);
18545
18546   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18547   clib_memcpy (mp->hw_addr, hw_addr, 6);
18548   mp->use_random_hw_addr = random_hw_addr;
18549   mp->is_pipe = is_pipe;
18550   mp->is_master = is_master;
18551   vec_free (if_name);
18552
18553   S (mp);
18554   W (ret);
18555   return ret;
18556 }
18557
18558 static int
18559 api_netmap_delete (vat_main_t * vam)
18560 {
18561   unformat_input_t *i = vam->input;
18562   vl_api_netmap_delete_t *mp;
18563   u8 *if_name = 0;
18564   int ret;
18565
18566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18567     {
18568       if (unformat (i, "name %s", &if_name))
18569         vec_add1 (if_name, 0);
18570       else
18571         break;
18572     }
18573
18574   if (!vec_len (if_name))
18575     {
18576       errmsg ("interface name must be specified");
18577       return -99;
18578     }
18579
18580   if (vec_len (if_name) > 64)
18581     {
18582       errmsg ("interface name too long");
18583       return -99;
18584     }
18585
18586   M (NETMAP_DELETE, mp);
18587
18588   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18589   vec_free (if_name);
18590
18591   S (mp);
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static u8 *
18597 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18598 {
18599   vl_api_fib_path_nh_proto_t proto =
18600     va_arg (*args, vl_api_fib_path_nh_proto_t);
18601
18602   switch (proto)
18603     {
18604     case FIB_API_PATH_NH_PROTO_IP4:
18605       s = format (s, "ip4");
18606       break;
18607     case FIB_API_PATH_NH_PROTO_IP6:
18608       s = format (s, "ip6");
18609       break;
18610     case FIB_API_PATH_NH_PROTO_MPLS:
18611       s = format (s, "mpls");
18612       break;
18613     case FIB_API_PATH_NH_PROTO_BIER:
18614       s = format (s, "bier");
18615       break;
18616     case FIB_API_PATH_NH_PROTO_ETHERNET:
18617       s = format (s, "ethernet");
18618       break;
18619     }
18620
18621   return (s);
18622 }
18623
18624 static u8 *
18625 format_vl_api_ip_address_union (u8 * s, va_list * args)
18626 {
18627   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18628   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18629
18630   switch (af)
18631     {
18632     case ADDRESS_IP4:
18633       s = format (s, "%U", format_ip4_address, u->ip4);
18634       break;
18635     case ADDRESS_IP6:
18636       s = format (s, "%U", format_ip6_address, u->ip6);
18637       break;
18638     }
18639   return (s);
18640 }
18641
18642 static u8 *
18643 format_vl_api_fib_path_type (u8 * s, va_list * args)
18644 {
18645   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18646
18647   switch (t)
18648     {
18649     case FIB_API_PATH_TYPE_NORMAL:
18650       s = format (s, "normal");
18651       break;
18652     case FIB_API_PATH_TYPE_LOCAL:
18653       s = format (s, "local");
18654       break;
18655     case FIB_API_PATH_TYPE_DROP:
18656       s = format (s, "drop");
18657       break;
18658     case FIB_API_PATH_TYPE_UDP_ENCAP:
18659       s = format (s, "udp-encap");
18660       break;
18661     case FIB_API_PATH_TYPE_BIER_IMP:
18662       s = format (s, "bier-imp");
18663       break;
18664     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18665       s = format (s, "unreach");
18666       break;
18667     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18668       s = format (s, "prohibit");
18669       break;
18670     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18671       s = format (s, "src-lookup");
18672       break;
18673     case FIB_API_PATH_TYPE_DVR:
18674       s = format (s, "dvr");
18675       break;
18676     case FIB_API_PATH_TYPE_INTERFACE_RX:
18677       s = format (s, "interface-rx");
18678       break;
18679     case FIB_API_PATH_TYPE_CLASSIFY:
18680       s = format (s, "classify");
18681       break;
18682     }
18683
18684   return (s);
18685 }
18686
18687 static void
18688 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18689 {
18690   print (vam->ofp,
18691          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18692          ntohl (fp->weight), ntohl (fp->sw_if_index),
18693          format_vl_api_fib_path_type, fp->type,
18694          format_fib_api_path_nh_proto, fp->proto,
18695          format_vl_api_ip_address_union, &fp->nh.address);
18696 }
18697
18698 static void
18699 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18700                                  vl_api_fib_path_t * fp)
18701 {
18702   struct in_addr ip4;
18703   struct in6_addr ip6;
18704
18705   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18706   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18707   vat_json_object_add_uint (node, "type", fp->type);
18708   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18709   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18710     {
18711       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18712       vat_json_object_add_ip4 (node, "next_hop", ip4);
18713     }
18714   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18715     {
18716       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18717       vat_json_object_add_ip6 (node, "next_hop", ip6);
18718     }
18719 }
18720
18721 static void
18722 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18723 {
18724   vat_main_t *vam = &vat_main;
18725   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18726   vl_api_fib_path_t *fp;
18727   i32 i;
18728
18729   print (vam->ofp, "sw_if_index %d via:",
18730          ntohl (mp->mt_tunnel.mt_sw_if_index));
18731   fp = mp->mt_tunnel.mt_paths;
18732   for (i = 0; i < count; i++)
18733     {
18734       vl_api_fib_path_print (vam, fp);
18735       fp++;
18736     }
18737
18738   print (vam->ofp, "");
18739 }
18740
18741 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18742 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18743
18744 static void
18745 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18746 {
18747   vat_main_t *vam = &vat_main;
18748   vat_json_node_t *node = NULL;
18749   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18750   vl_api_fib_path_t *fp;
18751   i32 i;
18752
18753   if (VAT_JSON_ARRAY != vam->json_tree.type)
18754     {
18755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18756       vat_json_init_array (&vam->json_tree);
18757     }
18758   node = vat_json_array_add (&vam->json_tree);
18759
18760   vat_json_init_object (node);
18761   vat_json_object_add_uint (node, "sw_if_index",
18762                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18763
18764   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18765
18766   fp = mp->mt_tunnel.mt_paths;
18767   for (i = 0; i < count; i++)
18768     {
18769       vl_api_mpls_fib_path_json_print (node, fp);
18770       fp++;
18771     }
18772 }
18773
18774 static int
18775 api_mpls_tunnel_dump (vat_main_t * vam)
18776 {
18777   vl_api_mpls_tunnel_dump_t *mp;
18778   vl_api_control_ping_t *mp_ping;
18779   int ret;
18780
18781   M (MPLS_TUNNEL_DUMP, mp);
18782
18783   S (mp);
18784
18785   /* Use a control ping for synchronization */
18786   MPING (CONTROL_PING, mp_ping);
18787   S (mp_ping);
18788
18789   W (ret);
18790   return ret;
18791 }
18792
18793 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18794 #define vl_api_mpls_table_details_t_print vl_noop_handler
18795
18796
18797 static void
18798 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18799 {
18800   vat_main_t *vam = &vat_main;
18801
18802   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18803 }
18804
18805 static void vl_api_mpls_table_details_t_handler_json
18806   (vl_api_mpls_table_details_t * mp)
18807 {
18808   vat_main_t *vam = &vat_main;
18809   vat_json_node_t *node = NULL;
18810
18811   if (VAT_JSON_ARRAY != vam->json_tree.type)
18812     {
18813       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18814       vat_json_init_array (&vam->json_tree);
18815     }
18816   node = vat_json_array_add (&vam->json_tree);
18817
18818   vat_json_init_object (node);
18819   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18820 }
18821
18822 static int
18823 api_mpls_table_dump (vat_main_t * vam)
18824 {
18825   vl_api_mpls_table_dump_t *mp;
18826   vl_api_control_ping_t *mp_ping;
18827   int ret;
18828
18829   M (MPLS_TABLE_DUMP, mp);
18830   S (mp);
18831
18832   /* Use a control ping for synchronization */
18833   MPING (CONTROL_PING, mp_ping);
18834   S (mp_ping);
18835
18836   W (ret);
18837   return ret;
18838 }
18839
18840 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18841 #define vl_api_mpls_route_details_t_print vl_noop_handler
18842
18843 static void
18844 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18845 {
18846   vat_main_t *vam = &vat_main;
18847   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18848   vl_api_fib_path_t *fp;
18849   int i;
18850
18851   print (vam->ofp,
18852          "table-id %d, label %u, ess_bit %u",
18853          ntohl (mp->mr_route.mr_table_id),
18854          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18855   fp = mp->mr_route.mr_paths;
18856   for (i = 0; i < count; i++)
18857     {
18858       vl_api_fib_path_print (vam, fp);
18859       fp++;
18860     }
18861 }
18862
18863 static void vl_api_mpls_route_details_t_handler_json
18864   (vl_api_mpls_route_details_t * mp)
18865 {
18866   vat_main_t *vam = &vat_main;
18867   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18868   vat_json_node_t *node = NULL;
18869   vl_api_fib_path_t *fp;
18870   int i;
18871
18872   if (VAT_JSON_ARRAY != vam->json_tree.type)
18873     {
18874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18875       vat_json_init_array (&vam->json_tree);
18876     }
18877   node = vat_json_array_add (&vam->json_tree);
18878
18879   vat_json_init_object (node);
18880   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18881   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18882   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18883   vat_json_object_add_uint (node, "path_count", count);
18884   fp = mp->mr_route.mr_paths;
18885   for (i = 0; i < count; i++)
18886     {
18887       vl_api_mpls_fib_path_json_print (node, fp);
18888       fp++;
18889     }
18890 }
18891
18892 static int
18893 api_mpls_route_dump (vat_main_t * vam)
18894 {
18895   unformat_input_t *input = vam->input;
18896   vl_api_mpls_route_dump_t *mp;
18897   vl_api_control_ping_t *mp_ping;
18898   u32 table_id;
18899   int ret;
18900
18901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18902     {
18903       if (unformat (input, "table_id %d", &table_id))
18904         ;
18905       else
18906         break;
18907     }
18908   if (table_id == ~0)
18909     {
18910       errmsg ("missing table id");
18911       return -99;
18912     }
18913
18914   M (MPLS_ROUTE_DUMP, mp);
18915
18916   mp->table.mt_table_id = ntohl (table_id);
18917   S (mp);
18918
18919   /* Use a control ping for synchronization */
18920   MPING (CONTROL_PING, mp_ping);
18921   S (mp_ping);
18922
18923   W (ret);
18924   return ret;
18925 }
18926
18927 #define vl_api_ip_table_details_t_endian vl_noop_handler
18928 #define vl_api_ip_table_details_t_print vl_noop_handler
18929
18930 static void
18931 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18932 {
18933   vat_main_t *vam = &vat_main;
18934
18935   print (vam->ofp,
18936          "%s; table-id %d, prefix %U/%d",
18937          mp->table.name, ntohl (mp->table.table_id));
18938 }
18939
18940
18941 static void vl_api_ip_table_details_t_handler_json
18942   (vl_api_ip_table_details_t * mp)
18943 {
18944   vat_main_t *vam = &vat_main;
18945   vat_json_node_t *node = NULL;
18946
18947   if (VAT_JSON_ARRAY != vam->json_tree.type)
18948     {
18949       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18950       vat_json_init_array (&vam->json_tree);
18951     }
18952   node = vat_json_array_add (&vam->json_tree);
18953
18954   vat_json_init_object (node);
18955   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18956 }
18957
18958 static int
18959 api_ip_table_dump (vat_main_t * vam)
18960 {
18961   vl_api_ip_table_dump_t *mp;
18962   vl_api_control_ping_t *mp_ping;
18963   int ret;
18964
18965   M (IP_TABLE_DUMP, mp);
18966   S (mp);
18967
18968   /* Use a control ping for synchronization */
18969   MPING (CONTROL_PING, mp_ping);
18970   S (mp_ping);
18971
18972   W (ret);
18973   return ret;
18974 }
18975
18976 static int
18977 api_ip_mtable_dump (vat_main_t * vam)
18978 {
18979   vl_api_ip_mtable_dump_t *mp;
18980   vl_api_control_ping_t *mp_ping;
18981   int ret;
18982
18983   M (IP_MTABLE_DUMP, mp);
18984   S (mp);
18985
18986   /* Use a control ping for synchronization */
18987   MPING (CONTROL_PING, mp_ping);
18988   S (mp_ping);
18989
18990   W (ret);
18991   return ret;
18992 }
18993
18994 static int
18995 api_ip_mroute_dump (vat_main_t * vam)
18996 {
18997   unformat_input_t *input = vam->input;
18998   vl_api_control_ping_t *mp_ping;
18999   vl_api_ip_mroute_dump_t *mp;
19000   int ret, is_ip6;
19001   u32 table_id;
19002
19003   is_ip6 = 0;
19004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19005     {
19006       if (unformat (input, "table_id %d", &table_id))
19007         ;
19008       else if (unformat (input, "ip6"))
19009         is_ip6 = 1;
19010       else if (unformat (input, "ip4"))
19011         is_ip6 = 0;
19012       else
19013         break;
19014     }
19015   if (table_id == ~0)
19016     {
19017       errmsg ("missing table id");
19018       return -99;
19019     }
19020
19021   M (IP_MROUTE_DUMP, mp);
19022   mp->table.table_id = table_id;
19023   mp->table.is_ip6 = is_ip6;
19024   S (mp);
19025
19026   /* Use a control ping for synchronization */
19027   MPING (CONTROL_PING, mp_ping);
19028   S (mp_ping);
19029
19030   W (ret);
19031   return ret;
19032 }
19033
19034 static void vl_api_ip_neighbor_details_t_handler
19035   (vl_api_ip_neighbor_details_t * mp)
19036 {
19037   vat_main_t *vam = &vat_main;
19038
19039   print (vam->ofp, "%c %U %U",
19040          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19041          format_vl_api_mac_address, &mp->neighbor.mac_address,
19042          format_vl_api_address, &mp->neighbor.ip_address);
19043 }
19044
19045 static void vl_api_ip_neighbor_details_t_handler_json
19046   (vl_api_ip_neighbor_details_t * mp)
19047 {
19048
19049   vat_main_t *vam = &vat_main;
19050   vat_json_node_t *node;
19051
19052   if (VAT_JSON_ARRAY != vam->json_tree.type)
19053     {
19054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19055       vat_json_init_array (&vam->json_tree);
19056     }
19057   node = vat_json_array_add (&vam->json_tree);
19058
19059   vat_json_init_object (node);
19060   vat_json_object_add_string_copy
19061     (node, "flag",
19062      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19063       (u8 *) "static" : (u8 *) "dynamic"));
19064
19065   vat_json_object_add_string_copy (node, "link_layer",
19066                                    format (0, "%U", format_vl_api_mac_address,
19067                                            &mp->neighbor.mac_address));
19068   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19069 }
19070
19071 static int
19072 api_ip_neighbor_dump (vat_main_t * vam)
19073 {
19074   unformat_input_t *i = vam->input;
19075   vl_api_ip_neighbor_dump_t *mp;
19076   vl_api_control_ping_t *mp_ping;
19077   u8 is_ipv6 = 0;
19078   u32 sw_if_index = ~0;
19079   int ret;
19080
19081   /* Parse args required to build the message */
19082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19083     {
19084       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19085         ;
19086       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19087         ;
19088       else if (unformat (i, "ip6"))
19089         is_ipv6 = 1;
19090       else
19091         break;
19092     }
19093
19094   if (sw_if_index == ~0)
19095     {
19096       errmsg ("missing interface name or sw_if_index");
19097       return -99;
19098     }
19099
19100   M (IP_NEIGHBOR_DUMP, mp);
19101   mp->is_ipv6 = (u8) is_ipv6;
19102   mp->sw_if_index = ntohl (sw_if_index);
19103   S (mp);
19104
19105   /* Use a control ping for synchronization */
19106   MPING (CONTROL_PING, mp_ping);
19107   S (mp_ping);
19108
19109   W (ret);
19110   return ret;
19111 }
19112
19113 #define vl_api_ip_route_details_t_endian vl_noop_handler
19114 #define vl_api_ip_route_details_t_print vl_noop_handler
19115
19116 static void
19117 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19118 {
19119   vat_main_t *vam = &vat_main;
19120   u8 count = mp->route.n_paths;
19121   vl_api_fib_path_t *fp;
19122   int i;
19123
19124   print (vam->ofp,
19125          "table-id %d, prefix %U/%d",
19126          ntohl (mp->route.table_id),
19127          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19128   for (i = 0; i < count; i++)
19129     {
19130       fp = &mp->route.paths[i];
19131
19132       vl_api_fib_path_print (vam, fp);
19133       fp++;
19134     }
19135 }
19136
19137 static void vl_api_ip_route_details_t_handler_json
19138   (vl_api_ip_route_details_t * mp)
19139 {
19140   vat_main_t *vam = &vat_main;
19141   u8 count = mp->route.n_paths;
19142   vat_json_node_t *node = NULL;
19143   struct in_addr ip4;
19144   struct in6_addr ip6;
19145   vl_api_fib_path_t *fp;
19146   int i;
19147
19148   if (VAT_JSON_ARRAY != vam->json_tree.type)
19149     {
19150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19151       vat_json_init_array (&vam->json_tree);
19152     }
19153   node = vat_json_array_add (&vam->json_tree);
19154
19155   vat_json_init_object (node);
19156   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19157   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19158     {
19159       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19160       vat_json_object_add_ip6 (node, "prefix", ip6);
19161     }
19162   else
19163     {
19164       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19165       vat_json_object_add_ip4 (node, "prefix", ip4);
19166     }
19167   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19168   vat_json_object_add_uint (node, "path_count", count);
19169   for (i = 0; i < count; i++)
19170     {
19171       fp = &mp->route.paths[i];
19172       vl_api_mpls_fib_path_json_print (node, fp);
19173     }
19174 }
19175
19176 static int
19177 api_ip_route_dump (vat_main_t * vam)
19178 {
19179   unformat_input_t *input = vam->input;
19180   vl_api_ip_route_dump_t *mp;
19181   vl_api_control_ping_t *mp_ping;
19182   u32 table_id;
19183   u8 is_ip6;
19184   int ret;
19185
19186   is_ip6 = 0;
19187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19188     {
19189       if (unformat (input, "table_id %d", &table_id))
19190         ;
19191       else if (unformat (input, "ip6"))
19192         is_ip6 = 1;
19193       else if (unformat (input, "ip4"))
19194         is_ip6 = 0;
19195       else
19196         break;
19197     }
19198   if (table_id == ~0)
19199     {
19200       errmsg ("missing table id");
19201       return -99;
19202     }
19203
19204   M (IP_ROUTE_DUMP, mp);
19205
19206   mp->table.table_id = table_id;
19207   mp->table.is_ip6 = is_ip6;
19208
19209   S (mp);
19210
19211   /* Use a control ping for synchronization */
19212   MPING (CONTROL_PING, mp_ping);
19213   S (mp_ping);
19214
19215   W (ret);
19216   return ret;
19217 }
19218
19219 int
19220 api_classify_table_ids (vat_main_t * vam)
19221 {
19222   vl_api_classify_table_ids_t *mp;
19223   int ret;
19224
19225   /* Construct the API message */
19226   M (CLASSIFY_TABLE_IDS, mp);
19227   mp->context = 0;
19228
19229   S (mp);
19230   W (ret);
19231   return ret;
19232 }
19233
19234 int
19235 api_classify_table_by_interface (vat_main_t * vam)
19236 {
19237   unformat_input_t *input = vam->input;
19238   vl_api_classify_table_by_interface_t *mp;
19239
19240   u32 sw_if_index = ~0;
19241   int ret;
19242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19243     {
19244       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19245         ;
19246       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19247         ;
19248       else
19249         break;
19250     }
19251   if (sw_if_index == ~0)
19252     {
19253       errmsg ("missing interface name or sw_if_index");
19254       return -99;
19255     }
19256
19257   /* Construct the API message */
19258   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19259   mp->context = 0;
19260   mp->sw_if_index = ntohl (sw_if_index);
19261
19262   S (mp);
19263   W (ret);
19264   return ret;
19265 }
19266
19267 int
19268 api_classify_table_info (vat_main_t * vam)
19269 {
19270   unformat_input_t *input = vam->input;
19271   vl_api_classify_table_info_t *mp;
19272
19273   u32 table_id = ~0;
19274   int ret;
19275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19276     {
19277       if (unformat (input, "table_id %d", &table_id))
19278         ;
19279       else
19280         break;
19281     }
19282   if (table_id == ~0)
19283     {
19284       errmsg ("missing table id");
19285       return -99;
19286     }
19287
19288   /* Construct the API message */
19289   M (CLASSIFY_TABLE_INFO, mp);
19290   mp->context = 0;
19291   mp->table_id = ntohl (table_id);
19292
19293   S (mp);
19294   W (ret);
19295   return ret;
19296 }
19297
19298 int
19299 api_classify_session_dump (vat_main_t * vam)
19300 {
19301   unformat_input_t *input = vam->input;
19302   vl_api_classify_session_dump_t *mp;
19303   vl_api_control_ping_t *mp_ping;
19304
19305   u32 table_id = ~0;
19306   int ret;
19307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19308     {
19309       if (unformat (input, "table_id %d", &table_id))
19310         ;
19311       else
19312         break;
19313     }
19314   if (table_id == ~0)
19315     {
19316       errmsg ("missing table id");
19317       return -99;
19318     }
19319
19320   /* Construct the API message */
19321   M (CLASSIFY_SESSION_DUMP, mp);
19322   mp->context = 0;
19323   mp->table_id = ntohl (table_id);
19324   S (mp);
19325
19326   /* Use a control ping for synchronization */
19327   MPING (CONTROL_PING, mp_ping);
19328   S (mp_ping);
19329
19330   W (ret);
19331   return ret;
19332 }
19333
19334 static void
19335 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19336 {
19337   vat_main_t *vam = &vat_main;
19338
19339   print (vam->ofp, "collector_address %U, collector_port %d, "
19340          "src_address %U, vrf_id %d, path_mtu %u, "
19341          "template_interval %u, udp_checksum %d",
19342          format_ip4_address, mp->collector_address,
19343          ntohs (mp->collector_port),
19344          format_ip4_address, mp->src_address,
19345          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19346          ntohl (mp->template_interval), mp->udp_checksum);
19347
19348   vam->retval = 0;
19349   vam->result_ready = 1;
19350 }
19351
19352 static void
19353   vl_api_ipfix_exporter_details_t_handler_json
19354   (vl_api_ipfix_exporter_details_t * mp)
19355 {
19356   vat_main_t *vam = &vat_main;
19357   vat_json_node_t node;
19358   struct in_addr collector_address;
19359   struct in_addr src_address;
19360
19361   vat_json_init_object (&node);
19362   clib_memcpy (&collector_address, &mp->collector_address,
19363                sizeof (collector_address));
19364   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19365   vat_json_object_add_uint (&node, "collector_port",
19366                             ntohs (mp->collector_port));
19367   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19368   vat_json_object_add_ip4 (&node, "src_address", src_address);
19369   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19370   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19371   vat_json_object_add_uint (&node, "template_interval",
19372                             ntohl (mp->template_interval));
19373   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19374
19375   vat_json_print (vam->ofp, &node);
19376   vat_json_free (&node);
19377   vam->retval = 0;
19378   vam->result_ready = 1;
19379 }
19380
19381 int
19382 api_ipfix_exporter_dump (vat_main_t * vam)
19383 {
19384   vl_api_ipfix_exporter_dump_t *mp;
19385   int ret;
19386
19387   /* Construct the API message */
19388   M (IPFIX_EXPORTER_DUMP, mp);
19389   mp->context = 0;
19390
19391   S (mp);
19392   W (ret);
19393   return ret;
19394 }
19395
19396 static int
19397 api_ipfix_classify_stream_dump (vat_main_t * vam)
19398 {
19399   vl_api_ipfix_classify_stream_dump_t *mp;
19400   int ret;
19401
19402   /* Construct the API message */
19403   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19404   mp->context = 0;
19405
19406   S (mp);
19407   W (ret);
19408   return ret;
19409   /* NOTREACHED */
19410   return 0;
19411 }
19412
19413 static void
19414   vl_api_ipfix_classify_stream_details_t_handler
19415   (vl_api_ipfix_classify_stream_details_t * mp)
19416 {
19417   vat_main_t *vam = &vat_main;
19418   print (vam->ofp, "domain_id %d, src_port %d",
19419          ntohl (mp->domain_id), ntohs (mp->src_port));
19420   vam->retval = 0;
19421   vam->result_ready = 1;
19422 }
19423
19424 static void
19425   vl_api_ipfix_classify_stream_details_t_handler_json
19426   (vl_api_ipfix_classify_stream_details_t * mp)
19427 {
19428   vat_main_t *vam = &vat_main;
19429   vat_json_node_t node;
19430
19431   vat_json_init_object (&node);
19432   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19433   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19434
19435   vat_json_print (vam->ofp, &node);
19436   vat_json_free (&node);
19437   vam->retval = 0;
19438   vam->result_ready = 1;
19439 }
19440
19441 static int
19442 api_ipfix_classify_table_dump (vat_main_t * vam)
19443 {
19444   vl_api_ipfix_classify_table_dump_t *mp;
19445   vl_api_control_ping_t *mp_ping;
19446   int ret;
19447
19448   if (!vam->json_output)
19449     {
19450       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19451              "transport_protocol");
19452     }
19453
19454   /* Construct the API message */
19455   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19456
19457   /* send it... */
19458   S (mp);
19459
19460   /* Use a control ping for synchronization */
19461   MPING (CONTROL_PING, mp_ping);
19462   S (mp_ping);
19463
19464   W (ret);
19465   return ret;
19466 }
19467
19468 static void
19469   vl_api_ipfix_classify_table_details_t_handler
19470   (vl_api_ipfix_classify_table_details_t * mp)
19471 {
19472   vat_main_t *vam = &vat_main;
19473   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19474          mp->transport_protocol);
19475 }
19476
19477 static void
19478   vl_api_ipfix_classify_table_details_t_handler_json
19479   (vl_api_ipfix_classify_table_details_t * mp)
19480 {
19481   vat_json_node_t *node = NULL;
19482   vat_main_t *vam = &vat_main;
19483
19484   if (VAT_JSON_ARRAY != vam->json_tree.type)
19485     {
19486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19487       vat_json_init_array (&vam->json_tree);
19488     }
19489
19490   node = vat_json_array_add (&vam->json_tree);
19491   vat_json_init_object (node);
19492
19493   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19494   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19495   vat_json_object_add_uint (node, "transport_protocol",
19496                             mp->transport_protocol);
19497 }
19498
19499 static int
19500 api_sw_interface_span_enable_disable (vat_main_t * vam)
19501 {
19502   unformat_input_t *i = vam->input;
19503   vl_api_sw_interface_span_enable_disable_t *mp;
19504   u32 src_sw_if_index = ~0;
19505   u32 dst_sw_if_index = ~0;
19506   u8 state = 3;
19507   int ret;
19508   u8 is_l2 = 0;
19509
19510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19511     {
19512       if (unformat
19513           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19514         ;
19515       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19516         ;
19517       else
19518         if (unformat
19519             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19520         ;
19521       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19522         ;
19523       else if (unformat (i, "disable"))
19524         state = 0;
19525       else if (unformat (i, "rx"))
19526         state = 1;
19527       else if (unformat (i, "tx"))
19528         state = 2;
19529       else if (unformat (i, "both"))
19530         state = 3;
19531       else if (unformat (i, "l2"))
19532         is_l2 = 1;
19533       else
19534         break;
19535     }
19536
19537   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19538
19539   mp->sw_if_index_from = htonl (src_sw_if_index);
19540   mp->sw_if_index_to = htonl (dst_sw_if_index);
19541   mp->state = state;
19542   mp->is_l2 = is_l2;
19543
19544   S (mp);
19545   W (ret);
19546   return ret;
19547 }
19548
19549 static void
19550 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19551                                             * mp)
19552 {
19553   vat_main_t *vam = &vat_main;
19554   u8 *sw_if_from_name = 0;
19555   u8 *sw_if_to_name = 0;
19556   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19557   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19558   char *states[] = { "none", "rx", "tx", "both" };
19559   hash_pair_t *p;
19560
19561   /* *INDENT-OFF* */
19562   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19563   ({
19564     if ((u32) p->value[0] == sw_if_index_from)
19565       {
19566         sw_if_from_name = (u8 *)(p->key);
19567         if (sw_if_to_name)
19568           break;
19569       }
19570     if ((u32) p->value[0] == sw_if_index_to)
19571       {
19572         sw_if_to_name = (u8 *)(p->key);
19573         if (sw_if_from_name)
19574           break;
19575       }
19576   }));
19577   /* *INDENT-ON* */
19578   print (vam->ofp, "%20s => %20s (%s) %s",
19579          sw_if_from_name, sw_if_to_name, states[mp->state],
19580          mp->is_l2 ? "l2" : "device");
19581 }
19582
19583 static void
19584   vl_api_sw_interface_span_details_t_handler_json
19585   (vl_api_sw_interface_span_details_t * mp)
19586 {
19587   vat_main_t *vam = &vat_main;
19588   vat_json_node_t *node = NULL;
19589   u8 *sw_if_from_name = 0;
19590   u8 *sw_if_to_name = 0;
19591   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19592   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19593   hash_pair_t *p;
19594
19595   /* *INDENT-OFF* */
19596   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19597   ({
19598     if ((u32) p->value[0] == sw_if_index_from)
19599       {
19600         sw_if_from_name = (u8 *)(p->key);
19601         if (sw_if_to_name)
19602           break;
19603       }
19604     if ((u32) p->value[0] == sw_if_index_to)
19605       {
19606         sw_if_to_name = (u8 *)(p->key);
19607         if (sw_if_from_name)
19608           break;
19609       }
19610   }));
19611   /* *INDENT-ON* */
19612
19613   if (VAT_JSON_ARRAY != vam->json_tree.type)
19614     {
19615       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19616       vat_json_init_array (&vam->json_tree);
19617     }
19618   node = vat_json_array_add (&vam->json_tree);
19619
19620   vat_json_init_object (node);
19621   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19622   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19623   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19624   if (0 != sw_if_to_name)
19625     {
19626       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19627     }
19628   vat_json_object_add_uint (node, "state", mp->state);
19629   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19630 }
19631
19632 static int
19633 api_sw_interface_span_dump (vat_main_t * vam)
19634 {
19635   unformat_input_t *input = vam->input;
19636   vl_api_sw_interface_span_dump_t *mp;
19637   vl_api_control_ping_t *mp_ping;
19638   u8 is_l2 = 0;
19639   int ret;
19640
19641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19642     {
19643       if (unformat (input, "l2"))
19644         is_l2 = 1;
19645       else
19646         break;
19647     }
19648
19649   M (SW_INTERFACE_SPAN_DUMP, mp);
19650   mp->is_l2 = is_l2;
19651   S (mp);
19652
19653   /* Use a control ping for synchronization */
19654   MPING (CONTROL_PING, mp_ping);
19655   S (mp_ping);
19656
19657   W (ret);
19658   return ret;
19659 }
19660
19661 int
19662 api_pg_create_interface (vat_main_t * vam)
19663 {
19664   unformat_input_t *input = vam->input;
19665   vl_api_pg_create_interface_t *mp;
19666
19667   u32 if_id = ~0, gso_size = 0;
19668   u8 gso_enabled = 0;
19669   int ret;
19670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19671     {
19672       if (unformat (input, "if_id %d", &if_id))
19673         ;
19674       else if (unformat (input, "gso-enabled"))
19675         {
19676           gso_enabled = 1;
19677           if (unformat (input, "gso-size %u", &gso_size))
19678             ;
19679           else
19680             {
19681               errmsg ("missing gso-size");
19682               return -99;
19683             }
19684         }
19685       else
19686         break;
19687     }
19688   if (if_id == ~0)
19689     {
19690       errmsg ("missing pg interface index");
19691       return -99;
19692     }
19693
19694   /* Construct the API message */
19695   M (PG_CREATE_INTERFACE, mp);
19696   mp->context = 0;
19697   mp->interface_id = ntohl (if_id);
19698   mp->gso_enabled = gso_enabled;
19699
19700   S (mp);
19701   W (ret);
19702   return ret;
19703 }
19704
19705 int
19706 api_pg_capture (vat_main_t * vam)
19707 {
19708   unformat_input_t *input = vam->input;
19709   vl_api_pg_capture_t *mp;
19710
19711   u32 if_id = ~0;
19712   u8 enable = 1;
19713   u32 count = 1;
19714   u8 pcap_file_set = 0;
19715   u8 *pcap_file = 0;
19716   int ret;
19717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19718     {
19719       if (unformat (input, "if_id %d", &if_id))
19720         ;
19721       else if (unformat (input, "pcap %s", &pcap_file))
19722         pcap_file_set = 1;
19723       else if (unformat (input, "count %d", &count))
19724         ;
19725       else if (unformat (input, "disable"))
19726         enable = 0;
19727       else
19728         break;
19729     }
19730   if (if_id == ~0)
19731     {
19732       errmsg ("missing pg interface index");
19733       return -99;
19734     }
19735   if (pcap_file_set > 0)
19736     {
19737       if (vec_len (pcap_file) > 255)
19738         {
19739           errmsg ("pcap file name is too long");
19740           return -99;
19741         }
19742     }
19743
19744   u32 name_len = vec_len (pcap_file);
19745   /* Construct the API message */
19746   M (PG_CAPTURE, mp);
19747   mp->context = 0;
19748   mp->interface_id = ntohl (if_id);
19749   mp->is_enabled = enable;
19750   mp->count = ntohl (count);
19751   mp->pcap_name_length = ntohl (name_len);
19752   if (pcap_file_set != 0)
19753     {
19754       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19755     }
19756   vec_free (pcap_file);
19757
19758   S (mp);
19759   W (ret);
19760   return ret;
19761 }
19762
19763 int
19764 api_pg_enable_disable (vat_main_t * vam)
19765 {
19766   unformat_input_t *input = vam->input;
19767   vl_api_pg_enable_disable_t *mp;
19768
19769   u8 enable = 1;
19770   u8 stream_name_set = 0;
19771   u8 *stream_name = 0;
19772   int ret;
19773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19774     {
19775       if (unformat (input, "stream %s", &stream_name))
19776         stream_name_set = 1;
19777       else if (unformat (input, "disable"))
19778         enable = 0;
19779       else
19780         break;
19781     }
19782
19783   if (stream_name_set > 0)
19784     {
19785       if (vec_len (stream_name) > 255)
19786         {
19787           errmsg ("stream name too long");
19788           return -99;
19789         }
19790     }
19791
19792   u32 name_len = vec_len (stream_name);
19793   /* Construct the API message */
19794   M (PG_ENABLE_DISABLE, mp);
19795   mp->context = 0;
19796   mp->is_enabled = enable;
19797   if (stream_name_set != 0)
19798     {
19799       mp->stream_name_length = ntohl (name_len);
19800       clib_memcpy (mp->stream_name, stream_name, name_len);
19801     }
19802   vec_free (stream_name);
19803
19804   S (mp);
19805   W (ret);
19806   return ret;
19807 }
19808
19809 int
19810 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19811 {
19812   unformat_input_t *input = vam->input;
19813   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19814
19815   u16 *low_ports = 0;
19816   u16 *high_ports = 0;
19817   u16 this_low;
19818   u16 this_hi;
19819   vl_api_prefix_t prefix;
19820   u32 tmp, tmp2;
19821   u8 prefix_set = 0;
19822   u32 vrf_id = ~0;
19823   u8 is_add = 1;
19824   int ret;
19825
19826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19827     {
19828       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19829         prefix_set = 1;
19830       else if (unformat (input, "vrf %d", &vrf_id))
19831         ;
19832       else if (unformat (input, "del"))
19833         is_add = 0;
19834       else if (unformat (input, "port %d", &tmp))
19835         {
19836           if (tmp == 0 || tmp > 65535)
19837             {
19838               errmsg ("port %d out of range", tmp);
19839               return -99;
19840             }
19841           this_low = tmp;
19842           this_hi = this_low + 1;
19843           vec_add1 (low_ports, this_low);
19844           vec_add1 (high_ports, this_hi);
19845         }
19846       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19847         {
19848           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19849             {
19850               errmsg ("incorrect range parameters");
19851               return -99;
19852             }
19853           this_low = tmp;
19854           /* Note: in debug CLI +1 is added to high before
19855              passing to real fn that does "the work"
19856              (ip_source_and_port_range_check_add_del).
19857              This fn is a wrapper around the binary API fn a
19858              control plane will call, which expects this increment
19859              to have occurred. Hence letting the binary API control
19860              plane fn do the increment for consistency between VAT
19861              and other control planes.
19862            */
19863           this_hi = tmp2;
19864           vec_add1 (low_ports, this_low);
19865           vec_add1 (high_ports, this_hi);
19866         }
19867       else
19868         break;
19869     }
19870
19871   if (prefix_set == 0)
19872     {
19873       errmsg ("<address>/<mask> not specified");
19874       return -99;
19875     }
19876
19877   if (vrf_id == ~0)
19878     {
19879       errmsg ("VRF ID required, not specified");
19880       return -99;
19881     }
19882
19883   if (vrf_id == 0)
19884     {
19885       errmsg
19886         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19887       return -99;
19888     }
19889
19890   if (vec_len (low_ports) == 0)
19891     {
19892       errmsg ("At least one port or port range required");
19893       return -99;
19894     }
19895
19896   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19897
19898   mp->is_add = is_add;
19899
19900   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19901
19902   mp->number_of_ranges = vec_len (low_ports);
19903
19904   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19905   vec_free (low_ports);
19906
19907   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19908   vec_free (high_ports);
19909
19910   mp->vrf_id = ntohl (vrf_id);
19911
19912   S (mp);
19913   W (ret);
19914   return ret;
19915 }
19916
19917 int
19918 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19919 {
19920   unformat_input_t *input = vam->input;
19921   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19922   u32 sw_if_index = ~0;
19923   int vrf_set = 0;
19924   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19925   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19926   u8 is_add = 1;
19927   int ret;
19928
19929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19930     {
19931       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19932         ;
19933       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19934         ;
19935       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19936         vrf_set = 1;
19937       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19938         vrf_set = 1;
19939       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19940         vrf_set = 1;
19941       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19942         vrf_set = 1;
19943       else if (unformat (input, "del"))
19944         is_add = 0;
19945       else
19946         break;
19947     }
19948
19949   if (sw_if_index == ~0)
19950     {
19951       errmsg ("Interface required but not specified");
19952       return -99;
19953     }
19954
19955   if (vrf_set == 0)
19956     {
19957       errmsg ("VRF ID required but not specified");
19958       return -99;
19959     }
19960
19961   if (tcp_out_vrf_id == 0
19962       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19963     {
19964       errmsg
19965         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19966       return -99;
19967     }
19968
19969   /* Construct the API message */
19970   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19971
19972   mp->sw_if_index = ntohl (sw_if_index);
19973   mp->is_add = is_add;
19974   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19975   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19976   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19977   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19978
19979   /* send it... */
19980   S (mp);
19981
19982   /* Wait for a reply... */
19983   W (ret);
19984   return ret;
19985 }
19986
19987 static int
19988 api_set_punt (vat_main_t * vam)
19989 {
19990   unformat_input_t *i = vam->input;
19991   vl_api_address_family_t af;
19992   vl_api_set_punt_t *mp;
19993   u32 protocol = ~0;
19994   u32 port = ~0;
19995   int is_add = 1;
19996   int ret;
19997
19998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19999     {
20000       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20001         ;
20002       else if (unformat (i, "protocol %d", &protocol))
20003         ;
20004       else if (unformat (i, "port %d", &port))
20005         ;
20006       else if (unformat (i, "del"))
20007         is_add = 0;
20008       else
20009         {
20010           clib_warning ("parse error '%U'", format_unformat_error, i);
20011           return -99;
20012         }
20013     }
20014
20015   M (SET_PUNT, mp);
20016
20017   mp->is_add = (u8) is_add;
20018   mp->punt.type = PUNT_API_TYPE_L4;
20019   mp->punt.punt.l4.af = af;
20020   mp->punt.punt.l4.protocol = (u8) protocol;
20021   mp->punt.punt.l4.port = htons ((u16) port);
20022
20023   S (mp);
20024   W (ret);
20025   return ret;
20026 }
20027
20028 static int
20029 api_delete_subif (vat_main_t * vam)
20030 {
20031   unformat_input_t *i = vam->input;
20032   vl_api_delete_subif_t *mp;
20033   u32 sw_if_index = ~0;
20034   int ret;
20035
20036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20037     {
20038       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20039         ;
20040       if (unformat (i, "sw_if_index %d", &sw_if_index))
20041         ;
20042       else
20043         break;
20044     }
20045
20046   if (sw_if_index == ~0)
20047     {
20048       errmsg ("missing sw_if_index");
20049       return -99;
20050     }
20051
20052   /* Construct the API message */
20053   M (DELETE_SUBIF, mp);
20054   mp->sw_if_index = ntohl (sw_if_index);
20055
20056   S (mp);
20057   W (ret);
20058   return ret;
20059 }
20060
20061 #define foreach_pbb_vtr_op      \
20062 _("disable",  L2_VTR_DISABLED)  \
20063 _("pop",  L2_VTR_POP_2)         \
20064 _("push",  L2_VTR_PUSH_2)
20065
20066 static int
20067 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20068 {
20069   unformat_input_t *i = vam->input;
20070   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20071   u32 sw_if_index = ~0, vtr_op = ~0;
20072   u16 outer_tag = ~0;
20073   u8 dmac[6], smac[6];
20074   u8 dmac_set = 0, smac_set = 0;
20075   u16 vlanid = 0;
20076   u32 sid = ~0;
20077   u32 tmp;
20078   int ret;
20079
20080   /* Shut up coverity */
20081   clib_memset (dmac, 0, sizeof (dmac));
20082   clib_memset (smac, 0, sizeof (smac));
20083
20084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20085     {
20086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20087         ;
20088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20089         ;
20090       else if (unformat (i, "vtr_op %d", &vtr_op))
20091         ;
20092 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20093       foreach_pbb_vtr_op
20094 #undef _
20095         else if (unformat (i, "translate_pbb_stag"))
20096         {
20097           if (unformat (i, "%d", &tmp))
20098             {
20099               vtr_op = L2_VTR_TRANSLATE_2_1;
20100               outer_tag = tmp;
20101             }
20102           else
20103             {
20104               errmsg
20105                 ("translate_pbb_stag operation requires outer tag definition");
20106               return -99;
20107             }
20108         }
20109       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20110         dmac_set++;
20111       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20112         smac_set++;
20113       else if (unformat (i, "sid %d", &sid))
20114         ;
20115       else if (unformat (i, "vlanid %d", &tmp))
20116         vlanid = tmp;
20117       else
20118         {
20119           clib_warning ("parse error '%U'", format_unformat_error, i);
20120           return -99;
20121         }
20122     }
20123
20124   if ((sw_if_index == ~0) || (vtr_op == ~0))
20125     {
20126       errmsg ("missing sw_if_index or vtr operation");
20127       return -99;
20128     }
20129   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20130       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20131     {
20132       errmsg
20133         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20134       return -99;
20135     }
20136
20137   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20138   mp->sw_if_index = ntohl (sw_if_index);
20139   mp->vtr_op = ntohl (vtr_op);
20140   mp->outer_tag = ntohs (outer_tag);
20141   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20142   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20143   mp->b_vlanid = ntohs (vlanid);
20144   mp->i_sid = ntohl (sid);
20145
20146   S (mp);
20147   W (ret);
20148   return ret;
20149 }
20150
20151 static int
20152 api_flow_classify_set_interface (vat_main_t * vam)
20153 {
20154   unformat_input_t *i = vam->input;
20155   vl_api_flow_classify_set_interface_t *mp;
20156   u32 sw_if_index;
20157   int sw_if_index_set;
20158   u32 ip4_table_index = ~0;
20159   u32 ip6_table_index = ~0;
20160   u8 is_add = 1;
20161   int ret;
20162
20163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20164     {
20165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20166         sw_if_index_set = 1;
20167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20168         sw_if_index_set = 1;
20169       else if (unformat (i, "del"))
20170         is_add = 0;
20171       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20172         ;
20173       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20174         ;
20175       else
20176         {
20177           clib_warning ("parse error '%U'", format_unformat_error, i);
20178           return -99;
20179         }
20180     }
20181
20182   if (sw_if_index_set == 0)
20183     {
20184       errmsg ("missing interface name or sw_if_index");
20185       return -99;
20186     }
20187
20188   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20189
20190   mp->sw_if_index = ntohl (sw_if_index);
20191   mp->ip4_table_index = ntohl (ip4_table_index);
20192   mp->ip6_table_index = ntohl (ip6_table_index);
20193   mp->is_add = is_add;
20194
20195   S (mp);
20196   W (ret);
20197   return ret;
20198 }
20199
20200 static int
20201 api_flow_classify_dump (vat_main_t * vam)
20202 {
20203   unformat_input_t *i = vam->input;
20204   vl_api_flow_classify_dump_t *mp;
20205   vl_api_control_ping_t *mp_ping;
20206   u8 type = FLOW_CLASSIFY_N_TABLES;
20207   int ret;
20208
20209   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20210     ;
20211   else
20212     {
20213       errmsg ("classify table type must be specified");
20214       return -99;
20215     }
20216
20217   if (!vam->json_output)
20218     {
20219       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20220     }
20221
20222   M (FLOW_CLASSIFY_DUMP, mp);
20223   mp->type = type;
20224   /* send it... */
20225   S (mp);
20226
20227   /* Use a control ping for synchronization */
20228   MPING (CONTROL_PING, mp_ping);
20229   S (mp_ping);
20230
20231   /* Wait for a reply... */
20232   W (ret);
20233   return ret;
20234 }
20235
20236 static int
20237 api_feature_enable_disable (vat_main_t * vam)
20238 {
20239   unformat_input_t *i = vam->input;
20240   vl_api_feature_enable_disable_t *mp;
20241   u8 *arc_name = 0;
20242   u8 *feature_name = 0;
20243   u32 sw_if_index = ~0;
20244   u8 enable = 1;
20245   int ret;
20246
20247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20248     {
20249       if (unformat (i, "arc_name %s", &arc_name))
20250         ;
20251       else if (unformat (i, "feature_name %s", &feature_name))
20252         ;
20253       else
20254         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20255         ;
20256       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20257         ;
20258       else if (unformat (i, "disable"))
20259         enable = 0;
20260       else
20261         break;
20262     }
20263
20264   if (arc_name == 0)
20265     {
20266       errmsg ("missing arc name");
20267       return -99;
20268     }
20269   if (vec_len (arc_name) > 63)
20270     {
20271       errmsg ("arc name too long");
20272     }
20273
20274   if (feature_name == 0)
20275     {
20276       errmsg ("missing feature name");
20277       return -99;
20278     }
20279   if (vec_len (feature_name) > 63)
20280     {
20281       errmsg ("feature name too long");
20282     }
20283
20284   if (sw_if_index == ~0)
20285     {
20286       errmsg ("missing interface name or sw_if_index");
20287       return -99;
20288     }
20289
20290   /* Construct the API message */
20291   M (FEATURE_ENABLE_DISABLE, mp);
20292   mp->sw_if_index = ntohl (sw_if_index);
20293   mp->enable = enable;
20294   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20295   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20296   vec_free (arc_name);
20297   vec_free (feature_name);
20298
20299   S (mp);
20300   W (ret);
20301   return ret;
20302 }
20303
20304 static int
20305 api_sw_interface_tag_add_del (vat_main_t * vam)
20306 {
20307   unformat_input_t *i = vam->input;
20308   vl_api_sw_interface_tag_add_del_t *mp;
20309   u32 sw_if_index = ~0;
20310   u8 *tag = 0;
20311   u8 enable = 1;
20312   int ret;
20313
20314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20315     {
20316       if (unformat (i, "tag %s", &tag))
20317         ;
20318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20319         ;
20320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20321         ;
20322       else if (unformat (i, "del"))
20323         enable = 0;
20324       else
20325         break;
20326     }
20327
20328   if (sw_if_index == ~0)
20329     {
20330       errmsg ("missing interface name or sw_if_index");
20331       return -99;
20332     }
20333
20334   if (enable && (tag == 0))
20335     {
20336       errmsg ("no tag specified");
20337       return -99;
20338     }
20339
20340   /* Construct the API message */
20341   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20342   mp->sw_if_index = ntohl (sw_if_index);
20343   mp->is_add = enable;
20344   if (enable)
20345     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20346   vec_free (tag);
20347
20348   S (mp);
20349   W (ret);
20350   return ret;
20351 }
20352
20353 static void vl_api_l2_xconnect_details_t_handler
20354   (vl_api_l2_xconnect_details_t * mp)
20355 {
20356   vat_main_t *vam = &vat_main;
20357
20358   print (vam->ofp, "%15d%15d",
20359          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20360 }
20361
20362 static void vl_api_l2_xconnect_details_t_handler_json
20363   (vl_api_l2_xconnect_details_t * mp)
20364 {
20365   vat_main_t *vam = &vat_main;
20366   vat_json_node_t *node = NULL;
20367
20368   if (VAT_JSON_ARRAY != vam->json_tree.type)
20369     {
20370       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20371       vat_json_init_array (&vam->json_tree);
20372     }
20373   node = vat_json_array_add (&vam->json_tree);
20374
20375   vat_json_init_object (node);
20376   vat_json_object_add_uint (node, "rx_sw_if_index",
20377                             ntohl (mp->rx_sw_if_index));
20378   vat_json_object_add_uint (node, "tx_sw_if_index",
20379                             ntohl (mp->tx_sw_if_index));
20380 }
20381
20382 static int
20383 api_l2_xconnect_dump (vat_main_t * vam)
20384 {
20385   vl_api_l2_xconnect_dump_t *mp;
20386   vl_api_control_ping_t *mp_ping;
20387   int ret;
20388
20389   if (!vam->json_output)
20390     {
20391       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20392     }
20393
20394   M (L2_XCONNECT_DUMP, mp);
20395
20396   S (mp);
20397
20398   /* Use a control ping for synchronization */
20399   MPING (CONTROL_PING, mp_ping);
20400   S (mp_ping);
20401
20402   W (ret);
20403   return ret;
20404 }
20405
20406 static int
20407 api_hw_interface_set_mtu (vat_main_t * vam)
20408 {
20409   unformat_input_t *i = vam->input;
20410   vl_api_hw_interface_set_mtu_t *mp;
20411   u32 sw_if_index = ~0;
20412   u32 mtu = 0;
20413   int ret;
20414
20415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20416     {
20417       if (unformat (i, "mtu %d", &mtu))
20418         ;
20419       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20420         ;
20421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20422         ;
20423       else
20424         break;
20425     }
20426
20427   if (sw_if_index == ~0)
20428     {
20429       errmsg ("missing interface name or sw_if_index");
20430       return -99;
20431     }
20432
20433   if (mtu == 0)
20434     {
20435       errmsg ("no mtu specified");
20436       return -99;
20437     }
20438
20439   /* Construct the API message */
20440   M (HW_INTERFACE_SET_MTU, mp);
20441   mp->sw_if_index = ntohl (sw_if_index);
20442   mp->mtu = ntohs ((u16) mtu);
20443
20444   S (mp);
20445   W (ret);
20446   return ret;
20447 }
20448
20449 static int
20450 api_p2p_ethernet_add (vat_main_t * vam)
20451 {
20452   unformat_input_t *i = vam->input;
20453   vl_api_p2p_ethernet_add_t *mp;
20454   u32 parent_if_index = ~0;
20455   u32 sub_id = ~0;
20456   u8 remote_mac[6];
20457   u8 mac_set = 0;
20458   int ret;
20459
20460   clib_memset (remote_mac, 0, sizeof (remote_mac));
20461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20462     {
20463       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20464         ;
20465       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20466         ;
20467       else
20468         if (unformat
20469             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20470         mac_set++;
20471       else if (unformat (i, "sub_id %d", &sub_id))
20472         ;
20473       else
20474         {
20475           clib_warning ("parse error '%U'", format_unformat_error, i);
20476           return -99;
20477         }
20478     }
20479
20480   if (parent_if_index == ~0)
20481     {
20482       errmsg ("missing interface name or sw_if_index");
20483       return -99;
20484     }
20485   if (mac_set == 0)
20486     {
20487       errmsg ("missing remote mac address");
20488       return -99;
20489     }
20490   if (sub_id == ~0)
20491     {
20492       errmsg ("missing sub-interface id");
20493       return -99;
20494     }
20495
20496   M (P2P_ETHERNET_ADD, mp);
20497   mp->parent_if_index = ntohl (parent_if_index);
20498   mp->subif_id = ntohl (sub_id);
20499   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20500
20501   S (mp);
20502   W (ret);
20503   return ret;
20504 }
20505
20506 static int
20507 api_p2p_ethernet_del (vat_main_t * vam)
20508 {
20509   unformat_input_t *i = vam->input;
20510   vl_api_p2p_ethernet_del_t *mp;
20511   u32 parent_if_index = ~0;
20512   u8 remote_mac[6];
20513   u8 mac_set = 0;
20514   int ret;
20515
20516   clib_memset (remote_mac, 0, sizeof (remote_mac));
20517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20518     {
20519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20520         ;
20521       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20522         ;
20523       else
20524         if (unformat
20525             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20526         mac_set++;
20527       else
20528         {
20529           clib_warning ("parse error '%U'", format_unformat_error, i);
20530           return -99;
20531         }
20532     }
20533
20534   if (parent_if_index == ~0)
20535     {
20536       errmsg ("missing interface name or sw_if_index");
20537       return -99;
20538     }
20539   if (mac_set == 0)
20540     {
20541       errmsg ("missing remote mac address");
20542       return -99;
20543     }
20544
20545   M (P2P_ETHERNET_DEL, mp);
20546   mp->parent_if_index = ntohl (parent_if_index);
20547   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20548
20549   S (mp);
20550   W (ret);
20551   return ret;
20552 }
20553
20554 static int
20555 api_lldp_config (vat_main_t * vam)
20556 {
20557   unformat_input_t *i = vam->input;
20558   vl_api_lldp_config_t *mp;
20559   int tx_hold = 0;
20560   int tx_interval = 0;
20561   u8 *sys_name = NULL;
20562   int ret;
20563
20564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20565     {
20566       if (unformat (i, "system-name %s", &sys_name))
20567         ;
20568       else if (unformat (i, "tx-hold %d", &tx_hold))
20569         ;
20570       else if (unformat (i, "tx-interval %d", &tx_interval))
20571         ;
20572       else
20573         {
20574           clib_warning ("parse error '%U'", format_unformat_error, i);
20575           return -99;
20576         }
20577     }
20578
20579   vec_add1 (sys_name, 0);
20580
20581   M (LLDP_CONFIG, mp);
20582   mp->tx_hold = htonl (tx_hold);
20583   mp->tx_interval = htonl (tx_interval);
20584   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20585   vec_free (sys_name);
20586
20587   S (mp);
20588   W (ret);
20589   return ret;
20590 }
20591
20592 static int
20593 api_sw_interface_set_lldp (vat_main_t * vam)
20594 {
20595   unformat_input_t *i = vam->input;
20596   vl_api_sw_interface_set_lldp_t *mp;
20597   u32 sw_if_index = ~0;
20598   u32 enable = 1;
20599   u8 *port_desc = NULL, *mgmt_oid = NULL;
20600   ip4_address_t ip4_addr;
20601   ip6_address_t ip6_addr;
20602   int ret;
20603
20604   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20605   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20606
20607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20608     {
20609       if (unformat (i, "disable"))
20610         enable = 0;
20611       else
20612         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20613         ;
20614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20615         ;
20616       else if (unformat (i, "port-desc %s", &port_desc))
20617         ;
20618       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20619         ;
20620       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20621         ;
20622       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20623         ;
20624       else
20625         break;
20626     }
20627
20628   if (sw_if_index == ~0)
20629     {
20630       errmsg ("missing interface name or sw_if_index");
20631       return -99;
20632     }
20633
20634   /* Construct the API message */
20635   vec_add1 (port_desc, 0);
20636   vec_add1 (mgmt_oid, 0);
20637   M (SW_INTERFACE_SET_LLDP, mp);
20638   mp->sw_if_index = ntohl (sw_if_index);
20639   mp->enable = enable;
20640   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20641   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20642   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20643   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20644   vec_free (port_desc);
20645   vec_free (mgmt_oid);
20646
20647   S (mp);
20648   W (ret);
20649   return ret;
20650 }
20651
20652 static int
20653 api_tcp_configure_src_addresses (vat_main_t * vam)
20654 {
20655   vl_api_tcp_configure_src_addresses_t *mp;
20656   unformat_input_t *i = vam->input;
20657   ip4_address_t v4first, v4last;
20658   ip6_address_t v6first, v6last;
20659   u8 range_set = 0;
20660   u32 vrf_id = 0;
20661   int ret;
20662
20663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20664     {
20665       if (unformat (i, "%U - %U",
20666                     unformat_ip4_address, &v4first,
20667                     unformat_ip4_address, &v4last))
20668         {
20669           if (range_set)
20670             {
20671               errmsg ("one range per message (range already set)");
20672               return -99;
20673             }
20674           range_set = 1;
20675         }
20676       else if (unformat (i, "%U - %U",
20677                          unformat_ip6_address, &v6first,
20678                          unformat_ip6_address, &v6last))
20679         {
20680           if (range_set)
20681             {
20682               errmsg ("one range per message (range already set)");
20683               return -99;
20684             }
20685           range_set = 2;
20686         }
20687       else if (unformat (i, "vrf %d", &vrf_id))
20688         ;
20689       else
20690         break;
20691     }
20692
20693   if (range_set == 0)
20694     {
20695       errmsg ("address range not set");
20696       return -99;
20697     }
20698
20699   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20700   mp->vrf_id = ntohl (vrf_id);
20701   /* ipv6? */
20702   if (range_set == 2)
20703     {
20704       mp->is_ipv6 = 1;
20705       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20706       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20707     }
20708   else
20709     {
20710       mp->is_ipv6 = 0;
20711       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20712       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20713     }
20714   S (mp);
20715   W (ret);
20716   return ret;
20717 }
20718
20719 static void vl_api_app_namespace_add_del_reply_t_handler
20720   (vl_api_app_namespace_add_del_reply_t * mp)
20721 {
20722   vat_main_t *vam = &vat_main;
20723   i32 retval = ntohl (mp->retval);
20724   if (vam->async_mode)
20725     {
20726       vam->async_errors += (retval < 0);
20727     }
20728   else
20729     {
20730       vam->retval = retval;
20731       if (retval == 0)
20732         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20733       vam->result_ready = 1;
20734     }
20735 }
20736
20737 static void vl_api_app_namespace_add_del_reply_t_handler_json
20738   (vl_api_app_namespace_add_del_reply_t * mp)
20739 {
20740   vat_main_t *vam = &vat_main;
20741   vat_json_node_t node;
20742
20743   vat_json_init_object (&node);
20744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20745   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20746
20747   vat_json_print (vam->ofp, &node);
20748   vat_json_free (&node);
20749
20750   vam->retval = ntohl (mp->retval);
20751   vam->result_ready = 1;
20752 }
20753
20754 static int
20755 api_app_namespace_add_del (vat_main_t * vam)
20756 {
20757   vl_api_app_namespace_add_del_t *mp;
20758   unformat_input_t *i = vam->input;
20759   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20760   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20761   u64 secret;
20762   int ret;
20763
20764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20765     {
20766       if (unformat (i, "id %_%v%_", &ns_id))
20767         ;
20768       else if (unformat (i, "secret %lu", &secret))
20769         secret_set = 1;
20770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20771         sw_if_index_set = 1;
20772       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20773         ;
20774       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20775         ;
20776       else
20777         break;
20778     }
20779   if (!ns_id || !secret_set || !sw_if_index_set)
20780     {
20781       errmsg ("namespace id, secret and sw_if_index must be set");
20782       return -99;
20783     }
20784   if (vec_len (ns_id) > 64)
20785     {
20786       errmsg ("namespace id too long");
20787       return -99;
20788     }
20789   M (APP_NAMESPACE_ADD_DEL, mp);
20790
20791   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20792   mp->namespace_id_len = vec_len (ns_id);
20793   mp->secret = clib_host_to_net_u64 (secret);
20794   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20795   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20796   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20797   vec_free (ns_id);
20798   S (mp);
20799   W (ret);
20800   return ret;
20801 }
20802
20803 static int
20804 api_sock_init_shm (vat_main_t * vam)
20805 {
20806 #if VPP_API_TEST_BUILTIN == 0
20807   unformat_input_t *i = vam->input;
20808   vl_api_shm_elem_config_t *config = 0;
20809   u64 size = 64 << 20;
20810   int rv;
20811
20812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20813     {
20814       if (unformat (i, "size %U", unformat_memory_size, &size))
20815         ;
20816       else
20817         break;
20818     }
20819
20820   /*
20821    * Canned custom ring allocator config.
20822    * Should probably parse all of this
20823    */
20824   vec_validate (config, 6);
20825   config[0].type = VL_API_VLIB_RING;
20826   config[0].size = 256;
20827   config[0].count = 32;
20828
20829   config[1].type = VL_API_VLIB_RING;
20830   config[1].size = 1024;
20831   config[1].count = 16;
20832
20833   config[2].type = VL_API_VLIB_RING;
20834   config[2].size = 4096;
20835   config[2].count = 2;
20836
20837   config[3].type = VL_API_CLIENT_RING;
20838   config[3].size = 256;
20839   config[3].count = 32;
20840
20841   config[4].type = VL_API_CLIENT_RING;
20842   config[4].size = 1024;
20843   config[4].count = 16;
20844
20845   config[5].type = VL_API_CLIENT_RING;
20846   config[5].size = 4096;
20847   config[5].count = 2;
20848
20849   config[6].type = VL_API_QUEUE;
20850   config[6].count = 128;
20851   config[6].size = sizeof (uword);
20852
20853   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20854   if (!rv)
20855     vam->client_index_invalid = 1;
20856   return rv;
20857 #else
20858   return -99;
20859 #endif
20860 }
20861
20862 static void
20863 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20864 {
20865   vat_main_t *vam = &vat_main;
20866
20867   if (mp->is_ip4)
20868     {
20869       print (vam->ofp,
20870              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20871              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20872              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20873              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20874              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20875              clib_net_to_host_u32 (mp->action_index), mp->tag);
20876     }
20877   else
20878     {
20879       print (vam->ofp,
20880              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20881              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20882              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20883              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20884              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20885              clib_net_to_host_u32 (mp->action_index), mp->tag);
20886     }
20887 }
20888
20889 static void
20890 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20891                                              mp)
20892 {
20893   vat_main_t *vam = &vat_main;
20894   vat_json_node_t *node = NULL;
20895   struct in6_addr ip6;
20896   struct in_addr ip4;
20897
20898   if (VAT_JSON_ARRAY != vam->json_tree.type)
20899     {
20900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20901       vat_json_init_array (&vam->json_tree);
20902     }
20903   node = vat_json_array_add (&vam->json_tree);
20904   vat_json_init_object (node);
20905
20906   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20907   vat_json_object_add_uint (node, "appns_index",
20908                             clib_net_to_host_u32 (mp->appns_index));
20909   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20910   vat_json_object_add_uint (node, "scope", mp->scope);
20911   vat_json_object_add_uint (node, "action_index",
20912                             clib_net_to_host_u32 (mp->action_index));
20913   vat_json_object_add_uint (node, "lcl_port",
20914                             clib_net_to_host_u16 (mp->lcl_port));
20915   vat_json_object_add_uint (node, "rmt_port",
20916                             clib_net_to_host_u16 (mp->rmt_port));
20917   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20918   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20919   vat_json_object_add_string_copy (node, "tag", mp->tag);
20920   if (mp->is_ip4)
20921     {
20922       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20923       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20924       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20925       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20926     }
20927   else
20928     {
20929       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20930       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20931       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20932       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20933     }
20934 }
20935
20936 static int
20937 api_session_rule_add_del (vat_main_t * vam)
20938 {
20939   vl_api_session_rule_add_del_t *mp;
20940   unformat_input_t *i = vam->input;
20941   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20942   u32 appns_index = 0, scope = 0;
20943   ip4_address_t lcl_ip4, rmt_ip4;
20944   ip6_address_t lcl_ip6, rmt_ip6;
20945   u8 is_ip4 = 1, conn_set = 0;
20946   u8 is_add = 1, *tag = 0;
20947   int ret;
20948
20949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20950     {
20951       if (unformat (i, "del"))
20952         is_add = 0;
20953       else if (unformat (i, "add"))
20954         ;
20955       else if (unformat (i, "proto tcp"))
20956         proto = 0;
20957       else if (unformat (i, "proto udp"))
20958         proto = 1;
20959       else if (unformat (i, "appns %d", &appns_index))
20960         ;
20961       else if (unformat (i, "scope %d", &scope))
20962         ;
20963       else if (unformat (i, "tag %_%v%_", &tag))
20964         ;
20965       else
20966         if (unformat
20967             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20968              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20969              &rmt_port))
20970         {
20971           is_ip4 = 1;
20972           conn_set = 1;
20973         }
20974       else
20975         if (unformat
20976             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20977              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20978              &rmt_port))
20979         {
20980           is_ip4 = 0;
20981           conn_set = 1;
20982         }
20983       else if (unformat (i, "action %d", &action))
20984         ;
20985       else
20986         break;
20987     }
20988   if (proto == ~0 || !conn_set || action == ~0)
20989     {
20990       errmsg ("transport proto, connection and action must be set");
20991       return -99;
20992     }
20993
20994   if (scope > 3)
20995     {
20996       errmsg ("scope should be 0-3");
20997       return -99;
20998     }
20999
21000   M (SESSION_RULE_ADD_DEL, mp);
21001
21002   mp->is_ip4 = is_ip4;
21003   mp->transport_proto = proto;
21004   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21005   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21006   mp->lcl_plen = lcl_plen;
21007   mp->rmt_plen = rmt_plen;
21008   mp->action_index = clib_host_to_net_u32 (action);
21009   mp->appns_index = clib_host_to_net_u32 (appns_index);
21010   mp->scope = scope;
21011   mp->is_add = is_add;
21012   if (is_ip4)
21013     {
21014       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21015       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21016     }
21017   else
21018     {
21019       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21020       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21021     }
21022   if (tag)
21023     {
21024       clib_memcpy (mp->tag, tag, vec_len (tag));
21025       vec_free (tag);
21026     }
21027
21028   S (mp);
21029   W (ret);
21030   return ret;
21031 }
21032
21033 static int
21034 api_session_rules_dump (vat_main_t * vam)
21035 {
21036   vl_api_session_rules_dump_t *mp;
21037   vl_api_control_ping_t *mp_ping;
21038   int ret;
21039
21040   if (!vam->json_output)
21041     {
21042       print (vam->ofp, "%=20s", "Session Rules");
21043     }
21044
21045   M (SESSION_RULES_DUMP, mp);
21046   /* send it... */
21047   S (mp);
21048
21049   /* Use a control ping for synchronization */
21050   MPING (CONTROL_PING, mp_ping);
21051   S (mp_ping);
21052
21053   /* Wait for a reply... */
21054   W (ret);
21055   return ret;
21056 }
21057
21058 static int
21059 api_ip_container_proxy_add_del (vat_main_t * vam)
21060 {
21061   vl_api_ip_container_proxy_add_del_t *mp;
21062   unformat_input_t *i = vam->input;
21063   u32 sw_if_index = ~0;
21064   vl_api_prefix_t pfx = { };
21065   u8 is_add = 1;
21066   int ret;
21067
21068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21069     {
21070       if (unformat (i, "del"))
21071         is_add = 0;
21072       else if (unformat (i, "add"))
21073         ;
21074       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21075         ;
21076       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21077         ;
21078       else
21079         break;
21080     }
21081   if (sw_if_index == ~0 || pfx.len == 0)
21082     {
21083       errmsg ("address and sw_if_index must be set");
21084       return -99;
21085     }
21086
21087   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21088
21089   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21090   mp->is_add = is_add;
21091   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21092
21093   S (mp);
21094   W (ret);
21095   return ret;
21096 }
21097
21098 static int
21099 api_qos_record_enable_disable (vat_main_t * vam)
21100 {
21101   unformat_input_t *i = vam->input;
21102   vl_api_qos_record_enable_disable_t *mp;
21103   u32 sw_if_index, qs = 0xff;
21104   u8 sw_if_index_set = 0;
21105   u8 enable = 1;
21106   int ret;
21107
21108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21109     {
21110       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21111         sw_if_index_set = 1;
21112       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21113         sw_if_index_set = 1;
21114       else if (unformat (i, "%U", unformat_qos_source, &qs))
21115         ;
21116       else if (unformat (i, "disable"))
21117         enable = 0;
21118       else
21119         {
21120           clib_warning ("parse error '%U'", format_unformat_error, i);
21121           return -99;
21122         }
21123     }
21124
21125   if (sw_if_index_set == 0)
21126     {
21127       errmsg ("missing interface name or sw_if_index");
21128       return -99;
21129     }
21130   if (qs == 0xff)
21131     {
21132       errmsg ("input location must be specified");
21133       return -99;
21134     }
21135
21136   M (QOS_RECORD_ENABLE_DISABLE, mp);
21137
21138   mp->record.sw_if_index = ntohl (sw_if_index);
21139   mp->record.input_source = qs;
21140   mp->enable = enable;
21141
21142   S (mp);
21143   W (ret);
21144   return ret;
21145 }
21146
21147
21148 static int
21149 q_or_quit (vat_main_t * vam)
21150 {
21151 #if VPP_API_TEST_BUILTIN == 0
21152   longjmp (vam->jump_buf, 1);
21153 #endif
21154   return 0;                     /* not so much */
21155 }
21156
21157 static int
21158 q (vat_main_t * vam)
21159 {
21160   return q_or_quit (vam);
21161 }
21162
21163 static int
21164 quit (vat_main_t * vam)
21165 {
21166   return q_or_quit (vam);
21167 }
21168
21169 static int
21170 comment (vat_main_t * vam)
21171 {
21172   return 0;
21173 }
21174
21175 static int
21176 elog_save (vat_main_t * vam)
21177 {
21178 #if VPP_API_TEST_BUILTIN == 0
21179   elog_main_t *em = &vam->elog_main;
21180   unformat_input_t *i = vam->input;
21181   char *file, *chroot_file;
21182   clib_error_t *error;
21183
21184   if (!unformat (i, "%s", &file))
21185     {
21186       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21187       return 0;
21188     }
21189
21190   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21191   if (strstr (file, "..") || index (file, '/'))
21192     {
21193       errmsg ("illegal characters in filename '%s'", file);
21194       return 0;
21195     }
21196
21197   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21198
21199   vec_free (file);
21200
21201   errmsg ("Saving %wd of %wd events to %s",
21202           elog_n_events_in_buffer (em),
21203           elog_buffer_capacity (em), chroot_file);
21204
21205   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21206   vec_free (chroot_file);
21207
21208   if (error)
21209     clib_error_report (error);
21210 #else
21211   errmsg ("Use the vpp event loger...");
21212 #endif
21213
21214   return 0;
21215 }
21216
21217 static int
21218 elog_setup (vat_main_t * vam)
21219 {
21220 #if VPP_API_TEST_BUILTIN == 0
21221   elog_main_t *em = &vam->elog_main;
21222   unformat_input_t *i = vam->input;
21223   u32 nevents = 128 << 10;
21224
21225   (void) unformat (i, "nevents %d", &nevents);
21226
21227   elog_init (em, nevents);
21228   vl_api_set_elog_main (em);
21229   vl_api_set_elog_trace_api_messages (1);
21230   errmsg ("Event logger initialized with %u events", nevents);
21231 #else
21232   errmsg ("Use the vpp event loger...");
21233 #endif
21234   return 0;
21235 }
21236
21237 static int
21238 elog_enable (vat_main_t * vam)
21239 {
21240 #if VPP_API_TEST_BUILTIN == 0
21241   elog_main_t *em = &vam->elog_main;
21242
21243   elog_enable_disable (em, 1 /* enable */ );
21244   vl_api_set_elog_trace_api_messages (1);
21245   errmsg ("Event logger enabled...");
21246 #else
21247   errmsg ("Use the vpp event loger...");
21248 #endif
21249   return 0;
21250 }
21251
21252 static int
21253 elog_disable (vat_main_t * vam)
21254 {
21255 #if VPP_API_TEST_BUILTIN == 0
21256   elog_main_t *em = &vam->elog_main;
21257
21258   elog_enable_disable (em, 0 /* enable */ );
21259   vl_api_set_elog_trace_api_messages (1);
21260   errmsg ("Event logger disabled...");
21261 #else
21262   errmsg ("Use the vpp event loger...");
21263 #endif
21264   return 0;
21265 }
21266
21267 static int
21268 statseg (vat_main_t * vam)
21269 {
21270   ssvm_private_t *ssvmp = &vam->stat_segment;
21271   ssvm_shared_header_t *shared_header = ssvmp->sh;
21272   vlib_counter_t **counters;
21273   u64 thread0_index1_packets;
21274   u64 thread0_index1_bytes;
21275   f64 vector_rate, input_rate;
21276   uword *p;
21277
21278   uword *counter_vector_by_name;
21279   if (vam->stat_segment_lockp == 0)
21280     {
21281       errmsg ("Stat segment not mapped...");
21282       return -99;
21283     }
21284
21285   /* look up "/if/rx for sw_if_index 1 as a test */
21286
21287   clib_spinlock_lock (vam->stat_segment_lockp);
21288
21289   counter_vector_by_name = (uword *) shared_header->opaque[1];
21290
21291   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21292   if (p == 0)
21293     {
21294       clib_spinlock_unlock (vam->stat_segment_lockp);
21295       errmsg ("/if/tx not found?");
21296       return -99;
21297     }
21298
21299   /* Fish per-thread vector of combined counters from shared memory */
21300   counters = (vlib_counter_t **) p[0];
21301
21302   if (vec_len (counters[0]) < 2)
21303     {
21304       clib_spinlock_unlock (vam->stat_segment_lockp);
21305       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21306       return -99;
21307     }
21308
21309   /* Read thread 0 sw_if_index 1 counter */
21310   thread0_index1_packets = counters[0][1].packets;
21311   thread0_index1_bytes = counters[0][1].bytes;
21312
21313   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21314   if (p == 0)
21315     {
21316       clib_spinlock_unlock (vam->stat_segment_lockp);
21317       errmsg ("vector_rate not found?");
21318       return -99;
21319     }
21320
21321   vector_rate = *(f64 *) (p[0]);
21322   p = hash_get_mem (counter_vector_by_name, "input_rate");
21323   if (p == 0)
21324     {
21325       clib_spinlock_unlock (vam->stat_segment_lockp);
21326       errmsg ("input_rate not found?");
21327       return -99;
21328     }
21329   input_rate = *(f64 *) (p[0]);
21330
21331   clib_spinlock_unlock (vam->stat_segment_lockp);
21332
21333   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21334          vector_rate, input_rate);
21335   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21336          thread0_index1_packets, thread0_index1_bytes);
21337
21338   return 0;
21339 }
21340
21341 static int
21342 cmd_cmp (void *a1, void *a2)
21343 {
21344   u8 **c1 = a1;
21345   u8 **c2 = a2;
21346
21347   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21348 }
21349
21350 static int
21351 help (vat_main_t * vam)
21352 {
21353   u8 **cmds = 0;
21354   u8 *name = 0;
21355   hash_pair_t *p;
21356   unformat_input_t *i = vam->input;
21357   int j;
21358
21359   if (unformat (i, "%s", &name))
21360     {
21361       uword *hs;
21362
21363       vec_add1 (name, 0);
21364
21365       hs = hash_get_mem (vam->help_by_name, name);
21366       if (hs)
21367         print (vam->ofp, "usage: %s %s", name, hs[0]);
21368       else
21369         print (vam->ofp, "No such msg / command '%s'", name);
21370       vec_free (name);
21371       return 0;
21372     }
21373
21374   print (vam->ofp, "Help is available for the following:");
21375
21376     /* *INDENT-OFF* */
21377     hash_foreach_pair (p, vam->function_by_name,
21378     ({
21379       vec_add1 (cmds, (u8 *)(p->key));
21380     }));
21381     /* *INDENT-ON* */
21382
21383   vec_sort_with_function (cmds, cmd_cmp);
21384
21385   for (j = 0; j < vec_len (cmds); j++)
21386     print (vam->ofp, "%s", cmds[j]);
21387
21388   vec_free (cmds);
21389   return 0;
21390 }
21391
21392 static int
21393 set (vat_main_t * vam)
21394 {
21395   u8 *name = 0, *value = 0;
21396   unformat_input_t *i = vam->input;
21397
21398   if (unformat (i, "%s", &name))
21399     {
21400       /* The input buffer is a vector, not a string. */
21401       value = vec_dup (i->buffer);
21402       vec_delete (value, i->index, 0);
21403       /* Almost certainly has a trailing newline */
21404       if (value[vec_len (value) - 1] == '\n')
21405         value[vec_len (value) - 1] = 0;
21406       /* Make sure it's a proper string, one way or the other */
21407       vec_add1 (value, 0);
21408       (void) clib_macro_set_value (&vam->macro_main,
21409                                    (char *) name, (char *) value);
21410     }
21411   else
21412     errmsg ("usage: set <name> <value>");
21413
21414   vec_free (name);
21415   vec_free (value);
21416   return 0;
21417 }
21418
21419 static int
21420 unset (vat_main_t * vam)
21421 {
21422   u8 *name = 0;
21423
21424   if (unformat (vam->input, "%s", &name))
21425     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21426       errmsg ("unset: %s wasn't set", name);
21427   vec_free (name);
21428   return 0;
21429 }
21430
21431 typedef struct
21432 {
21433   u8 *name;
21434   u8 *value;
21435 } macro_sort_t;
21436
21437
21438 static int
21439 macro_sort_cmp (void *a1, void *a2)
21440 {
21441   macro_sort_t *s1 = a1;
21442   macro_sort_t *s2 = a2;
21443
21444   return strcmp ((char *) (s1->name), (char *) (s2->name));
21445 }
21446
21447 static int
21448 dump_macro_table (vat_main_t * vam)
21449 {
21450   macro_sort_t *sort_me = 0, *sm;
21451   int i;
21452   hash_pair_t *p;
21453
21454     /* *INDENT-OFF* */
21455     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21456     ({
21457       vec_add2 (sort_me, sm, 1);
21458       sm->name = (u8 *)(p->key);
21459       sm->value = (u8 *) (p->value[0]);
21460     }));
21461     /* *INDENT-ON* */
21462
21463   vec_sort_with_function (sort_me, macro_sort_cmp);
21464
21465   if (vec_len (sort_me))
21466     print (vam->ofp, "%-15s%s", "Name", "Value");
21467   else
21468     print (vam->ofp, "The macro table is empty...");
21469
21470   for (i = 0; i < vec_len (sort_me); i++)
21471     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21472   return 0;
21473 }
21474
21475 static int
21476 dump_node_table (vat_main_t * vam)
21477 {
21478   int i, j;
21479   vlib_node_t *node, *next_node;
21480
21481   if (vec_len (vam->graph_nodes) == 0)
21482     {
21483       print (vam->ofp, "Node table empty, issue get_node_graph...");
21484       return 0;
21485     }
21486
21487   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21488     {
21489       node = vam->graph_nodes[0][i];
21490       print (vam->ofp, "[%d] %s", i, node->name);
21491       for (j = 0; j < vec_len (node->next_nodes); j++)
21492         {
21493           if (node->next_nodes[j] != ~0)
21494             {
21495               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21496               print (vam->ofp, "  [%d] %s", j, next_node->name);
21497             }
21498         }
21499     }
21500   return 0;
21501 }
21502
21503 static int
21504 value_sort_cmp (void *a1, void *a2)
21505 {
21506   name_sort_t *n1 = a1;
21507   name_sort_t *n2 = a2;
21508
21509   if (n1->value < n2->value)
21510     return -1;
21511   if (n1->value > n2->value)
21512     return 1;
21513   return 0;
21514 }
21515
21516
21517 static int
21518 dump_msg_api_table (vat_main_t * vam)
21519 {
21520   api_main_t *am = &api_main;
21521   name_sort_t *nses = 0, *ns;
21522   hash_pair_t *hp;
21523   int i;
21524
21525   /* *INDENT-OFF* */
21526   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21527   ({
21528     vec_add2 (nses, ns, 1);
21529     ns->name = (u8 *)(hp->key);
21530     ns->value = (u32) hp->value[0];
21531   }));
21532   /* *INDENT-ON* */
21533
21534   vec_sort_with_function (nses, value_sort_cmp);
21535
21536   for (i = 0; i < vec_len (nses); i++)
21537     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21538   vec_free (nses);
21539   return 0;
21540 }
21541
21542 static int
21543 get_msg_id (vat_main_t * vam)
21544 {
21545   u8 *name_and_crc;
21546   u32 message_index;
21547
21548   if (unformat (vam->input, "%s", &name_and_crc))
21549     {
21550       message_index = vl_msg_api_get_msg_index (name_and_crc);
21551       if (message_index == ~0)
21552         {
21553           print (vam->ofp, " '%s' not found", name_and_crc);
21554           return 0;
21555         }
21556       print (vam->ofp, " '%s' has message index %d",
21557              name_and_crc, message_index);
21558       return 0;
21559     }
21560   errmsg ("name_and_crc required...");
21561   return 0;
21562 }
21563
21564 static int
21565 search_node_table (vat_main_t * vam)
21566 {
21567   unformat_input_t *line_input = vam->input;
21568   u8 *node_to_find;
21569   int j;
21570   vlib_node_t *node, *next_node;
21571   uword *p;
21572
21573   if (vam->graph_node_index_by_name == 0)
21574     {
21575       print (vam->ofp, "Node table empty, issue get_node_graph...");
21576       return 0;
21577     }
21578
21579   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21580     {
21581       if (unformat (line_input, "%s", &node_to_find))
21582         {
21583           vec_add1 (node_to_find, 0);
21584           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21585           if (p == 0)
21586             {
21587               print (vam->ofp, "%s not found...", node_to_find);
21588               goto out;
21589             }
21590           node = vam->graph_nodes[0][p[0]];
21591           print (vam->ofp, "[%d] %s", p[0], node->name);
21592           for (j = 0; j < vec_len (node->next_nodes); j++)
21593             {
21594               if (node->next_nodes[j] != ~0)
21595                 {
21596                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21597                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21598                 }
21599             }
21600         }
21601
21602       else
21603         {
21604           clib_warning ("parse error '%U'", format_unformat_error,
21605                         line_input);
21606           return -99;
21607         }
21608
21609     out:
21610       vec_free (node_to_find);
21611
21612     }
21613
21614   return 0;
21615 }
21616
21617
21618 static int
21619 script (vat_main_t * vam)
21620 {
21621 #if (VPP_API_TEST_BUILTIN==0)
21622   u8 *s = 0;
21623   char *save_current_file;
21624   unformat_input_t save_input;
21625   jmp_buf save_jump_buf;
21626   u32 save_line_number;
21627
21628   FILE *new_fp, *save_ifp;
21629
21630   if (unformat (vam->input, "%s", &s))
21631     {
21632       new_fp = fopen ((char *) s, "r");
21633       if (new_fp == 0)
21634         {
21635           errmsg ("Couldn't open script file %s", s);
21636           vec_free (s);
21637           return -99;
21638         }
21639     }
21640   else
21641     {
21642       errmsg ("Missing script name");
21643       return -99;
21644     }
21645
21646   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21647   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21648   save_ifp = vam->ifp;
21649   save_line_number = vam->input_line_number;
21650   save_current_file = (char *) vam->current_file;
21651
21652   vam->input_line_number = 0;
21653   vam->ifp = new_fp;
21654   vam->current_file = s;
21655   do_one_file (vam);
21656
21657   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21658   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21659   vam->ifp = save_ifp;
21660   vam->input_line_number = save_line_number;
21661   vam->current_file = (u8 *) save_current_file;
21662   vec_free (s);
21663
21664   return 0;
21665 #else
21666   clib_warning ("use the exec command...");
21667   return -99;
21668 #endif
21669 }
21670
21671 static int
21672 echo (vat_main_t * vam)
21673 {
21674   print (vam->ofp, "%v", vam->input->buffer);
21675   return 0;
21676 }
21677
21678 /* List of API message constructors, CLI names map to api_xxx */
21679 #define foreach_vpe_api_msg                                             \
21680 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21681 _(sw_interface_dump,"")                                                 \
21682 _(sw_interface_set_flags,                                               \
21683   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21684 _(sw_interface_add_del_address,                                         \
21685   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21686 _(sw_interface_set_rx_mode,                                             \
21687   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21688 _(sw_interface_set_rx_placement,                                        \
21689   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21690 _(sw_interface_rx_placement_dump,                                       \
21691   "[<intfc> | sw_if_index <id>]")                                         \
21692 _(sw_interface_set_table,                                               \
21693   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21694 _(sw_interface_set_mpls_enable,                                         \
21695   "<intfc> | sw_if_index [disable | dis]")                              \
21696 _(sw_interface_set_vpath,                                               \
21697   "<intfc> | sw_if_index <id> enable | disable")                        \
21698 _(sw_interface_set_vxlan_bypass,                                        \
21699   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21700 _(sw_interface_set_geneve_bypass,                                       \
21701   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21702 _(sw_interface_set_l2_xconnect,                                         \
21703   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21704   "enable | disable")                                                   \
21705 _(sw_interface_set_l2_bridge,                                           \
21706   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21707   "[shg <split-horizon-group>] [bvi]\n"                                 \
21708   "enable | disable")                                                   \
21709 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21710 _(bridge_domain_add_del,                                                \
21711   "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") \
21712 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21713 _(l2fib_add_del,                                                        \
21714   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21715 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21716 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21717 _(l2_flags,                                                             \
21718   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21719 _(bridge_flags,                                                         \
21720   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21721 _(tap_create_v2,                                                        \
21722   "id <num> [hw-addr <mac-addr>] [rx-ring-size <num>] [tx-ring-size <num>] [host-if-name <name>] [host-mac-addr <host-mac-address>] [host-ns <name>] [host-bridge <bridge-name>] [host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6-addr>] [host-ip4-gw <ip4-addr>] [host-ip6-gw <ip6-addr>] [host-mtu-size <mtu>] [gso | no-gso]") \
21723 _(tap_delete_v2,                                                        \
21724   "<vpp-if-name> | sw_if_index <id>")                                   \
21725 _(sw_interface_tap_v2_dump, "")                                         \
21726 _(virtio_pci_create,                                                    \
21727   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21728 _(virtio_pci_delete,                                                    \
21729   "<vpp-if-name> | sw_if_index <id>")                                   \
21730 _(sw_interface_virtio_pci_dump, "")                                     \
21731 _(bond_create,                                                          \
21732   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21733   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21734   "[id <if-id>]")                                                       \
21735 _(bond_delete,                                                          \
21736   "<vpp-if-name> | sw_if_index <id>")                                   \
21737 _(bond_enslave,                                                         \
21738   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21739 _(bond_detach_slave,                                                    \
21740   "sw_if_index <n>")                                                    \
21741 _(sw_interface_bond_dump, "")                                           \
21742 _(sw_interface_slave_dump,                                              \
21743   "<vpp-if-name> | sw_if_index <id>")                                   \
21744 _(ip_table_add_del,                                                     \
21745   "table <n> [ipv6] [add | del]\n")                                     \
21746 _(ip_route_add_del,                                                     \
21747   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21748   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21749   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21750   "[multipath] [count <n>] [del]")                                      \
21751 _(ip_mroute_add_del,                                                    \
21752   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21753   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21754 _(mpls_table_add_del,                                                   \
21755   "table <n> [add | del]\n")                                            \
21756 _(mpls_route_add_del,                                                   \
21757   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21758   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21759   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21760   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21761   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21762   "[count <n>] [del]")                                                  \
21763 _(mpls_ip_bind_unbind,                                                  \
21764   "<label> <addr/len>")                                                 \
21765 _(mpls_tunnel_add_del,                                                  \
21766   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21767   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21768   "[l2-only]  [out-label <n>]")                                         \
21769 _(sr_mpls_policy_add,                                                   \
21770   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21771 _(sr_mpls_policy_del,                                                   \
21772   "bsid <id>")                                                          \
21773 _(bier_table_add_del,                                                   \
21774   "<label> <sub-domain> <set> <bsl> [del]")                             \
21775 _(bier_route_add_del,                                                   \
21776   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21777   "[<intfc> | sw_if_index <id>]"                                        \
21778   "[weight <n>] [del] [multipath]")                                     \
21779 _(proxy_arp_add_del,                                                    \
21780   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21781 _(proxy_arp_intfc_enable_disable,                                       \
21782   "<intfc> | sw_if_index <id> enable | disable")                        \
21783 _(sw_interface_set_unnumbered,                                          \
21784   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21785 _(ip_neighbor_add_del,                                                  \
21786   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21787   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21788 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21789 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21790   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21791   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21792   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21793 _(reset_fib, "vrf <n> [ipv6]")                                          \
21794 _(dhcp_proxy_config,                                                    \
21795   "svr <v46-address> src <v46-address>\n"                               \
21796    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21797 _(dhcp_proxy_set_vss,                                                   \
21798   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21799 _(dhcp_proxy_dump, "ip6")                                               \
21800 _(dhcp_client_config,                                                   \
21801   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21802 _(set_ip_flow_hash,                                                     \
21803   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21804 _(sw_interface_ip6_enable_disable,                                      \
21805   "<intfc> | sw_if_index <id> enable | disable")                        \
21806 _(ip6nd_proxy_add_del,                                                  \
21807   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21808 _(ip6nd_proxy_dump, "")                                                 \
21809 _(sw_interface_ip6nd_ra_prefix,                                         \
21810   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21811   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21812   "[nolink] [isno]")                                                    \
21813 _(sw_interface_ip6nd_ra_config,                                         \
21814   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21815   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21816   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21817 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21818 _(l2_patch_add_del,                                                     \
21819   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21820   "enable | disable")                                                   \
21821 _(sr_localsid_add_del,                                                  \
21822   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21823   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21824 _(classify_add_del_table,                                               \
21825   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21826   " [del] [del-chain] mask <mask-value>\n"                              \
21827   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21828   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21829 _(classify_add_del_session,                                             \
21830   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21831   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21832   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21833   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21834 _(classify_set_interface_ip_table,                                      \
21835   "<intfc> | sw_if_index <nn> table <nn>")                              \
21836 _(classify_set_interface_l2_tables,                                     \
21837   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21838   "  [other-table <nn>]")                                               \
21839 _(get_node_index, "node <node-name")                                    \
21840 _(add_node_next, "node <node-name> next <next-node-name>")              \
21841 _(l2tpv3_create_tunnel,                                                 \
21842   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21843   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21844   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21845 _(l2tpv3_set_tunnel_cookies,                                            \
21846   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21847   "[new_remote_cookie <nn>]\n")                                         \
21848 _(l2tpv3_interface_enable_disable,                                      \
21849   "<intfc> | sw_if_index <nn> enable | disable")                        \
21850 _(l2tpv3_set_lookup_key,                                                \
21851   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21852 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21853 _(vxlan_offload_rx,                                                     \
21854   "hw { <interface name> | hw_if_index <nn>} "                          \
21855   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21856 _(vxlan_add_del_tunnel,                                                 \
21857   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21858   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21859   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21860 _(geneve_add_del_tunnel,                                                \
21861   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21862   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21863   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21864 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21865 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21866 _(gre_tunnel_add_del,                                                   \
21867   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21868   "[teb | erspan <session-id>] [del]")                                  \
21869 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21870 _(l2_fib_clear_table, "")                                               \
21871 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21872 _(l2_interface_vlan_tag_rewrite,                                        \
21873   "<intfc> | sw_if_index <nn> \n"                                       \
21874   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21875   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21876 _(create_vhost_user_if,                                                 \
21877         "socket <filename> [server] [renumber <dev_instance>] "         \
21878         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21879         "[mac <mac_address>]")                                          \
21880 _(modify_vhost_user_if,                                                 \
21881         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21882         "[server] [renumber <dev_instance>] [gso]")                     \
21883 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21884 _(sw_interface_vhost_user_dump, "")                                     \
21885 _(show_version, "")                                                     \
21886 _(show_threads, "")                                                     \
21887 _(vxlan_gpe_add_del_tunnel,                                             \
21888   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21889   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21890   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21891   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21892 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21893 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21894 _(interface_name_renumber,                                              \
21895   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21896 _(input_acl_set_interface,                                              \
21897   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21898   "  [l2-table <nn>] [del]")                                            \
21899 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21900 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21901   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21902 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21903 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21904 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21905 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21906 _(ip_dump, "ipv4 | ipv6")                                               \
21907 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21908 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21909   "  spid_id <n> ")                                                     \
21910 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21911   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21912   "  integ_alg <alg> integ_key <hex>")                                  \
21913 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21914   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21915   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21916   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21917 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21918   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21919   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21920   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21921   "  [instance <n>]")     \
21922 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21923 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21924 _(delete_loopback,"sw_if_index <nn>")                                   \
21925 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21926 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21927 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21928 _(want_interface_events,  "enable|disable")                             \
21929 _(get_first_msg_id, "client <name>")                                    \
21930 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21931 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21932   "fib-id <nn> [ip4][ip6][default]")                                    \
21933 _(get_node_graph, " ")                                                  \
21934 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21935 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21936 _(ioam_disable, "")                                                     \
21937 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21938                             " sw_if_index <sw_if_index> p <priority> "  \
21939                             "w <weight>] [del]")                        \
21940 _(one_add_del_locator, "locator-set <locator_name> "                    \
21941                         "iface <intf> | sw_if_index <sw_if_index> "     \
21942                         "p <priority> w <weight> [del]")                \
21943 _(one_add_del_local_eid,"vni <vni> eid "                                \
21944                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21945                          "locator-set <locator_name> [del]"             \
21946                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21947 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21948 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21949 _(one_enable_disable, "enable|disable")                                 \
21950 _(one_map_register_enable_disable, "enable|disable")                    \
21951 _(one_map_register_fallback_threshold, "<value>")                       \
21952 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21953 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21954                                "[seid <seid>] "                         \
21955                                "rloc <locator> p <prio> "               \
21956                                "w <weight> [rloc <loc> ... ] "          \
21957                                "action <action> [del-all]")             \
21958 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21959                           "<local-eid>")                                \
21960 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21961 _(one_use_petr, "ip-address> | disable")                                \
21962 _(one_map_request_mode, "src-dst|dst-only")                             \
21963 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21964 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21965 _(one_locator_set_dump, "[local | remote]")                             \
21966 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21967 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21968                        "[local] | [remote]")                            \
21969 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21970 _(one_ndp_bd_get, "")                                                   \
21971 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21972 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21973 _(one_l2_arp_bd_get, "")                                                \
21974 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21975 _(one_stats_enable_disable, "enable|disable")                           \
21976 _(show_one_stats_enable_disable, "")                                    \
21977 _(one_eid_table_vni_dump, "")                                           \
21978 _(one_eid_table_map_dump, "l2|l3")                                      \
21979 _(one_map_resolver_dump, "")                                            \
21980 _(one_map_server_dump, "")                                              \
21981 _(one_adjacencies_get, "vni <vni>")                                     \
21982 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21983 _(show_one_rloc_probe_state, "")                                        \
21984 _(show_one_map_register_state, "")                                      \
21985 _(show_one_status, "")                                                  \
21986 _(one_stats_dump, "")                                                   \
21987 _(one_stats_flush, "")                                                  \
21988 _(one_get_map_request_itr_rlocs, "")                                    \
21989 _(one_map_register_set_ttl, "<ttl>")                                    \
21990 _(one_set_transport_protocol, "udp|api")                                \
21991 _(one_get_transport_protocol, "")                                       \
21992 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21993 _(one_show_xtr_mode, "")                                                \
21994 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21995 _(one_show_pitr_mode, "")                                               \
21996 _(one_enable_disable_petr_mode, "enable|disable")                       \
21997 _(one_show_petr_mode, "")                                               \
21998 _(show_one_nsh_mapping, "")                                             \
21999 _(show_one_pitr, "")                                                    \
22000 _(show_one_use_petr, "")                                                \
22001 _(show_one_map_request_mode, "")                                        \
22002 _(show_one_map_register_ttl, "")                                        \
22003 _(show_one_map_register_fallback_threshold, "")                         \
22004 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22005                             " sw_if_index <sw_if_index> p <priority> "  \
22006                             "w <weight>] [del]")                        \
22007 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22008                         "iface <intf> | sw_if_index <sw_if_index> "     \
22009                         "p <priority> w <weight> [del]")                \
22010 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22011                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22012                          "locator-set <locator_name> [del]"             \
22013                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22014 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22015 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22016 _(lisp_enable_disable, "enable|disable")                                \
22017 _(lisp_map_register_enable_disable, "enable|disable")                   \
22018 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22019 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22020                                "[seid <seid>] "                         \
22021                                "rloc <locator> p <prio> "               \
22022                                "w <weight> [rloc <loc> ... ] "          \
22023                                "action <action> [del-all]")             \
22024 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22025                           "<local-eid>")                                \
22026 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22027 _(lisp_use_petr, "<ip-address> | disable")                              \
22028 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22029 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22030 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22031 _(lisp_locator_set_dump, "[local | remote]")                            \
22032 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22033 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22034                        "[local] | [remote]")                            \
22035 _(lisp_eid_table_vni_dump, "")                                          \
22036 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22037 _(lisp_map_resolver_dump, "")                                           \
22038 _(lisp_map_server_dump, "")                                             \
22039 _(lisp_adjacencies_get, "vni <vni>")                                    \
22040 _(gpe_fwd_entry_vnis_get, "")                                           \
22041 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22042 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22043                                 "[table <table-id>]")                   \
22044 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22045 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22046 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22047 _(gpe_get_encap_mode, "")                                               \
22048 _(lisp_gpe_add_del_iface, "up|down")                                    \
22049 _(lisp_gpe_enable_disable, "enable|disable")                            \
22050 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22051   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22052 _(show_lisp_rloc_probe_state, "")                                       \
22053 _(show_lisp_map_register_state, "")                                     \
22054 _(show_lisp_status, "")                                                 \
22055 _(lisp_get_map_request_itr_rlocs, "")                                   \
22056 _(show_lisp_pitr, "")                                                   \
22057 _(show_lisp_use_petr, "")                                               \
22058 _(show_lisp_map_request_mode, "")                                       \
22059 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22060 _(af_packet_delete, "name <host interface name>")                       \
22061 _(af_packet_dump, "")                                                   \
22062 _(policer_add_del, "name <policer name> <params> [del]")                \
22063 _(policer_dump, "[name <policer name>]")                                \
22064 _(policer_classify_set_interface,                                       \
22065   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22066   "  [l2-table <nn>] [del]")                                            \
22067 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22068 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22069     "[master|slave]")                                                   \
22070 _(netmap_delete, "name <interface name>")                               \
22071 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22072 _(mpls_table_dump, "")                                                  \
22073 _(mpls_route_dump, "table-id <ID>")                                     \
22074 _(classify_table_ids, "")                                               \
22075 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22076 _(classify_table_info, "table_id <nn>")                                 \
22077 _(classify_session_dump, "table_id <nn>")                               \
22078 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22079     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22080     "[template_interval <nn>] [udp_checksum]")                          \
22081 _(ipfix_exporter_dump, "")                                              \
22082 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22083 _(ipfix_classify_stream_dump, "")                                       \
22084 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22085 _(ipfix_classify_table_dump, "")                                        \
22086 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22087 _(sw_interface_span_dump, "[l2]")                                           \
22088 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22089 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22090 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22091 _(pg_enable_disable, "[stream <id>] disable")                           \
22092 _(ip_source_and_port_range_check_add_del,                               \
22093   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22094 _(ip_source_and_port_range_check_interface_add_del,                     \
22095   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22096   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22097 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22098 _(l2_interface_pbb_tag_rewrite,                                         \
22099   "<intfc> | sw_if_index <nn> \n"                                       \
22100   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22101   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22102 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22103 _(flow_classify_set_interface,                                          \
22104   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22105 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22106 _(ip_table_dump, "")                                                    \
22107 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22108 _(ip_mtable_dump, "")                                                   \
22109 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22110 _(feature_enable_disable, "arc_name <arc_name> "                        \
22111   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22112 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22113 "[disable]")                                                            \
22114 _(l2_xconnect_dump, "")                                                 \
22115 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22116 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22117 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22118 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22119 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22120 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22121 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22122   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22123 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22124 _(sock_init_shm, "size <nnn>")                                          \
22125 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22126 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22127   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22128 _(session_rules_dump, "")                                               \
22129 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22130 _(output_acl_set_interface,                                             \
22131   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22132   "  [l2-table <nn>] [del]")                                            \
22133 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22134
22135 /* List of command functions, CLI names map directly to functions */
22136 #define foreach_cli_function                                    \
22137 _(comment, "usage: comment <ignore-rest-of-line>")              \
22138 _(dump_interface_table, "usage: dump_interface_table")          \
22139 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22140 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22141 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22142 _(dump_macro_table, "usage: dump_macro_table ")                 \
22143 _(dump_node_table, "usage: dump_node_table")                    \
22144 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22145 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22146 _(elog_disable, "usage: elog_disable")                          \
22147 _(elog_enable, "usage: elog_enable")                            \
22148 _(elog_save, "usage: elog_save <filename>")                     \
22149 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22150 _(echo, "usage: echo <message>")                                \
22151 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22152 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22153 _(help, "usage: help")                                          \
22154 _(q, "usage: quit")                                             \
22155 _(quit, "usage: quit")                                          \
22156 _(search_node_table, "usage: search_node_table <name>...")      \
22157 _(set, "usage: set <variable-name> <value>")                    \
22158 _(script, "usage: script <file-name>")                          \
22159 _(statseg, "usage: statseg")                                    \
22160 _(unset, "usage: unset <variable-name>")
22161
22162 #define _(N,n)                                  \
22163     static void vl_api_##n##_t_handler_uni      \
22164     (vl_api_##n##_t * mp)                       \
22165     {                                           \
22166         vat_main_t * vam = &vat_main;           \
22167         if (vam->json_output) {                 \
22168             vl_api_##n##_t_handler_json(mp);    \
22169         } else {                                \
22170             vl_api_##n##_t_handler(mp);         \
22171         }                                       \
22172     }
22173 foreach_vpe_api_reply_msg;
22174 #if VPP_API_TEST_BUILTIN == 0
22175 foreach_standalone_reply_msg;
22176 #endif
22177 #undef _
22178
22179 void
22180 vat_api_hookup (vat_main_t * vam)
22181 {
22182 #define _(N,n)                                                  \
22183     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22184                            vl_api_##n##_t_handler_uni,          \
22185                            vl_noop_handler,                     \
22186                            vl_api_##n##_t_endian,               \
22187                            vl_api_##n##_t_print,                \
22188                            sizeof(vl_api_##n##_t), 1);
22189   foreach_vpe_api_reply_msg;
22190 #if VPP_API_TEST_BUILTIN == 0
22191   foreach_standalone_reply_msg;
22192 #endif
22193 #undef _
22194
22195 #if (VPP_API_TEST_BUILTIN==0)
22196   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22197
22198   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22199
22200   vam->function_by_name = hash_create_string (0, sizeof (uword));
22201
22202   vam->help_by_name = hash_create_string (0, sizeof (uword));
22203 #endif
22204
22205   /* API messages we can send */
22206 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22207   foreach_vpe_api_msg;
22208 #undef _
22209
22210   /* Help strings */
22211 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22212   foreach_vpe_api_msg;
22213 #undef _
22214
22215   /* CLI functions */
22216 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22217   foreach_cli_function;
22218 #undef _
22219
22220   /* Help strings */
22221 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22222   foreach_cli_function;
22223 #undef _
22224 }
22225
22226 #if VPP_API_TEST_BUILTIN
22227 static clib_error_t *
22228 vat_api_hookup_shim (vlib_main_t * vm)
22229 {
22230   vat_api_hookup (&vat_main);
22231   return 0;
22232 }
22233
22234 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22235 #endif
22236
22237 /*
22238  * fd.io coding-style-patch-verification: ON
22239  *
22240  * Local Variables:
22241  * eval: (c-set-style "gnu")
22242  * End:
22243  */