build: fix running error with vmxnet3_test_plugin.so
[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->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
997
998       sub->sub_number_of_tags = mp->sub_number_of_tags;
999       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1000       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1001
1002       /* vlan tag rewrite */
1003       sub->vtr_op = ntohl (mp->vtr_op);
1004       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1005       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1006       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1007     }
1008 }
1009
1010 static void vl_api_sw_interface_details_t_handler_json
1011   (vl_api_sw_interface_details_t * mp)
1012 {
1013   vat_main_t *vam = &vat_main;
1014   vat_json_node_t *node = NULL;
1015
1016   if (VAT_JSON_ARRAY != vam->json_tree.type)
1017     {
1018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1019       vat_json_init_array (&vam->json_tree);
1020     }
1021   node = vat_json_array_add (&vam->json_tree);
1022
1023   vat_json_init_object (node);
1024   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1025   vat_json_object_add_uint (node, "sup_sw_if_index",
1026                             ntohl (mp->sup_sw_if_index));
1027   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1028                              sizeof (mp->l2_address));
1029   vat_json_object_add_string_copy (node, "interface_name",
1030                                    mp->interface_name);
1031   vat_json_object_add_uint (node, "flags", mp->flags);
1032   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1033   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1034   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1035   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1036   vat_json_object_add_uint (node, "sub_number_of_tags",
1037                             mp->sub_number_of_tags);
1038   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1039                             ntohs (mp->sub_outer_vlan_id));
1040   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1041                             ntohs (mp->sub_inner_vlan_id));
1042   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1043   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1044   vat_json_object_add_uint (node, "vtr_push_dot1q",
1045                             ntohl (mp->vtr_push_dot1q));
1046   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1047   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1048   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1049     {
1050       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1051                                        format (0, "%U",
1052                                                format_ethernet_address,
1053                                                &mp->b_dmac));
1054       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1055                                        format (0, "%U",
1056                                                format_ethernet_address,
1057                                                &mp->b_smac));
1058       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1059       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1060     }
1061 }
1062
1063 #if VPP_API_TEST_BUILTIN == 0
1064 static void vl_api_sw_interface_event_t_handler
1065   (vl_api_sw_interface_event_t * mp)
1066 {
1067   vat_main_t *vam = &vat_main;
1068   if (vam->interface_event_display)
1069     errmsg ("interface flags: sw_if_index %d %s %s",
1070             ntohl (mp->sw_if_index),
1071             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1072             "admin-up" : "admin-down",
1073             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1074             "link-up" : "link-down");
1075 }
1076 #endif
1077
1078 __clib_unused static void
1079 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1080 {
1081   /* JSON output not supported */
1082 }
1083
1084 static void
1085 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   vam->retval = retval;
1091   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   vat_json_node_t node;
1100   api_main_t *am = &api_main;
1101   void *oldheap;
1102   u8 *reply;
1103
1104   vat_json_init_object (&node);
1105   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1106   vat_json_object_add_uint (&node, "reply_in_shmem",
1107                             ntohl (mp->reply_in_shmem));
1108   /* Toss the shared-memory original... */
1109   pthread_mutex_lock (&am->vlib_rp->mutex);
1110   oldheap = svm_push_data_heap (am->vlib_rp);
1111
1112   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1113   vec_free (reply);
1114
1115   svm_pop_heap (oldheap);
1116   pthread_mutex_unlock (&am->vlib_rp->mutex);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       errmsg ("        program: %s", mp->program);
1328       errmsg ("        version: %s", mp->version);
1329       errmsg ("     build date: %s", mp->build_date);
1330       errmsg ("build directory: %s", mp->build_directory);
1331     }
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_show_version_reply_t_handler_json
1337   (vl_api_show_version_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_string_copy (&node, "program", mp->program);
1345   vat_json_object_add_string_copy (&node, "version", mp->version);
1346   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    mp->build_directory);
1349
1350   vat_json_print (vam->ofp, &node);
1351   vat_json_free (&node);
1352
1353   vam->retval = ntohl (mp->retval);
1354   vam->result_ready = 1;
1355 }
1356
1357 static void vl_api_show_threads_reply_t_handler
1358   (vl_api_show_threads_reply_t * mp)
1359 {
1360   vat_main_t *vam = &vat_main;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   for (i = 0; i < count; i++)
1368     print (vam->ofp,
1369            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1370            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1371            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1372            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1373            ntohl (mp->thread_data[i].cpu_socket));
1374
1375   vam->retval = retval;
1376   vam->result_ready = 1;
1377 }
1378
1379 static void vl_api_show_threads_reply_t_handler_json
1380   (vl_api_show_threads_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   vat_json_node_t node;
1384   vl_api_thread_data_t *td;
1385   i32 retval = ntohl (mp->retval);
1386   int i, count = 0;
1387
1388   if (retval >= 0)
1389     count = ntohl (mp->count);
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", retval);
1393   vat_json_object_add_uint (&node, "count", count);
1394
1395   for (i = 0; i < count; i++)
1396     {
1397       td = &mp->thread_data[i];
1398       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1399       vat_json_object_add_string_copy (&node, "name", td->name);
1400       vat_json_object_add_string_copy (&node, "type", td->type);
1401       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1402       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1403       vat_json_object_add_int (&node, "core", ntohl (td->id));
1404       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1405     }
1406
1407   vat_json_print (vam->ofp, &node);
1408   vat_json_free (&node);
1409
1410   vam->retval = retval;
1411   vam->result_ready = 1;
1412 }
1413
1414 static int
1415 api_show_threads (vat_main_t * vam)
1416 {
1417   vl_api_show_threads_t *mp;
1418   int ret;
1419
1420   print (vam->ofp,
1421          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1422          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1423
1424   M (SHOW_THREADS, mp);
1425
1426   S (mp);
1427   W (ret);
1428   return ret;
1429 }
1430
1431 static void
1432 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1433 {
1434   u32 sw_if_index = ntohl (mp->sw_if_index);
1435   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1436           mp->mac_ip ? "mac/ip binding" : "address resolution",
1437           ntohl (mp->pid), format_ip4_address, mp->ip,
1438           format_vl_api_mac_address, &mp->mac, sw_if_index);
1439 }
1440
1441 static void
1442 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1443 {
1444   /* JSON output not supported */
1445 }
1446
1447 static void
1448 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1449 {
1450   u32 sw_if_index = ntohl (mp->sw_if_index);
1451   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1452           mp->mac_ip ? "mac/ip binding" : "address resolution",
1453           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1454           format_vl_api_mac_address, mp->mac, sw_if_index);
1455 }
1456
1457 static void
1458 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1459 {
1460   /* JSON output not supported */
1461 }
1462
1463 static void
1464 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1465 {
1466   u32 n_macs = ntohl (mp->n_macs);
1467   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1468           ntohl (mp->pid), mp->client_index, n_macs);
1469   int i;
1470   for (i = 0; i < n_macs; i++)
1471     {
1472       vl_api_mac_entry_t *mac = &mp->mac[i];
1473       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1474               i + 1, ntohl (mac->sw_if_index),
1475               format_ethernet_address, mac->mac_addr, mac->action);
1476       if (i == 1000)
1477         break;
1478     }
1479 }
1480
1481 static void
1482 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1483 {
1484   /* JSON output not supported */
1485 }
1486
1487 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1488 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1489
1490 /*
1491  * Special-case: build the bridge domain table, maintain
1492  * the next bd id vbl.
1493  */
1494 static void vl_api_bridge_domain_details_t_handler
1495   (vl_api_bridge_domain_details_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1499   int i;
1500
1501   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1502          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1503
1504   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1505          ntohl (mp->bd_id), mp->learn, mp->forward,
1506          mp->flood, ntohl (mp->bvi_sw_if_index),
1507          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1508
1509   if (n_sw_ifs)
1510     {
1511       vl_api_bridge_domain_sw_if_t *sw_ifs;
1512       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1513              "Interface Name");
1514
1515       sw_ifs = mp->sw_if_details;
1516       for (i = 0; i < n_sw_ifs; i++)
1517         {
1518           u8 *sw_if_name = 0;
1519           u32 sw_if_index;
1520           hash_pair_t *p;
1521
1522           sw_if_index = ntohl (sw_ifs->sw_if_index);
1523
1524           /* *INDENT-OFF* */
1525           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1526                              ({
1527                                if ((u32) p->value[0] == sw_if_index)
1528                                  {
1529                                    sw_if_name = (u8 *)(p->key);
1530                                    break;
1531                                  }
1532                              }));
1533           /* *INDENT-ON* */
1534           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1535                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1536                  "sw_if_index not found!");
1537
1538           sw_ifs++;
1539         }
1540     }
1541 }
1542
1543 static void vl_api_bridge_domain_details_t_handler_json
1544   (vl_api_bridge_domain_details_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t *node, *array = NULL;
1548   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1549
1550   if (VAT_JSON_ARRAY != vam->json_tree.type)
1551     {
1552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1553       vat_json_init_array (&vam->json_tree);
1554     }
1555   node = vat_json_array_add (&vam->json_tree);
1556
1557   vat_json_init_object (node);
1558   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1559   vat_json_object_add_uint (node, "flood", mp->flood);
1560   vat_json_object_add_uint (node, "forward", mp->forward);
1561   vat_json_object_add_uint (node, "learn", mp->learn);
1562   vat_json_object_add_uint (node, "bvi_sw_if_index",
1563                             ntohl (mp->bvi_sw_if_index));
1564   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1565   array = vat_json_object_add (node, "sw_if");
1566   vat_json_init_array (array);
1567
1568
1569
1570   if (n_sw_ifs)
1571     {
1572       vl_api_bridge_domain_sw_if_t *sw_ifs;
1573       int i;
1574
1575       sw_ifs = mp->sw_if_details;
1576       for (i = 0; i < n_sw_ifs; i++)
1577         {
1578           node = vat_json_array_add (array);
1579           vat_json_init_object (node);
1580           vat_json_object_add_uint (node, "sw_if_index",
1581                                     ntohl (sw_ifs->sw_if_index));
1582           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1583           sw_ifs++;
1584         }
1585     }
1586 }
1587
1588 static void vl_api_control_ping_reply_t_handler
1589   (vl_api_control_ping_reply_t * mp)
1590 {
1591   vat_main_t *vam = &vat_main;
1592   i32 retval = ntohl (mp->retval);
1593   if (vam->async_mode)
1594     {
1595       vam->async_errors += (retval < 0);
1596     }
1597   else
1598     {
1599       vam->retval = retval;
1600       vam->result_ready = 1;
1601     }
1602   if (vam->socket_client_main)
1603     vam->socket_client_main->control_pings_outstanding--;
1604 }
1605
1606 static void vl_api_control_ping_reply_t_handler_json
1607   (vl_api_control_ping_reply_t * mp)
1608 {
1609   vat_main_t *vam = &vat_main;
1610   i32 retval = ntohl (mp->retval);
1611
1612   if (VAT_JSON_NONE != vam->json_tree.type)
1613     {
1614       vat_json_print (vam->ofp, &vam->json_tree);
1615       vat_json_free (&vam->json_tree);
1616       vam->json_tree.type = VAT_JSON_NONE;
1617     }
1618   else
1619     {
1620       /* just print [] */
1621       vat_json_init_array (&vam->json_tree);
1622       vat_json_print (vam->ofp, &vam->json_tree);
1623       vam->json_tree.type = VAT_JSON_NONE;
1624     }
1625
1626   vam->retval = retval;
1627   vam->result_ready = 1;
1628 }
1629
1630 static void
1631   vl_api_bridge_domain_set_mac_age_reply_t_handler
1632   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1648   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void
1664 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->result_ready = 1;
1676     }
1677 }
1678
1679 static void vl_api_l2_flags_reply_t_handler_json
1680   (vl_api_l2_flags_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   vat_json_node_t node;
1684
1685   vat_json_init_object (&node);
1686   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1687   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1688                             ntohl (mp->resulting_feature_bitmap));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_bridge_flags_reply_t_handler
1698   (vl_api_bridge_flags_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_bridge_flags_reply_t_handler_json
1714   (vl_api_bridge_flags_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1722                             ntohl (mp->resulting_feature_bitmap));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void
1732 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->sw_if_index = ntohl (mp->sw_if_index);
1744       vam->result_ready = 1;
1745     }
1746
1747 }
1748
1749 static void vl_api_tap_create_v2_reply_t_handler_json
1750   (vl_api_tap_create_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764
1765 }
1766
1767 static void
1768 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1769 {
1770   vat_main_t *vam = &vat_main;
1771   i32 retval = ntohl (mp->retval);
1772   if (vam->async_mode)
1773     {
1774       vam->async_errors += (retval < 0);
1775     }
1776   else
1777     {
1778       vam->retval = retval;
1779       vam->result_ready = 1;
1780     }
1781 }
1782
1783 static void vl_api_tap_delete_v2_reply_t_handler_json
1784   (vl_api_tap_delete_v2_reply_t * mp)
1785 {
1786   vat_main_t *vam = &vat_main;
1787   vat_json_node_t node;
1788
1789   vat_json_init_object (&node);
1790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void
1800 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1801                                           mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->sw_if_index = ntohl (mp->sw_if_index);
1813       vam->result_ready = 1;
1814     }
1815 }
1816
1817 static void vl_api_virtio_pci_create_reply_t_handler_json
1818   (vl_api_virtio_pci_create_reply_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821   vat_json_node_t node;
1822
1823   vat_json_init_object (&node);
1824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1825   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1826
1827   vat_json_print (vam->ofp, &node);
1828   vat_json_free (&node);
1829
1830   vam->retval = ntohl (mp->retval);
1831   vam->result_ready = 1;
1832
1833 }
1834
1835 static void
1836 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1837                                           mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841   if (vam->async_mode)
1842     {
1843       vam->async_errors += (retval < 0);
1844     }
1845   else
1846     {
1847       vam->retval = retval;
1848       vam->result_ready = 1;
1849     }
1850 }
1851
1852 static void vl_api_virtio_pci_delete_reply_t_handler_json
1853   (vl_api_virtio_pci_delete_reply_t * mp)
1854 {
1855   vat_main_t *vam = &vat_main;
1856   vat_json_node_t node;
1857
1858   vat_json_init_object (&node);
1859   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1860
1861   vat_json_print (vam->ofp, &node);
1862   vat_json_free (&node);
1863
1864   vam->retval = ntohl (mp->retval);
1865   vam->result_ready = 1;
1866 }
1867
1868 static void
1869 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   i32 retval = ntohl (mp->retval);
1873
1874   if (vam->async_mode)
1875     {
1876       vam->async_errors += (retval < 0);
1877     }
1878   else
1879     {
1880       vam->retval = retval;
1881       vam->sw_if_index = ntohl (mp->sw_if_index);
1882       vam->result_ready = 1;
1883     }
1884 }
1885
1886 static void vl_api_bond_create_reply_t_handler_json
1887   (vl_api_bond_create_reply_t * mp)
1888 {
1889   vat_main_t *vam = &vat_main;
1890   vat_json_node_t node;
1891
1892   vat_json_init_object (&node);
1893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1894   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1895
1896   vat_json_print (vam->ofp, &node);
1897   vat_json_free (&node);
1898
1899   vam->retval = ntohl (mp->retval);
1900   vam->result_ready = 1;
1901 }
1902
1903 static void
1904 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   i32 retval = ntohl (mp->retval);
1908
1909   if (vam->async_mode)
1910     {
1911       vam->async_errors += (retval < 0);
1912     }
1913   else
1914     {
1915       vam->retval = retval;
1916       vam->result_ready = 1;
1917     }
1918 }
1919
1920 static void vl_api_bond_delete_reply_t_handler_json
1921   (vl_api_bond_delete_reply_t * mp)
1922 {
1923   vat_main_t *vam = &vat_main;
1924   vat_json_node_t node;
1925
1926   vat_json_init_object (&node);
1927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1928
1929   vat_json_print (vam->ofp, &node);
1930   vat_json_free (&node);
1931
1932   vam->retval = ntohl (mp->retval);
1933   vam->result_ready = 1;
1934 }
1935
1936 static void
1937 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1938 {
1939   vat_main_t *vam = &vat_main;
1940   i32 retval = ntohl (mp->retval);
1941
1942   if (vam->async_mode)
1943     {
1944       vam->async_errors += (retval < 0);
1945     }
1946   else
1947     {
1948       vam->retval = retval;
1949       vam->result_ready = 1;
1950     }
1951 }
1952
1953 static void vl_api_bond_enslave_reply_t_handler_json
1954   (vl_api_bond_enslave_reply_t * mp)
1955 {
1956   vat_main_t *vam = &vat_main;
1957   vat_json_node_t node;
1958
1959   vat_json_init_object (&node);
1960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1961
1962   vat_json_print (vam->ofp, &node);
1963   vat_json_free (&node);
1964
1965   vam->retval = ntohl (mp->retval);
1966   vam->result_ready = 1;
1967 }
1968
1969 static void
1970 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1971                                           mp)
1972 {
1973   vat_main_t *vam = &vat_main;
1974   i32 retval = ntohl (mp->retval);
1975
1976   if (vam->async_mode)
1977     {
1978       vam->async_errors += (retval < 0);
1979     }
1980   else
1981     {
1982       vam->retval = retval;
1983       vam->result_ready = 1;
1984     }
1985 }
1986
1987 static void vl_api_bond_detach_slave_reply_t_handler_json
1988   (vl_api_bond_detach_slave_reply_t * mp)
1989 {
1990   vat_main_t *vam = &vat_main;
1991   vat_json_node_t node;
1992
1993   vat_json_init_object (&node);
1994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1995
1996   vat_json_print (vam->ofp, &node);
1997   vat_json_free (&node);
1998
1999   vam->retval = ntohl (mp->retval);
2000   vam->result_ready = 1;
2001 }
2002
2003 static int
2004 api_sw_interface_set_bond_weight (vat_main_t * vam)
2005 {
2006   unformat_input_t *i = vam->input;
2007   vl_api_sw_interface_set_bond_weight_t *mp;
2008   u32 sw_if_index = ~0;
2009   u32 weight = 0;
2010   u8 weight_enter = 0;
2011   int ret;
2012
2013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2014     {
2015       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2016         ;
2017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2018         ;
2019       else if (unformat (i, "weight %u", &weight))
2020         weight_enter = 1;
2021       else
2022         break;
2023     }
2024
2025   if (sw_if_index == ~0)
2026     {
2027       errmsg ("missing interface name or sw_if_index");
2028       return -99;
2029     }
2030   if (weight_enter == 0)
2031     {
2032       errmsg ("missing valid weight");
2033       return -99;
2034     }
2035
2036   /* Construct the API message */
2037   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2038   mp->sw_if_index = ntohl (sw_if_index);
2039   mp->weight = ntohl (weight);
2040
2041   S (mp);
2042   W (ret);
2043   return ret;
2044 }
2045
2046 static void vl_api_sw_interface_bond_details_t_handler
2047   (vl_api_sw_interface_bond_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050
2051   print (vam->ofp,
2052          "%-16s %-12d %-12U %-13U %-14u %-14u",
2053          mp->interface_name, ntohl (mp->sw_if_index),
2054          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2055          ntohl (mp->active_slaves), ntohl (mp->slaves));
2056 }
2057
2058 static void vl_api_sw_interface_bond_details_t_handler_json
2059   (vl_api_sw_interface_bond_details_t * mp)
2060 {
2061   vat_main_t *vam = &vat_main;
2062   vat_json_node_t *node = NULL;
2063
2064   if (VAT_JSON_ARRAY != vam->json_tree.type)
2065     {
2066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2067       vat_json_init_array (&vam->json_tree);
2068     }
2069   node = vat_json_array_add (&vam->json_tree);
2070
2071   vat_json_init_object (node);
2072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2073   vat_json_object_add_string_copy (node, "interface_name",
2074                                    mp->interface_name);
2075   vat_json_object_add_uint (node, "mode", mp->mode);
2076   vat_json_object_add_uint (node, "load_balance", mp->lb);
2077   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2078   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2079 }
2080
2081 static int
2082 api_sw_interface_bond_dump (vat_main_t * vam)
2083 {
2084   vl_api_sw_interface_bond_dump_t *mp;
2085   vl_api_control_ping_t *mp_ping;
2086   int ret;
2087
2088   print (vam->ofp,
2089          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2090          "interface name", "sw_if_index", "mode", "load balance",
2091          "active slaves", "slaves");
2092
2093   /* Get list of bond interfaces */
2094   M (SW_INTERFACE_BOND_DUMP, mp);
2095   S (mp);
2096
2097   /* Use a control ping for synchronization */
2098   MPING (CONTROL_PING, mp_ping);
2099   S (mp_ping);
2100
2101   W (ret);
2102   return ret;
2103 }
2104
2105 static void vl_api_sw_interface_slave_details_t_handler
2106   (vl_api_sw_interface_slave_details_t * mp)
2107 {
2108   vat_main_t *vam = &vat_main;
2109
2110   print (vam->ofp,
2111          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2112          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2113          ntohl (mp->weight), mp->is_local_numa);
2114 }
2115
2116 static void vl_api_sw_interface_slave_details_t_handler_json
2117   (vl_api_sw_interface_slave_details_t * mp)
2118 {
2119   vat_main_t *vam = &vat_main;
2120   vat_json_node_t *node = NULL;
2121
2122   if (VAT_JSON_ARRAY != vam->json_tree.type)
2123     {
2124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2125       vat_json_init_array (&vam->json_tree);
2126     }
2127   node = vat_json_array_add (&vam->json_tree);
2128
2129   vat_json_init_object (node);
2130   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2131   vat_json_object_add_string_copy (node, "interface_name",
2132                                    mp->interface_name);
2133   vat_json_object_add_uint (node, "passive", mp->is_passive);
2134   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2135   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2136   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2137 }
2138
2139 static int
2140 api_sw_interface_slave_dump (vat_main_t * vam)
2141 {
2142   unformat_input_t *i = vam->input;
2143   vl_api_sw_interface_slave_dump_t *mp;
2144   vl_api_control_ping_t *mp_ping;
2145   u32 sw_if_index = ~0;
2146   u8 sw_if_index_set = 0;
2147   int ret;
2148
2149   /* Parse args required to build the message */
2150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2151     {
2152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2153         sw_if_index_set = 1;
2154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2155         sw_if_index_set = 1;
2156       else
2157         break;
2158     }
2159
2160   if (sw_if_index_set == 0)
2161     {
2162       errmsg ("missing vpp interface name. ");
2163       return -99;
2164     }
2165
2166   print (vam->ofp,
2167          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2168          "slave interface name", "sw_if_index", "passive", "long_timeout",
2169          "weight", "local numa");
2170
2171   /* Get list of bond interfaces */
2172   M (SW_INTERFACE_SLAVE_DUMP, mp);
2173   mp->sw_if_index = ntohl (sw_if_index);
2174   S (mp);
2175
2176   /* Use a control ping for synchronization */
2177   MPING (CONTROL_PING, mp_ping);
2178   S (mp_ping);
2179
2180   W (ret);
2181   return ret;
2182 }
2183
2184 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2185   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   i32 retval = ntohl (mp->retval);
2189   if (vam->async_mode)
2190     {
2191       vam->async_errors += (retval < 0);
2192     }
2193   else
2194     {
2195       vam->retval = retval;
2196       vam->sw_if_index = ntohl (mp->sw_if_index);
2197       vam->result_ready = 1;
2198     }
2199   vam->regenerate_interface_table = 1;
2200 }
2201
2202 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2203   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2204 {
2205   vat_main_t *vam = &vat_main;
2206   vat_json_node_t node;
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2211                             ntohl (mp->sw_if_index));
2212
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2221   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->sw_if_index = ntohl (mp->sw_if_index);
2233       vam->result_ready = 1;
2234     }
2235 }
2236
2237 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2238   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t node;
2242
2243   vat_json_init_object (&node);
2244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2245   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2246
2247   vat_json_print (vam->ofp, &node);
2248   vat_json_free (&node);
2249
2250   vam->retval = ntohl (mp->retval);
2251   vam->result_ready = 1;
2252 }
2253
2254 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2255   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   i32 retval = ntohl (mp->retval);
2259   if (vam->async_mode)
2260     {
2261       vam->async_errors += (retval < 0);
2262     }
2263   else
2264     {
2265       vam->retval = retval;
2266       vam->result_ready = 1;
2267     }
2268 }
2269
2270 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2271   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2272 {
2273   vat_main_t *vam = &vat_main;
2274   vat_json_node_t node;
2275
2276   vat_json_init_object (&node);
2277   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2278   vat_json_object_add_uint (&node, "fwd_entry_index",
2279                             clib_net_to_host_u32 (mp->fwd_entry_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 u8 *
2289 format_lisp_transport_protocol (u8 * s, va_list * args)
2290 {
2291   u32 proto = va_arg (*args, u32);
2292
2293   switch (proto)
2294     {
2295     case 1:
2296       return format (s, "udp");
2297     case 2:
2298       return format (s, "api");
2299     default:
2300       return 0;
2301     }
2302   return 0;
2303 }
2304
2305 static void vl_api_one_get_transport_protocol_reply_t_handler
2306   (vl_api_one_get_transport_protocol_reply_t * mp)
2307 {
2308   vat_main_t *vam = &vat_main;
2309   i32 retval = ntohl (mp->retval);
2310   if (vam->async_mode)
2311     {
2312       vam->async_errors += (retval < 0);
2313     }
2314   else
2315     {
2316       u32 proto = mp->protocol;
2317       print (vam->ofp, "Transport protocol: %U",
2318              format_lisp_transport_protocol, proto);
2319       vam->retval = retval;
2320       vam->result_ready = 1;
2321     }
2322 }
2323
2324 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2325   (vl_api_one_get_transport_protocol_reply_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t node;
2329   u8 *s;
2330
2331   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2332   vec_add1 (s, 0);
2333
2334   vat_json_init_object (&node);
2335   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2336   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2337
2338   vec_free (s);
2339   vat_json_print (vam->ofp, &node);
2340   vat_json_free (&node);
2341
2342   vam->retval = ntohl (mp->retval);
2343   vam->result_ready = 1;
2344 }
2345
2346 static void vl_api_one_add_del_locator_set_reply_t_handler
2347   (vl_api_one_add_del_locator_set_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   i32 retval = ntohl (mp->retval);
2351   if (vam->async_mode)
2352     {
2353       vam->async_errors += (retval < 0);
2354     }
2355   else
2356     {
2357       vam->retval = retval;
2358       vam->result_ready = 1;
2359     }
2360 }
2361
2362 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2363   (vl_api_one_add_del_locator_set_reply_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t node;
2367
2368   vat_json_init_object (&node);
2369   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2370   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2371
2372   vat_json_print (vam->ofp, &node);
2373   vat_json_free (&node);
2374
2375   vam->retval = ntohl (mp->retval);
2376   vam->result_ready = 1;
2377 }
2378
2379 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2380   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   i32 retval = ntohl (mp->retval);
2384   if (vam->async_mode)
2385     {
2386       vam->async_errors += (retval < 0);
2387     }
2388   else
2389     {
2390       vam->retval = retval;
2391       vam->sw_if_index = ntohl (mp->sw_if_index);
2392       vam->result_ready = 1;
2393     }
2394   vam->regenerate_interface_table = 1;
2395 }
2396
2397 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2398   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   vat_json_node_t node;
2402
2403   vat_json_init_object (&node);
2404   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2405   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static void vl_api_vxlan_offload_rx_reply_t_handler
2415   (vl_api_vxlan_offload_rx_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   i32 retval = ntohl (mp->retval);
2419   if (vam->async_mode)
2420     {
2421       vam->async_errors += (retval < 0);
2422     }
2423   else
2424     {
2425       vam->retval = retval;
2426       vam->result_ready = 1;
2427     }
2428 }
2429
2430 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2431   (vl_api_vxlan_offload_rx_reply_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434   vat_json_node_t node;
2435
2436   vat_json_init_object (&node);
2437   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2438
2439   vat_json_print (vam->ofp, &node);
2440   vat_json_free (&node);
2441
2442   vam->retval = ntohl (mp->retval);
2443   vam->result_ready = 1;
2444 }
2445
2446 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2447   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2448 {
2449   vat_main_t *vam = &vat_main;
2450   i32 retval = ntohl (mp->retval);
2451   if (vam->async_mode)
2452     {
2453       vam->async_errors += (retval < 0);
2454     }
2455   else
2456     {
2457       vam->retval = retval;
2458       vam->sw_if_index = ntohl (mp->sw_if_index);
2459       vam->result_ready = 1;
2460     }
2461 }
2462
2463 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2464   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467   vat_json_node_t node;
2468
2469   vat_json_init_object (&node);
2470   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2471   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2472
2473   vat_json_print (vam->ofp, &node);
2474   vat_json_free (&node);
2475
2476   vam->retval = ntohl (mp->retval);
2477   vam->result_ready = 1;
2478 }
2479
2480 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2481   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   i32 retval = ntohl (mp->retval);
2485   if (vam->async_mode)
2486     {
2487       vam->async_errors += (retval < 0);
2488     }
2489   else
2490     {
2491       vam->retval = retval;
2492       vam->sw_if_index = ntohl (mp->sw_if_index);
2493       vam->result_ready = 1;
2494     }
2495   vam->regenerate_interface_table = 1;
2496 }
2497
2498 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2499   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2500 {
2501   vat_main_t *vam = &vat_main;
2502   vat_json_node_t node;
2503
2504   vat_json_init_object (&node);
2505   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2506   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2507
2508   vat_json_print (vam->ofp, &node);
2509   vat_json_free (&node);
2510
2511   vam->retval = ntohl (mp->retval);
2512   vam->result_ready = 1;
2513 }
2514
2515 static void vl_api_gre_tunnel_add_del_reply_t_handler
2516   (vl_api_gre_tunnel_add_del_reply_t * mp)
2517 {
2518   vat_main_t *vam = &vat_main;
2519   i32 retval = ntohl (mp->retval);
2520   if (vam->async_mode)
2521     {
2522       vam->async_errors += (retval < 0);
2523     }
2524   else
2525     {
2526       vam->retval = retval;
2527       vam->sw_if_index = ntohl (mp->sw_if_index);
2528       vam->result_ready = 1;
2529     }
2530 }
2531
2532 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2533   (vl_api_gre_tunnel_add_del_reply_t * mp)
2534 {
2535   vat_main_t *vam = &vat_main;
2536   vat_json_node_t node;
2537
2538   vat_json_init_object (&node);
2539   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2540   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2541
2542   vat_json_print (vam->ofp, &node);
2543   vat_json_free (&node);
2544
2545   vam->retval = ntohl (mp->retval);
2546   vam->result_ready = 1;
2547 }
2548
2549 static void vl_api_create_vhost_user_if_reply_t_handler
2550   (vl_api_create_vhost_user_if_reply_t * mp)
2551 {
2552   vat_main_t *vam = &vat_main;
2553   i32 retval = ntohl (mp->retval);
2554   if (vam->async_mode)
2555     {
2556       vam->async_errors += (retval < 0);
2557     }
2558   else
2559     {
2560       vam->retval = retval;
2561       vam->sw_if_index = ntohl (mp->sw_if_index);
2562       vam->result_ready = 1;
2563     }
2564   vam->regenerate_interface_table = 1;
2565 }
2566
2567 static void vl_api_create_vhost_user_if_reply_t_handler_json
2568   (vl_api_create_vhost_user_if_reply_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t node;
2572
2573   vat_json_init_object (&node);
2574   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2575   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2576
2577   vat_json_print (vam->ofp, &node);
2578   vat_json_free (&node);
2579
2580   vam->retval = ntohl (mp->retval);
2581   vam->result_ready = 1;
2582 }
2583
2584 static void vl_api_ip_address_details_t_handler
2585   (vl_api_ip_address_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_address_details_t empty_ip_address_details = { {0} };
2589   ip_address_details_t *address = NULL;
2590   ip_details_t *current_ip_details = NULL;
2591   ip_details_t *details = NULL;
2592
2593   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2594
2595   if (!details || vam->current_sw_if_index >= vec_len (details)
2596       || !details[vam->current_sw_if_index].present)
2597     {
2598       errmsg ("ip address details arrived but not stored");
2599       errmsg ("ip_dump should be called first");
2600       return;
2601     }
2602
2603   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2604
2605 #define addresses (current_ip_details->addr)
2606
2607   vec_validate_init_empty (addresses, vec_len (addresses),
2608                            empty_ip_address_details);
2609
2610   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2611
2612   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2613   address->prefix_length = mp->prefix.len;
2614 #undef addresses
2615 }
2616
2617 static void vl_api_ip_address_details_t_handler_json
2618   (vl_api_ip_address_details_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621   vat_json_node_t *node = NULL;
2622
2623   if (VAT_JSON_ARRAY != vam->json_tree.type)
2624     {
2625       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2626       vat_json_init_array (&vam->json_tree);
2627     }
2628   node = vat_json_array_add (&vam->json_tree);
2629
2630   vat_json_init_object (node);
2631   vat_json_object_add_prefix (node, &mp->prefix);
2632 }
2633
2634 static void
2635 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2636 {
2637   vat_main_t *vam = &vat_main;
2638   static ip_details_t empty_ip_details = { 0 };
2639   ip_details_t *ip = NULL;
2640   u32 sw_if_index = ~0;
2641
2642   sw_if_index = ntohl (mp->sw_if_index);
2643
2644   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645                            sw_if_index, empty_ip_details);
2646
2647   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2648                          sw_if_index);
2649
2650   ip->present = 1;
2651 }
2652
2653 static void
2654 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2655 {
2656   vat_main_t *vam = &vat_main;
2657
2658   if (VAT_JSON_ARRAY != vam->json_tree.type)
2659     {
2660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2661       vat_json_init_array (&vam->json_tree);
2662     }
2663   vat_json_array_add_uint (&vam->json_tree,
2664                            clib_net_to_host_u32 (mp->sw_if_index));
2665 }
2666
2667 static void
2668 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2669 {
2670   u8 *s, i;
2671
2672   s = format (0, "DHCP compl event: pid %d %s hostname %s host_addr %U "
2673               "host_mac %U router_addr %U",
2674               ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2675               mp->lease.hostname,
2676               format_ip4_address, mp->lease.host_address,
2677               format_ethernet_address, mp->lease.host_mac,
2678               format_ip4_address, mp->lease.router_address);
2679
2680   for (i = 0; i < mp->lease.count; i++)
2681     s =
2682       format (s, " domain_server_addr %U", format_ip4_address,
2683               mp->lease.domain_server[i].address);
2684
2685   errmsg ((char *) s);
2686   vec_free (s);
2687 }
2688
2689 static void vl_api_dhcp_compl_event_t_handler_json
2690   (vl_api_dhcp_compl_event_t * mp)
2691 {
2692   /* JSON output not supported */
2693 }
2694
2695 static void vl_api_get_first_msg_id_reply_t_handler
2696   (vl_api_get_first_msg_id_reply_t * mp)
2697 {
2698   vat_main_t *vam = &vat_main;
2699   i32 retval = ntohl (mp->retval);
2700
2701   if (vam->async_mode)
2702     {
2703       vam->async_errors += (retval < 0);
2704     }
2705   else
2706     {
2707       vam->retval = retval;
2708       vam->result_ready = 1;
2709     }
2710   if (retval >= 0)
2711     {
2712       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2713     }
2714 }
2715
2716 static void vl_api_get_first_msg_id_reply_t_handler_json
2717   (vl_api_get_first_msg_id_reply_t * mp)
2718 {
2719   vat_main_t *vam = &vat_main;
2720   vat_json_node_t node;
2721
2722   vat_json_init_object (&node);
2723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2724   vat_json_object_add_uint (&node, "first_msg_id",
2725                             (uint) ntohs (mp->first_msg_id));
2726
2727   vat_json_print (vam->ofp, &node);
2728   vat_json_free (&node);
2729
2730   vam->retval = ntohl (mp->retval);
2731   vam->result_ready = 1;
2732 }
2733
2734 static void vl_api_get_node_graph_reply_t_handler
2735   (vl_api_get_node_graph_reply_t * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738   api_main_t *am = &api_main;
2739   i32 retval = ntohl (mp->retval);
2740   u8 *pvt_copy, *reply;
2741   void *oldheap;
2742   vlib_node_t *node;
2743   int i;
2744
2745   if (vam->async_mode)
2746     {
2747       vam->async_errors += (retval < 0);
2748     }
2749   else
2750     {
2751       vam->retval = retval;
2752       vam->result_ready = 1;
2753     }
2754
2755   /* "Should never happen..." */
2756   if (retval != 0)
2757     return;
2758
2759   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2760   pvt_copy = vec_dup (reply);
2761
2762   /* Toss the shared-memory original... */
2763   pthread_mutex_lock (&am->vlib_rp->mutex);
2764   oldheap = svm_push_data_heap (am->vlib_rp);
2765
2766   vec_free (reply);
2767
2768   svm_pop_heap (oldheap);
2769   pthread_mutex_unlock (&am->vlib_rp->mutex);
2770
2771   if (vam->graph_nodes)
2772     {
2773       hash_free (vam->graph_node_index_by_name);
2774
2775       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2776         {
2777           node = vam->graph_nodes[0][i];
2778           vec_free (node->name);
2779           vec_free (node->next_nodes);
2780           vec_free (node);
2781         }
2782       vec_free (vam->graph_nodes[0]);
2783       vec_free (vam->graph_nodes);
2784     }
2785
2786   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2787   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2788   vec_free (pvt_copy);
2789
2790   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2791     {
2792       node = vam->graph_nodes[0][i];
2793       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2794     }
2795 }
2796
2797 static void vl_api_get_node_graph_reply_t_handler_json
2798   (vl_api_get_node_graph_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   api_main_t *am = &api_main;
2802   void *oldheap;
2803   vat_json_node_t node;
2804   u8 *reply;
2805
2806   /* $$$$ make this real? */
2807   vat_json_init_object (&node);
2808   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2809   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2810
2811   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2812
2813   /* Toss the shared-memory original... */
2814   pthread_mutex_lock (&am->vlib_rp->mutex);
2815   oldheap = svm_push_data_heap (am->vlib_rp);
2816
2817   vec_free (reply);
2818
2819   svm_pop_heap (oldheap);
2820   pthread_mutex_unlock (&am->vlib_rp->mutex);
2821
2822   vat_json_print (vam->ofp, &node);
2823   vat_json_free (&node);
2824
2825   vam->retval = ntohl (mp->retval);
2826   vam->result_ready = 1;
2827 }
2828
2829 static void
2830 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2831 {
2832   vat_main_t *vam = &vat_main;
2833   u8 *s = 0;
2834
2835   if (mp->local)
2836     {
2837       s = format (s, "%=16d%=16d%=16d",
2838                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2839     }
2840   else
2841     {
2842       s = format (s, "%=16U%=16d%=16d",
2843                   mp->is_ipv6 ? format_ip6_address :
2844                   format_ip4_address,
2845                   mp->ip_address, mp->priority, mp->weight);
2846     }
2847
2848   print (vam->ofp, "%v", s);
2849   vec_free (s);
2850 }
2851
2852 static void
2853 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2854 {
2855   vat_main_t *vam = &vat_main;
2856   vat_json_node_t *node = NULL;
2857   struct in6_addr ip6;
2858   struct in_addr ip4;
2859
2860   if (VAT_JSON_ARRAY != vam->json_tree.type)
2861     {
2862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2863       vat_json_init_array (&vam->json_tree);
2864     }
2865   node = vat_json_array_add (&vam->json_tree);
2866   vat_json_init_object (node);
2867
2868   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2869   vat_json_object_add_uint (node, "priority", mp->priority);
2870   vat_json_object_add_uint (node, "weight", mp->weight);
2871
2872   if (mp->local)
2873     vat_json_object_add_uint (node, "sw_if_index",
2874                               clib_net_to_host_u32 (mp->sw_if_index));
2875   else
2876     {
2877       if (mp->is_ipv6)
2878         {
2879           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2880           vat_json_object_add_ip6 (node, "address", ip6);
2881         }
2882       else
2883         {
2884           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2885           vat_json_object_add_ip4 (node, "address", ip4);
2886         }
2887     }
2888 }
2889
2890 static void
2891 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2892                                           mp)
2893 {
2894   vat_main_t *vam = &vat_main;
2895   u8 *ls_name = 0;
2896
2897   ls_name = format (0, "%s", mp->ls_name);
2898
2899   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2900          ls_name);
2901   vec_free (ls_name);
2902 }
2903
2904 static void
2905   vl_api_one_locator_set_details_t_handler_json
2906   (vl_api_one_locator_set_details_t * mp)
2907 {
2908   vat_main_t *vam = &vat_main;
2909   vat_json_node_t *node = 0;
2910   u8 *ls_name = 0;
2911
2912   ls_name = format (0, "%s", mp->ls_name);
2913   vec_add1 (ls_name, 0);
2914
2915   if (VAT_JSON_ARRAY != vam->json_tree.type)
2916     {
2917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2918       vat_json_init_array (&vam->json_tree);
2919     }
2920   node = vat_json_array_add (&vam->json_tree);
2921
2922   vat_json_init_object (node);
2923   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2924   vat_json_object_add_uint (node, "ls_index",
2925                             clib_net_to_host_u32 (mp->ls_index));
2926   vec_free (ls_name);
2927 }
2928
2929 typedef struct
2930 {
2931   u32 spi;
2932   u8 si;
2933 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2934
2935 uword
2936 unformat_nsh_address (unformat_input_t * input, va_list * args)
2937 {
2938   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2939   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2940 }
2941
2942 u8 *
2943 format_nsh_address_vat (u8 * s, va_list * args)
2944 {
2945   nsh_t *a = va_arg (*args, nsh_t *);
2946   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2947 }
2948
2949 static u8 *
2950 format_lisp_flat_eid (u8 * s, va_list * args)
2951 {
2952   u32 type = va_arg (*args, u32);
2953   u8 *eid = va_arg (*args, u8 *);
2954   u32 eid_len = va_arg (*args, u32);
2955
2956   switch (type)
2957     {
2958     case 0:
2959       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2960     case 1:
2961       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2962     case 2:
2963       return format (s, "%U", format_ethernet_address, eid);
2964     case 3:
2965       return format (s, "%U", format_nsh_address_vat, eid);
2966     }
2967   return 0;
2968 }
2969
2970 static u8 *
2971 format_lisp_eid_vat (u8 * s, va_list * args)
2972 {
2973   u32 type = va_arg (*args, u32);
2974   u8 *eid = va_arg (*args, u8 *);
2975   u32 eid_len = va_arg (*args, u32);
2976   u8 *seid = va_arg (*args, u8 *);
2977   u32 seid_len = va_arg (*args, u32);
2978   u32 is_src_dst = va_arg (*args, u32);
2979
2980   if (is_src_dst)
2981     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2982
2983   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2984
2985   return s;
2986 }
2987
2988 static void
2989 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2990 {
2991   vat_main_t *vam = &vat_main;
2992   u8 *s = 0, *eid = 0;
2993
2994   if (~0 == mp->locator_set_index)
2995     s = format (0, "action: %d", mp->action);
2996   else
2997     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2998
2999   eid = format (0, "%U", format_lisp_eid_vat,
3000                 mp->eid_type,
3001                 mp->eid,
3002                 mp->eid_prefix_len,
3003                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3004   vec_add1 (eid, 0);
3005
3006   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3007          clib_net_to_host_u32 (mp->vni),
3008          eid,
3009          mp->is_local ? "local" : "remote",
3010          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3011          clib_net_to_host_u16 (mp->key_id), mp->key);
3012
3013   vec_free (s);
3014   vec_free (eid);
3015 }
3016
3017 static void
3018 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3019                                              * mp)
3020 {
3021   vat_main_t *vam = &vat_main;
3022   vat_json_node_t *node = 0;
3023   u8 *eid = 0;
3024
3025   if (VAT_JSON_ARRAY != vam->json_tree.type)
3026     {
3027       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3028       vat_json_init_array (&vam->json_tree);
3029     }
3030   node = vat_json_array_add (&vam->json_tree);
3031
3032   vat_json_init_object (node);
3033   if (~0 == mp->locator_set_index)
3034     vat_json_object_add_uint (node, "action", mp->action);
3035   else
3036     vat_json_object_add_uint (node, "locator_set_index",
3037                               clib_net_to_host_u32 (mp->locator_set_index));
3038
3039   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3040   if (mp->eid_type == 3)
3041     {
3042       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3043       vat_json_init_object (nsh_json);
3044       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3045       vat_json_object_add_uint (nsh_json, "spi",
3046                                 clib_net_to_host_u32 (nsh->spi));
3047       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3048     }
3049   else
3050     {
3051       eid = format (0, "%U", format_lisp_eid_vat,
3052                     mp->eid_type,
3053                     mp->eid,
3054                     mp->eid_prefix_len,
3055                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3056       vec_add1 (eid, 0);
3057       vat_json_object_add_string_copy (node, "eid", eid);
3058       vec_free (eid);
3059     }
3060   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3061   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3062   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3063
3064   if (mp->key_id)
3065     {
3066       vat_json_object_add_uint (node, "key_id",
3067                                 clib_net_to_host_u16 (mp->key_id));
3068       vat_json_object_add_string_copy (node, "key", mp->key);
3069     }
3070 }
3071
3072 static void
3073 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3074 {
3075   vat_main_t *vam = &vat_main;
3076   u8 *seid = 0, *deid = 0;
3077   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3078
3079   deid = format (0, "%U", format_lisp_eid_vat,
3080                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3081
3082   seid = format (0, "%U", format_lisp_eid_vat,
3083                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3084
3085   vec_add1 (deid, 0);
3086   vec_add1 (seid, 0);
3087
3088   if (mp->is_ip4)
3089     format_ip_address_fcn = format_ip4_address;
3090   else
3091     format_ip_address_fcn = format_ip6_address;
3092
3093
3094   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3095          clib_net_to_host_u32 (mp->vni),
3096          seid, deid,
3097          format_ip_address_fcn, mp->lloc,
3098          format_ip_address_fcn, mp->rloc,
3099          clib_net_to_host_u32 (mp->pkt_count),
3100          clib_net_to_host_u32 (mp->bytes));
3101
3102   vec_free (deid);
3103   vec_free (seid);
3104 }
3105
3106 static void
3107 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3108 {
3109   struct in6_addr ip6;
3110   struct in_addr ip4;
3111   vat_main_t *vam = &vat_main;
3112   vat_json_node_t *node = 0;
3113   u8 *deid = 0, *seid = 0;
3114
3115   if (VAT_JSON_ARRAY != vam->json_tree.type)
3116     {
3117       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3118       vat_json_init_array (&vam->json_tree);
3119     }
3120   node = vat_json_array_add (&vam->json_tree);
3121
3122   vat_json_init_object (node);
3123   deid = format (0, "%U", format_lisp_eid_vat,
3124                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3125
3126   seid = format (0, "%U", format_lisp_eid_vat,
3127                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3128
3129   vec_add1 (deid, 0);
3130   vec_add1 (seid, 0);
3131
3132   vat_json_object_add_string_copy (node, "seid", seid);
3133   vat_json_object_add_string_copy (node, "deid", deid);
3134   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3135
3136   if (mp->is_ip4)
3137     {
3138       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3139       vat_json_object_add_ip4 (node, "lloc", ip4);
3140       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3141       vat_json_object_add_ip4 (node, "rloc", ip4);
3142     }
3143   else
3144     {
3145       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3146       vat_json_object_add_ip6 (node, "lloc", ip6);
3147       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3148       vat_json_object_add_ip6 (node, "rloc", ip6);
3149     }
3150   vat_json_object_add_uint (node, "pkt_count",
3151                             clib_net_to_host_u32 (mp->pkt_count));
3152   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3153
3154   vec_free (deid);
3155   vec_free (seid);
3156 }
3157
3158 static void
3159   vl_api_one_eid_table_map_details_t_handler
3160   (vl_api_one_eid_table_map_details_t * mp)
3161 {
3162   vat_main_t *vam = &vat_main;
3163
3164   u8 *line = format (0, "%=10d%=10d",
3165                      clib_net_to_host_u32 (mp->vni),
3166                      clib_net_to_host_u32 (mp->dp_table));
3167   print (vam->ofp, "%v", line);
3168   vec_free (line);
3169 }
3170
3171 static void
3172   vl_api_one_eid_table_map_details_t_handler_json
3173   (vl_api_one_eid_table_map_details_t * mp)
3174 {
3175   vat_main_t *vam = &vat_main;
3176   vat_json_node_t *node = NULL;
3177
3178   if (VAT_JSON_ARRAY != vam->json_tree.type)
3179     {
3180       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3181       vat_json_init_array (&vam->json_tree);
3182     }
3183   node = vat_json_array_add (&vam->json_tree);
3184   vat_json_init_object (node);
3185   vat_json_object_add_uint (node, "dp_table",
3186                             clib_net_to_host_u32 (mp->dp_table));
3187   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3188 }
3189
3190 static void
3191   vl_api_one_eid_table_vni_details_t_handler
3192   (vl_api_one_eid_table_vni_details_t * mp)
3193 {
3194   vat_main_t *vam = &vat_main;
3195
3196   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3197   print (vam->ofp, "%v", line);
3198   vec_free (line);
3199 }
3200
3201 static void
3202   vl_api_one_eid_table_vni_details_t_handler_json
3203   (vl_api_one_eid_table_vni_details_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   vat_json_node_t *node = NULL;
3207
3208   if (VAT_JSON_ARRAY != vam->json_tree.type)
3209     {
3210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3211       vat_json_init_array (&vam->json_tree);
3212     }
3213   node = vat_json_array_add (&vam->json_tree);
3214   vat_json_init_object (node);
3215   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3216 }
3217
3218 static void
3219   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3220   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3221 {
3222   vat_main_t *vam = &vat_main;
3223   int retval = clib_net_to_host_u32 (mp->retval);
3224
3225   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3226   print (vam->ofp, "fallback threshold value: %d", mp->value);
3227
3228   vam->retval = retval;
3229   vam->result_ready = 1;
3230 }
3231
3232 static void
3233   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3234   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3235 {
3236   vat_main_t *vam = &vat_main;
3237   vat_json_node_t _node, *node = &_node;
3238   int retval = clib_net_to_host_u32 (mp->retval);
3239
3240   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3241   vat_json_init_object (node);
3242   vat_json_object_add_uint (node, "value", mp->value);
3243
3244   vat_json_print (vam->ofp, node);
3245   vat_json_free (node);
3246
3247   vam->retval = retval;
3248   vam->result_ready = 1;
3249 }
3250
3251 static void
3252   vl_api_show_one_map_register_state_reply_t_handler
3253   (vl_api_show_one_map_register_state_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   int retval = clib_net_to_host_u32 (mp->retval);
3257
3258   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3259
3260   vam->retval = retval;
3261   vam->result_ready = 1;
3262 }
3263
3264 static void
3265   vl_api_show_one_map_register_state_reply_t_handler_json
3266   (vl_api_show_one_map_register_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
3274   vat_json_init_object (node);
3275   vat_json_object_add_string_copy (node, "state", s);
3276
3277   vat_json_print (vam->ofp, node);
3278   vat_json_free (node);
3279
3280   vam->retval = retval;
3281   vam->result_ready = 1;
3282   vec_free (s);
3283 }
3284
3285 static void
3286   vl_api_show_one_rloc_probe_state_reply_t_handler
3287   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3288 {
3289   vat_main_t *vam = &vat_main;
3290   int retval = clib_net_to_host_u32 (mp->retval);
3291
3292   if (retval)
3293     goto end;
3294
3295   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3296 end:
3297   vam->retval = retval;
3298   vam->result_ready = 1;
3299 }
3300
3301 static void
3302   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3303   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3304 {
3305   vat_main_t *vam = &vat_main;
3306   vat_json_node_t _node, *node = &_node;
3307   int retval = clib_net_to_host_u32 (mp->retval);
3308
3309   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3310   vat_json_init_object (node);
3311   vat_json_object_add_string_copy (node, "state", s);
3312
3313   vat_json_print (vam->ofp, node);
3314   vat_json_free (node);
3315
3316   vam->retval = retval;
3317   vam->result_ready = 1;
3318   vec_free (s);
3319 }
3320
3321 static void
3322   vl_api_show_one_stats_enable_disable_reply_t_handler
3323   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   int retval = clib_net_to_host_u32 (mp->retval);
3327
3328   if (retval)
3329     goto end;
3330
3331   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3332 end:
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3339   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3346   vat_json_init_object (node);
3347   vat_json_object_add_string_copy (node, "state", s);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354   vec_free (s);
3355 }
3356
3357 static void
3358 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3359 {
3360   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3361   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3362   e->vni = clib_net_to_host_u32 (e->vni);
3363 }
3364
3365 static void
3366   gpe_fwd_entries_get_reply_t_net_to_host
3367   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3368 {
3369   u32 i;
3370
3371   mp->count = clib_net_to_host_u32 (mp->count);
3372   for (i = 0; i < mp->count; i++)
3373     {
3374       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3375     }
3376 }
3377
3378 static u8 *
3379 format_gpe_encap_mode (u8 * s, va_list * args)
3380 {
3381   u32 mode = va_arg (*args, u32);
3382
3383   switch (mode)
3384     {
3385     case 0:
3386       return format (s, "lisp");
3387     case 1:
3388       return format (s, "vxlan");
3389     }
3390   return 0;
3391 }
3392
3393 static void
3394   vl_api_gpe_get_encap_mode_reply_t_handler
3395   (vl_api_gpe_get_encap_mode_reply_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398
3399   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3400   vam->retval = ntohl (mp->retval);
3401   vam->result_ready = 1;
3402 }
3403
3404 static void
3405   vl_api_gpe_get_encap_mode_reply_t_handler_json
3406   (vl_api_gpe_get_encap_mode_reply_t * mp)
3407 {
3408   vat_main_t *vam = &vat_main;
3409   vat_json_node_t node;
3410
3411   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3412   vec_add1 (encap_mode, 0);
3413
3414   vat_json_init_object (&node);
3415   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3416
3417   vec_free (encap_mode);
3418   vat_json_print (vam->ofp, &node);
3419   vat_json_free (&node);
3420
3421   vam->retval = ntohl (mp->retval);
3422   vam->result_ready = 1;
3423 }
3424
3425 static void
3426   vl_api_gpe_fwd_entry_path_details_t_handler
3427   (vl_api_gpe_fwd_entry_path_details_t * mp)
3428 {
3429   vat_main_t *vam = &vat_main;
3430   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3431
3432   if (mp->lcl_loc.is_ip4)
3433     format_ip_address_fcn = format_ip4_address;
3434   else
3435     format_ip_address_fcn = format_ip6_address;
3436
3437   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3438          format_ip_address_fcn, &mp->lcl_loc,
3439          format_ip_address_fcn, &mp->rmt_loc);
3440 }
3441
3442 static void
3443 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3444 {
3445   struct in6_addr ip6;
3446   struct in_addr ip4;
3447
3448   if (loc->is_ip4)
3449     {
3450       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3451       vat_json_object_add_ip4 (n, "address", ip4);
3452     }
3453   else
3454     {
3455       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3456       vat_json_object_add_ip6 (n, "address", ip6);
3457     }
3458   vat_json_object_add_uint (n, "weight", loc->weight);
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entry_path_details_t_handler_json
3463   (vl_api_gpe_fwd_entry_path_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   vat_json_node_t *node = NULL;
3467   vat_json_node_t *loc_node;
3468
3469   if (VAT_JSON_ARRAY != vam->json_tree.type)
3470     {
3471       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3472       vat_json_init_array (&vam->json_tree);
3473     }
3474   node = vat_json_array_add (&vam->json_tree);
3475   vat_json_init_object (node);
3476
3477   loc_node = vat_json_object_add (node, "local_locator");
3478   vat_json_init_object (loc_node);
3479   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3480
3481   loc_node = vat_json_object_add (node, "remote_locator");
3482   vat_json_init_object (loc_node);
3483   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3484 }
3485
3486 static void
3487   vl_api_gpe_fwd_entries_get_reply_t_handler
3488   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   u32 i;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493   vl_api_gpe_fwd_entry_t *e;
3494
3495   if (retval)
3496     goto end;
3497
3498   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3499
3500   for (i = 0; i < mp->count; i++)
3501     {
3502       e = &mp->entries[i];
3503       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3504              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3505              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3506     }
3507
3508 end:
3509   vam->retval = retval;
3510   vam->result_ready = 1;
3511 }
3512
3513 static void
3514   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3515   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3516 {
3517   u8 *s = 0;
3518   vat_main_t *vam = &vat_main;
3519   vat_json_node_t *e = 0, root;
3520   u32 i;
3521   int retval = clib_net_to_host_u32 (mp->retval);
3522   vl_api_gpe_fwd_entry_t *fwd;
3523
3524   if (retval)
3525     goto end;
3526
3527   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3528   vat_json_init_array (&root);
3529
3530   for (i = 0; i < mp->count; i++)
3531     {
3532       e = vat_json_array_add (&root);
3533       fwd = &mp->entries[i];
3534
3535       vat_json_init_object (e);
3536       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3537       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3538       vat_json_object_add_int (e, "vni", fwd->vni);
3539       vat_json_object_add_int (e, "action", fwd->action);
3540
3541       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3542                   fwd->leid_prefix_len);
3543       vec_add1 (s, 0);
3544       vat_json_object_add_string_copy (e, "leid", s);
3545       vec_free (s);
3546
3547       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3548                   fwd->reid_prefix_len);
3549       vec_add1 (s, 0);
3550       vat_json_object_add_string_copy (e, "reid", s);
3551       vec_free (s);
3552     }
3553
3554   vat_json_print (vam->ofp, &root);
3555   vat_json_free (&root);
3556
3557 end:
3558   vam->retval = retval;
3559   vam->result_ready = 1;
3560 }
3561
3562 static void
3563   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3564   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3565 {
3566   vat_main_t *vam = &vat_main;
3567   u32 i, n;
3568   int retval = clib_net_to_host_u32 (mp->retval);
3569   vl_api_gpe_native_fwd_rpath_t *r;
3570
3571   if (retval)
3572     goto end;
3573
3574   n = clib_net_to_host_u32 (mp->count);
3575
3576   for (i = 0; i < n; i++)
3577     {
3578       r = &mp->entries[i];
3579       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3580              clib_net_to_host_u32 (r->fib_index),
3581              clib_net_to_host_u32 (r->nh_sw_if_index),
3582              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3583     }
3584
3585 end:
3586   vam->retval = retval;
3587   vam->result_ready = 1;
3588 }
3589
3590 static void
3591   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3592   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   vat_json_node_t root, *e;
3596   u32 i, n;
3597   int retval = clib_net_to_host_u32 (mp->retval);
3598   vl_api_gpe_native_fwd_rpath_t *r;
3599   u8 *s;
3600
3601   if (retval)
3602     goto end;
3603
3604   n = clib_net_to_host_u32 (mp->count);
3605   vat_json_init_array (&root);
3606
3607   for (i = 0; i < n; i++)
3608     {
3609       e = vat_json_array_add (&root);
3610       vat_json_init_object (e);
3611       r = &mp->entries[i];
3612       s =
3613         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3614                 r->nh_addr);
3615       vec_add1 (s, 0);
3616       vat_json_object_add_string_copy (e, "ip4", s);
3617       vec_free (s);
3618
3619       vat_json_object_add_uint (e, "fib_index",
3620                                 clib_net_to_host_u32 (r->fib_index));
3621       vat_json_object_add_uint (e, "nh_sw_if_index",
3622                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3623     }
3624
3625   vat_json_print (vam->ofp, &root);
3626   vat_json_free (&root);
3627
3628 end:
3629   vam->retval = retval;
3630   vam->result_ready = 1;
3631 }
3632
3633 static void
3634   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3635   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3636 {
3637   vat_main_t *vam = &vat_main;
3638   u32 i, n;
3639   int retval = clib_net_to_host_u32 (mp->retval);
3640
3641   if (retval)
3642     goto end;
3643
3644   n = clib_net_to_host_u32 (mp->count);
3645
3646   for (i = 0; i < n; i++)
3647     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3648
3649 end:
3650   vam->retval = retval;
3651   vam->result_ready = 1;
3652 }
3653
3654 static void
3655   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3656   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3657 {
3658   vat_main_t *vam = &vat_main;
3659   vat_json_node_t root;
3660   u32 i, n;
3661   int retval = clib_net_to_host_u32 (mp->retval);
3662
3663   if (retval)
3664     goto end;
3665
3666   n = clib_net_to_host_u32 (mp->count);
3667   vat_json_init_array (&root);
3668
3669   for (i = 0; i < n; i++)
3670     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3671
3672   vat_json_print (vam->ofp, &root);
3673   vat_json_free (&root);
3674
3675 end:
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_one_ndp_entries_get_reply_t_handler
3682   (vl_api_one_ndp_entries_get_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   u32 i, n;
3686   int retval = clib_net_to_host_u32 (mp->retval);
3687
3688   if (retval)
3689     goto end;
3690
3691   n = clib_net_to_host_u32 (mp->count);
3692
3693   for (i = 0; i < n; i++)
3694     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3695            format_ethernet_address, mp->entries[i].mac);
3696
3697 end:
3698   vam->retval = retval;
3699   vam->result_ready = 1;
3700 }
3701
3702 static void
3703   vl_api_one_ndp_entries_get_reply_t_handler_json
3704   (vl_api_one_ndp_entries_get_reply_t * mp)
3705 {
3706   u8 *s = 0;
3707   vat_main_t *vam = &vat_main;
3708   vat_json_node_t *e = 0, root;
3709   u32 i, n;
3710   int retval = clib_net_to_host_u32 (mp->retval);
3711   vl_api_one_ndp_entry_t *arp_entry;
3712
3713   if (retval)
3714     goto end;
3715
3716   n = clib_net_to_host_u32 (mp->count);
3717   vat_json_init_array (&root);
3718
3719   for (i = 0; i < n; i++)
3720     {
3721       e = vat_json_array_add (&root);
3722       arp_entry = &mp->entries[i];
3723
3724       vat_json_init_object (e);
3725       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3726       vec_add1 (s, 0);
3727
3728       vat_json_object_add_string_copy (e, "mac", s);
3729       vec_free (s);
3730
3731       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3732       vec_add1 (s, 0);
3733       vat_json_object_add_string_copy (e, "ip6", s);
3734       vec_free (s);
3735     }
3736
3737   vat_json_print (vam->ofp, &root);
3738   vat_json_free (&root);
3739
3740 end:
3741   vam->retval = retval;
3742   vam->result_ready = 1;
3743 }
3744
3745 static void
3746   vl_api_one_l2_arp_entries_get_reply_t_handler
3747   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3748 {
3749   vat_main_t *vam = &vat_main;
3750   u32 i, n;
3751   int retval = clib_net_to_host_u32 (mp->retval);
3752
3753   if (retval)
3754     goto end;
3755
3756   n = clib_net_to_host_u32 (mp->count);
3757
3758   for (i = 0; i < n; i++)
3759     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3760            format_ethernet_address, mp->entries[i].mac);
3761
3762 end:
3763   vam->retval = retval;
3764   vam->result_ready = 1;
3765 }
3766
3767 static void
3768   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3769   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3770 {
3771   u8 *s = 0;
3772   vat_main_t *vam = &vat_main;
3773   vat_json_node_t *e = 0, root;
3774   u32 i, n;
3775   int retval = clib_net_to_host_u32 (mp->retval);
3776   vl_api_one_l2_arp_entry_t *arp_entry;
3777
3778   if (retval)
3779     goto end;
3780
3781   n = clib_net_to_host_u32 (mp->count);
3782   vat_json_init_array (&root);
3783
3784   for (i = 0; i < n; i++)
3785     {
3786       e = vat_json_array_add (&root);
3787       arp_entry = &mp->entries[i];
3788
3789       vat_json_init_object (e);
3790       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3791       vec_add1 (s, 0);
3792
3793       vat_json_object_add_string_copy (e, "mac", s);
3794       vec_free (s);
3795
3796       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3797       vec_add1 (s, 0);
3798       vat_json_object_add_string_copy (e, "ip4", s);
3799       vec_free (s);
3800     }
3801
3802   vat_json_print (vam->ofp, &root);
3803   vat_json_free (&root);
3804
3805 end:
3806   vam->retval = retval;
3807   vam->result_ready = 1;
3808 }
3809
3810 static void
3811 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3812 {
3813   vat_main_t *vam = &vat_main;
3814   u32 i, n;
3815   int retval = clib_net_to_host_u32 (mp->retval);
3816
3817   if (retval)
3818     goto end;
3819
3820   n = clib_net_to_host_u32 (mp->count);
3821
3822   for (i = 0; i < n; i++)
3823     {
3824       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3825     }
3826
3827 end:
3828   vam->retval = retval;
3829   vam->result_ready = 1;
3830 }
3831
3832 static void
3833   vl_api_one_ndp_bd_get_reply_t_handler_json
3834   (vl_api_one_ndp_bd_get_reply_t * mp)
3835 {
3836   vat_main_t *vam = &vat_main;
3837   vat_json_node_t root;
3838   u32 i, n;
3839   int retval = clib_net_to_host_u32 (mp->retval);
3840
3841   if (retval)
3842     goto end;
3843
3844   n = clib_net_to_host_u32 (mp->count);
3845   vat_json_init_array (&root);
3846
3847   for (i = 0; i < n; i++)
3848     {
3849       vat_json_array_add_uint (&root,
3850                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3851     }
3852
3853   vat_json_print (vam->ofp, &root);
3854   vat_json_free (&root);
3855
3856 end:
3857   vam->retval = retval;
3858   vam->result_ready = 1;
3859 }
3860
3861 static void
3862   vl_api_one_l2_arp_bd_get_reply_t_handler
3863   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3864 {
3865   vat_main_t *vam = &vat_main;
3866   u32 i, n;
3867   int retval = clib_net_to_host_u32 (mp->retval);
3868
3869   if (retval)
3870     goto end;
3871
3872   n = clib_net_to_host_u32 (mp->count);
3873
3874   for (i = 0; i < n; i++)
3875     {
3876       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3877     }
3878
3879 end:
3880   vam->retval = retval;
3881   vam->result_ready = 1;
3882 }
3883
3884 static void
3885   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3886   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3887 {
3888   vat_main_t *vam = &vat_main;
3889   vat_json_node_t root;
3890   u32 i, n;
3891   int retval = clib_net_to_host_u32 (mp->retval);
3892
3893   if (retval)
3894     goto end;
3895
3896   n = clib_net_to_host_u32 (mp->count);
3897   vat_json_init_array (&root);
3898
3899   for (i = 0; i < n; i++)
3900     {
3901       vat_json_array_add_uint (&root,
3902                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3903     }
3904
3905   vat_json_print (vam->ofp, &root);
3906   vat_json_free (&root);
3907
3908 end:
3909   vam->retval = retval;
3910   vam->result_ready = 1;
3911 }
3912
3913 static void
3914   vl_api_one_adjacencies_get_reply_t_handler
3915   (vl_api_one_adjacencies_get_reply_t * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918   u32 i, n;
3919   int retval = clib_net_to_host_u32 (mp->retval);
3920   vl_api_one_adjacency_t *a;
3921
3922   if (retval)
3923     goto end;
3924
3925   n = clib_net_to_host_u32 (mp->count);
3926
3927   for (i = 0; i < n; i++)
3928     {
3929       a = &mp->adjacencies[i];
3930       print (vam->ofp, "%U %40U",
3931              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3932              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3933     }
3934
3935 end:
3936   vam->retval = retval;
3937   vam->result_ready = 1;
3938 }
3939
3940 static void
3941   vl_api_one_adjacencies_get_reply_t_handler_json
3942   (vl_api_one_adjacencies_get_reply_t * mp)
3943 {
3944   u8 *s = 0;
3945   vat_main_t *vam = &vat_main;
3946   vat_json_node_t *e = 0, root;
3947   u32 i, n;
3948   int retval = clib_net_to_host_u32 (mp->retval);
3949   vl_api_one_adjacency_t *a;
3950
3951   if (retval)
3952     goto end;
3953
3954   n = clib_net_to_host_u32 (mp->count);
3955   vat_json_init_array (&root);
3956
3957   for (i = 0; i < n; i++)
3958     {
3959       e = vat_json_array_add (&root);
3960       a = &mp->adjacencies[i];
3961
3962       vat_json_init_object (e);
3963       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3964                   a->leid_prefix_len);
3965       vec_add1 (s, 0);
3966       vat_json_object_add_string_copy (e, "leid", s);
3967       vec_free (s);
3968
3969       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3970                   a->reid_prefix_len);
3971       vec_add1 (s, 0);
3972       vat_json_object_add_string_copy (e, "reid", s);
3973       vec_free (s);
3974     }
3975
3976   vat_json_print (vam->ofp, &root);
3977   vat_json_free (&root);
3978
3979 end:
3980   vam->retval = retval;
3981   vam->result_ready = 1;
3982 }
3983
3984 static void
3985 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3986 {
3987   vat_main_t *vam = &vat_main;
3988
3989   print (vam->ofp, "%=20U",
3990          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3991          mp->ip_address);
3992 }
3993
3994 static void
3995   vl_api_one_map_server_details_t_handler_json
3996   (vl_api_one_map_server_details_t * mp)
3997 {
3998   vat_main_t *vam = &vat_main;
3999   vat_json_node_t *node = NULL;
4000   struct in6_addr ip6;
4001   struct in_addr ip4;
4002
4003   if (VAT_JSON_ARRAY != vam->json_tree.type)
4004     {
4005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4006       vat_json_init_array (&vam->json_tree);
4007     }
4008   node = vat_json_array_add (&vam->json_tree);
4009
4010   vat_json_init_object (node);
4011   if (mp->is_ipv6)
4012     {
4013       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4014       vat_json_object_add_ip6 (node, "map-server", ip6);
4015     }
4016   else
4017     {
4018       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4019       vat_json_object_add_ip4 (node, "map-server", ip4);
4020     }
4021 }
4022
4023 static void
4024 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4025                                            * mp)
4026 {
4027   vat_main_t *vam = &vat_main;
4028
4029   print (vam->ofp, "%=20U",
4030          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4031          mp->ip_address);
4032 }
4033
4034 static void
4035   vl_api_one_map_resolver_details_t_handler_json
4036   (vl_api_one_map_resolver_details_t * mp)
4037 {
4038   vat_main_t *vam = &vat_main;
4039   vat_json_node_t *node = NULL;
4040   struct in6_addr ip6;
4041   struct in_addr ip4;
4042
4043   if (VAT_JSON_ARRAY != vam->json_tree.type)
4044     {
4045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4046       vat_json_init_array (&vam->json_tree);
4047     }
4048   node = vat_json_array_add (&vam->json_tree);
4049
4050   vat_json_init_object (node);
4051   if (mp->is_ipv6)
4052     {
4053       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4054       vat_json_object_add_ip6 (node, "map resolver", ip6);
4055     }
4056   else
4057     {
4058       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4059       vat_json_object_add_ip4 (node, "map resolver", ip4);
4060     }
4061 }
4062
4063 static void
4064 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4065 {
4066   vat_main_t *vam = &vat_main;
4067   i32 retval = ntohl (mp->retval);
4068
4069   if (0 <= retval)
4070     {
4071       print (vam->ofp, "feature: %s\ngpe: %s",
4072              mp->feature_status ? "enabled" : "disabled",
4073              mp->gpe_status ? "enabled" : "disabled");
4074     }
4075
4076   vam->retval = retval;
4077   vam->result_ready = 1;
4078 }
4079
4080 static void
4081   vl_api_show_one_status_reply_t_handler_json
4082   (vl_api_show_one_status_reply_t * mp)
4083 {
4084   vat_main_t *vam = &vat_main;
4085   vat_json_node_t node;
4086   u8 *gpe_status = NULL;
4087   u8 *feature_status = NULL;
4088
4089   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4090   feature_status = format (0, "%s",
4091                            mp->feature_status ? "enabled" : "disabled");
4092   vec_add1 (gpe_status, 0);
4093   vec_add1 (feature_status, 0);
4094
4095   vat_json_init_object (&node);
4096   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4097   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4098
4099   vec_free (gpe_status);
4100   vec_free (feature_status);
4101
4102   vat_json_print (vam->ofp, &node);
4103   vat_json_free (&node);
4104
4105   vam->retval = ntohl (mp->retval);
4106   vam->result_ready = 1;
4107 }
4108
4109 static void
4110   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4111   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4112 {
4113   vat_main_t *vam = &vat_main;
4114   i32 retval = ntohl (mp->retval);
4115
4116   if (retval >= 0)
4117     {
4118       print (vam->ofp, "%=20s", mp->locator_set_name);
4119     }
4120
4121   vam->retval = retval;
4122   vam->result_ready = 1;
4123 }
4124
4125 static void
4126   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4127   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4128 {
4129   vat_main_t *vam = &vat_main;
4130   vat_json_node_t *node = NULL;
4131
4132   if (VAT_JSON_ARRAY != vam->json_tree.type)
4133     {
4134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4135       vat_json_init_array (&vam->json_tree);
4136     }
4137   node = vat_json_array_add (&vam->json_tree);
4138
4139   vat_json_init_object (node);
4140   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4141
4142   vat_json_print (vam->ofp, node);
4143   vat_json_free (node);
4144
4145   vam->retval = ntohl (mp->retval);
4146   vam->result_ready = 1;
4147 }
4148
4149 static u8 *
4150 format_lisp_map_request_mode (u8 * s, va_list * args)
4151 {
4152   u32 mode = va_arg (*args, u32);
4153
4154   switch (mode)
4155     {
4156     case 0:
4157       return format (0, "dst-only");
4158     case 1:
4159       return format (0, "src-dst");
4160     }
4161   return 0;
4162 }
4163
4164 static void
4165   vl_api_show_one_map_request_mode_reply_t_handler
4166   (vl_api_show_one_map_request_mode_reply_t * mp)
4167 {
4168   vat_main_t *vam = &vat_main;
4169   i32 retval = ntohl (mp->retval);
4170
4171   if (0 <= retval)
4172     {
4173       u32 mode = mp->mode;
4174       print (vam->ofp, "map_request_mode: %U",
4175              format_lisp_map_request_mode, mode);
4176     }
4177
4178   vam->retval = retval;
4179   vam->result_ready = 1;
4180 }
4181
4182 static void
4183   vl_api_show_one_map_request_mode_reply_t_handler_json
4184   (vl_api_show_one_map_request_mode_reply_t * mp)
4185 {
4186   vat_main_t *vam = &vat_main;
4187   vat_json_node_t node;
4188   u8 *s = 0;
4189   u32 mode;
4190
4191   mode = mp->mode;
4192   s = format (0, "%U", format_lisp_map_request_mode, mode);
4193   vec_add1 (s, 0);
4194
4195   vat_json_init_object (&node);
4196   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4197   vat_json_print (vam->ofp, &node);
4198   vat_json_free (&node);
4199
4200   vec_free (s);
4201   vam->retval = ntohl (mp->retval);
4202   vam->result_ready = 1;
4203 }
4204
4205 static void
4206   vl_api_one_show_xtr_mode_reply_t_handler
4207   (vl_api_one_show_xtr_mode_reply_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210   i32 retval = ntohl (mp->retval);
4211
4212   if (0 <= retval)
4213     {
4214       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4215     }
4216
4217   vam->retval = retval;
4218   vam->result_ready = 1;
4219 }
4220
4221 static void
4222   vl_api_one_show_xtr_mode_reply_t_handler_json
4223   (vl_api_one_show_xtr_mode_reply_t * mp)
4224 {
4225   vat_main_t *vam = &vat_main;
4226   vat_json_node_t node;
4227   u8 *status = 0;
4228
4229   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4230   vec_add1 (status, 0);
4231
4232   vat_json_init_object (&node);
4233   vat_json_object_add_string_copy (&node, "status", status);
4234
4235   vec_free (status);
4236
4237   vat_json_print (vam->ofp, &node);
4238   vat_json_free (&node);
4239
4240   vam->retval = ntohl (mp->retval);
4241   vam->result_ready = 1;
4242 }
4243
4244 static void
4245   vl_api_one_show_pitr_mode_reply_t_handler
4246   (vl_api_one_show_pitr_mode_reply_t * mp)
4247 {
4248   vat_main_t *vam = &vat_main;
4249   i32 retval = ntohl (mp->retval);
4250
4251   if (0 <= retval)
4252     {
4253       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4254     }
4255
4256   vam->retval = retval;
4257   vam->result_ready = 1;
4258 }
4259
4260 static void
4261   vl_api_one_show_pitr_mode_reply_t_handler_json
4262   (vl_api_one_show_pitr_mode_reply_t * mp)
4263 {
4264   vat_main_t *vam = &vat_main;
4265   vat_json_node_t node;
4266   u8 *status = 0;
4267
4268   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4269   vec_add1 (status, 0);
4270
4271   vat_json_init_object (&node);
4272   vat_json_object_add_string_copy (&node, "status", status);
4273
4274   vec_free (status);
4275
4276   vat_json_print (vam->ofp, &node);
4277   vat_json_free (&node);
4278
4279   vam->retval = ntohl (mp->retval);
4280   vam->result_ready = 1;
4281 }
4282
4283 static void
4284   vl_api_one_show_petr_mode_reply_t_handler
4285   (vl_api_one_show_petr_mode_reply_t * mp)
4286 {
4287   vat_main_t *vam = &vat_main;
4288   i32 retval = ntohl (mp->retval);
4289
4290   if (0 <= retval)
4291     {
4292       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4293     }
4294
4295   vam->retval = retval;
4296   vam->result_ready = 1;
4297 }
4298
4299 static void
4300   vl_api_one_show_petr_mode_reply_t_handler_json
4301   (vl_api_one_show_petr_mode_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   vat_json_node_t node;
4305   u8 *status = 0;
4306
4307   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4308   vec_add1 (status, 0);
4309
4310   vat_json_init_object (&node);
4311   vat_json_object_add_string_copy (&node, "status", status);
4312
4313   vec_free (status);
4314
4315   vat_json_print (vam->ofp, &node);
4316   vat_json_free (&node);
4317
4318   vam->retval = ntohl (mp->retval);
4319   vam->result_ready = 1;
4320 }
4321
4322 static void
4323   vl_api_show_one_use_petr_reply_t_handler
4324   (vl_api_show_one_use_petr_reply_t * mp)
4325 {
4326   vat_main_t *vam = &vat_main;
4327   i32 retval = ntohl (mp->retval);
4328
4329   if (0 <= retval)
4330     {
4331       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4332       if (mp->status)
4333         {
4334           print (vam->ofp, "Proxy-ETR address; %U",
4335                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4336                  mp->address);
4337         }
4338     }
4339
4340   vam->retval = retval;
4341   vam->result_ready = 1;
4342 }
4343
4344 static void
4345   vl_api_show_one_use_petr_reply_t_handler_json
4346   (vl_api_show_one_use_petr_reply_t * mp)
4347 {
4348   vat_main_t *vam = &vat_main;
4349   vat_json_node_t node;
4350   u8 *status = 0;
4351   struct in_addr ip4;
4352   struct in6_addr ip6;
4353
4354   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4355   vec_add1 (status, 0);
4356
4357   vat_json_init_object (&node);
4358   vat_json_object_add_string_copy (&node, "status", status);
4359   if (mp->status)
4360     {
4361       if (mp->is_ip4)
4362         {
4363           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4364           vat_json_object_add_ip6 (&node, "address", ip6);
4365         }
4366       else
4367         {
4368           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4369           vat_json_object_add_ip4 (&node, "address", ip4);
4370         }
4371     }
4372
4373   vec_free (status);
4374
4375   vat_json_print (vam->ofp, &node);
4376   vat_json_free (&node);
4377
4378   vam->retval = ntohl (mp->retval);
4379   vam->result_ready = 1;
4380 }
4381
4382 static void
4383   vl_api_show_one_nsh_mapping_reply_t_handler
4384   (vl_api_show_one_nsh_mapping_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   if (0 <= retval)
4390     {
4391       print (vam->ofp, "%-20s%-16s",
4392              mp->is_set ? "set" : "not-set",
4393              mp->is_set ? (char *) mp->locator_set_name : "");
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401   vl_api_show_one_nsh_mapping_reply_t_handler_json
4402   (vl_api_show_one_nsh_mapping_reply_t * mp)
4403 {
4404   vat_main_t *vam = &vat_main;
4405   vat_json_node_t node;
4406   u8 *status = 0;
4407
4408   status = format (0, "%s", mp->is_set ? "yes" : "no");
4409   vec_add1 (status, 0);
4410
4411   vat_json_init_object (&node);
4412   vat_json_object_add_string_copy (&node, "is_set", status);
4413   if (mp->is_set)
4414     {
4415       vat_json_object_add_string_copy (&node, "locator_set",
4416                                        mp->locator_set_name);
4417     }
4418
4419   vec_free (status);
4420
4421   vat_json_print (vam->ofp, &node);
4422   vat_json_free (&node);
4423
4424   vam->retval = ntohl (mp->retval);
4425   vam->result_ready = 1;
4426 }
4427
4428 static void
4429   vl_api_show_one_map_register_ttl_reply_t_handler
4430   (vl_api_show_one_map_register_ttl_reply_t * mp)
4431 {
4432   vat_main_t *vam = &vat_main;
4433   i32 retval = ntohl (mp->retval);
4434
4435   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4436
4437   if (0 <= retval)
4438     {
4439       print (vam->ofp, "ttl: %u", mp->ttl);
4440     }
4441
4442   vam->retval = retval;
4443   vam->result_ready = 1;
4444 }
4445
4446 static void
4447   vl_api_show_one_map_register_ttl_reply_t_handler_json
4448   (vl_api_show_one_map_register_ttl_reply_t * mp)
4449 {
4450   vat_main_t *vam = &vat_main;
4451   vat_json_node_t node;
4452
4453   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4454   vat_json_init_object (&node);
4455   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4456
4457   vat_json_print (vam->ofp, &node);
4458   vat_json_free (&node);
4459
4460   vam->retval = ntohl (mp->retval);
4461   vam->result_ready = 1;
4462 }
4463
4464 static void
4465 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4466 {
4467   vat_main_t *vam = &vat_main;
4468   i32 retval = ntohl (mp->retval);
4469
4470   if (0 <= retval)
4471     {
4472       print (vam->ofp, "%-20s%-16s",
4473              mp->status ? "enabled" : "disabled",
4474              mp->status ? (char *) mp->locator_set_name : "");
4475     }
4476
4477   vam->retval = retval;
4478   vam->result_ready = 1;
4479 }
4480
4481 static void
4482 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4483 {
4484   vat_main_t *vam = &vat_main;
4485   vat_json_node_t node;
4486   u8 *status = 0;
4487
4488   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4489   vec_add1 (status, 0);
4490
4491   vat_json_init_object (&node);
4492   vat_json_object_add_string_copy (&node, "status", status);
4493   if (mp->status)
4494     {
4495       vat_json_object_add_string_copy (&node, "locator_set",
4496                                        mp->locator_set_name);
4497     }
4498
4499   vec_free (status);
4500
4501   vat_json_print (vam->ofp, &node);
4502   vat_json_free (&node);
4503
4504   vam->retval = ntohl (mp->retval);
4505   vam->result_ready = 1;
4506 }
4507
4508 static u8 *
4509 format_policer_type (u8 * s, va_list * va)
4510 {
4511   u32 i = va_arg (*va, u32);
4512
4513   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4514     s = format (s, "1r2c");
4515   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4516     s = format (s, "1r3c");
4517   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4518     s = format (s, "2r3c-2698");
4519   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4520     s = format (s, "2r3c-4115");
4521   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4522     s = format (s, "2r3c-mef5cf1");
4523   else
4524     s = format (s, "ILLEGAL");
4525   return s;
4526 }
4527
4528 static u8 *
4529 format_policer_rate_type (u8 * s, va_list * va)
4530 {
4531   u32 i = va_arg (*va, u32);
4532
4533   if (i == SSE2_QOS_RATE_KBPS)
4534     s = format (s, "kbps");
4535   else if (i == SSE2_QOS_RATE_PPS)
4536     s = format (s, "pps");
4537   else
4538     s = format (s, "ILLEGAL");
4539   return s;
4540 }
4541
4542 static u8 *
4543 format_policer_round_type (u8 * s, va_list * va)
4544 {
4545   u32 i = va_arg (*va, u32);
4546
4547   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4548     s = format (s, "closest");
4549   else if (i == SSE2_QOS_ROUND_TO_UP)
4550     s = format (s, "up");
4551   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4552     s = format (s, "down");
4553   else
4554     s = format (s, "ILLEGAL");
4555   return s;
4556 }
4557
4558 static u8 *
4559 format_policer_action_type (u8 * s, va_list * va)
4560 {
4561   u32 i = va_arg (*va, u32);
4562
4563   if (i == SSE2_QOS_ACTION_DROP)
4564     s = format (s, "drop");
4565   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4566     s = format (s, "transmit");
4567   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4568     s = format (s, "mark-and-transmit");
4569   else
4570     s = format (s, "ILLEGAL");
4571   return s;
4572 }
4573
4574 static u8 *
4575 format_dscp (u8 * s, va_list * va)
4576 {
4577   u32 i = va_arg (*va, u32);
4578   char *t = 0;
4579
4580   switch (i)
4581     {
4582 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4583       foreach_vnet_dscp
4584 #undef _
4585     default:
4586       return format (s, "ILLEGAL");
4587     }
4588   s = format (s, "%s", t);
4589   return s;
4590 }
4591
4592 static void
4593 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4594 {
4595   vat_main_t *vam = &vat_main;
4596   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4597
4598   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4599     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4600   else
4601     conform_dscp_str = format (0, "");
4602
4603   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4604     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4605   else
4606     exceed_dscp_str = format (0, "");
4607
4608   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4609     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4610   else
4611     violate_dscp_str = format (0, "");
4612
4613   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4614          "rate type %U, round type %U, %s rate, %s color-aware, "
4615          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4616          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4617          "conform action %U%s, exceed action %U%s, violate action %U%s",
4618          mp->name,
4619          format_policer_type, mp->type,
4620          ntohl (mp->cir),
4621          ntohl (mp->eir),
4622          clib_net_to_host_u64 (mp->cb),
4623          clib_net_to_host_u64 (mp->eb),
4624          format_policer_rate_type, mp->rate_type,
4625          format_policer_round_type, mp->round_type,
4626          mp->single_rate ? "single" : "dual",
4627          mp->color_aware ? "is" : "not",
4628          ntohl (mp->cir_tokens_per_period),
4629          ntohl (mp->pir_tokens_per_period),
4630          ntohl (mp->scale),
4631          ntohl (mp->current_limit),
4632          ntohl (mp->current_bucket),
4633          ntohl (mp->extended_limit),
4634          ntohl (mp->extended_bucket),
4635          clib_net_to_host_u64 (mp->last_update_time),
4636          format_policer_action_type, mp->conform_action_type,
4637          conform_dscp_str,
4638          format_policer_action_type, mp->exceed_action_type,
4639          exceed_dscp_str,
4640          format_policer_action_type, mp->violate_action_type,
4641          violate_dscp_str);
4642
4643   vec_free (conform_dscp_str);
4644   vec_free (exceed_dscp_str);
4645   vec_free (violate_dscp_str);
4646 }
4647
4648 static void vl_api_policer_details_t_handler_json
4649   (vl_api_policer_details_t * mp)
4650 {
4651   vat_main_t *vam = &vat_main;
4652   vat_json_node_t *node;
4653   u8 *rate_type_str, *round_type_str, *type_str;
4654   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4655
4656   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4657   round_type_str =
4658     format (0, "%U", format_policer_round_type, mp->round_type);
4659   type_str = format (0, "%U", format_policer_type, mp->type);
4660   conform_action_str = format (0, "%U", format_policer_action_type,
4661                                mp->conform_action_type);
4662   exceed_action_str = format (0, "%U", format_policer_action_type,
4663                               mp->exceed_action_type);
4664   violate_action_str = format (0, "%U", format_policer_action_type,
4665                                mp->violate_action_type);
4666
4667   if (VAT_JSON_ARRAY != vam->json_tree.type)
4668     {
4669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4670       vat_json_init_array (&vam->json_tree);
4671     }
4672   node = vat_json_array_add (&vam->json_tree);
4673
4674   vat_json_init_object (node);
4675   vat_json_object_add_string_copy (node, "name", mp->name);
4676   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4677   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4678   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4679   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4680   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4681   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4682   vat_json_object_add_string_copy (node, "type", type_str);
4683   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4684   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4685   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4686   vat_json_object_add_uint (node, "cir_tokens_per_period",
4687                             ntohl (mp->cir_tokens_per_period));
4688   vat_json_object_add_uint (node, "eir_tokens_per_period",
4689                             ntohl (mp->pir_tokens_per_period));
4690   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4691   vat_json_object_add_uint (node, "current_bucket",
4692                             ntohl (mp->current_bucket));
4693   vat_json_object_add_uint (node, "extended_limit",
4694                             ntohl (mp->extended_limit));
4695   vat_json_object_add_uint (node, "extended_bucket",
4696                             ntohl (mp->extended_bucket));
4697   vat_json_object_add_uint (node, "last_update_time",
4698                             ntohl (mp->last_update_time));
4699   vat_json_object_add_string_copy (node, "conform_action",
4700                                    conform_action_str);
4701   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4702     {
4703       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4704       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4705       vec_free (dscp_str);
4706     }
4707   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4708   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4709     {
4710       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4711       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4712       vec_free (dscp_str);
4713     }
4714   vat_json_object_add_string_copy (node, "violate_action",
4715                                    violate_action_str);
4716   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4717     {
4718       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4719       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4720       vec_free (dscp_str);
4721     }
4722
4723   vec_free (rate_type_str);
4724   vec_free (round_type_str);
4725   vec_free (type_str);
4726   vec_free (conform_action_str);
4727   vec_free (exceed_action_str);
4728   vec_free (violate_action_str);
4729 }
4730
4731 static void
4732 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4733                                            mp)
4734 {
4735   vat_main_t *vam = &vat_main;
4736   int i, count = ntohl (mp->count);
4737
4738   if (count > 0)
4739     print (vam->ofp, "classify table ids (%d) : ", count);
4740   for (i = 0; i < count; i++)
4741     {
4742       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4743       print (vam->ofp, (i < count - 1) ? "," : "");
4744     }
4745   vam->retval = ntohl (mp->retval);
4746   vam->result_ready = 1;
4747 }
4748
4749 static void
4750   vl_api_classify_table_ids_reply_t_handler_json
4751   (vl_api_classify_table_ids_reply_t * mp)
4752 {
4753   vat_main_t *vam = &vat_main;
4754   int i, count = ntohl (mp->count);
4755
4756   if (count > 0)
4757     {
4758       vat_json_node_t node;
4759
4760       vat_json_init_object (&node);
4761       for (i = 0; i < count; i++)
4762         {
4763           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4764         }
4765       vat_json_print (vam->ofp, &node);
4766       vat_json_free (&node);
4767     }
4768   vam->retval = ntohl (mp->retval);
4769   vam->result_ready = 1;
4770 }
4771
4772 static void
4773   vl_api_classify_table_by_interface_reply_t_handler
4774   (vl_api_classify_table_by_interface_reply_t * mp)
4775 {
4776   vat_main_t *vam = &vat_main;
4777   u32 table_id;
4778
4779   table_id = ntohl (mp->l2_table_id);
4780   if (table_id != ~0)
4781     print (vam->ofp, "l2 table id : %d", table_id);
4782   else
4783     print (vam->ofp, "l2 table id : No input ACL tables configured");
4784   table_id = ntohl (mp->ip4_table_id);
4785   if (table_id != ~0)
4786     print (vam->ofp, "ip4 table id : %d", table_id);
4787   else
4788     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4789   table_id = ntohl (mp->ip6_table_id);
4790   if (table_id != ~0)
4791     print (vam->ofp, "ip6 table id : %d", table_id);
4792   else
4793     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4794   vam->retval = ntohl (mp->retval);
4795   vam->result_ready = 1;
4796 }
4797
4798 static void
4799   vl_api_classify_table_by_interface_reply_t_handler_json
4800   (vl_api_classify_table_by_interface_reply_t * mp)
4801 {
4802   vat_main_t *vam = &vat_main;
4803   vat_json_node_t node;
4804
4805   vat_json_init_object (&node);
4806
4807   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4808   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4809   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4810
4811   vat_json_print (vam->ofp, &node);
4812   vat_json_free (&node);
4813
4814   vam->retval = ntohl (mp->retval);
4815   vam->result_ready = 1;
4816 }
4817
4818 static void vl_api_policer_add_del_reply_t_handler
4819   (vl_api_policer_add_del_reply_t * mp)
4820 {
4821   vat_main_t *vam = &vat_main;
4822   i32 retval = ntohl (mp->retval);
4823   if (vam->async_mode)
4824     {
4825       vam->async_errors += (retval < 0);
4826     }
4827   else
4828     {
4829       vam->retval = retval;
4830       vam->result_ready = 1;
4831       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4832         /*
4833          * Note: this is just barely thread-safe, depends on
4834          * the main thread spinning waiting for an answer...
4835          */
4836         errmsg ("policer index %d", ntohl (mp->policer_index));
4837     }
4838 }
4839
4840 static void vl_api_policer_add_del_reply_t_handler_json
4841   (vl_api_policer_add_del_reply_t * mp)
4842 {
4843   vat_main_t *vam = &vat_main;
4844   vat_json_node_t node;
4845
4846   vat_json_init_object (&node);
4847   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4848   vat_json_object_add_uint (&node, "policer_index",
4849                             ntohl (mp->policer_index));
4850
4851   vat_json_print (vam->ofp, &node);
4852   vat_json_free (&node);
4853
4854   vam->retval = ntohl (mp->retval);
4855   vam->result_ready = 1;
4856 }
4857
4858 /* Format hex dump. */
4859 u8 *
4860 format_hex_bytes (u8 * s, va_list * va)
4861 {
4862   u8 *bytes = va_arg (*va, u8 *);
4863   int n_bytes = va_arg (*va, int);
4864   uword i;
4865
4866   /* Print short or long form depending on byte count. */
4867   uword short_form = n_bytes <= 32;
4868   u32 indent = format_get_indent (s);
4869
4870   if (n_bytes == 0)
4871     return s;
4872
4873   for (i = 0; i < n_bytes; i++)
4874     {
4875       if (!short_form && (i % 32) == 0)
4876         s = format (s, "%08x: ", i);
4877       s = format (s, "%02x", bytes[i]);
4878       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4879         s = format (s, "\n%U", format_white_space, indent);
4880     }
4881
4882   return s;
4883 }
4884
4885 static void
4886 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4887                                             * mp)
4888 {
4889   vat_main_t *vam = &vat_main;
4890   i32 retval = ntohl (mp->retval);
4891   if (retval == 0)
4892     {
4893       print (vam->ofp, "classify table info :");
4894       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4895              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4896              ntohl (mp->miss_next_index));
4897       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4898              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4899              ntohl (mp->match_n_vectors));
4900       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4901              ntohl (mp->mask_length));
4902     }
4903   vam->retval = retval;
4904   vam->result_ready = 1;
4905 }
4906
4907 static void
4908   vl_api_classify_table_info_reply_t_handler_json
4909   (vl_api_classify_table_info_reply_t * mp)
4910 {
4911   vat_main_t *vam = &vat_main;
4912   vat_json_node_t node;
4913
4914   i32 retval = ntohl (mp->retval);
4915   if (retval == 0)
4916     {
4917       vat_json_init_object (&node);
4918
4919       vat_json_object_add_int (&node, "sessions",
4920                                ntohl (mp->active_sessions));
4921       vat_json_object_add_int (&node, "nexttbl",
4922                                ntohl (mp->next_table_index));
4923       vat_json_object_add_int (&node, "nextnode",
4924                                ntohl (mp->miss_next_index));
4925       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4926       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4927       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4928       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4929                       ntohl (mp->mask_length), 0);
4930       vat_json_object_add_string_copy (&node, "mask", s);
4931
4932       vat_json_print (vam->ofp, &node);
4933       vat_json_free (&node);
4934     }
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void
4940 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4941                                            mp)
4942 {
4943   vat_main_t *vam = &vat_main;
4944
4945   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4946          ntohl (mp->hit_next_index), ntohl (mp->advance),
4947          ntohl (mp->opaque_index));
4948   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4949          ntohl (mp->match_length));
4950 }
4951
4952 static void
4953   vl_api_classify_session_details_t_handler_json
4954   (vl_api_classify_session_details_t * mp)
4955 {
4956   vat_main_t *vam = &vat_main;
4957   vat_json_node_t *node = NULL;
4958
4959   if (VAT_JSON_ARRAY != vam->json_tree.type)
4960     {
4961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4962       vat_json_init_array (&vam->json_tree);
4963     }
4964   node = vat_json_array_add (&vam->json_tree);
4965
4966   vat_json_init_object (node);
4967   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4968   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4969   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4970   u8 *s =
4971     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4972             0);
4973   vat_json_object_add_string_copy (node, "match", s);
4974 }
4975
4976 static void vl_api_pg_create_interface_reply_t_handler
4977   (vl_api_pg_create_interface_reply_t * mp)
4978 {
4979   vat_main_t *vam = &vat_main;
4980
4981   vam->retval = ntohl (mp->retval);
4982   vam->result_ready = 1;
4983 }
4984
4985 static void vl_api_pg_create_interface_reply_t_handler_json
4986   (vl_api_pg_create_interface_reply_t * mp)
4987 {
4988   vat_main_t *vam = &vat_main;
4989   vat_json_node_t node;
4990
4991   i32 retval = ntohl (mp->retval);
4992   if (retval == 0)
4993     {
4994       vat_json_init_object (&node);
4995
4996       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4997
4998       vat_json_print (vam->ofp, &node);
4999       vat_json_free (&node);
5000     }
5001   vam->retval = ntohl (mp->retval);
5002   vam->result_ready = 1;
5003 }
5004
5005 static void vl_api_policer_classify_details_t_handler
5006   (vl_api_policer_classify_details_t * mp)
5007 {
5008   vat_main_t *vam = &vat_main;
5009
5010   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5011          ntohl (mp->table_index));
5012 }
5013
5014 static void vl_api_policer_classify_details_t_handler_json
5015   (vl_api_policer_classify_details_t * mp)
5016 {
5017   vat_main_t *vam = &vat_main;
5018   vat_json_node_t *node;
5019
5020   if (VAT_JSON_ARRAY != vam->json_tree.type)
5021     {
5022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5023       vat_json_init_array (&vam->json_tree);
5024     }
5025   node = vat_json_array_add (&vam->json_tree);
5026
5027   vat_json_init_object (node);
5028   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5029   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5030 }
5031
5032 static void vl_api_flow_classify_details_t_handler
5033   (vl_api_flow_classify_details_t * mp)
5034 {
5035   vat_main_t *vam = &vat_main;
5036
5037   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5038          ntohl (mp->table_index));
5039 }
5040
5041 static void vl_api_flow_classify_details_t_handler_json
5042   (vl_api_flow_classify_details_t * mp)
5043 {
5044   vat_main_t *vam = &vat_main;
5045   vat_json_node_t *node;
5046
5047   if (VAT_JSON_ARRAY != vam->json_tree.type)
5048     {
5049       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5050       vat_json_init_array (&vam->json_tree);
5051     }
5052   node = vat_json_array_add (&vam->json_tree);
5053
5054   vat_json_init_object (node);
5055   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5056   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5057 }
5058
5059 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5060 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5061 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5062 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5063 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5064 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5065 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5066 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5067 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5068 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5069
5070 /*
5071  * Generate boilerplate reply handlers, which
5072  * dig the return value out of the xxx_reply_t API message,
5073  * stick it into vam->retval, and set vam->result_ready
5074  *
5075  * Could also do this by pointing N message decode slots at
5076  * a single function, but that could break in subtle ways.
5077  */
5078
5079 #define foreach_standard_reply_retval_handler           \
5080 _(sw_interface_set_flags_reply)                         \
5081 _(sw_interface_add_del_address_reply)                   \
5082 _(sw_interface_set_rx_mode_reply)                       \
5083 _(sw_interface_set_rx_placement_reply)                  \
5084 _(sw_interface_set_table_reply)                         \
5085 _(sw_interface_set_mpls_enable_reply)                   \
5086 _(sw_interface_set_vpath_reply)                         \
5087 _(sw_interface_set_vxlan_bypass_reply)                  \
5088 _(sw_interface_set_geneve_bypass_reply)                 \
5089 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5090 _(sw_interface_set_l2_bridge_reply)                     \
5091 _(sw_interface_set_bond_weight_reply)                   \
5092 _(bridge_domain_add_del_reply)                          \
5093 _(sw_interface_set_l2_xconnect_reply)                   \
5094 _(l2fib_add_del_reply)                                  \
5095 _(l2fib_flush_int_reply)                                \
5096 _(l2fib_flush_bd_reply)                                 \
5097 _(ip_route_add_del_reply)                               \
5098 _(ip_table_add_del_reply)                               \
5099 _(ip_mroute_add_del_reply)                              \
5100 _(mpls_route_add_del_reply)                             \
5101 _(mpls_table_add_del_reply)                             \
5102 _(mpls_ip_bind_unbind_reply)                            \
5103 _(bier_route_add_del_reply)                             \
5104 _(bier_table_add_del_reply)                             \
5105 _(proxy_arp_add_del_reply)                              \
5106 _(proxy_arp_intfc_enable_disable_reply)                 \
5107 _(sw_interface_set_unnumbered_reply)                    \
5108 _(ip_neighbor_add_del_reply)                            \
5109 _(reset_fib_reply)                                      \
5110 _(dhcp_proxy_config_reply)                              \
5111 _(dhcp_proxy_set_vss_reply)                             \
5112 _(dhcp_client_config_reply)                             \
5113 _(set_ip_flow_hash_reply)                               \
5114 _(sw_interface_ip6_enable_disable_reply)                \
5115 _(ip6nd_proxy_add_del_reply)                            \
5116 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5117 _(sw_interface_ip6nd_ra_config_reply)                   \
5118 _(set_arp_neighbor_limit_reply)                         \
5119 _(l2_patch_add_del_reply)                               \
5120 _(sr_mpls_policy_add_reply)                             \
5121 _(sr_mpls_policy_mod_reply)                             \
5122 _(sr_mpls_policy_del_reply)                             \
5123 _(sr_policy_add_reply)                                  \
5124 _(sr_policy_mod_reply)                                  \
5125 _(sr_policy_del_reply)                                  \
5126 _(sr_localsid_add_del_reply)                            \
5127 _(sr_steering_add_del_reply)                            \
5128 _(classify_add_del_session_reply)                       \
5129 _(classify_set_interface_ip_table_reply)                \
5130 _(classify_set_interface_l2_tables_reply)               \
5131 _(l2tpv3_set_tunnel_cookies_reply)                      \
5132 _(l2tpv3_interface_enable_disable_reply)                \
5133 _(l2tpv3_set_lookup_key_reply)                          \
5134 _(l2_fib_clear_table_reply)                             \
5135 _(l2_interface_efp_filter_reply)                        \
5136 _(l2_interface_vlan_tag_rewrite_reply)                  \
5137 _(modify_vhost_user_if_reply)                           \
5138 _(delete_vhost_user_if_reply)                           \
5139 _(ip_probe_neighbor_reply)                              \
5140 _(ip_scan_neighbor_enable_disable_reply)                \
5141 _(want_ip4_arp_events_reply)                            \
5142 _(want_ip6_nd_events_reply)                             \
5143 _(want_l2_macs_events_reply)                            \
5144 _(input_acl_set_interface_reply)                        \
5145 _(ipsec_spd_add_del_reply)                              \
5146 _(ipsec_interface_add_del_spd_reply)                    \
5147 _(ipsec_spd_entry_add_del_reply)                        \
5148 _(ipsec_sad_entry_add_del_reply)                        \
5149 _(ipsec_tunnel_if_add_del_reply)                        \
5150 _(ipsec_tunnel_if_set_sa_reply)                         \
5151 _(delete_loopback_reply)                                \
5152 _(bd_ip_mac_add_del_reply)                              \
5153 _(bd_ip_mac_flush_reply)                                \
5154 _(want_interface_events_reply)                          \
5155 _(cop_interface_enable_disable_reply)                   \
5156 _(cop_whitelist_enable_disable_reply)                   \
5157 _(sw_interface_clear_stats_reply)                       \
5158 _(ioam_enable_reply)                                    \
5159 _(ioam_disable_reply)                                   \
5160 _(one_add_del_locator_reply)                            \
5161 _(one_add_del_local_eid_reply)                          \
5162 _(one_add_del_remote_mapping_reply)                     \
5163 _(one_add_del_adjacency_reply)                          \
5164 _(one_add_del_map_resolver_reply)                       \
5165 _(one_add_del_map_server_reply)                         \
5166 _(one_enable_disable_reply)                             \
5167 _(one_rloc_probe_enable_disable_reply)                  \
5168 _(one_map_register_enable_disable_reply)                \
5169 _(one_map_register_set_ttl_reply)                       \
5170 _(one_set_transport_protocol_reply)                     \
5171 _(one_map_register_fallback_threshold_reply)            \
5172 _(one_pitr_set_locator_set_reply)                       \
5173 _(one_map_request_mode_reply)                           \
5174 _(one_add_del_map_request_itr_rlocs_reply)              \
5175 _(one_eid_table_add_del_map_reply)                      \
5176 _(one_use_petr_reply)                                   \
5177 _(one_stats_enable_disable_reply)                       \
5178 _(one_add_del_l2_arp_entry_reply)                       \
5179 _(one_add_del_ndp_entry_reply)                          \
5180 _(one_stats_flush_reply)                                \
5181 _(one_enable_disable_xtr_mode_reply)                    \
5182 _(one_enable_disable_pitr_mode_reply)                   \
5183 _(one_enable_disable_petr_mode_reply)                   \
5184 _(gpe_enable_disable_reply)                             \
5185 _(gpe_set_encap_mode_reply)                             \
5186 _(gpe_add_del_iface_reply)                              \
5187 _(gpe_add_del_native_fwd_rpath_reply)                   \
5188 _(af_packet_delete_reply)                               \
5189 _(policer_classify_set_interface_reply)                 \
5190 _(netmap_create_reply)                                  \
5191 _(netmap_delete_reply)                                  \
5192 _(set_ipfix_exporter_reply)                             \
5193 _(set_ipfix_classify_stream_reply)                      \
5194 _(ipfix_classify_table_add_del_reply)                   \
5195 _(flow_classify_set_interface_reply)                    \
5196 _(sw_interface_span_enable_disable_reply)               \
5197 _(pg_capture_reply)                                     \
5198 _(pg_enable_disable_reply)                              \
5199 _(ip_source_and_port_range_check_add_del_reply)         \
5200 _(ip_source_and_port_range_check_interface_add_del_reply)\
5201 _(delete_subif_reply)                                   \
5202 _(l2_interface_pbb_tag_rewrite_reply)                   \
5203 _(set_punt_reply)                                       \
5204 _(feature_enable_disable_reply)                         \
5205 _(sw_interface_tag_add_del_reply)                       \
5206 _(hw_interface_set_mtu_reply)                           \
5207 _(p2p_ethernet_add_reply)                               \
5208 _(p2p_ethernet_del_reply)                               \
5209 _(lldp_config_reply)                                    \
5210 _(sw_interface_set_lldp_reply)                          \
5211 _(tcp_configure_src_addresses_reply)                    \
5212 _(session_rule_add_del_reply)                           \
5213 _(ip_container_proxy_add_del_reply)                     \
5214 _(output_acl_set_interface_reply)                       \
5215 _(qos_record_enable_disable_reply)
5216
5217 #define _(n)                                    \
5218     static void vl_api_##n##_t_handler          \
5219     (vl_api_##n##_t * mp)                       \
5220     {                                           \
5221         vat_main_t * vam = &vat_main;           \
5222         i32 retval = ntohl(mp->retval);         \
5223         if (vam->async_mode) {                  \
5224             vam->async_errors += (retval < 0);  \
5225         } else {                                \
5226             vam->retval = retval;               \
5227             vam->result_ready = 1;              \
5228         }                                       \
5229     }
5230 foreach_standard_reply_retval_handler;
5231 #undef _
5232
5233 #define _(n)                                    \
5234     static void vl_api_##n##_t_handler_json     \
5235     (vl_api_##n##_t * mp)                       \
5236     {                                           \
5237         vat_main_t * vam = &vat_main;           \
5238         vat_json_node_t node;                   \
5239         vat_json_init_object(&node);            \
5240         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5241         vat_json_print(vam->ofp, &node);        \
5242         vam->retval = ntohl(mp->retval);        \
5243         vam->result_ready = 1;                  \
5244     }
5245 foreach_standard_reply_retval_handler;
5246 #undef _
5247
5248 /*
5249  * Table of message reply handlers, must include boilerplate handlers
5250  * we just generated
5251  */
5252
5253 #define foreach_vpe_api_reply_msg                                       \
5254 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5255 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5256 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5257 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5258 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5259 _(CLI_REPLY, cli_reply)                                                 \
5260 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5261 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5262   sw_interface_add_del_address_reply)                                   \
5263 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5264 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5265 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5266 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5267 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5268 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5269 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5270 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5271 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5272 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5273   sw_interface_set_l2_xconnect_reply)                                   \
5274 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5275   sw_interface_set_l2_bridge_reply)                                     \
5276 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5277 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5278 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5279 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5280 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5281 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5282 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5283 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5284 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5285 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5286 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5287 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5288 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5289 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5290 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5291 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5292 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5293 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5294 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5295 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5296 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5297 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5298 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5299 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5300 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5301 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5302 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5303 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5304 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5305 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5306 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5307   proxy_arp_intfc_enable_disable_reply)                                 \
5308 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5309 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5310   sw_interface_set_unnumbered_reply)                                    \
5311 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5312 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5313 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5314 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5315 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5316 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5317 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5318 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5319 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5320 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5321   sw_interface_ip6_enable_disable_reply)                                \
5322 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5323 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5324 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5325   sw_interface_ip6nd_ra_prefix_reply)                                   \
5326 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5327   sw_interface_ip6nd_ra_config_reply)                                   \
5328 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5329 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5330 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5331 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5332 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5333 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5334 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5335 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5336 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5337 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5338 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5339 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5340 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5341 classify_set_interface_ip_table_reply)                                  \
5342 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5343   classify_set_interface_l2_tables_reply)                               \
5344 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5345 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5346 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5347 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5348 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5349   l2tpv3_interface_enable_disable_reply)                                \
5350 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5351 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5352 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5353 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5354 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5355 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5356 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5357 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5358 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5359 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5360 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5361 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5362 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5363 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5364 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5365 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5366 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5367 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5368 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5369 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5370 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5371 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5372 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5373 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5374 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5375 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5376 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5377 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5378 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5379 _(L2_MACS_EVENT, l2_macs_event)                                         \
5380 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5381 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5382 _(IP_DETAILS, ip_details)                                               \
5383 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5384 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5385 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5386 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5387 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5388 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5389 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5390 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5391 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5392 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5393 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5394 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5395 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5396 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5397 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5398 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5399 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5400 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5401 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5402 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5403 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5404 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5405 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5406 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5407 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5408 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5409 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5410 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5411 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5412   one_map_register_enable_disable_reply)                                \
5413 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5414 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5415 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5416 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5417   one_map_register_fallback_threshold_reply)                            \
5418 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5419   one_rloc_probe_enable_disable_reply)                                  \
5420 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5421 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5422 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5423 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5424 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5425 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5426 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5427 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5428 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5429 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5430 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5431 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5432 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5433 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5434 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5435 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5436   show_one_stats_enable_disable_reply)                                  \
5437 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5438 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5439 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5440 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5441 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5442 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5443 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5444 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5445   one_enable_disable_pitr_mode_reply)                                   \
5446 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5447   one_enable_disable_petr_mode_reply)                                   \
5448 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5449 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5450 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5451 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5452 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5453 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5454 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5455 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5456 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5457 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5458 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5459 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5460   gpe_add_del_native_fwd_rpath_reply)                                   \
5461 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5462   gpe_fwd_entry_path_details)                                           \
5463 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5464 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5465   one_add_del_map_request_itr_rlocs_reply)                              \
5466 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5467   one_get_map_request_itr_rlocs_reply)                                  \
5468 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5469 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5470 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5471 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5472 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5473 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5474   show_one_map_register_state_reply)                                    \
5475 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5476 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5477   show_one_map_register_fallback_threshold_reply)                       \
5478 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5479 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5480 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5481 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5482 _(POLICER_DETAILS, policer_details)                                     \
5483 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5484 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5485 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5486 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5487 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5488 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5489 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5490 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5491 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5492 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5493 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5494 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5495 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5496 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5497 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5498 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5499 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5500 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5501 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5502 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5503 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5504 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5505 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5506 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5507 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5508 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5509  ip_source_and_port_range_check_add_del_reply)                          \
5510 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5511  ip_source_and_port_range_check_interface_add_del_reply)                \
5512 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5513 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5514 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5515 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5516 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5517 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5518 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5519 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5520 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5521 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5522 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5523 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5524 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5525 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5526 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5527 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5528 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5529 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5530 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5531 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5532 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5533 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5534
5535 #define foreach_standalone_reply_msg                                    \
5536 _(SW_INTERFACE_EVENT, sw_interface_event)
5537
5538 typedef struct
5539 {
5540   u8 *name;
5541   u32 value;
5542 } name_sort_t;
5543
5544 #define STR_VTR_OP_CASE(op)     \
5545     case L2_VTR_ ## op:         \
5546         return "" # op;
5547
5548 static const char *
5549 str_vtr_op (u32 vtr_op)
5550 {
5551   switch (vtr_op)
5552     {
5553       STR_VTR_OP_CASE (DISABLED);
5554       STR_VTR_OP_CASE (PUSH_1);
5555       STR_VTR_OP_CASE (PUSH_2);
5556       STR_VTR_OP_CASE (POP_1);
5557       STR_VTR_OP_CASE (POP_2);
5558       STR_VTR_OP_CASE (TRANSLATE_1_1);
5559       STR_VTR_OP_CASE (TRANSLATE_1_2);
5560       STR_VTR_OP_CASE (TRANSLATE_2_1);
5561       STR_VTR_OP_CASE (TRANSLATE_2_2);
5562     }
5563
5564   return "UNKNOWN";
5565 }
5566
5567 static int
5568 dump_sub_interface_table (vat_main_t * vam)
5569 {
5570   const sw_interface_subif_t *sub = NULL;
5571
5572   if (vam->json_output)
5573     {
5574       clib_warning
5575         ("JSON output supported only for VPE API calls and dump_stats_table");
5576       return -99;
5577     }
5578
5579   print (vam->ofp,
5580          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5581          "Interface", "sw_if_index",
5582          "sub id", "dot1ad", "tags", "outer id",
5583          "inner id", "exact", "default", "outer any", "inner any");
5584
5585   vec_foreach (sub, vam->sw_if_subif_table)
5586   {
5587     print (vam->ofp,
5588            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5589            sub->interface_name,
5590            sub->sw_if_index,
5591            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5592            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5593            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5594            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5595     if (sub->vtr_op != L2_VTR_DISABLED)
5596       {
5597         print (vam->ofp,
5598                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5599                "tag1: %d tag2: %d ]",
5600                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5601                sub->vtr_tag1, sub->vtr_tag2);
5602       }
5603   }
5604
5605   return 0;
5606 }
5607
5608 static int
5609 name_sort_cmp (void *a1, void *a2)
5610 {
5611   name_sort_t *n1 = a1;
5612   name_sort_t *n2 = a2;
5613
5614   return strcmp ((char *) n1->name, (char *) n2->name);
5615 }
5616
5617 static int
5618 dump_interface_table (vat_main_t * vam)
5619 {
5620   hash_pair_t *p;
5621   name_sort_t *nses = 0, *ns;
5622
5623   if (vam->json_output)
5624     {
5625       clib_warning
5626         ("JSON output supported only for VPE API calls and dump_stats_table");
5627       return -99;
5628     }
5629
5630   /* *INDENT-OFF* */
5631   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5632   ({
5633     vec_add2 (nses, ns, 1);
5634     ns->name = (u8 *)(p->key);
5635     ns->value = (u32) p->value[0];
5636   }));
5637   /* *INDENT-ON* */
5638
5639   vec_sort_with_function (nses, name_sort_cmp);
5640
5641   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5642   vec_foreach (ns, nses)
5643   {
5644     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5645   }
5646   vec_free (nses);
5647   return 0;
5648 }
5649
5650 static int
5651 dump_ip_table (vat_main_t * vam, int is_ipv6)
5652 {
5653   const ip_details_t *det = NULL;
5654   const ip_address_details_t *address = NULL;
5655   u32 i = ~0;
5656
5657   print (vam->ofp, "%-12s", "sw_if_index");
5658
5659   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5660   {
5661     i++;
5662     if (!det->present)
5663       {
5664         continue;
5665       }
5666     print (vam->ofp, "%-12d", i);
5667     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5668     if (!det->addr)
5669       {
5670         continue;
5671       }
5672     vec_foreach (address, det->addr)
5673     {
5674       print (vam->ofp,
5675              "            %-30U%-13d",
5676              is_ipv6 ? format_ip6_address : format_ip4_address,
5677              address->ip, address->prefix_length);
5678     }
5679   }
5680
5681   return 0;
5682 }
5683
5684 static int
5685 dump_ipv4_table (vat_main_t * vam)
5686 {
5687   if (vam->json_output)
5688     {
5689       clib_warning
5690         ("JSON output supported only for VPE API calls and dump_stats_table");
5691       return -99;
5692     }
5693
5694   return dump_ip_table (vam, 0);
5695 }
5696
5697 static int
5698 dump_ipv6_table (vat_main_t * vam)
5699 {
5700   if (vam->json_output)
5701     {
5702       clib_warning
5703         ("JSON output supported only for VPE API calls and dump_stats_table");
5704       return -99;
5705     }
5706
5707   return dump_ip_table (vam, 1);
5708 }
5709
5710 /*
5711  * Pass CLI buffers directly in the CLI_INBAND API message,
5712  * instead of an additional shared memory area.
5713  */
5714 static int
5715 exec_inband (vat_main_t * vam)
5716 {
5717   vl_api_cli_inband_t *mp;
5718   unformat_input_t *i = vam->input;
5719   int ret;
5720
5721   if (vec_len (i->buffer) == 0)
5722     return -1;
5723
5724   if (vam->exec_mode == 0 && unformat (i, "mode"))
5725     {
5726       vam->exec_mode = 1;
5727       return 0;
5728     }
5729   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5730     {
5731       vam->exec_mode = 0;
5732       return 0;
5733     }
5734
5735   /*
5736    * In order for the CLI command to work, it
5737    * must be a vector ending in \n, not a C-string ending
5738    * in \n\0.
5739    */
5740   u32 len = vec_len (vam->input->buffer);
5741   M2 (CLI_INBAND, mp, len);
5742   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5743
5744   S (mp);
5745   W (ret);
5746   /* json responses may or may not include a useful reply... */
5747   if (vec_len (vam->cmd_reply))
5748     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5749   return ret;
5750 }
5751
5752 int
5753 exec (vat_main_t * vam)
5754 {
5755   return exec_inband (vam);
5756 }
5757
5758 static int
5759 api_create_loopback (vat_main_t * vam)
5760 {
5761   unformat_input_t *i = vam->input;
5762   vl_api_create_loopback_t *mp;
5763   vl_api_create_loopback_instance_t *mp_lbi;
5764   u8 mac_address[6];
5765   u8 mac_set = 0;
5766   u8 is_specified = 0;
5767   u32 user_instance = 0;
5768   int ret;
5769
5770   clib_memset (mac_address, 0, sizeof (mac_address));
5771
5772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5773     {
5774       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5775         mac_set = 1;
5776       if (unformat (i, "instance %d", &user_instance))
5777         is_specified = 1;
5778       else
5779         break;
5780     }
5781
5782   if (is_specified)
5783     {
5784       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5785       mp_lbi->is_specified = is_specified;
5786       if (is_specified)
5787         mp_lbi->user_instance = htonl (user_instance);
5788       if (mac_set)
5789         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5790       S (mp_lbi);
5791     }
5792   else
5793     {
5794       /* Construct the API message */
5795       M (CREATE_LOOPBACK, mp);
5796       if (mac_set)
5797         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5798       S (mp);
5799     }
5800
5801   W (ret);
5802   return ret;
5803 }
5804
5805 static int
5806 api_delete_loopback (vat_main_t * vam)
5807 {
5808   unformat_input_t *i = vam->input;
5809   vl_api_delete_loopback_t *mp;
5810   u32 sw_if_index = ~0;
5811   int ret;
5812
5813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5814     {
5815       if (unformat (i, "sw_if_index %d", &sw_if_index))
5816         ;
5817       else
5818         break;
5819     }
5820
5821   if (sw_if_index == ~0)
5822     {
5823       errmsg ("missing sw_if_index");
5824       return -99;
5825     }
5826
5827   /* Construct the API message */
5828   M (DELETE_LOOPBACK, mp);
5829   mp->sw_if_index = ntohl (sw_if_index);
5830
5831   S (mp);
5832   W (ret);
5833   return ret;
5834 }
5835
5836 static int
5837 api_want_interface_events (vat_main_t * vam)
5838 {
5839   unformat_input_t *i = vam->input;
5840   vl_api_want_interface_events_t *mp;
5841   int enable = -1;
5842   int ret;
5843
5844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5845     {
5846       if (unformat (i, "enable"))
5847         enable = 1;
5848       else if (unformat (i, "disable"))
5849         enable = 0;
5850       else
5851         break;
5852     }
5853
5854   if (enable == -1)
5855     {
5856       errmsg ("missing enable|disable");
5857       return -99;
5858     }
5859
5860   M (WANT_INTERFACE_EVENTS, mp);
5861   mp->enable_disable = enable;
5862
5863   vam->interface_event_display = enable;
5864
5865   S (mp);
5866   W (ret);
5867   return ret;
5868 }
5869
5870
5871 /* Note: non-static, called once to set up the initial intfc table */
5872 int
5873 api_sw_interface_dump (vat_main_t * vam)
5874 {
5875   vl_api_sw_interface_dump_t *mp;
5876   vl_api_control_ping_t *mp_ping;
5877   hash_pair_t *p;
5878   name_sort_t *nses = 0, *ns;
5879   sw_interface_subif_t *sub = NULL;
5880   int ret;
5881
5882   /* Toss the old name table */
5883   /* *INDENT-OFF* */
5884   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5885   ({
5886     vec_add2 (nses, ns, 1);
5887     ns->name = (u8 *)(p->key);
5888     ns->value = (u32) p->value[0];
5889   }));
5890   /* *INDENT-ON* */
5891
5892   hash_free (vam->sw_if_index_by_interface_name);
5893
5894   vec_foreach (ns, nses) vec_free (ns->name);
5895
5896   vec_free (nses);
5897
5898   vec_foreach (sub, vam->sw_if_subif_table)
5899   {
5900     vec_free (sub->interface_name);
5901   }
5902   vec_free (vam->sw_if_subif_table);
5903
5904   /* recreate the interface name hash table */
5905   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5906
5907   /*
5908    * Ask for all interface names. Otherwise, the epic catalog of
5909    * name filters becomes ridiculously long, and vat ends up needing
5910    * to be taught about new interface types.
5911    */
5912   M (SW_INTERFACE_DUMP, mp);
5913   S (mp);
5914
5915   /* Use a control ping for synchronization */
5916   MPING (CONTROL_PING, mp_ping);
5917   S (mp_ping);
5918
5919   W (ret);
5920   return ret;
5921 }
5922
5923 static int
5924 api_sw_interface_set_flags (vat_main_t * vam)
5925 {
5926   unformat_input_t *i = vam->input;
5927   vl_api_sw_interface_set_flags_t *mp;
5928   u32 sw_if_index;
5929   u8 sw_if_index_set = 0;
5930   u8 admin_up = 0;
5931   int ret;
5932
5933   /* Parse args required to build the message */
5934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5935     {
5936       if (unformat (i, "admin-up"))
5937         admin_up = 1;
5938       else if (unformat (i, "admin-down"))
5939         admin_up = 0;
5940       else
5941         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5942         sw_if_index_set = 1;
5943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5944         sw_if_index_set = 1;
5945       else
5946         break;
5947     }
5948
5949   if (sw_if_index_set == 0)
5950     {
5951       errmsg ("missing interface name or sw_if_index");
5952       return -99;
5953     }
5954
5955   /* Construct the API message */
5956   M (SW_INTERFACE_SET_FLAGS, mp);
5957   mp->sw_if_index = ntohl (sw_if_index);
5958   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5959
5960   /* send it... */
5961   S (mp);
5962
5963   /* Wait for a reply, return the good/bad news... */
5964   W (ret);
5965   return ret;
5966 }
5967
5968 static int
5969 api_sw_interface_set_rx_mode (vat_main_t * vam)
5970 {
5971   unformat_input_t *i = vam->input;
5972   vl_api_sw_interface_set_rx_mode_t *mp;
5973   u32 sw_if_index;
5974   u8 sw_if_index_set = 0;
5975   int ret;
5976   u8 queue_id_valid = 0;
5977   u32 queue_id;
5978   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5979
5980   /* Parse args required to build the message */
5981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5982     {
5983       if (unformat (i, "queue %d", &queue_id))
5984         queue_id_valid = 1;
5985       else if (unformat (i, "polling"))
5986         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5987       else if (unformat (i, "interrupt"))
5988         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5989       else if (unformat (i, "adaptive"))
5990         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5991       else
5992         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5993         sw_if_index_set = 1;
5994       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5995         sw_if_index_set = 1;
5996       else
5997         break;
5998     }
5999
6000   if (sw_if_index_set == 0)
6001     {
6002       errmsg ("missing interface name or sw_if_index");
6003       return -99;
6004     }
6005   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6006     {
6007       errmsg ("missing rx-mode");
6008       return -99;
6009     }
6010
6011   /* Construct the API message */
6012   M (SW_INTERFACE_SET_RX_MODE, mp);
6013   mp->sw_if_index = ntohl (sw_if_index);
6014   mp->mode = (vl_api_rx_mode_t) mode;
6015   mp->queue_id_valid = queue_id_valid;
6016   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6017
6018   /* send it... */
6019   S (mp);
6020
6021   /* Wait for a reply, return the good/bad news... */
6022   W (ret);
6023   return ret;
6024 }
6025
6026 static int
6027 api_sw_interface_set_rx_placement (vat_main_t * vam)
6028 {
6029   unformat_input_t *i = vam->input;
6030   vl_api_sw_interface_set_rx_placement_t *mp;
6031   u32 sw_if_index;
6032   u8 sw_if_index_set = 0;
6033   int ret;
6034   u8 is_main = 0;
6035   u32 queue_id, thread_index;
6036
6037   /* Parse args required to build the message */
6038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6039     {
6040       if (unformat (i, "queue %d", &queue_id))
6041         ;
6042       else if (unformat (i, "main"))
6043         is_main = 1;
6044       else if (unformat (i, "worker %d", &thread_index))
6045         ;
6046       else
6047         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6048         sw_if_index_set = 1;
6049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6050         sw_if_index_set = 1;
6051       else
6052         break;
6053     }
6054
6055   if (sw_if_index_set == 0)
6056     {
6057       errmsg ("missing interface name or sw_if_index");
6058       return -99;
6059     }
6060
6061   if (is_main)
6062     thread_index = 0;
6063   /* Construct the API message */
6064   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6065   mp->sw_if_index = ntohl (sw_if_index);
6066   mp->worker_id = ntohl (thread_index);
6067   mp->queue_id = ntohl (queue_id);
6068   mp->is_main = is_main;
6069
6070   /* send it... */
6071   S (mp);
6072   /* Wait for a reply, return the good/bad news... */
6073   W (ret);
6074   return ret;
6075 }
6076
6077 static void vl_api_sw_interface_rx_placement_details_t_handler
6078   (vl_api_sw_interface_rx_placement_details_t * mp)
6079 {
6080   vat_main_t *vam = &vat_main;
6081   u32 worker_id = ntohl (mp->worker_id);
6082
6083   print (vam->ofp,
6084          "\n%-11d %-11s %-6d %-5d %-9s",
6085          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6086          worker_id, ntohl (mp->queue_id),
6087          (mp->mode ==
6088           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6089 }
6090
6091 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6092   (vl_api_sw_interface_rx_placement_details_t * mp)
6093 {
6094   vat_main_t *vam = &vat_main;
6095   vat_json_node_t *node = NULL;
6096
6097   if (VAT_JSON_ARRAY != vam->json_tree.type)
6098     {
6099       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6100       vat_json_init_array (&vam->json_tree);
6101     }
6102   node = vat_json_array_add (&vam->json_tree);
6103
6104   vat_json_init_object (node);
6105   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6106   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6107   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6108   vat_json_object_add_uint (node, "mode", mp->mode);
6109 }
6110
6111 static int
6112 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6113 {
6114   unformat_input_t *i = vam->input;
6115   vl_api_sw_interface_rx_placement_dump_t *mp;
6116   vl_api_control_ping_t *mp_ping;
6117   int ret;
6118   u32 sw_if_index;
6119   u8 sw_if_index_set = 0;
6120
6121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6122     {
6123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6124         sw_if_index_set++;
6125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6126         sw_if_index_set++;
6127       else
6128         break;
6129     }
6130
6131   print (vam->ofp,
6132          "\n%-11s %-11s %-6s %-5s %-4s",
6133          "sw_if_index", "main/worker", "thread", "queue", "mode");
6134
6135   /* Dump Interface rx placement */
6136   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6137
6138   if (sw_if_index_set)
6139     mp->sw_if_index = htonl (sw_if_index);
6140   else
6141     mp->sw_if_index = ~0;
6142
6143   S (mp);
6144
6145   /* Use a control ping for synchronization */
6146   MPING (CONTROL_PING, mp_ping);
6147   S (mp_ping);
6148
6149   W (ret);
6150   return ret;
6151 }
6152
6153 static int
6154 api_sw_interface_clear_stats (vat_main_t * vam)
6155 {
6156   unformat_input_t *i = vam->input;
6157   vl_api_sw_interface_clear_stats_t *mp;
6158   u32 sw_if_index;
6159   u8 sw_if_index_set = 0;
6160   int ret;
6161
6162   /* Parse args required to build the message */
6163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6164     {
6165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6166         sw_if_index_set = 1;
6167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6168         sw_if_index_set = 1;
6169       else
6170         break;
6171     }
6172
6173   /* Construct the API message */
6174   M (SW_INTERFACE_CLEAR_STATS, mp);
6175
6176   if (sw_if_index_set == 1)
6177     mp->sw_if_index = ntohl (sw_if_index);
6178   else
6179     mp->sw_if_index = ~0;
6180
6181   /* send it... */
6182   S (mp);
6183
6184   /* Wait for a reply, return the good/bad news... */
6185   W (ret);
6186   return ret;
6187 }
6188
6189 static int
6190 api_sw_interface_add_del_address (vat_main_t * vam)
6191 {
6192   unformat_input_t *i = vam->input;
6193   vl_api_sw_interface_add_del_address_t *mp;
6194   u32 sw_if_index;
6195   u8 sw_if_index_set = 0;
6196   u8 is_add = 1, del_all = 0;
6197   u32 address_length = 0;
6198   u8 v4_address_set = 0;
6199   u8 v6_address_set = 0;
6200   ip4_address_t v4address;
6201   ip6_address_t v6address;
6202   int ret;
6203
6204   /* Parse args required to build the message */
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "del-all"))
6208         del_all = 1;
6209       else if (unformat (i, "del"))
6210         is_add = 0;
6211       else
6212         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6213         sw_if_index_set = 1;
6214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6215         sw_if_index_set = 1;
6216       else if (unformat (i, "%U/%d",
6217                          unformat_ip4_address, &v4address, &address_length))
6218         v4_address_set = 1;
6219       else if (unformat (i, "%U/%d",
6220                          unformat_ip6_address, &v6address, &address_length))
6221         v6_address_set = 1;
6222       else
6223         break;
6224     }
6225
6226   if (sw_if_index_set == 0)
6227     {
6228       errmsg ("missing interface name or sw_if_index");
6229       return -99;
6230     }
6231   if (v4_address_set && v6_address_set)
6232     {
6233       errmsg ("both v4 and v6 addresses set");
6234       return -99;
6235     }
6236   if (!v4_address_set && !v6_address_set && !del_all)
6237     {
6238       errmsg ("no addresses set");
6239       return -99;
6240     }
6241
6242   /* Construct the API message */
6243   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6244
6245   mp->sw_if_index = ntohl (sw_if_index);
6246   mp->is_add = is_add;
6247   mp->del_all = del_all;
6248   if (v6_address_set)
6249     {
6250       mp->prefix.address.af = ADDRESS_IP6;
6251       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6252     }
6253   else
6254     {
6255       mp->prefix.address.af = ADDRESS_IP4;
6256       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6257     }
6258   mp->prefix.len = address_length;
6259
6260   /* send it... */
6261   S (mp);
6262
6263   /* Wait for a reply, return good/bad news  */
6264   W (ret);
6265   return ret;
6266 }
6267
6268 static int
6269 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6270 {
6271   unformat_input_t *i = vam->input;
6272   vl_api_sw_interface_set_mpls_enable_t *mp;
6273   u32 sw_if_index;
6274   u8 sw_if_index_set = 0;
6275   u8 enable = 1;
6276   int ret;
6277
6278   /* Parse args required to build the message */
6279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6280     {
6281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6282         sw_if_index_set = 1;
6283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6284         sw_if_index_set = 1;
6285       else if (unformat (i, "disable"))
6286         enable = 0;
6287       else if (unformat (i, "dis"))
6288         enable = 0;
6289       else
6290         break;
6291     }
6292
6293   if (sw_if_index_set == 0)
6294     {
6295       errmsg ("missing interface name or sw_if_index");
6296       return -99;
6297     }
6298
6299   /* Construct the API message */
6300   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6301
6302   mp->sw_if_index = ntohl (sw_if_index);
6303   mp->enable = enable;
6304
6305   /* send it... */
6306   S (mp);
6307
6308   /* Wait for a reply... */
6309   W (ret);
6310   return ret;
6311 }
6312
6313 static int
6314 api_sw_interface_set_table (vat_main_t * vam)
6315 {
6316   unformat_input_t *i = vam->input;
6317   vl_api_sw_interface_set_table_t *mp;
6318   u32 sw_if_index, vrf_id = 0;
6319   u8 sw_if_index_set = 0;
6320   u8 is_ipv6 = 0;
6321   int ret;
6322
6323   /* Parse args required to build the message */
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6327         sw_if_index_set = 1;
6328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6329         sw_if_index_set = 1;
6330       else if (unformat (i, "vrf %d", &vrf_id))
6331         ;
6332       else if (unformat (i, "ipv6"))
6333         is_ipv6 = 1;
6334       else
6335         break;
6336     }
6337
6338   if (sw_if_index_set == 0)
6339     {
6340       errmsg ("missing interface name or sw_if_index");
6341       return -99;
6342     }
6343
6344   /* Construct the API message */
6345   M (SW_INTERFACE_SET_TABLE, mp);
6346
6347   mp->sw_if_index = ntohl (sw_if_index);
6348   mp->is_ipv6 = is_ipv6;
6349   mp->vrf_id = ntohl (vrf_id);
6350
6351   /* send it... */
6352   S (mp);
6353
6354   /* Wait for a reply... */
6355   W (ret);
6356   return ret;
6357 }
6358
6359 static void vl_api_sw_interface_get_table_reply_t_handler
6360   (vl_api_sw_interface_get_table_reply_t * mp)
6361 {
6362   vat_main_t *vam = &vat_main;
6363
6364   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6365
6366   vam->retval = ntohl (mp->retval);
6367   vam->result_ready = 1;
6368
6369 }
6370
6371 static void vl_api_sw_interface_get_table_reply_t_handler_json
6372   (vl_api_sw_interface_get_table_reply_t * mp)
6373 {
6374   vat_main_t *vam = &vat_main;
6375   vat_json_node_t node;
6376
6377   vat_json_init_object (&node);
6378   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6379   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6380
6381   vat_json_print (vam->ofp, &node);
6382   vat_json_free (&node);
6383
6384   vam->retval = ntohl (mp->retval);
6385   vam->result_ready = 1;
6386 }
6387
6388 static int
6389 api_sw_interface_get_table (vat_main_t * vam)
6390 {
6391   unformat_input_t *i = vam->input;
6392   vl_api_sw_interface_get_table_t *mp;
6393   u32 sw_if_index;
6394   u8 sw_if_index_set = 0;
6395   u8 is_ipv6 = 0;
6396   int ret;
6397
6398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6399     {
6400       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6403         sw_if_index_set = 1;
6404       else if (unformat (i, "ipv6"))
6405         is_ipv6 = 1;
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   M (SW_INTERFACE_GET_TABLE, mp);
6417   mp->sw_if_index = htonl (sw_if_index);
6418   mp->is_ipv6 = is_ipv6;
6419
6420   S (mp);
6421   W (ret);
6422   return ret;
6423 }
6424
6425 static int
6426 api_sw_interface_set_vpath (vat_main_t * vam)
6427 {
6428   unformat_input_t *i = vam->input;
6429   vl_api_sw_interface_set_vpath_t *mp;
6430   u32 sw_if_index = 0;
6431   u8 sw_if_index_set = 0;
6432   u8 is_enable = 0;
6433   int ret;
6434
6435   /* Parse args required to build the message */
6436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6437     {
6438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6439         sw_if_index_set = 1;
6440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "enable"))
6443         is_enable = 1;
6444       else if (unformat (i, "disable"))
6445         is_enable = 0;
6446       else
6447         break;
6448     }
6449
6450   if (sw_if_index_set == 0)
6451     {
6452       errmsg ("missing interface name or sw_if_index");
6453       return -99;
6454     }
6455
6456   /* Construct the API message */
6457   M (SW_INTERFACE_SET_VPATH, mp);
6458
6459   mp->sw_if_index = ntohl (sw_if_index);
6460   mp->enable = is_enable;
6461
6462   /* send it... */
6463   S (mp);
6464
6465   /* Wait for a reply... */
6466   W (ret);
6467   return ret;
6468 }
6469
6470 static int
6471 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6472 {
6473   unformat_input_t *i = vam->input;
6474   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6475   u32 sw_if_index = 0;
6476   u8 sw_if_index_set = 0;
6477   u8 is_enable = 1;
6478   u8 is_ipv6 = 0;
6479   int ret;
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6485         sw_if_index_set = 1;
6486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6487         sw_if_index_set = 1;
6488       else if (unformat (i, "enable"))
6489         is_enable = 1;
6490       else if (unformat (i, "disable"))
6491         is_enable = 0;
6492       else if (unformat (i, "ip4"))
6493         is_ipv6 = 0;
6494       else if (unformat (i, "ip6"))
6495         is_ipv6 = 1;
6496       else
6497         break;
6498     }
6499
6500   if (sw_if_index_set == 0)
6501     {
6502       errmsg ("missing interface name or sw_if_index");
6503       return -99;
6504     }
6505
6506   /* Construct the API message */
6507   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6508
6509   mp->sw_if_index = ntohl (sw_if_index);
6510   mp->enable = is_enable;
6511   mp->is_ipv6 = is_ipv6;
6512
6513   /* send it... */
6514   S (mp);
6515
6516   /* Wait for a reply... */
6517   W (ret);
6518   return ret;
6519 }
6520
6521 static int
6522 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6523 {
6524   unformat_input_t *i = vam->input;
6525   vl_api_sw_interface_set_geneve_bypass_t *mp;
6526   u32 sw_if_index = 0;
6527   u8 sw_if_index_set = 0;
6528   u8 is_enable = 1;
6529   u8 is_ipv6 = 0;
6530   int ret;
6531
6532   /* Parse args required to build the message */
6533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6534     {
6535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6536         sw_if_index_set = 1;
6537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6538         sw_if_index_set = 1;
6539       else if (unformat (i, "enable"))
6540         is_enable = 1;
6541       else if (unformat (i, "disable"))
6542         is_enable = 0;
6543       else if (unformat (i, "ip4"))
6544         is_ipv6 = 0;
6545       else if (unformat (i, "ip6"))
6546         is_ipv6 = 1;
6547       else
6548         break;
6549     }
6550
6551   if (sw_if_index_set == 0)
6552     {
6553       errmsg ("missing interface name or sw_if_index");
6554       return -99;
6555     }
6556
6557   /* Construct the API message */
6558   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6559
6560   mp->sw_if_index = ntohl (sw_if_index);
6561   mp->enable = is_enable;
6562   mp->is_ipv6 = is_ipv6;
6563
6564   /* send it... */
6565   S (mp);
6566
6567   /* Wait for a reply... */
6568   W (ret);
6569   return ret;
6570 }
6571
6572 static int
6573 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6574 {
6575   unformat_input_t *i = vam->input;
6576   vl_api_sw_interface_set_l2_xconnect_t *mp;
6577   u32 rx_sw_if_index;
6578   u8 rx_sw_if_index_set = 0;
6579   u32 tx_sw_if_index;
6580   u8 tx_sw_if_index_set = 0;
6581   u8 enable = 1;
6582   int ret;
6583
6584   /* Parse args required to build the message */
6585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6586     {
6587       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6588         rx_sw_if_index_set = 1;
6589       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6590         tx_sw_if_index_set = 1;
6591       else if (unformat (i, "rx"))
6592         {
6593           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594             {
6595               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6596                             &rx_sw_if_index))
6597                 rx_sw_if_index_set = 1;
6598             }
6599           else
6600             break;
6601         }
6602       else if (unformat (i, "tx"))
6603         {
6604           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6605             {
6606               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6607                             &tx_sw_if_index))
6608                 tx_sw_if_index_set = 1;
6609             }
6610           else
6611             break;
6612         }
6613       else if (unformat (i, "enable"))
6614         enable = 1;
6615       else if (unformat (i, "disable"))
6616         enable = 0;
6617       else
6618         break;
6619     }
6620
6621   if (rx_sw_if_index_set == 0)
6622     {
6623       errmsg ("missing rx interface name or rx_sw_if_index");
6624       return -99;
6625     }
6626
6627   if (enable && (tx_sw_if_index_set == 0))
6628     {
6629       errmsg ("missing tx interface name or tx_sw_if_index");
6630       return -99;
6631     }
6632
6633   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6634
6635   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6636   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6637   mp->enable = enable;
6638
6639   S (mp);
6640   W (ret);
6641   return ret;
6642 }
6643
6644 static int
6645 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6646 {
6647   unformat_input_t *i = vam->input;
6648   vl_api_sw_interface_set_l2_bridge_t *mp;
6649   vl_api_l2_port_type_t port_type;
6650   u32 rx_sw_if_index;
6651   u8 rx_sw_if_index_set = 0;
6652   u32 bd_id;
6653   u8 bd_id_set = 0;
6654   u32 shg = 0;
6655   u8 enable = 1;
6656   int ret;
6657
6658   port_type = L2_API_PORT_TYPE_NORMAL;
6659
6660   /* Parse args required to build the message */
6661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6662     {
6663       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6664         rx_sw_if_index_set = 1;
6665       else if (unformat (i, "bd_id %d", &bd_id))
6666         bd_id_set = 1;
6667       else
6668         if (unformat
6669             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6670         rx_sw_if_index_set = 1;
6671       else if (unformat (i, "shg %d", &shg))
6672         ;
6673       else if (unformat (i, "bvi"))
6674         port_type = L2_API_PORT_TYPE_BVI;
6675       else if (unformat (i, "uu-fwd"))
6676         port_type = L2_API_PORT_TYPE_UU_FWD;
6677       else if (unformat (i, "enable"))
6678         enable = 1;
6679       else if (unformat (i, "disable"))
6680         enable = 0;
6681       else
6682         break;
6683     }
6684
6685   if (rx_sw_if_index_set == 0)
6686     {
6687       errmsg ("missing rx interface name or sw_if_index");
6688       return -99;
6689     }
6690
6691   if (enable && (bd_id_set == 0))
6692     {
6693       errmsg ("missing bridge domain");
6694       return -99;
6695     }
6696
6697   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6698
6699   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6700   mp->bd_id = ntohl (bd_id);
6701   mp->shg = (u8) shg;
6702   mp->port_type = ntohl (port_type);
6703   mp->enable = enable;
6704
6705   S (mp);
6706   W (ret);
6707   return ret;
6708 }
6709
6710 static int
6711 api_bridge_domain_dump (vat_main_t * vam)
6712 {
6713   unformat_input_t *i = vam->input;
6714   vl_api_bridge_domain_dump_t *mp;
6715   vl_api_control_ping_t *mp_ping;
6716   u32 bd_id = ~0;
6717   int ret;
6718
6719   /* Parse args required to build the message */
6720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6721     {
6722       if (unformat (i, "bd_id %d", &bd_id))
6723         ;
6724       else
6725         break;
6726     }
6727
6728   M (BRIDGE_DOMAIN_DUMP, mp);
6729   mp->bd_id = ntohl (bd_id);
6730   S (mp);
6731
6732   /* Use a control ping for synchronization */
6733   MPING (CONTROL_PING, mp_ping);
6734   S (mp_ping);
6735
6736   W (ret);
6737   return ret;
6738 }
6739
6740 static int
6741 api_bridge_domain_add_del (vat_main_t * vam)
6742 {
6743   unformat_input_t *i = vam->input;
6744   vl_api_bridge_domain_add_del_t *mp;
6745   u32 bd_id = ~0;
6746   u8 is_add = 1;
6747   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6748   u8 *bd_tag = NULL;
6749   u32 mac_age = 0;
6750   int ret;
6751
6752   /* Parse args required to build the message */
6753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6754     {
6755       if (unformat (i, "bd_id %d", &bd_id))
6756         ;
6757       else if (unformat (i, "flood %d", &flood))
6758         ;
6759       else if (unformat (i, "uu-flood %d", &uu_flood))
6760         ;
6761       else if (unformat (i, "forward %d", &forward))
6762         ;
6763       else if (unformat (i, "learn %d", &learn))
6764         ;
6765       else if (unformat (i, "arp-term %d", &arp_term))
6766         ;
6767       else if (unformat (i, "mac-age %d", &mac_age))
6768         ;
6769       else if (unformat (i, "bd-tag %s", &bd_tag))
6770         ;
6771       else if (unformat (i, "del"))
6772         {
6773           is_add = 0;
6774           flood = uu_flood = forward = learn = 0;
6775         }
6776       else
6777         break;
6778     }
6779
6780   if (bd_id == ~0)
6781     {
6782       errmsg ("missing bridge domain");
6783       ret = -99;
6784       goto done;
6785     }
6786
6787   if (mac_age > 255)
6788     {
6789       errmsg ("mac age must be less than 256 ");
6790       ret = -99;
6791       goto done;
6792     }
6793
6794   if ((bd_tag) && (vec_len (bd_tag) > 63))
6795     {
6796       errmsg ("bd-tag cannot be longer than 63");
6797       ret = -99;
6798       goto done;
6799     }
6800
6801   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6802
6803   mp->bd_id = ntohl (bd_id);
6804   mp->flood = flood;
6805   mp->uu_flood = uu_flood;
6806   mp->forward = forward;
6807   mp->learn = learn;
6808   mp->arp_term = arp_term;
6809   mp->is_add = is_add;
6810   mp->mac_age = (u8) mac_age;
6811   if (bd_tag)
6812     {
6813       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6814       mp->bd_tag[vec_len (bd_tag)] = 0;
6815     }
6816   S (mp);
6817   W (ret);
6818
6819 done:
6820   vec_free (bd_tag);
6821   return ret;
6822 }
6823
6824 static int
6825 api_l2fib_flush_bd (vat_main_t * vam)
6826 {
6827   unformat_input_t *i = vam->input;
6828   vl_api_l2fib_flush_bd_t *mp;
6829   u32 bd_id = ~0;
6830   int ret;
6831
6832   /* Parse args required to build the message */
6833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6834     {
6835       if (unformat (i, "bd_id %d", &bd_id));
6836       else
6837         break;
6838     }
6839
6840   if (bd_id == ~0)
6841     {
6842       errmsg ("missing bridge domain");
6843       return -99;
6844     }
6845
6846   M (L2FIB_FLUSH_BD, mp);
6847
6848   mp->bd_id = htonl (bd_id);
6849
6850   S (mp);
6851   W (ret);
6852   return ret;
6853 }
6854
6855 static int
6856 api_l2fib_flush_int (vat_main_t * vam)
6857 {
6858   unformat_input_t *i = vam->input;
6859   vl_api_l2fib_flush_int_t *mp;
6860   u32 sw_if_index = ~0;
6861   int ret;
6862
6863   /* Parse args required to build the message */
6864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6865     {
6866       if (unformat (i, "sw_if_index %d", &sw_if_index));
6867       else
6868         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6869       else
6870         break;
6871     }
6872
6873   if (sw_if_index == ~0)
6874     {
6875       errmsg ("missing interface name or sw_if_index");
6876       return -99;
6877     }
6878
6879   M (L2FIB_FLUSH_INT, mp);
6880
6881   mp->sw_if_index = ntohl (sw_if_index);
6882
6883   S (mp);
6884   W (ret);
6885   return ret;
6886 }
6887
6888 static int
6889 api_l2fib_add_del (vat_main_t * vam)
6890 {
6891   unformat_input_t *i = vam->input;
6892   vl_api_l2fib_add_del_t *mp;
6893   f64 timeout;
6894   u8 mac[6] = { 0 };
6895   u8 mac_set = 0;
6896   u32 bd_id;
6897   u8 bd_id_set = 0;
6898   u32 sw_if_index = 0;
6899   u8 sw_if_index_set = 0;
6900   u8 is_add = 1;
6901   u8 static_mac = 0;
6902   u8 filter_mac = 0;
6903   u8 bvi_mac = 0;
6904   int count = 1;
6905   f64 before = 0;
6906   int j;
6907
6908   /* Parse args required to build the message */
6909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6910     {
6911       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6912         mac_set = 1;
6913       else if (unformat (i, "bd_id %d", &bd_id))
6914         bd_id_set = 1;
6915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6916         sw_if_index_set = 1;
6917       else if (unformat (i, "sw_if"))
6918         {
6919           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6920             {
6921               if (unformat
6922                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6923                 sw_if_index_set = 1;
6924             }
6925           else
6926             break;
6927         }
6928       else if (unformat (i, "static"))
6929         static_mac = 1;
6930       else if (unformat (i, "filter"))
6931         {
6932           filter_mac = 1;
6933           static_mac = 1;
6934         }
6935       else if (unformat (i, "bvi"))
6936         {
6937           bvi_mac = 1;
6938           static_mac = 1;
6939         }
6940       else if (unformat (i, "del"))
6941         is_add = 0;
6942       else if (unformat (i, "count %d", &count))
6943         ;
6944       else
6945         break;
6946     }
6947
6948   if (mac_set == 0)
6949     {
6950       errmsg ("missing mac address");
6951       return -99;
6952     }
6953
6954   if (bd_id_set == 0)
6955     {
6956       errmsg ("missing bridge domain");
6957       return -99;
6958     }
6959
6960   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6961     {
6962       errmsg ("missing interface name or sw_if_index");
6963       return -99;
6964     }
6965
6966   if (count > 1)
6967     {
6968       /* Turn on async mode */
6969       vam->async_mode = 1;
6970       vam->async_errors = 0;
6971       before = vat_time_now (vam);
6972     }
6973
6974   for (j = 0; j < count; j++)
6975     {
6976       M (L2FIB_ADD_DEL, mp);
6977
6978       clib_memcpy (mp->mac, mac, 6);
6979       mp->bd_id = ntohl (bd_id);
6980       mp->is_add = is_add;
6981       mp->sw_if_index = ntohl (sw_if_index);
6982
6983       if (is_add)
6984         {
6985           mp->static_mac = static_mac;
6986           mp->filter_mac = filter_mac;
6987           mp->bvi_mac = bvi_mac;
6988         }
6989       increment_mac_address (mac);
6990       /* send it... */
6991       S (mp);
6992     }
6993
6994   if (count > 1)
6995     {
6996       vl_api_control_ping_t *mp_ping;
6997       f64 after;
6998
6999       /* Shut off async mode */
7000       vam->async_mode = 0;
7001
7002       MPING (CONTROL_PING, mp_ping);
7003       S (mp_ping);
7004
7005       timeout = vat_time_now (vam) + 1.0;
7006       while (vat_time_now (vam) < timeout)
7007         if (vam->result_ready == 1)
7008           goto out;
7009       vam->retval = -99;
7010
7011     out:
7012       if (vam->retval == -99)
7013         errmsg ("timeout");
7014
7015       if (vam->async_errors > 0)
7016         {
7017           errmsg ("%d asynchronous errors", vam->async_errors);
7018           vam->retval = -98;
7019         }
7020       vam->async_errors = 0;
7021       after = vat_time_now (vam);
7022
7023       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7024              count, after - before, count / (after - before));
7025     }
7026   else
7027     {
7028       int ret;
7029
7030       /* Wait for a reply... */
7031       W (ret);
7032       return ret;
7033     }
7034   /* Return the good/bad news */
7035   return (vam->retval);
7036 }
7037
7038 static int
7039 api_bridge_domain_set_mac_age (vat_main_t * vam)
7040 {
7041   unformat_input_t *i = vam->input;
7042   vl_api_bridge_domain_set_mac_age_t *mp;
7043   u32 bd_id = ~0;
7044   u32 mac_age = 0;
7045   int ret;
7046
7047   /* Parse args required to build the message */
7048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049     {
7050       if (unformat (i, "bd_id %d", &bd_id));
7051       else if (unformat (i, "mac-age %d", &mac_age));
7052       else
7053         break;
7054     }
7055
7056   if (bd_id == ~0)
7057     {
7058       errmsg ("missing bridge domain");
7059       return -99;
7060     }
7061
7062   if (mac_age > 255)
7063     {
7064       errmsg ("mac age must be less than 256 ");
7065       return -99;
7066     }
7067
7068   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7069
7070   mp->bd_id = htonl (bd_id);
7071   mp->mac_age = (u8) mac_age;
7072
7073   S (mp);
7074   W (ret);
7075   return ret;
7076 }
7077
7078 static int
7079 api_l2_flags (vat_main_t * vam)
7080 {
7081   unformat_input_t *i = vam->input;
7082   vl_api_l2_flags_t *mp;
7083   u32 sw_if_index;
7084   u32 flags = 0;
7085   u8 sw_if_index_set = 0;
7086   u8 is_set = 0;
7087   int ret;
7088
7089   /* Parse args required to build the message */
7090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7091     {
7092       if (unformat (i, "sw_if_index %d", &sw_if_index))
7093         sw_if_index_set = 1;
7094       else if (unformat (i, "sw_if"))
7095         {
7096           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7097             {
7098               if (unformat
7099                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7100                 sw_if_index_set = 1;
7101             }
7102           else
7103             break;
7104         }
7105       else if (unformat (i, "learn"))
7106         flags |= L2_LEARN;
7107       else if (unformat (i, "forward"))
7108         flags |= L2_FWD;
7109       else if (unformat (i, "flood"))
7110         flags |= L2_FLOOD;
7111       else if (unformat (i, "uu-flood"))
7112         flags |= L2_UU_FLOOD;
7113       else if (unformat (i, "arp-term"))
7114         flags |= L2_ARP_TERM;
7115       else if (unformat (i, "off"))
7116         is_set = 0;
7117       else if (unformat (i, "disable"))
7118         is_set = 0;
7119       else
7120         break;
7121     }
7122
7123   if (sw_if_index_set == 0)
7124     {
7125       errmsg ("missing interface name or sw_if_index");
7126       return -99;
7127     }
7128
7129   M (L2_FLAGS, mp);
7130
7131   mp->sw_if_index = ntohl (sw_if_index);
7132   mp->feature_bitmap = ntohl (flags);
7133   mp->is_set = is_set;
7134
7135   S (mp);
7136   W (ret);
7137   return ret;
7138 }
7139
7140 static int
7141 api_bridge_flags (vat_main_t * vam)
7142 {
7143   unformat_input_t *i = vam->input;
7144   vl_api_bridge_flags_t *mp;
7145   u32 bd_id;
7146   u8 bd_id_set = 0;
7147   u8 is_set = 1;
7148   bd_flags_t flags = 0;
7149   int ret;
7150
7151   /* Parse args required to build the message */
7152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7153     {
7154       if (unformat (i, "bd_id %d", &bd_id))
7155         bd_id_set = 1;
7156       else if (unformat (i, "learn"))
7157         flags |= BRIDGE_API_FLAG_LEARN;
7158       else if (unformat (i, "forward"))
7159         flags |= BRIDGE_API_FLAG_FWD;
7160       else if (unformat (i, "flood"))
7161         flags |= BRIDGE_API_FLAG_FLOOD;
7162       else if (unformat (i, "uu-flood"))
7163         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7164       else if (unformat (i, "arp-term"))
7165         flags |= BRIDGE_API_FLAG_ARP_TERM;
7166       else if (unformat (i, "off"))
7167         is_set = 0;
7168       else if (unformat (i, "disable"))
7169         is_set = 0;
7170       else
7171         break;
7172     }
7173
7174   if (bd_id_set == 0)
7175     {
7176       errmsg ("missing bridge domain");
7177       return -99;
7178     }
7179
7180   M (BRIDGE_FLAGS, mp);
7181
7182   mp->bd_id = ntohl (bd_id);
7183   mp->flags = ntohl (flags);
7184   mp->is_set = is_set;
7185
7186   S (mp);
7187   W (ret);
7188   return ret;
7189 }
7190
7191 static int
7192 api_bd_ip_mac_add_del (vat_main_t * vam)
7193 {
7194   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7195   vl_api_mac_address_t mac = { 0 };
7196   unformat_input_t *i = vam->input;
7197   vl_api_bd_ip_mac_add_del_t *mp;
7198   u32 bd_id;
7199   u8 is_add = 1;
7200   u8 bd_id_set = 0;
7201   u8 ip_set = 0;
7202   u8 mac_set = 0;
7203   int ret;
7204
7205
7206   /* Parse args required to build the message */
7207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7208     {
7209       if (unformat (i, "bd_id %d", &bd_id))
7210         {
7211           bd_id_set++;
7212         }
7213       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7214         {
7215           ip_set++;
7216         }
7217       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7218         {
7219           mac_set++;
7220         }
7221       else if (unformat (i, "del"))
7222         is_add = 0;
7223       else
7224         break;
7225     }
7226
7227   if (bd_id_set == 0)
7228     {
7229       errmsg ("missing bridge domain");
7230       return -99;
7231     }
7232   else if (ip_set == 0)
7233     {
7234       errmsg ("missing IP address");
7235       return -99;
7236     }
7237   else if (mac_set == 0)
7238     {
7239       errmsg ("missing MAC address");
7240       return -99;
7241     }
7242
7243   M (BD_IP_MAC_ADD_DEL, mp);
7244
7245   mp->entry.bd_id = ntohl (bd_id);
7246   mp->is_add = is_add;
7247
7248   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7249   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7250
7251   S (mp);
7252   W (ret);
7253   return ret;
7254 }
7255
7256 static int
7257 api_bd_ip_mac_flush (vat_main_t * vam)
7258 {
7259   unformat_input_t *i = vam->input;
7260   vl_api_bd_ip_mac_flush_t *mp;
7261   u32 bd_id;
7262   u8 bd_id_set = 0;
7263   int ret;
7264
7265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7266     {
7267       if (unformat (i, "bd_id %d", &bd_id))
7268         {
7269           bd_id_set++;
7270         }
7271       else
7272         break;
7273     }
7274
7275   if (bd_id_set == 0)
7276     {
7277       errmsg ("missing bridge domain");
7278       return -99;
7279     }
7280
7281   M (BD_IP_MAC_FLUSH, mp);
7282
7283   mp->bd_id = ntohl (bd_id);
7284
7285   S (mp);
7286   W (ret);
7287   return ret;
7288 }
7289
7290 static void vl_api_bd_ip_mac_details_t_handler
7291   (vl_api_bd_ip_mac_details_t * mp)
7292 {
7293   vat_main_t *vam = &vat_main;
7294
7295   print (vam->ofp,
7296          "\n%-5d %U %U",
7297          ntohl (mp->entry.bd_id),
7298          format_vl_api_mac_address, mp->entry.mac,
7299          format_vl_api_address, &mp->entry.ip);
7300 }
7301
7302 static void vl_api_bd_ip_mac_details_t_handler_json
7303   (vl_api_bd_ip_mac_details_t * mp)
7304 {
7305   vat_main_t *vam = &vat_main;
7306   vat_json_node_t *node = NULL;
7307
7308   if (VAT_JSON_ARRAY != vam->json_tree.type)
7309     {
7310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7311       vat_json_init_array (&vam->json_tree);
7312     }
7313   node = vat_json_array_add (&vam->json_tree);
7314
7315   vat_json_init_object (node);
7316   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7317   vat_json_object_add_string_copy (node, "mac_address",
7318                                    format (0, "%U", format_vl_api_mac_address,
7319                                            &mp->entry.mac));
7320   u8 *ip = 0;
7321
7322   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7323   vat_json_object_add_string_copy (node, "ip_address", ip);
7324   vec_free (ip);
7325 }
7326
7327 static int
7328 api_bd_ip_mac_dump (vat_main_t * vam)
7329 {
7330   unformat_input_t *i = vam->input;
7331   vl_api_bd_ip_mac_dump_t *mp;
7332   vl_api_control_ping_t *mp_ping;
7333   int ret;
7334   u32 bd_id;
7335   u8 bd_id_set = 0;
7336
7337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7338     {
7339       if (unformat (i, "bd_id %d", &bd_id))
7340         {
7341           bd_id_set++;
7342         }
7343       else
7344         break;
7345     }
7346
7347   print (vam->ofp,
7348          "\n%-5s %-7s %-20s %-30s",
7349          "bd_id", "is_ipv6", "mac_address", "ip_address");
7350
7351   /* Dump Bridge Domain Ip to Mac entries */
7352   M (BD_IP_MAC_DUMP, mp);
7353
7354   if (bd_id_set)
7355     mp->bd_id = htonl (bd_id);
7356   else
7357     mp->bd_id = ~0;
7358
7359   S (mp);
7360
7361   /* Use a control ping for synchronization */
7362   MPING (CONTROL_PING, mp_ping);
7363   S (mp_ping);
7364
7365   W (ret);
7366   return ret;
7367 }
7368
7369 static int
7370 api_tap_create_v2 (vat_main_t * vam)
7371 {
7372   unformat_input_t *i = vam->input;
7373   vl_api_tap_create_v2_t *mp;
7374 #define TAP_FLAG_GSO (1 << 0)
7375   u8 mac_address[6];
7376   u8 random_mac = 1;
7377   u32 id = ~0;
7378   u8 *host_if_name = 0;
7379   u8 *host_ns = 0;
7380   u8 host_mac_addr[6];
7381   u8 host_mac_addr_set = 0;
7382   u8 *host_bridge = 0;
7383   ip4_address_t host_ip4_addr;
7384   ip4_address_t host_ip4_gw;
7385   u8 host_ip4_gw_set = 0;
7386   u32 host_ip4_prefix_len = 0;
7387   ip6_address_t host_ip6_addr;
7388   ip6_address_t host_ip6_gw;
7389   u8 host_ip6_gw_set = 0;
7390   u32 host_ip6_prefix_len = 0;
7391   u8 host_mtu_set = 0;
7392   u32 host_mtu_size = 0;
7393   u32 tap_flags = 0;
7394   int ret;
7395   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7396
7397   clib_memset (mac_address, 0, sizeof (mac_address));
7398
7399   /* Parse args required to build the message */
7400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7401     {
7402       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7403         {
7404           random_mac = 0;
7405         }
7406       else if (unformat (i, "id %u", &id))
7407         ;
7408       else if (unformat (i, "host-if-name %s", &host_if_name))
7409         ;
7410       else if (unformat (i, "host-ns %s", &host_ns))
7411         ;
7412       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7413                          host_mac_addr))
7414         host_mac_addr_set = 1;
7415       else if (unformat (i, "host-bridge %s", &host_bridge))
7416         ;
7417       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7418                          &host_ip4_addr, &host_ip4_prefix_len))
7419         ;
7420       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7421                          &host_ip6_addr, &host_ip6_prefix_len))
7422         ;
7423       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7424                          &host_ip4_gw))
7425         host_ip4_gw_set = 1;
7426       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7427                          &host_ip6_gw))
7428         host_ip6_gw_set = 1;
7429       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7430         ;
7431       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7432         ;
7433       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7434         host_mtu_set = 1;
7435       else if (unformat (i, "no-gso"))
7436         tap_flags &= ~TAP_FLAG_GSO;
7437       else if (unformat (i, "gso"))
7438         tap_flags |= TAP_FLAG_GSO;
7439       else
7440         break;
7441     }
7442
7443   if (vec_len (host_if_name) > 63)
7444     {
7445       errmsg ("tap name too long. ");
7446       return -99;
7447     }
7448   if (vec_len (host_ns) > 63)
7449     {
7450       errmsg ("host name space too long. ");
7451       return -99;
7452     }
7453   if (vec_len (host_bridge) > 63)
7454     {
7455       errmsg ("host bridge name too long. ");
7456       return -99;
7457     }
7458   if (host_ip4_prefix_len > 32)
7459     {
7460       errmsg ("host ip4 prefix length not valid. ");
7461       return -99;
7462     }
7463   if (host_ip6_prefix_len > 128)
7464     {
7465       errmsg ("host ip6 prefix length not valid. ");
7466       return -99;
7467     }
7468   if (!is_pow2 (rx_ring_sz))
7469     {
7470       errmsg ("rx ring size must be power of 2. ");
7471       return -99;
7472     }
7473   if (rx_ring_sz > 32768)
7474     {
7475       errmsg ("rx ring size must be 32768 or lower. ");
7476       return -99;
7477     }
7478   if (!is_pow2 (tx_ring_sz))
7479     {
7480       errmsg ("tx ring size must be power of 2. ");
7481       return -99;
7482     }
7483   if (tx_ring_sz > 32768)
7484     {
7485       errmsg ("tx ring size must be 32768 or lower. ");
7486       return -99;
7487     }
7488   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7489     {
7490       errmsg ("host MTU size must be in between 64 and 65355. ");
7491       return -99;
7492     }
7493
7494   /* Construct the API message */
7495   M (TAP_CREATE_V2, mp);
7496
7497   mp->use_random_mac = random_mac;
7498
7499   mp->id = ntohl (id);
7500   mp->host_namespace_set = host_ns != 0;
7501   mp->host_bridge_set = host_bridge != 0;
7502   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7503   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7504   mp->rx_ring_sz = ntohs (rx_ring_sz);
7505   mp->tx_ring_sz = ntohs (tx_ring_sz);
7506   mp->host_mtu_set = host_mtu_set;
7507   mp->host_mtu_size = ntohl (host_mtu_size);
7508   mp->tap_flags = ntohl (tap_flags);
7509
7510   if (random_mac == 0)
7511     clib_memcpy (mp->mac_address, mac_address, 6);
7512   if (host_mac_addr_set)
7513     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7514   if (host_if_name)
7515     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7516   if (host_ns)
7517     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7518   if (host_bridge)
7519     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7520   if (host_ip4_prefix_len)
7521     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7522   if (host_ip6_prefix_len)
7523     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7524   if (host_ip4_gw_set)
7525     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7526   if (host_ip6_gw_set)
7527     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7528
7529   vec_free (host_ns);
7530   vec_free (host_if_name);
7531   vec_free (host_bridge);
7532
7533   /* send it... */
7534   S (mp);
7535
7536   /* Wait for a reply... */
7537   W (ret);
7538   return ret;
7539 }
7540
7541 static int
7542 api_tap_delete_v2 (vat_main_t * vam)
7543 {
7544   unformat_input_t *i = vam->input;
7545   vl_api_tap_delete_v2_t *mp;
7546   u32 sw_if_index = ~0;
7547   u8 sw_if_index_set = 0;
7548   int ret;
7549
7550   /* Parse args required to build the message */
7551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7552     {
7553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7554         sw_if_index_set = 1;
7555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7556         sw_if_index_set = 1;
7557       else
7558         break;
7559     }
7560
7561   if (sw_if_index_set == 0)
7562     {
7563       errmsg ("missing vpp interface name. ");
7564       return -99;
7565     }
7566
7567   /* Construct the API message */
7568   M (TAP_DELETE_V2, mp);
7569
7570   mp->sw_if_index = ntohl (sw_if_index);
7571
7572   /* send it... */
7573   S (mp);
7574
7575   /* Wait for a reply... */
7576   W (ret);
7577   return ret;
7578 }
7579
7580 uword
7581 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7582 {
7583   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7584   u32 x[4];
7585
7586   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7587     return 0;
7588
7589   addr->domain = x[0];
7590   addr->bus = x[1];
7591   addr->slot = x[2];
7592   addr->function = x[3];
7593
7594   return 1;
7595 }
7596
7597 static int
7598 api_virtio_pci_create (vat_main_t * vam)
7599 {
7600   unformat_input_t *i = vam->input;
7601   vl_api_virtio_pci_create_t *mp;
7602   u8 mac_address[6];
7603   u8 random_mac = 1;
7604   u8 gso_enabled = 0;
7605   u32 pci_addr = 0;
7606   u64 features = (u64) ~ (0ULL);
7607   int ret;
7608
7609   clib_memset (mac_address, 0, sizeof (mac_address));
7610
7611   /* Parse args required to build the message */
7612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7613     {
7614       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7615         {
7616           random_mac = 0;
7617         }
7618       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7619         ;
7620       else if (unformat (i, "features 0x%llx", &features))
7621         ;
7622       else if (unformat (i, "gso-enabled"))
7623         gso_enabled = 1;
7624       else
7625         break;
7626     }
7627
7628   if (pci_addr == 0)
7629     {
7630       errmsg ("pci address must be non zero. ");
7631       return -99;
7632     }
7633
7634   /* Construct the API message */
7635   M (VIRTIO_PCI_CREATE, mp);
7636
7637   mp->use_random_mac = random_mac;
7638
7639   mp->pci_addr = htonl (pci_addr);
7640   mp->features = clib_host_to_net_u64 (features);
7641   mp->gso_enabled = gso_enabled;
7642
7643   if (random_mac == 0)
7644     clib_memcpy (mp->mac_address, mac_address, 6);
7645
7646   /* send it... */
7647   S (mp);
7648
7649   /* Wait for a reply... */
7650   W (ret);
7651   return ret;
7652 }
7653
7654 static int
7655 api_virtio_pci_delete (vat_main_t * vam)
7656 {
7657   unformat_input_t *i = vam->input;
7658   vl_api_virtio_pci_delete_t *mp;
7659   u32 sw_if_index = ~0;
7660   u8 sw_if_index_set = 0;
7661   int ret;
7662
7663   /* Parse args required to build the message */
7664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7665     {
7666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7667         sw_if_index_set = 1;
7668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7669         sw_if_index_set = 1;
7670       else
7671         break;
7672     }
7673
7674   if (sw_if_index_set == 0)
7675     {
7676       errmsg ("missing vpp interface name. ");
7677       return -99;
7678     }
7679
7680   /* Construct the API message */
7681   M (VIRTIO_PCI_DELETE, mp);
7682
7683   mp->sw_if_index = htonl (sw_if_index);
7684
7685   /* send it... */
7686   S (mp);
7687
7688   /* Wait for a reply... */
7689   W (ret);
7690   return ret;
7691 }
7692
7693 static int
7694 api_bond_create (vat_main_t * vam)
7695 {
7696   unformat_input_t *i = vam->input;
7697   vl_api_bond_create_t *mp;
7698   u8 mac_address[6];
7699   u8 custom_mac = 0;
7700   int ret;
7701   u8 mode;
7702   u8 lb;
7703   u8 mode_is_set = 0;
7704   u32 id = ~0;
7705   u8 numa_only = 0;
7706
7707   clib_memset (mac_address, 0, sizeof (mac_address));
7708   lb = BOND_LB_L2;
7709
7710   /* Parse args required to build the message */
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7714         mode_is_set = 1;
7715       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7716                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7717         ;
7718       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7719                          mac_address))
7720         custom_mac = 1;
7721       else if (unformat (i, "numa-only"))
7722         numa_only = 1;
7723       else if (unformat (i, "id %u", &id))
7724         ;
7725       else
7726         break;
7727     }
7728
7729   if (mode_is_set == 0)
7730     {
7731       errmsg ("Missing bond mode. ");
7732       return -99;
7733     }
7734
7735   /* Construct the API message */
7736   M (BOND_CREATE, mp);
7737
7738   mp->use_custom_mac = custom_mac;
7739
7740   mp->mode = mode;
7741   mp->lb = lb;
7742   mp->id = htonl (id);
7743   mp->numa_only = numa_only;
7744
7745   if (custom_mac)
7746     clib_memcpy (mp->mac_address, mac_address, 6);
7747
7748   /* send it... */
7749   S (mp);
7750
7751   /* Wait for a reply... */
7752   W (ret);
7753   return ret;
7754 }
7755
7756 static int
7757 api_bond_delete (vat_main_t * vam)
7758 {
7759   unformat_input_t *i = vam->input;
7760   vl_api_bond_delete_t *mp;
7761   u32 sw_if_index = ~0;
7762   u8 sw_if_index_set = 0;
7763   int ret;
7764
7765   /* Parse args required to build the message */
7766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7767     {
7768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7769         sw_if_index_set = 1;
7770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7771         sw_if_index_set = 1;
7772       else
7773         break;
7774     }
7775
7776   if (sw_if_index_set == 0)
7777     {
7778       errmsg ("missing vpp interface name. ");
7779       return -99;
7780     }
7781
7782   /* Construct the API message */
7783   M (BOND_DELETE, mp);
7784
7785   mp->sw_if_index = ntohl (sw_if_index);
7786
7787   /* send it... */
7788   S (mp);
7789
7790   /* Wait for a reply... */
7791   W (ret);
7792   return ret;
7793 }
7794
7795 static int
7796 api_bond_enslave (vat_main_t * vam)
7797 {
7798   unformat_input_t *i = vam->input;
7799   vl_api_bond_enslave_t *mp;
7800   u32 bond_sw_if_index;
7801   int ret;
7802   u8 is_passive;
7803   u8 is_long_timeout;
7804   u32 bond_sw_if_index_is_set = 0;
7805   u32 sw_if_index;
7806   u8 sw_if_index_is_set = 0;
7807
7808   /* Parse args required to build the message */
7809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7810     {
7811       if (unformat (i, "sw_if_index %d", &sw_if_index))
7812         sw_if_index_is_set = 1;
7813       else if (unformat (i, "bond %u", &bond_sw_if_index))
7814         bond_sw_if_index_is_set = 1;
7815       else if (unformat (i, "passive %d", &is_passive))
7816         ;
7817       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7818         ;
7819       else
7820         break;
7821     }
7822
7823   if (bond_sw_if_index_is_set == 0)
7824     {
7825       errmsg ("Missing bond sw_if_index. ");
7826       return -99;
7827     }
7828   if (sw_if_index_is_set == 0)
7829     {
7830       errmsg ("Missing slave sw_if_index. ");
7831       return -99;
7832     }
7833
7834   /* Construct the API message */
7835   M (BOND_ENSLAVE, mp);
7836
7837   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7838   mp->sw_if_index = ntohl (sw_if_index);
7839   mp->is_long_timeout = is_long_timeout;
7840   mp->is_passive = is_passive;
7841
7842   /* send it... */
7843   S (mp);
7844
7845   /* Wait for a reply... */
7846   W (ret);
7847   return ret;
7848 }
7849
7850 static int
7851 api_bond_detach_slave (vat_main_t * vam)
7852 {
7853   unformat_input_t *i = vam->input;
7854   vl_api_bond_detach_slave_t *mp;
7855   u32 sw_if_index = ~0;
7856   u8 sw_if_index_set = 0;
7857   int ret;
7858
7859   /* Parse args required to build the message */
7860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7861     {
7862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7863         sw_if_index_set = 1;
7864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7865         sw_if_index_set = 1;
7866       else
7867         break;
7868     }
7869
7870   if (sw_if_index_set == 0)
7871     {
7872       errmsg ("missing vpp interface name. ");
7873       return -99;
7874     }
7875
7876   /* Construct the API message */
7877   M (BOND_DETACH_SLAVE, mp);
7878
7879   mp->sw_if_index = ntohl (sw_if_index);
7880
7881   /* send it... */
7882   S (mp);
7883
7884   /* Wait for a reply... */
7885   W (ret);
7886   return ret;
7887 }
7888
7889 static int
7890 api_ip_table_add_del (vat_main_t * vam)
7891 {
7892   unformat_input_t *i = vam->input;
7893   vl_api_ip_table_add_del_t *mp;
7894   u32 table_id = ~0;
7895   u8 is_ipv6 = 0;
7896   u8 is_add = 1;
7897   int ret = 0;
7898
7899   /* Parse args required to build the message */
7900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7901     {
7902       if (unformat (i, "ipv6"))
7903         is_ipv6 = 1;
7904       else if (unformat (i, "del"))
7905         is_add = 0;
7906       else if (unformat (i, "add"))
7907         is_add = 1;
7908       else if (unformat (i, "table %d", &table_id))
7909         ;
7910       else
7911         {
7912           clib_warning ("parse error '%U'", format_unformat_error, i);
7913           return -99;
7914         }
7915     }
7916
7917   if (~0 == table_id)
7918     {
7919       errmsg ("missing table-ID");
7920       return -99;
7921     }
7922
7923   /* Construct the API message */
7924   M (IP_TABLE_ADD_DEL, mp);
7925
7926   mp->table.table_id = ntohl (table_id);
7927   mp->table.is_ip6 = is_ipv6;
7928   mp->is_add = is_add;
7929
7930   /* send it... */
7931   S (mp);
7932
7933   /* Wait for a reply... */
7934   W (ret);
7935
7936   return ret;
7937 }
7938
7939 uword
7940 unformat_fib_path (unformat_input_t * input, va_list * args)
7941 {
7942   vat_main_t *vam = va_arg (*args, vat_main_t *);
7943   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7944   u32 weight, preference;
7945   mpls_label_t out_label;
7946
7947   clib_memset (path, 0, sizeof (*path));
7948   path->weight = 1;
7949   path->sw_if_index = ~0;
7950   path->rpf_id = ~0;
7951   path->n_labels = 0;
7952
7953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (input, "%U %U",
7956                     unformat_vl_api_ip4_address,
7957                     &path->nh.address.ip4,
7958                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7959         {
7960           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7961         }
7962       else if (unformat (input, "%U %U",
7963                          unformat_vl_api_ip6_address,
7964                          &path->nh.address.ip6,
7965                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7966         {
7967           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7968         }
7969       else if (unformat (input, "weight %u", &weight))
7970         {
7971           path->weight = weight;
7972         }
7973       else if (unformat (input, "preference %u", &preference))
7974         {
7975           path->preference = preference;
7976         }
7977       else if (unformat (input, "%U next-hop-table %d",
7978                          unformat_vl_api_ip4_address,
7979                          &path->nh.address.ip4, &path->table_id))
7980         {
7981           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7982         }
7983       else if (unformat (input, "%U next-hop-table %d",
7984                          unformat_vl_api_ip6_address,
7985                          &path->nh.address.ip6, &path->table_id))
7986         {
7987           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7988         }
7989       else if (unformat (input, "%U",
7990                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7991         {
7992           /*
7993            * the recursive next-hops are by default in the default table
7994            */
7995           path->table_id = 0;
7996           path->sw_if_index = ~0;
7997           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7998         }
7999       else if (unformat (input, "%U",
8000                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
8001         {
8002           /*
8003            * the recursive next-hops are by default in the default table
8004            */
8005           path->table_id = 0;
8006           path->sw_if_index = ~0;
8007           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8008         }
8009       else if (unformat (input, "resolve-via-host"))
8010         {
8011           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
8012         }
8013       else if (unformat (input, "resolve-via-attached"))
8014         {
8015           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
8016         }
8017       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
8018         {
8019           path->type = FIB_API_PATH_TYPE_LOCAL;
8020           path->sw_if_index = ~0;
8021           path->proto = FIB_API_PATH_NH_PROTO_IP4;
8022         }
8023       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
8024         {
8025           path->type = FIB_API_PATH_TYPE_LOCAL;
8026           path->sw_if_index = ~0;
8027           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8028         }
8029       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8030         ;
8031       else if (unformat (input, "via-label %d", &path->nh.via_label))
8032         {
8033           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8034           path->sw_if_index = ~0;
8035         }
8036       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8037         {
8038           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8039           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8040         }
8041       else if (unformat (input, "local"))
8042         {
8043           path->type = FIB_API_PATH_TYPE_LOCAL;
8044         }
8045       else if (unformat (input, "out-labels"))
8046         {
8047           while (unformat (input, "%d", &out_label))
8048             {
8049               path->label_stack[path->n_labels].label = out_label;
8050               path->label_stack[path->n_labels].is_uniform = 0;
8051               path->label_stack[path->n_labels].ttl = 64;
8052               path->n_labels++;
8053             }
8054         }
8055       else if (unformat (input, "via"))
8056         {
8057           /* new path, back up and return */
8058           unformat_put_input (input);
8059           unformat_put_input (input);
8060           unformat_put_input (input);
8061           unformat_put_input (input);
8062           break;
8063         }
8064       else
8065         {
8066           return (0);
8067         }
8068     }
8069
8070   path->proto = ntohl (path->proto);
8071   path->type = ntohl (path->type);
8072   path->flags = ntohl (path->flags);
8073   path->table_id = ntohl (path->table_id);
8074   path->sw_if_index = ntohl (path->sw_if_index);
8075
8076   return (1);
8077 }
8078
8079 static int
8080 api_ip_route_add_del (vat_main_t * vam)
8081 {
8082   unformat_input_t *i = vam->input;
8083   vl_api_ip_route_add_del_t *mp;
8084   u32 vrf_id = 0;
8085   u8 is_add = 1;
8086   u8 is_multipath = 0;
8087   u8 prefix_set = 0;
8088   u8 path_count = 0;
8089   vl_api_prefix_t pfx = { };
8090   vl_api_fib_path_t paths[8];
8091   int count = 1;
8092   int j;
8093   f64 before = 0;
8094   u32 random_add_del = 0;
8095   u32 *random_vector = 0;
8096   u32 random_seed = 0xdeaddabe;
8097
8098   /* Parse args required to build the message */
8099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8100     {
8101       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8102         prefix_set = 1;
8103       else if (unformat (i, "del"))
8104         is_add = 0;
8105       else if (unformat (i, "add"))
8106         is_add = 1;
8107       else if (unformat (i, "vrf %d", &vrf_id))
8108         ;
8109       else if (unformat (i, "count %d", &count))
8110         ;
8111       else if (unformat (i, "random"))
8112         random_add_del = 1;
8113       else if (unformat (i, "multipath"))
8114         is_multipath = 1;
8115       else if (unformat (i, "seed %d", &random_seed))
8116         ;
8117       else
8118         if (unformat
8119             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8120         {
8121           path_count++;
8122           if (8 == path_count)
8123             {
8124               errmsg ("max 8 paths");
8125               return -99;
8126             }
8127         }
8128       else
8129         {
8130           clib_warning ("parse error '%U'", format_unformat_error, i);
8131           return -99;
8132         }
8133     }
8134
8135   if (!path_count)
8136     {
8137       errmsg ("specify a path; via ...");
8138       return -99;
8139     }
8140   if (prefix_set == 0)
8141     {
8142       errmsg ("missing prefix");
8143       return -99;
8144     }
8145
8146   /* Generate a pile of unique, random routes */
8147   if (random_add_del)
8148     {
8149       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8150       u32 this_random_address;
8151       uword *random_hash;
8152
8153       random_hash = hash_create (count, sizeof (uword));
8154
8155       hash_set (random_hash, i->as_u32, 1);
8156       for (j = 0; j <= count; j++)
8157         {
8158           do
8159             {
8160               this_random_address = random_u32 (&random_seed);
8161               this_random_address =
8162                 clib_host_to_net_u32 (this_random_address);
8163             }
8164           while (hash_get (random_hash, this_random_address));
8165           vec_add1 (random_vector, this_random_address);
8166           hash_set (random_hash, this_random_address, 1);
8167         }
8168       hash_free (random_hash);
8169       set_ip4_address (&pfx.address, random_vector[0]);
8170     }
8171
8172   if (count > 1)
8173     {
8174       /* Turn on async mode */
8175       vam->async_mode = 1;
8176       vam->async_errors = 0;
8177       before = vat_time_now (vam);
8178     }
8179
8180   for (j = 0; j < count; j++)
8181     {
8182       /* Construct the API message */
8183       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8184
8185       mp->is_add = is_add;
8186       mp->is_multipath = is_multipath;
8187
8188       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8189       mp->route.table_id = ntohl (vrf_id);
8190       mp->route.n_paths = path_count;
8191
8192       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8193
8194       if (random_add_del)
8195         set_ip4_address (&pfx.address, random_vector[j + 1]);
8196       else
8197         increment_address (&pfx.address);
8198       /* send it... */
8199       S (mp);
8200       /* If we receive SIGTERM, stop now... */
8201       if (vam->do_exit)
8202         break;
8203     }
8204
8205   /* When testing multiple add/del ops, use a control-ping to sync */
8206   if (count > 1)
8207     {
8208       vl_api_control_ping_t *mp_ping;
8209       f64 after;
8210       f64 timeout;
8211
8212       /* Shut off async mode */
8213       vam->async_mode = 0;
8214
8215       MPING (CONTROL_PING, mp_ping);
8216       S (mp_ping);
8217
8218       timeout = vat_time_now (vam) + 1.0;
8219       while (vat_time_now (vam) < timeout)
8220         if (vam->result_ready == 1)
8221           goto out;
8222       vam->retval = -99;
8223
8224     out:
8225       if (vam->retval == -99)
8226         errmsg ("timeout");
8227
8228       if (vam->async_errors > 0)
8229         {
8230           errmsg ("%d asynchronous errors", vam->async_errors);
8231           vam->retval = -98;
8232         }
8233       vam->async_errors = 0;
8234       after = vat_time_now (vam);
8235
8236       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8237       if (j > 0)
8238         count = j;
8239
8240       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8241              count, after - before, count / (after - before));
8242     }
8243   else
8244     {
8245       int ret;
8246
8247       /* Wait for a reply... */
8248       W (ret);
8249       return ret;
8250     }
8251
8252   /* Return the good/bad news */
8253   return (vam->retval);
8254 }
8255
8256 static int
8257 api_ip_mroute_add_del (vat_main_t * vam)
8258 {
8259   unformat_input_t *i = vam->input;
8260   u8 path_set = 0, prefix_set = 0, is_add = 1;
8261   vl_api_ip_mroute_add_del_t *mp;
8262   mfib_entry_flags_t eflags = 0;
8263   vl_api_mfib_path_t path;
8264   vl_api_mprefix_t pfx = { };
8265   u32 vrf_id = 0;
8266   int ret;
8267
8268   /* Parse args required to build the message */
8269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8270     {
8271       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8272         {
8273           prefix_set = 1;
8274           pfx.grp_address_length = htons (pfx.grp_address_length);
8275         }
8276       else if (unformat (i, "del"))
8277         is_add = 0;
8278       else if (unformat (i, "add"))
8279         is_add = 1;
8280       else if (unformat (i, "vrf %d", &vrf_id))
8281         ;
8282       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8283         path.itf_flags = htonl (path.itf_flags);
8284       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8285         ;
8286       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8287         path_set = 1;
8288       else
8289         {
8290           clib_warning ("parse error '%U'", format_unformat_error, i);
8291           return -99;
8292         }
8293     }
8294
8295   if (prefix_set == 0)
8296     {
8297       errmsg ("missing addresses\n");
8298       return -99;
8299     }
8300   if (path_set == 0)
8301     {
8302       errmsg ("missing path\n");
8303       return -99;
8304     }
8305
8306   /* Construct the API message */
8307   M (IP_MROUTE_ADD_DEL, mp);
8308
8309   mp->is_add = is_add;
8310   mp->is_multipath = 1;
8311
8312   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8313   mp->route.table_id = htonl (vrf_id);
8314   mp->route.n_paths = 1;
8315   mp->route.entry_flags = htonl (eflags);
8316
8317   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8318
8319   /* send it... */
8320   S (mp);
8321   /* Wait for a reply... */
8322   W (ret);
8323   return ret;
8324 }
8325
8326 static int
8327 api_mpls_table_add_del (vat_main_t * vam)
8328 {
8329   unformat_input_t *i = vam->input;
8330   vl_api_mpls_table_add_del_t *mp;
8331   u32 table_id = ~0;
8332   u8 is_add = 1;
8333   int ret = 0;
8334
8335   /* Parse args required to build the message */
8336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (i, "table %d", &table_id))
8339         ;
8340       else if (unformat (i, "del"))
8341         is_add = 0;
8342       else if (unformat (i, "add"))
8343         is_add = 1;
8344       else
8345         {
8346           clib_warning ("parse error '%U'", format_unformat_error, i);
8347           return -99;
8348         }
8349     }
8350
8351   if (~0 == table_id)
8352     {
8353       errmsg ("missing table-ID");
8354       return -99;
8355     }
8356
8357   /* Construct the API message */
8358   M (MPLS_TABLE_ADD_DEL, mp);
8359
8360   mp->mt_table.mt_table_id = ntohl (table_id);
8361   mp->mt_is_add = is_add;
8362
8363   /* send it... */
8364   S (mp);
8365
8366   /* Wait for a reply... */
8367   W (ret);
8368
8369   return ret;
8370 }
8371
8372 static int
8373 api_mpls_route_add_del (vat_main_t * vam)
8374 {
8375   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8376   mpls_label_t local_label = MPLS_LABEL_INVALID;
8377   unformat_input_t *i = vam->input;
8378   vl_api_mpls_route_add_del_t *mp;
8379   vl_api_fib_path_t paths[8];
8380   int count = 1, j;
8381   f64 before = 0;
8382
8383   /* Parse args required to build the message */
8384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8385     {
8386       if (unformat (i, "%d", &local_label))
8387         ;
8388       else if (unformat (i, "eos"))
8389         is_eos = 1;
8390       else if (unformat (i, "non-eos"))
8391         is_eos = 0;
8392       else if (unformat (i, "del"))
8393         is_add = 0;
8394       else if (unformat (i, "add"))
8395         is_add = 1;
8396       else if (unformat (i, "multipath"))
8397         is_multipath = 1;
8398       else if (unformat (i, "count %d", &count))
8399         ;
8400       else
8401         if (unformat
8402             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8403         {
8404           path_count++;
8405           if (8 == path_count)
8406             {
8407               errmsg ("max 8 paths");
8408               return -99;
8409             }
8410         }
8411       else
8412         {
8413           clib_warning ("parse error '%U'", format_unformat_error, i);
8414           return -99;
8415         }
8416     }
8417
8418   if (!path_count)
8419     {
8420       errmsg ("specify a path; via ...");
8421       return -99;
8422     }
8423
8424   if (MPLS_LABEL_INVALID == local_label)
8425     {
8426       errmsg ("missing label");
8427       return -99;
8428     }
8429
8430   if (count > 1)
8431     {
8432       /* Turn on async mode */
8433       vam->async_mode = 1;
8434       vam->async_errors = 0;
8435       before = vat_time_now (vam);
8436     }
8437
8438   for (j = 0; j < count; j++)
8439     {
8440       /* Construct the API message */
8441       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8442
8443       mp->mr_is_add = is_add;
8444       mp->mr_is_multipath = is_multipath;
8445
8446       mp->mr_route.mr_label = local_label;
8447       mp->mr_route.mr_eos = is_eos;
8448       mp->mr_route.mr_table_id = 0;
8449       mp->mr_route.mr_n_paths = path_count;
8450
8451       clib_memcpy (&mp->mr_route.mr_paths, paths,
8452                    sizeof (paths[0]) * path_count);
8453
8454       local_label++;
8455
8456       /* send it... */
8457       S (mp);
8458       /* If we receive SIGTERM, stop now... */
8459       if (vam->do_exit)
8460         break;
8461     }
8462
8463   /* When testing multiple add/del ops, use a control-ping to sync */
8464   if (count > 1)
8465     {
8466       vl_api_control_ping_t *mp_ping;
8467       f64 after;
8468       f64 timeout;
8469
8470       /* Shut off async mode */
8471       vam->async_mode = 0;
8472
8473       MPING (CONTROL_PING, mp_ping);
8474       S (mp_ping);
8475
8476       timeout = vat_time_now (vam) + 1.0;
8477       while (vat_time_now (vam) < timeout)
8478         if (vam->result_ready == 1)
8479           goto out;
8480       vam->retval = -99;
8481
8482     out:
8483       if (vam->retval == -99)
8484         errmsg ("timeout");
8485
8486       if (vam->async_errors > 0)
8487         {
8488           errmsg ("%d asynchronous errors", vam->async_errors);
8489           vam->retval = -98;
8490         }
8491       vam->async_errors = 0;
8492       after = vat_time_now (vam);
8493
8494       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8495       if (j > 0)
8496         count = j;
8497
8498       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8499              count, after - before, count / (after - before));
8500     }
8501   else
8502     {
8503       int ret;
8504
8505       /* Wait for a reply... */
8506       W (ret);
8507       return ret;
8508     }
8509
8510   /* Return the good/bad news */
8511   return (vam->retval);
8512   return (0);
8513 }
8514
8515 static int
8516 api_mpls_ip_bind_unbind (vat_main_t * vam)
8517 {
8518   unformat_input_t *i = vam->input;
8519   vl_api_mpls_ip_bind_unbind_t *mp;
8520   u32 ip_table_id = 0;
8521   u8 is_bind = 1;
8522   vl_api_prefix_t pfx;
8523   u8 prefix_set = 0;
8524   mpls_label_t local_label = MPLS_LABEL_INVALID;
8525   int ret;
8526
8527   /* Parse args required to build the message */
8528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8529     {
8530       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8531         prefix_set = 1;
8532       else if (unformat (i, "%d", &local_label))
8533         ;
8534       else if (unformat (i, "table-id %d", &ip_table_id))
8535         ;
8536       else if (unformat (i, "unbind"))
8537         is_bind = 0;
8538       else if (unformat (i, "bind"))
8539         is_bind = 1;
8540       else
8541         {
8542           clib_warning ("parse error '%U'", format_unformat_error, i);
8543           return -99;
8544         }
8545     }
8546
8547   if (!prefix_set)
8548     {
8549       errmsg ("IP prefix not set");
8550       return -99;
8551     }
8552
8553   if (MPLS_LABEL_INVALID == local_label)
8554     {
8555       errmsg ("missing label");
8556       return -99;
8557     }
8558
8559   /* Construct the API message */
8560   M (MPLS_IP_BIND_UNBIND, mp);
8561
8562   mp->mb_is_bind = is_bind;
8563   mp->mb_ip_table_id = ntohl (ip_table_id);
8564   mp->mb_mpls_table_id = 0;
8565   mp->mb_label = ntohl (local_label);
8566   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8567
8568   /* send it... */
8569   S (mp);
8570
8571   /* Wait for a reply... */
8572   W (ret);
8573   return ret;
8574   return (0);
8575 }
8576
8577 static int
8578 api_sr_mpls_policy_add (vat_main_t * vam)
8579 {
8580   unformat_input_t *i = vam->input;
8581   vl_api_sr_mpls_policy_add_t *mp;
8582   u32 bsid = 0;
8583   u32 weight = 1;
8584   u8 type = 0;
8585   u8 n_segments = 0;
8586   u32 sid;
8587   u32 *segments = NULL;
8588   int ret;
8589
8590   /* Parse args required to build the message */
8591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8592     {
8593       if (unformat (i, "bsid %d", &bsid))
8594         ;
8595       else if (unformat (i, "weight %d", &weight))
8596         ;
8597       else if (unformat (i, "spray"))
8598         type = 1;
8599       else if (unformat (i, "next %d", &sid))
8600         {
8601           n_segments += 1;
8602           vec_add1 (segments, htonl (sid));
8603         }
8604       else
8605         {
8606           clib_warning ("parse error '%U'", format_unformat_error, i);
8607           return -99;
8608         }
8609     }
8610
8611   if (bsid == 0)
8612     {
8613       errmsg ("bsid not set");
8614       return -99;
8615     }
8616
8617   if (n_segments == 0)
8618     {
8619       errmsg ("no sid in segment stack");
8620       return -99;
8621     }
8622
8623   /* Construct the API message */
8624   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8625
8626   mp->bsid = htonl (bsid);
8627   mp->weight = htonl (weight);
8628   mp->type = type;
8629   mp->n_segments = n_segments;
8630   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8631   vec_free (segments);
8632
8633   /* send it... */
8634   S (mp);
8635
8636   /* Wait for a reply... */
8637   W (ret);
8638   return ret;
8639 }
8640
8641 static int
8642 api_sr_mpls_policy_del (vat_main_t * vam)
8643 {
8644   unformat_input_t *i = vam->input;
8645   vl_api_sr_mpls_policy_del_t *mp;
8646   u32 bsid = 0;
8647   int ret;
8648
8649   /* Parse args required to build the message */
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "bsid %d", &bsid))
8653         ;
8654       else
8655         {
8656           clib_warning ("parse error '%U'", format_unformat_error, i);
8657           return -99;
8658         }
8659     }
8660
8661   if (bsid == 0)
8662     {
8663       errmsg ("bsid not set");
8664       return -99;
8665     }
8666
8667   /* Construct the API message */
8668   M (SR_MPLS_POLICY_DEL, mp);
8669
8670   mp->bsid = htonl (bsid);
8671
8672   /* send it... */
8673   S (mp);
8674
8675   /* Wait for a reply... */
8676   W (ret);
8677   return ret;
8678 }
8679
8680 static int
8681 api_bier_table_add_del (vat_main_t * vam)
8682 {
8683   unformat_input_t *i = vam->input;
8684   vl_api_bier_table_add_del_t *mp;
8685   u8 is_add = 1;
8686   u32 set = 0, sub_domain = 0, hdr_len = 3;
8687   mpls_label_t local_label = MPLS_LABEL_INVALID;
8688   int ret;
8689
8690   /* Parse args required to build the message */
8691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8692     {
8693       if (unformat (i, "sub-domain %d", &sub_domain))
8694         ;
8695       else if (unformat (i, "set %d", &set))
8696         ;
8697       else if (unformat (i, "label %d", &local_label))
8698         ;
8699       else if (unformat (i, "hdr-len %d", &hdr_len))
8700         ;
8701       else if (unformat (i, "add"))
8702         is_add = 1;
8703       else if (unformat (i, "del"))
8704         is_add = 0;
8705       else
8706         {
8707           clib_warning ("parse error '%U'", format_unformat_error, i);
8708           return -99;
8709         }
8710     }
8711
8712   if (MPLS_LABEL_INVALID == local_label)
8713     {
8714       errmsg ("missing label\n");
8715       return -99;
8716     }
8717
8718   /* Construct the API message */
8719   M (BIER_TABLE_ADD_DEL, mp);
8720
8721   mp->bt_is_add = is_add;
8722   mp->bt_label = ntohl (local_label);
8723   mp->bt_tbl_id.bt_set = set;
8724   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8725   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8726
8727   /* send it... */
8728   S (mp);
8729
8730   /* Wait for a reply... */
8731   W (ret);
8732
8733   return (ret);
8734 }
8735
8736 static int
8737 api_bier_route_add_del (vat_main_t * vam)
8738 {
8739   unformat_input_t *i = vam->input;
8740   vl_api_bier_route_add_del_t *mp;
8741   u8 is_add = 1;
8742   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8743   ip4_address_t v4_next_hop_address;
8744   ip6_address_t v6_next_hop_address;
8745   u8 next_hop_set = 0;
8746   u8 next_hop_proto_is_ip4 = 1;
8747   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8748   int ret;
8749
8750   /* Parse args required to build the message */
8751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8752     {
8753       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8754         {
8755           next_hop_proto_is_ip4 = 1;
8756           next_hop_set = 1;
8757         }
8758       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8759         {
8760           next_hop_proto_is_ip4 = 0;
8761           next_hop_set = 1;
8762         }
8763       if (unformat (i, "sub-domain %d", &sub_domain))
8764         ;
8765       else if (unformat (i, "set %d", &set))
8766         ;
8767       else if (unformat (i, "hdr-len %d", &hdr_len))
8768         ;
8769       else if (unformat (i, "bp %d", &bp))
8770         ;
8771       else if (unformat (i, "add"))
8772         is_add = 1;
8773       else if (unformat (i, "del"))
8774         is_add = 0;
8775       else if (unformat (i, "out-label %d", &next_hop_out_label))
8776         ;
8777       else
8778         {
8779           clib_warning ("parse error '%U'", format_unformat_error, i);
8780           return -99;
8781         }
8782     }
8783
8784   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8785     {
8786       errmsg ("next hop / label set\n");
8787       return -99;
8788     }
8789   if (0 == bp)
8790     {
8791       errmsg ("bit=position not set\n");
8792       return -99;
8793     }
8794
8795   /* Construct the API message */
8796   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8797
8798   mp->br_is_add = is_add;
8799   mp->br_route.br_tbl_id.bt_set = set;
8800   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8801   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8802   mp->br_route.br_bp = ntohs (bp);
8803   mp->br_route.br_n_paths = 1;
8804   mp->br_route.br_paths[0].n_labels = 1;
8805   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8806   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8807                                     FIB_API_PATH_NH_PROTO_IP4 :
8808                                     FIB_API_PATH_NH_PROTO_IP6);
8809
8810   if (next_hop_proto_is_ip4)
8811     {
8812       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8813                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8814     }
8815   else
8816     {
8817       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8818                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8819     }
8820
8821   /* send it... */
8822   S (mp);
8823
8824   /* Wait for a reply... */
8825   W (ret);
8826
8827   return (ret);
8828 }
8829
8830 static int
8831 api_proxy_arp_add_del (vat_main_t * vam)
8832 {
8833   unformat_input_t *i = vam->input;
8834   vl_api_proxy_arp_add_del_t *mp;
8835   u32 vrf_id = 0;
8836   u8 is_add = 1;
8837   vl_api_ip4_address_t lo, hi;
8838   u8 range_set = 0;
8839   int ret;
8840
8841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8842     {
8843       if (unformat (i, "vrf %d", &vrf_id))
8844         ;
8845       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8846                          unformat_vl_api_ip4_address, &hi))
8847         range_set = 1;
8848       else if (unformat (i, "del"))
8849         is_add = 0;
8850       else
8851         {
8852           clib_warning ("parse error '%U'", format_unformat_error, i);
8853           return -99;
8854         }
8855     }
8856
8857   if (range_set == 0)
8858     {
8859       errmsg ("address range not set");
8860       return -99;
8861     }
8862
8863   M (PROXY_ARP_ADD_DEL, mp);
8864
8865   mp->proxy.table_id = ntohl (vrf_id);
8866   mp->is_add = is_add;
8867   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8868   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8869
8870   S (mp);
8871   W (ret);
8872   return ret;
8873 }
8874
8875 static int
8876 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8877 {
8878   unformat_input_t *i = vam->input;
8879   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8880   u32 sw_if_index;
8881   u8 enable = 1;
8882   u8 sw_if_index_set = 0;
8883   int ret;
8884
8885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8886     {
8887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8888         sw_if_index_set = 1;
8889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8890         sw_if_index_set = 1;
8891       else if (unformat (i, "enable"))
8892         enable = 1;
8893       else if (unformat (i, "disable"))
8894         enable = 0;
8895       else
8896         {
8897           clib_warning ("parse error '%U'", format_unformat_error, i);
8898           return -99;
8899         }
8900     }
8901
8902   if (sw_if_index_set == 0)
8903     {
8904       errmsg ("missing interface name or sw_if_index");
8905       return -99;
8906     }
8907
8908   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8909
8910   mp->sw_if_index = ntohl (sw_if_index);
8911   mp->enable_disable = enable;
8912
8913   S (mp);
8914   W (ret);
8915   return ret;
8916 }
8917
8918 static int
8919 api_mpls_tunnel_add_del (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_mpls_tunnel_add_del_t *mp;
8923
8924   vl_api_fib_path_t paths[8];
8925   u32 sw_if_index = ~0;
8926   u8 path_count = 0;
8927   u8 l2_only = 0;
8928   u8 is_add = 1;
8929   int ret;
8930
8931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8932     {
8933       if (unformat (i, "add"))
8934         is_add = 1;
8935       else
8936         if (unformat
8937             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8938         is_add = 0;
8939       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8940         is_add = 0;
8941       else if (unformat (i, "l2-only"))
8942         l2_only = 1;
8943       else
8944         if (unformat
8945             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8946         {
8947           path_count++;
8948           if (8 == path_count)
8949             {
8950               errmsg ("max 8 paths");
8951               return -99;
8952             }
8953         }
8954       else
8955         {
8956           clib_warning ("parse error '%U'", format_unformat_error, i);
8957           return -99;
8958         }
8959     }
8960
8961   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8962
8963   mp->mt_is_add = is_add;
8964   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8965   mp->mt_tunnel.mt_l2_only = l2_only;
8966   mp->mt_tunnel.mt_is_multicast = 0;
8967   mp->mt_tunnel.mt_n_paths = path_count;
8968
8969   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8970                sizeof (paths[0]) * path_count);
8971
8972   S (mp);
8973   W (ret);
8974   return ret;
8975 }
8976
8977 static int
8978 api_sw_interface_set_unnumbered (vat_main_t * vam)
8979 {
8980   unformat_input_t *i = vam->input;
8981   vl_api_sw_interface_set_unnumbered_t *mp;
8982   u32 sw_if_index;
8983   u32 unnum_sw_index = ~0;
8984   u8 is_add = 1;
8985   u8 sw_if_index_set = 0;
8986   int ret;
8987
8988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8989     {
8990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8991         sw_if_index_set = 1;
8992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8993         sw_if_index_set = 1;
8994       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8995         ;
8996       else if (unformat (i, "del"))
8997         is_add = 0;
8998       else
8999         {
9000           clib_warning ("parse error '%U'", format_unformat_error, i);
9001           return -99;
9002         }
9003     }
9004
9005   if (sw_if_index_set == 0)
9006     {
9007       errmsg ("missing interface name or sw_if_index");
9008       return -99;
9009     }
9010
9011   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9012
9013   mp->sw_if_index = ntohl (sw_if_index);
9014   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9015   mp->is_add = is_add;
9016
9017   S (mp);
9018   W (ret);
9019   return ret;
9020 }
9021
9022 static int
9023 api_ip_neighbor_add_del (vat_main_t * vam)
9024 {
9025   vl_api_mac_address_t mac_address;
9026   unformat_input_t *i = vam->input;
9027   vl_api_ip_neighbor_add_del_t *mp;
9028   vl_api_address_t ip_address;
9029   u32 sw_if_index;
9030   u8 sw_if_index_set = 0;
9031   u8 is_add = 1;
9032   u8 mac_set = 0;
9033   u8 address_set = 0;
9034   int ret;
9035   ip_neighbor_flags_t flags;
9036
9037   flags = IP_NEIGHBOR_FLAG_NONE;
9038   clib_memset (&ip_address, 0, sizeof (ip_address));
9039   clib_memset (&mac_address, 0, sizeof (mac_address));
9040
9041   /* Parse args required to build the message */
9042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9043     {
9044       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9045         {
9046           mac_set = 1;
9047         }
9048       else if (unformat (i, "del"))
9049         is_add = 0;
9050       else
9051         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9052         sw_if_index_set = 1;
9053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9054         sw_if_index_set = 1;
9055       else if (unformat (i, "static"))
9056         flags |= IP_NEIGHBOR_FLAG_STATIC;
9057       else if (unformat (i, "no-fib-entry"))
9058         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9059       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9060         address_set = 1;
9061       else
9062         {
9063           clib_warning ("parse error '%U'", format_unformat_error, i);
9064           return -99;
9065         }
9066     }
9067
9068   if (sw_if_index_set == 0)
9069     {
9070       errmsg ("missing interface name or sw_if_index");
9071       return -99;
9072     }
9073   if (!address_set)
9074     {
9075       errmsg ("no address set");
9076       return -99;
9077     }
9078
9079   /* Construct the API message */
9080   M (IP_NEIGHBOR_ADD_DEL, mp);
9081
9082   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9083   mp->is_add = is_add;
9084   mp->neighbor.flags = htonl (flags);
9085   if (mac_set)
9086     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9087                  sizeof (mac_address));
9088   if (address_set)
9089     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9090
9091   /* send it... */
9092   S (mp);
9093
9094   /* Wait for a reply, return good/bad news  */
9095   W (ret);
9096   return ret;
9097 }
9098
9099 static int
9100 api_create_vlan_subif (vat_main_t * vam)
9101 {
9102   unformat_input_t *i = vam->input;
9103   vl_api_create_vlan_subif_t *mp;
9104   u32 sw_if_index;
9105   u8 sw_if_index_set = 0;
9106   u32 vlan_id;
9107   u8 vlan_id_set = 0;
9108   int ret;
9109
9110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (i, "sw_if_index %d", &sw_if_index))
9113         sw_if_index_set = 1;
9114       else
9115         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9116         sw_if_index_set = 1;
9117       else if (unformat (i, "vlan %d", &vlan_id))
9118         vlan_id_set = 1;
9119       else
9120         {
9121           clib_warning ("parse error '%U'", format_unformat_error, i);
9122           return -99;
9123         }
9124     }
9125
9126   if (sw_if_index_set == 0)
9127     {
9128       errmsg ("missing interface name or sw_if_index");
9129       return -99;
9130     }
9131
9132   if (vlan_id_set == 0)
9133     {
9134       errmsg ("missing vlan_id");
9135       return -99;
9136     }
9137   M (CREATE_VLAN_SUBIF, mp);
9138
9139   mp->sw_if_index = ntohl (sw_if_index);
9140   mp->vlan_id = ntohl (vlan_id);
9141
9142   S (mp);
9143   W (ret);
9144   return ret;
9145 }
9146
9147 #define foreach_create_subif_bit                \
9148 _(no_tags)                                      \
9149 _(one_tag)                                      \
9150 _(two_tags)                                     \
9151 _(dot1ad)                                       \
9152 _(exact_match)                                  \
9153 _(default_sub)                                  \
9154 _(outer_vlan_id_any)                            \
9155 _(inner_vlan_id_any)
9156
9157 #define foreach_create_subif_flag               \
9158 _(0, "no_tags")                                 \
9159 _(1, "one_tag")                                 \
9160 _(2, "two_tags")                                \
9161 _(3, "dot1ad")                                  \
9162 _(4, "exact_match")                             \
9163 _(5, "default_sub")                             \
9164 _(6, "outer_vlan_id_any")                       \
9165 _(7, "inner_vlan_id_any")
9166
9167 static int
9168 api_create_subif (vat_main_t * vam)
9169 {
9170   unformat_input_t *i = vam->input;
9171   vl_api_create_subif_t *mp;
9172   u32 sw_if_index;
9173   u8 sw_if_index_set = 0;
9174   u32 sub_id;
9175   u8 sub_id_set = 0;
9176   u32 __attribute__ ((unused)) no_tags = 0;
9177   u32 __attribute__ ((unused)) one_tag = 0;
9178   u32 __attribute__ ((unused)) two_tags = 0;
9179   u32 __attribute__ ((unused)) dot1ad = 0;
9180   u32 __attribute__ ((unused)) exact_match = 0;
9181   u32 __attribute__ ((unused)) default_sub = 0;
9182   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9183   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9184   u32 tmp;
9185   u16 outer_vlan_id = 0;
9186   u16 inner_vlan_id = 0;
9187   int ret;
9188
9189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9190     {
9191       if (unformat (i, "sw_if_index %d", &sw_if_index))
9192         sw_if_index_set = 1;
9193       else
9194         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9195         sw_if_index_set = 1;
9196       else if (unformat (i, "sub_id %d", &sub_id))
9197         sub_id_set = 1;
9198       else if (unformat (i, "outer_vlan_id %d", &tmp))
9199         outer_vlan_id = tmp;
9200       else if (unformat (i, "inner_vlan_id %d", &tmp))
9201         inner_vlan_id = tmp;
9202
9203 #define _(a) else if (unformat (i, #a)) a = 1 ;
9204       foreach_create_subif_bit
9205 #undef _
9206         else
9207         {
9208           clib_warning ("parse error '%U'", format_unformat_error, i);
9209           return -99;
9210         }
9211     }
9212
9213   if (sw_if_index_set == 0)
9214     {
9215       errmsg ("missing interface name or sw_if_index");
9216       return -99;
9217     }
9218
9219   if (sub_id_set == 0)
9220     {
9221       errmsg ("missing sub_id");
9222       return -99;
9223     }
9224   M (CREATE_SUBIF, mp);
9225
9226   mp->sw_if_index = ntohl (sw_if_index);
9227   mp->sub_id = ntohl (sub_id);
9228
9229 #define _(a,b) mp->sub_if_flags |= (1 << a);
9230   foreach_create_subif_flag;
9231 #undef _
9232
9233   mp->outer_vlan_id = ntohs (outer_vlan_id);
9234   mp->inner_vlan_id = ntohs (inner_vlan_id);
9235
9236   S (mp);
9237   W (ret);
9238   return ret;
9239 }
9240
9241 static int
9242 api_reset_fib (vat_main_t * vam)
9243 {
9244   unformat_input_t *i = vam->input;
9245   vl_api_reset_fib_t *mp;
9246   u32 vrf_id = 0;
9247   u8 is_ipv6 = 0;
9248   u8 vrf_id_set = 0;
9249
9250   int ret;
9251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9252     {
9253       if (unformat (i, "vrf %d", &vrf_id))
9254         vrf_id_set = 1;
9255       else if (unformat (i, "ipv6"))
9256         is_ipv6 = 1;
9257       else
9258         {
9259           clib_warning ("parse error '%U'", format_unformat_error, i);
9260           return -99;
9261         }
9262     }
9263
9264   if (vrf_id_set == 0)
9265     {
9266       errmsg ("missing vrf id");
9267       return -99;
9268     }
9269
9270   M (RESET_FIB, mp);
9271
9272   mp->vrf_id = ntohl (vrf_id);
9273   mp->is_ipv6 = is_ipv6;
9274
9275   S (mp);
9276   W (ret);
9277   return ret;
9278 }
9279
9280 static int
9281 api_dhcp_proxy_config (vat_main_t * vam)
9282 {
9283   unformat_input_t *i = vam->input;
9284   vl_api_dhcp_proxy_config_t *mp;
9285   u32 rx_vrf_id = 0;
9286   u32 server_vrf_id = 0;
9287   u8 is_add = 1;
9288   u8 v4_address_set = 0;
9289   u8 v6_address_set = 0;
9290   ip4_address_t v4address;
9291   ip6_address_t v6address;
9292   u8 v4_src_address_set = 0;
9293   u8 v6_src_address_set = 0;
9294   ip4_address_t v4srcaddress;
9295   ip6_address_t v6srcaddress;
9296   int ret;
9297
9298   /* Parse args required to build the message */
9299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9300     {
9301       if (unformat (i, "del"))
9302         is_add = 0;
9303       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9304         ;
9305       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9306         ;
9307       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9308         v4_address_set = 1;
9309       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9310         v6_address_set = 1;
9311       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9312         v4_src_address_set = 1;
9313       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9314         v6_src_address_set = 1;
9315       else
9316         break;
9317     }
9318
9319   if (v4_address_set && v6_address_set)
9320     {
9321       errmsg ("both v4 and v6 server addresses set");
9322       return -99;
9323     }
9324   if (!v4_address_set && !v6_address_set)
9325     {
9326       errmsg ("no server addresses set");
9327       return -99;
9328     }
9329
9330   if (v4_src_address_set && v6_src_address_set)
9331     {
9332       errmsg ("both v4 and v6  src addresses set");
9333       return -99;
9334     }
9335   if (!v4_src_address_set && !v6_src_address_set)
9336     {
9337       errmsg ("no src addresses set");
9338       return -99;
9339     }
9340
9341   if (!(v4_src_address_set && v4_address_set) &&
9342       !(v6_src_address_set && v6_address_set))
9343     {
9344       errmsg ("no matching server and src addresses set");
9345       return -99;
9346     }
9347
9348   /* Construct the API message */
9349   M (DHCP_PROXY_CONFIG, mp);
9350
9351   mp->is_add = is_add;
9352   mp->rx_vrf_id = ntohl (rx_vrf_id);
9353   mp->server_vrf_id = ntohl (server_vrf_id);
9354   if (v6_address_set)
9355     {
9356       mp->is_ipv6 = 1;
9357       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9358       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9359     }
9360   else
9361     {
9362       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9363       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9364     }
9365
9366   /* send it... */
9367   S (mp);
9368
9369   /* Wait for a reply, return good/bad news  */
9370   W (ret);
9371   return ret;
9372 }
9373
9374 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9375 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9376
9377 static void
9378 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9379 {
9380   vat_main_t *vam = &vat_main;
9381   u32 i, count = mp->count;
9382   vl_api_dhcp_server_t *s;
9383
9384   if (mp->is_ipv6)
9385     print (vam->ofp,
9386            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9387            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9388            ntohl (mp->rx_vrf_id),
9389            format_ip6_address, mp->dhcp_src_address,
9390            mp->vss_type, mp->vss_vpn_ascii_id,
9391            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9392   else
9393     print (vam->ofp,
9394            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9395            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9396            ntohl (mp->rx_vrf_id),
9397            format_ip4_address, mp->dhcp_src_address,
9398            mp->vss_type, mp->vss_vpn_ascii_id,
9399            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9400
9401   for (i = 0; i < count; i++)
9402     {
9403       s = &mp->servers[i];
9404
9405       if (mp->is_ipv6)
9406         print (vam->ofp,
9407                " Server Table-ID %d, Server Address %U",
9408                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9409       else
9410         print (vam->ofp,
9411                " Server Table-ID %d, Server Address %U",
9412                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9413     }
9414 }
9415
9416 static void vl_api_dhcp_proxy_details_t_handler_json
9417   (vl_api_dhcp_proxy_details_t * mp)
9418 {
9419   vat_main_t *vam = &vat_main;
9420   vat_json_node_t *node = NULL;
9421   u32 i, count = mp->count;
9422   struct in_addr ip4;
9423   struct in6_addr ip6;
9424   vl_api_dhcp_server_t *s;
9425
9426   if (VAT_JSON_ARRAY != vam->json_tree.type)
9427     {
9428       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9429       vat_json_init_array (&vam->json_tree);
9430     }
9431   node = vat_json_array_add (&vam->json_tree);
9432
9433   vat_json_init_object (node);
9434   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9435   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9436                              sizeof (mp->vss_type));
9437   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9438                                    mp->vss_vpn_ascii_id);
9439   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9440   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9441
9442   if (mp->is_ipv6)
9443     {
9444       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9445       vat_json_object_add_ip6 (node, "src_address", ip6);
9446     }
9447   else
9448     {
9449       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9450       vat_json_object_add_ip4 (node, "src_address", ip4);
9451     }
9452
9453   for (i = 0; i < count; i++)
9454     {
9455       s = &mp->servers[i];
9456
9457       vat_json_object_add_uint (node, "server-table-id",
9458                                 ntohl (s->server_vrf_id));
9459
9460       if (mp->is_ipv6)
9461         {
9462           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9463           vat_json_object_add_ip4 (node, "src_address", ip4);
9464         }
9465       else
9466         {
9467           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9468           vat_json_object_add_ip6 (node, "server_address", ip6);
9469         }
9470     }
9471 }
9472
9473 static int
9474 api_dhcp_proxy_dump (vat_main_t * vam)
9475 {
9476   unformat_input_t *i = vam->input;
9477   vl_api_control_ping_t *mp_ping;
9478   vl_api_dhcp_proxy_dump_t *mp;
9479   u8 is_ipv6 = 0;
9480   int ret;
9481
9482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9483     {
9484       if (unformat (i, "ipv6"))
9485         is_ipv6 = 1;
9486       else
9487         {
9488           clib_warning ("parse error '%U'", format_unformat_error, i);
9489           return -99;
9490         }
9491     }
9492
9493   M (DHCP_PROXY_DUMP, mp);
9494
9495   mp->is_ip6 = is_ipv6;
9496   S (mp);
9497
9498   /* Use a control ping for synchronization */
9499   MPING (CONTROL_PING, mp_ping);
9500   S (mp_ping);
9501
9502   W (ret);
9503   return ret;
9504 }
9505
9506 static int
9507 api_dhcp_proxy_set_vss (vat_main_t * vam)
9508 {
9509   unformat_input_t *i = vam->input;
9510   vl_api_dhcp_proxy_set_vss_t *mp;
9511   u8 is_ipv6 = 0;
9512   u8 is_add = 1;
9513   u32 tbl_id = ~0;
9514   u8 vss_type = VSS_TYPE_DEFAULT;
9515   u8 *vpn_ascii_id = 0;
9516   u32 oui = 0;
9517   u32 fib_id = 0;
9518   int ret;
9519
9520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9521     {
9522       if (unformat (i, "tbl_id %d", &tbl_id))
9523         ;
9524       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9525         vss_type = VSS_TYPE_ASCII;
9526       else if (unformat (i, "fib_id %d", &fib_id))
9527         vss_type = VSS_TYPE_VPN_ID;
9528       else if (unformat (i, "oui %d", &oui))
9529         vss_type = VSS_TYPE_VPN_ID;
9530       else if (unformat (i, "ipv6"))
9531         is_ipv6 = 1;
9532       else if (unformat (i, "del"))
9533         is_add = 0;
9534       else
9535         break;
9536     }
9537
9538   if (tbl_id == ~0)
9539     {
9540       errmsg ("missing tbl_id ");
9541       vec_free (vpn_ascii_id);
9542       return -99;
9543     }
9544
9545   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9546     {
9547       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9548       vec_free (vpn_ascii_id);
9549       return -99;
9550     }
9551
9552   M (DHCP_PROXY_SET_VSS, mp);
9553   mp->tbl_id = ntohl (tbl_id);
9554   mp->vss_type = vss_type;
9555   if (vpn_ascii_id)
9556     {
9557       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9558       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9559     }
9560   mp->vpn_index = ntohl (fib_id);
9561   mp->oui = ntohl (oui);
9562   mp->is_ipv6 = is_ipv6;
9563   mp->is_add = is_add;
9564
9565   S (mp);
9566   W (ret);
9567
9568   vec_free (vpn_ascii_id);
9569   return ret;
9570 }
9571
9572 static int
9573 api_dhcp_client_config (vat_main_t * vam)
9574 {
9575   unformat_input_t *i = vam->input;
9576   vl_api_dhcp_client_config_t *mp;
9577   u32 sw_if_index;
9578   u8 sw_if_index_set = 0;
9579   u8 is_add = 1;
9580   u8 *hostname = 0;
9581   u8 disable_event = 0;
9582   int ret;
9583
9584   /* Parse args required to build the message */
9585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9586     {
9587       if (unformat (i, "del"))
9588         is_add = 0;
9589       else
9590         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9591         sw_if_index_set = 1;
9592       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9593         sw_if_index_set = 1;
9594       else if (unformat (i, "hostname %s", &hostname))
9595         ;
9596       else if (unformat (i, "disable_event"))
9597         disable_event = 1;
9598       else
9599         break;
9600     }
9601
9602   if (sw_if_index_set == 0)
9603     {
9604       errmsg ("missing interface name or sw_if_index");
9605       return -99;
9606     }
9607
9608   if (vec_len (hostname) > 63)
9609     {
9610       errmsg ("hostname too long");
9611     }
9612   vec_add1 (hostname, 0);
9613
9614   /* Construct the API message */
9615   M (DHCP_CLIENT_CONFIG, mp);
9616
9617   mp->is_add = is_add;
9618   mp->client.sw_if_index = htonl (sw_if_index);
9619   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
9620   vec_free (hostname);
9621   mp->client.want_dhcp_event = disable_event ? 0 : 1;
9622   mp->client.pid = htonl (getpid ());
9623
9624   /* send it... */
9625   S (mp);
9626
9627   /* Wait for a reply, return good/bad news  */
9628   W (ret);
9629   return ret;
9630 }
9631
9632 static int
9633 api_set_ip_flow_hash (vat_main_t * vam)
9634 {
9635   unformat_input_t *i = vam->input;
9636   vl_api_set_ip_flow_hash_t *mp;
9637   u32 vrf_id = 0;
9638   u8 is_ipv6 = 0;
9639   u8 vrf_id_set = 0;
9640   u8 src = 0;
9641   u8 dst = 0;
9642   u8 sport = 0;
9643   u8 dport = 0;
9644   u8 proto = 0;
9645   u8 reverse = 0;
9646   int ret;
9647
9648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (i, "vrf %d", &vrf_id))
9651         vrf_id_set = 1;
9652       else if (unformat (i, "ipv6"))
9653         is_ipv6 = 1;
9654       else if (unformat (i, "src"))
9655         src = 1;
9656       else if (unformat (i, "dst"))
9657         dst = 1;
9658       else if (unformat (i, "sport"))
9659         sport = 1;
9660       else if (unformat (i, "dport"))
9661         dport = 1;
9662       else if (unformat (i, "proto"))
9663         proto = 1;
9664       else if (unformat (i, "reverse"))
9665         reverse = 1;
9666
9667       else
9668         {
9669           clib_warning ("parse error '%U'", format_unformat_error, i);
9670           return -99;
9671         }
9672     }
9673
9674   if (vrf_id_set == 0)
9675     {
9676       errmsg ("missing vrf id");
9677       return -99;
9678     }
9679
9680   M (SET_IP_FLOW_HASH, mp);
9681   mp->src = src;
9682   mp->dst = dst;
9683   mp->sport = sport;
9684   mp->dport = dport;
9685   mp->proto = proto;
9686   mp->reverse = reverse;
9687   mp->vrf_id = ntohl (vrf_id);
9688   mp->is_ipv6 = is_ipv6;
9689
9690   S (mp);
9691   W (ret);
9692   return ret;
9693 }
9694
9695 static int
9696 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9697 {
9698   unformat_input_t *i = vam->input;
9699   vl_api_sw_interface_ip6_enable_disable_t *mp;
9700   u32 sw_if_index;
9701   u8 sw_if_index_set = 0;
9702   u8 enable = 0;
9703   int ret;
9704
9705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9708         sw_if_index_set = 1;
9709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9710         sw_if_index_set = 1;
9711       else if (unformat (i, "enable"))
9712         enable = 1;
9713       else if (unformat (i, "disable"))
9714         enable = 0;
9715       else
9716         {
9717           clib_warning ("parse error '%U'", format_unformat_error, i);
9718           return -99;
9719         }
9720     }
9721
9722   if (sw_if_index_set == 0)
9723     {
9724       errmsg ("missing interface name or sw_if_index");
9725       return -99;
9726     }
9727
9728   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9729
9730   mp->sw_if_index = ntohl (sw_if_index);
9731   mp->enable = enable;
9732
9733   S (mp);
9734   W (ret);
9735   return ret;
9736 }
9737
9738 static int
9739 api_ip6nd_proxy_add_del (vat_main_t * vam)
9740 {
9741   unformat_input_t *i = vam->input;
9742   vl_api_ip6nd_proxy_add_del_t *mp;
9743   u32 sw_if_index = ~0;
9744   u8 v6_address_set = 0;
9745   vl_api_ip6_address_t v6address;
9746   u8 is_del = 0;
9747   int ret;
9748
9749   /* Parse args required to build the message */
9750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9751     {
9752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9753         ;
9754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9755         ;
9756       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9757         v6_address_set = 1;
9758       if (unformat (i, "del"))
9759         is_del = 1;
9760       else
9761         {
9762           clib_warning ("parse error '%U'", format_unformat_error, i);
9763           return -99;
9764         }
9765     }
9766
9767   if (sw_if_index == ~0)
9768     {
9769       errmsg ("missing interface name or sw_if_index");
9770       return -99;
9771     }
9772   if (!v6_address_set)
9773     {
9774       errmsg ("no address set");
9775       return -99;
9776     }
9777
9778   /* Construct the API message */
9779   M (IP6ND_PROXY_ADD_DEL, mp);
9780
9781   mp->is_del = is_del;
9782   mp->sw_if_index = ntohl (sw_if_index);
9783   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9784
9785   /* send it... */
9786   S (mp);
9787
9788   /* Wait for a reply, return good/bad news  */
9789   W (ret);
9790   return ret;
9791 }
9792
9793 static int
9794 api_ip6nd_proxy_dump (vat_main_t * vam)
9795 {
9796   vl_api_ip6nd_proxy_dump_t *mp;
9797   vl_api_control_ping_t *mp_ping;
9798   int ret;
9799
9800   M (IP6ND_PROXY_DUMP, mp);
9801
9802   S (mp);
9803
9804   /* Use a control ping for synchronization */
9805   MPING (CONTROL_PING, mp_ping);
9806   S (mp_ping);
9807
9808   W (ret);
9809   return ret;
9810 }
9811
9812 static void vl_api_ip6nd_proxy_details_t_handler
9813   (vl_api_ip6nd_proxy_details_t * mp)
9814 {
9815   vat_main_t *vam = &vat_main;
9816
9817   print (vam->ofp, "host %U sw_if_index %d",
9818          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9819 }
9820
9821 static void vl_api_ip6nd_proxy_details_t_handler_json
9822   (vl_api_ip6nd_proxy_details_t * mp)
9823 {
9824   vat_main_t *vam = &vat_main;
9825   struct in6_addr ip6;
9826   vat_json_node_t *node = NULL;
9827
9828   if (VAT_JSON_ARRAY != vam->json_tree.type)
9829     {
9830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9831       vat_json_init_array (&vam->json_tree);
9832     }
9833   node = vat_json_array_add (&vam->json_tree);
9834
9835   vat_json_init_object (node);
9836   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9837
9838   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9839   vat_json_object_add_ip6 (node, "host", ip6);
9840 }
9841
9842 static int
9843 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9844 {
9845   unformat_input_t *i = vam->input;
9846   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9847   u32 sw_if_index;
9848   u8 sw_if_index_set = 0;
9849   u8 v6_address_set = 0;
9850   vl_api_prefix_t pfx;
9851   u8 use_default = 0;
9852   u8 no_advertise = 0;
9853   u8 off_link = 0;
9854   u8 no_autoconfig = 0;
9855   u8 no_onlink = 0;
9856   u8 is_no = 0;
9857   u32 val_lifetime = 0;
9858   u32 pref_lifetime = 0;
9859   int ret;
9860
9861   /* Parse args required to build the message */
9862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9863     {
9864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9865         sw_if_index_set = 1;
9866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9867         sw_if_index_set = 1;
9868       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9869         v6_address_set = 1;
9870       else if (unformat (i, "val_life %d", &val_lifetime))
9871         ;
9872       else if (unformat (i, "pref_life %d", &pref_lifetime))
9873         ;
9874       else if (unformat (i, "def"))
9875         use_default = 1;
9876       else if (unformat (i, "noadv"))
9877         no_advertise = 1;
9878       else if (unformat (i, "offl"))
9879         off_link = 1;
9880       else if (unformat (i, "noauto"))
9881         no_autoconfig = 1;
9882       else if (unformat (i, "nolink"))
9883         no_onlink = 1;
9884       else if (unformat (i, "isno"))
9885         is_no = 1;
9886       else
9887         {
9888           clib_warning ("parse error '%U'", format_unformat_error, i);
9889           return -99;
9890         }
9891     }
9892
9893   if (sw_if_index_set == 0)
9894     {
9895       errmsg ("missing interface name or sw_if_index");
9896       return -99;
9897     }
9898   if (!v6_address_set)
9899     {
9900       errmsg ("no address set");
9901       return -99;
9902     }
9903
9904   /* Construct the API message */
9905   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9906
9907   mp->sw_if_index = ntohl (sw_if_index);
9908   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9909   mp->use_default = use_default;
9910   mp->no_advertise = no_advertise;
9911   mp->off_link = off_link;
9912   mp->no_autoconfig = no_autoconfig;
9913   mp->no_onlink = no_onlink;
9914   mp->is_no = is_no;
9915   mp->val_lifetime = ntohl (val_lifetime);
9916   mp->pref_lifetime = ntohl (pref_lifetime);
9917
9918   /* send it... */
9919   S (mp);
9920
9921   /* Wait for a reply, return good/bad news  */
9922   W (ret);
9923   return ret;
9924 }
9925
9926 static int
9927 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9928 {
9929   unformat_input_t *i = vam->input;
9930   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9931   u32 sw_if_index;
9932   u8 sw_if_index_set = 0;
9933   u8 suppress = 0;
9934   u8 managed = 0;
9935   u8 other = 0;
9936   u8 ll_option = 0;
9937   u8 send_unicast = 0;
9938   u8 cease = 0;
9939   u8 is_no = 0;
9940   u8 default_router = 0;
9941   u32 max_interval = 0;
9942   u32 min_interval = 0;
9943   u32 lifetime = 0;
9944   u32 initial_count = 0;
9945   u32 initial_interval = 0;
9946   int ret;
9947
9948
9949   /* Parse args required to build the message */
9950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9951     {
9952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9953         sw_if_index_set = 1;
9954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9955         sw_if_index_set = 1;
9956       else if (unformat (i, "maxint %d", &max_interval))
9957         ;
9958       else if (unformat (i, "minint %d", &min_interval))
9959         ;
9960       else if (unformat (i, "life %d", &lifetime))
9961         ;
9962       else if (unformat (i, "count %d", &initial_count))
9963         ;
9964       else if (unformat (i, "interval %d", &initial_interval))
9965         ;
9966       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9967         suppress = 1;
9968       else if (unformat (i, "managed"))
9969         managed = 1;
9970       else if (unformat (i, "other"))
9971         other = 1;
9972       else if (unformat (i, "ll"))
9973         ll_option = 1;
9974       else if (unformat (i, "send"))
9975         send_unicast = 1;
9976       else if (unformat (i, "cease"))
9977         cease = 1;
9978       else if (unformat (i, "isno"))
9979         is_no = 1;
9980       else if (unformat (i, "def"))
9981         default_router = 1;
9982       else
9983         {
9984           clib_warning ("parse error '%U'", format_unformat_error, i);
9985           return -99;
9986         }
9987     }
9988
9989   if (sw_if_index_set == 0)
9990     {
9991       errmsg ("missing interface name or sw_if_index");
9992       return -99;
9993     }
9994
9995   /* Construct the API message */
9996   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9997
9998   mp->sw_if_index = ntohl (sw_if_index);
9999   mp->max_interval = ntohl (max_interval);
10000   mp->min_interval = ntohl (min_interval);
10001   mp->lifetime = ntohl (lifetime);
10002   mp->initial_count = ntohl (initial_count);
10003   mp->initial_interval = ntohl (initial_interval);
10004   mp->suppress = suppress;
10005   mp->managed = managed;
10006   mp->other = other;
10007   mp->ll_option = ll_option;
10008   mp->send_unicast = send_unicast;
10009   mp->cease = cease;
10010   mp->is_no = is_no;
10011   mp->default_router = default_router;
10012
10013   /* send it... */
10014   S (mp);
10015
10016   /* Wait for a reply, return good/bad news  */
10017   W (ret);
10018   return ret;
10019 }
10020
10021 static int
10022 api_set_arp_neighbor_limit (vat_main_t * vam)
10023 {
10024   unformat_input_t *i = vam->input;
10025   vl_api_set_arp_neighbor_limit_t *mp;
10026   u32 arp_nbr_limit;
10027   u8 limit_set = 0;
10028   u8 is_ipv6 = 0;
10029   int ret;
10030
10031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10032     {
10033       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10034         limit_set = 1;
10035       else if (unformat (i, "ipv6"))
10036         is_ipv6 = 1;
10037       else
10038         {
10039           clib_warning ("parse error '%U'", format_unformat_error, i);
10040           return -99;
10041         }
10042     }
10043
10044   if (limit_set == 0)
10045     {
10046       errmsg ("missing limit value");
10047       return -99;
10048     }
10049
10050   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10051
10052   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10053   mp->is_ipv6 = is_ipv6;
10054
10055   S (mp);
10056   W (ret);
10057   return ret;
10058 }
10059
10060 static int
10061 api_l2_patch_add_del (vat_main_t * vam)
10062 {
10063   unformat_input_t *i = vam->input;
10064   vl_api_l2_patch_add_del_t *mp;
10065   u32 rx_sw_if_index;
10066   u8 rx_sw_if_index_set = 0;
10067   u32 tx_sw_if_index;
10068   u8 tx_sw_if_index_set = 0;
10069   u8 is_add = 1;
10070   int ret;
10071
10072   /* Parse args required to build the message */
10073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10074     {
10075       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10076         rx_sw_if_index_set = 1;
10077       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10078         tx_sw_if_index_set = 1;
10079       else if (unformat (i, "rx"))
10080         {
10081           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10082             {
10083               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10084                             &rx_sw_if_index))
10085                 rx_sw_if_index_set = 1;
10086             }
10087           else
10088             break;
10089         }
10090       else if (unformat (i, "tx"))
10091         {
10092           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10093             {
10094               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10095                             &tx_sw_if_index))
10096                 tx_sw_if_index_set = 1;
10097             }
10098           else
10099             break;
10100         }
10101       else if (unformat (i, "del"))
10102         is_add = 0;
10103       else
10104         break;
10105     }
10106
10107   if (rx_sw_if_index_set == 0)
10108     {
10109       errmsg ("missing rx interface name or rx_sw_if_index");
10110       return -99;
10111     }
10112
10113   if (tx_sw_if_index_set == 0)
10114     {
10115       errmsg ("missing tx interface name or tx_sw_if_index");
10116       return -99;
10117     }
10118
10119   M (L2_PATCH_ADD_DEL, mp);
10120
10121   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10122   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10123   mp->is_add = is_add;
10124
10125   S (mp);
10126   W (ret);
10127   return ret;
10128 }
10129
10130 u8 is_del;
10131 u8 localsid_addr[16];
10132 u8 end_psp;
10133 u8 behavior;
10134 u32 sw_if_index;
10135 u32 vlan_index;
10136 u32 fib_table;
10137 u8 nh_addr[16];
10138
10139 static int
10140 api_sr_localsid_add_del (vat_main_t * vam)
10141 {
10142   unformat_input_t *i = vam->input;
10143   vl_api_sr_localsid_add_del_t *mp;
10144
10145   u8 is_del;
10146   ip6_address_t localsid;
10147   u8 end_psp = 0;
10148   u8 behavior = ~0;
10149   u32 sw_if_index;
10150   u32 fib_table = ~(u32) 0;
10151   ip6_address_t nh_addr6;
10152   ip4_address_t nh_addr4;
10153   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10154   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10155
10156   bool nexthop_set = 0;
10157
10158   int ret;
10159
10160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10161     {
10162       if (unformat (i, "del"))
10163         is_del = 1;
10164       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10165       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10166         nexthop_set = 1;
10167       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10168         nexthop_set = 1;
10169       else if (unformat (i, "behavior %u", &behavior));
10170       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10171       else if (unformat (i, "fib-table %u", &fib_table));
10172       else if (unformat (i, "end.psp %u", &behavior));
10173       else
10174         break;
10175     }
10176
10177   M (SR_LOCALSID_ADD_DEL, mp);
10178
10179   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10180   if (nexthop_set)
10181     {
10182       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10183       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10184     }
10185   mp->behavior = behavior;
10186   mp->sw_if_index = ntohl (sw_if_index);
10187   mp->fib_table = ntohl (fib_table);
10188   mp->end_psp = end_psp;
10189   mp->is_del = is_del;
10190
10191   S (mp);
10192   W (ret);
10193   return ret;
10194 }
10195
10196 static int
10197 api_ioam_enable (vat_main_t * vam)
10198 {
10199   unformat_input_t *input = vam->input;
10200   vl_api_ioam_enable_t *mp;
10201   u32 id = 0;
10202   int has_trace_option = 0;
10203   int has_pot_option = 0;
10204   int has_seqno_option = 0;
10205   int has_analyse_option = 0;
10206   int ret;
10207
10208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10209     {
10210       if (unformat (input, "trace"))
10211         has_trace_option = 1;
10212       else if (unformat (input, "pot"))
10213         has_pot_option = 1;
10214       else if (unformat (input, "seqno"))
10215         has_seqno_option = 1;
10216       else if (unformat (input, "analyse"))
10217         has_analyse_option = 1;
10218       else
10219         break;
10220     }
10221   M (IOAM_ENABLE, mp);
10222   mp->id = htons (id);
10223   mp->seqno = has_seqno_option;
10224   mp->analyse = has_analyse_option;
10225   mp->pot_enable = has_pot_option;
10226   mp->trace_enable = has_trace_option;
10227
10228   S (mp);
10229   W (ret);
10230   return ret;
10231 }
10232
10233
10234 static int
10235 api_ioam_disable (vat_main_t * vam)
10236 {
10237   vl_api_ioam_disable_t *mp;
10238   int ret;
10239
10240   M (IOAM_DISABLE, mp);
10241   S (mp);
10242   W (ret);
10243   return ret;
10244 }
10245
10246 #define foreach_tcp_proto_field                 \
10247 _(src_port)                                     \
10248 _(dst_port)
10249
10250 #define foreach_udp_proto_field                 \
10251 _(src_port)                                     \
10252 _(dst_port)
10253
10254 #define foreach_ip4_proto_field                 \
10255 _(src_address)                                  \
10256 _(dst_address)                                  \
10257 _(tos)                                          \
10258 _(length)                                       \
10259 _(fragment_id)                                  \
10260 _(ttl)                                          \
10261 _(protocol)                                     \
10262 _(checksum)
10263
10264 typedef struct
10265 {
10266   u16 src_port, dst_port;
10267 } tcpudp_header_t;
10268
10269 #if VPP_API_TEST_BUILTIN == 0
10270 uword
10271 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10272 {
10273   u8 **maskp = va_arg (*args, u8 **);
10274   u8 *mask = 0;
10275   u8 found_something = 0;
10276   tcp_header_t *tcp;
10277
10278 #define _(a) u8 a=0;
10279   foreach_tcp_proto_field;
10280 #undef _
10281
10282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10283     {
10284       if (0);
10285 #define _(a) else if (unformat (input, #a)) a=1;
10286       foreach_tcp_proto_field
10287 #undef _
10288         else
10289         break;
10290     }
10291
10292 #define _(a) found_something += a;
10293   foreach_tcp_proto_field;
10294 #undef _
10295
10296   if (found_something == 0)
10297     return 0;
10298
10299   vec_validate (mask, sizeof (*tcp) - 1);
10300
10301   tcp = (tcp_header_t *) mask;
10302
10303 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10304   foreach_tcp_proto_field;
10305 #undef _
10306
10307   *maskp = mask;
10308   return 1;
10309 }
10310
10311 uword
10312 unformat_udp_mask (unformat_input_t * input, va_list * args)
10313 {
10314   u8 **maskp = va_arg (*args, u8 **);
10315   u8 *mask = 0;
10316   u8 found_something = 0;
10317   udp_header_t *udp;
10318
10319 #define _(a) u8 a=0;
10320   foreach_udp_proto_field;
10321 #undef _
10322
10323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (0);
10326 #define _(a) else if (unformat (input, #a)) a=1;
10327       foreach_udp_proto_field
10328 #undef _
10329         else
10330         break;
10331     }
10332
10333 #define _(a) found_something += a;
10334   foreach_udp_proto_field;
10335 #undef _
10336
10337   if (found_something == 0)
10338     return 0;
10339
10340   vec_validate (mask, sizeof (*udp) - 1);
10341
10342   udp = (udp_header_t *) mask;
10343
10344 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10345   foreach_udp_proto_field;
10346 #undef _
10347
10348   *maskp = mask;
10349   return 1;
10350 }
10351
10352 uword
10353 unformat_l4_mask (unformat_input_t * input, va_list * args)
10354 {
10355   u8 **maskp = va_arg (*args, u8 **);
10356   u16 src_port = 0, dst_port = 0;
10357   tcpudp_header_t *tcpudp;
10358
10359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10360     {
10361       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10362         return 1;
10363       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10364         return 1;
10365       else if (unformat (input, "src_port"))
10366         src_port = 0xFFFF;
10367       else if (unformat (input, "dst_port"))
10368         dst_port = 0xFFFF;
10369       else
10370         return 0;
10371     }
10372
10373   if (!src_port && !dst_port)
10374     return 0;
10375
10376   u8 *mask = 0;
10377   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10378
10379   tcpudp = (tcpudp_header_t *) mask;
10380   tcpudp->src_port = src_port;
10381   tcpudp->dst_port = dst_port;
10382
10383   *maskp = mask;
10384
10385   return 1;
10386 }
10387
10388 uword
10389 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10390 {
10391   u8 **maskp = va_arg (*args, u8 **);
10392   u8 *mask = 0;
10393   u8 found_something = 0;
10394   ip4_header_t *ip;
10395
10396 #define _(a) u8 a=0;
10397   foreach_ip4_proto_field;
10398 #undef _
10399   u8 version = 0;
10400   u8 hdr_length = 0;
10401
10402
10403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10404     {
10405       if (unformat (input, "version"))
10406         version = 1;
10407       else if (unformat (input, "hdr_length"))
10408         hdr_length = 1;
10409       else if (unformat (input, "src"))
10410         src_address = 1;
10411       else if (unformat (input, "dst"))
10412         dst_address = 1;
10413       else if (unformat (input, "proto"))
10414         protocol = 1;
10415
10416 #define _(a) else if (unformat (input, #a)) a=1;
10417       foreach_ip4_proto_field
10418 #undef _
10419         else
10420         break;
10421     }
10422
10423 #define _(a) found_something += a;
10424   foreach_ip4_proto_field;
10425 #undef _
10426
10427   if (found_something == 0)
10428     return 0;
10429
10430   vec_validate (mask, sizeof (*ip) - 1);
10431
10432   ip = (ip4_header_t *) mask;
10433
10434 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10435   foreach_ip4_proto_field;
10436 #undef _
10437
10438   ip->ip_version_and_header_length = 0;
10439
10440   if (version)
10441     ip->ip_version_and_header_length |= 0xF0;
10442
10443   if (hdr_length)
10444     ip->ip_version_and_header_length |= 0x0F;
10445
10446   *maskp = mask;
10447   return 1;
10448 }
10449
10450 #define foreach_ip6_proto_field                 \
10451 _(src_address)                                  \
10452 _(dst_address)                                  \
10453 _(payload_length)                               \
10454 _(hop_limit)                                    \
10455 _(protocol)
10456
10457 uword
10458 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10459 {
10460   u8 **maskp = va_arg (*args, u8 **);
10461   u8 *mask = 0;
10462   u8 found_something = 0;
10463   ip6_header_t *ip;
10464   u32 ip_version_traffic_class_and_flow_label;
10465
10466 #define _(a) u8 a=0;
10467   foreach_ip6_proto_field;
10468 #undef _
10469   u8 version = 0;
10470   u8 traffic_class = 0;
10471   u8 flow_label = 0;
10472
10473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10474     {
10475       if (unformat (input, "version"))
10476         version = 1;
10477       else if (unformat (input, "traffic-class"))
10478         traffic_class = 1;
10479       else if (unformat (input, "flow-label"))
10480         flow_label = 1;
10481       else if (unformat (input, "src"))
10482         src_address = 1;
10483       else if (unformat (input, "dst"))
10484         dst_address = 1;
10485       else if (unformat (input, "proto"))
10486         protocol = 1;
10487
10488 #define _(a) else if (unformat (input, #a)) a=1;
10489       foreach_ip6_proto_field
10490 #undef _
10491         else
10492         break;
10493     }
10494
10495 #define _(a) found_something += a;
10496   foreach_ip6_proto_field;
10497 #undef _
10498
10499   if (found_something == 0)
10500     return 0;
10501
10502   vec_validate (mask, sizeof (*ip) - 1);
10503
10504   ip = (ip6_header_t *) mask;
10505
10506 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10507   foreach_ip6_proto_field;
10508 #undef _
10509
10510   ip_version_traffic_class_and_flow_label = 0;
10511
10512   if (version)
10513     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10514
10515   if (traffic_class)
10516     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10517
10518   if (flow_label)
10519     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10520
10521   ip->ip_version_traffic_class_and_flow_label =
10522     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10523
10524   *maskp = mask;
10525   return 1;
10526 }
10527
10528 uword
10529 unformat_l3_mask (unformat_input_t * input, va_list * args)
10530 {
10531   u8 **maskp = va_arg (*args, u8 **);
10532
10533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10534     {
10535       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10536         return 1;
10537       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10538         return 1;
10539       else
10540         break;
10541     }
10542   return 0;
10543 }
10544
10545 uword
10546 unformat_l2_mask (unformat_input_t * input, va_list * args)
10547 {
10548   u8 **maskp = va_arg (*args, u8 **);
10549   u8 *mask = 0;
10550   u8 src = 0;
10551   u8 dst = 0;
10552   u8 proto = 0;
10553   u8 tag1 = 0;
10554   u8 tag2 = 0;
10555   u8 ignore_tag1 = 0;
10556   u8 ignore_tag2 = 0;
10557   u8 cos1 = 0;
10558   u8 cos2 = 0;
10559   u8 dot1q = 0;
10560   u8 dot1ad = 0;
10561   int len = 14;
10562
10563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10564     {
10565       if (unformat (input, "src"))
10566         src = 1;
10567       else if (unformat (input, "dst"))
10568         dst = 1;
10569       else if (unformat (input, "proto"))
10570         proto = 1;
10571       else if (unformat (input, "tag1"))
10572         tag1 = 1;
10573       else if (unformat (input, "tag2"))
10574         tag2 = 1;
10575       else if (unformat (input, "ignore-tag1"))
10576         ignore_tag1 = 1;
10577       else if (unformat (input, "ignore-tag2"))
10578         ignore_tag2 = 1;
10579       else if (unformat (input, "cos1"))
10580         cos1 = 1;
10581       else if (unformat (input, "cos2"))
10582         cos2 = 1;
10583       else if (unformat (input, "dot1q"))
10584         dot1q = 1;
10585       else if (unformat (input, "dot1ad"))
10586         dot1ad = 1;
10587       else
10588         break;
10589     }
10590   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10591        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10592     return 0;
10593
10594   if (tag1 || ignore_tag1 || cos1 || dot1q)
10595     len = 18;
10596   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10597     len = 22;
10598
10599   vec_validate (mask, len - 1);
10600
10601   if (dst)
10602     clib_memset (mask, 0xff, 6);
10603
10604   if (src)
10605     clib_memset (mask + 6, 0xff, 6);
10606
10607   if (tag2 || dot1ad)
10608     {
10609       /* inner vlan tag */
10610       if (tag2)
10611         {
10612           mask[19] = 0xff;
10613           mask[18] = 0x0f;
10614         }
10615       if (cos2)
10616         mask[18] |= 0xe0;
10617       if (proto)
10618         mask[21] = mask[20] = 0xff;
10619       if (tag1)
10620         {
10621           mask[15] = 0xff;
10622           mask[14] = 0x0f;
10623         }
10624       if (cos1)
10625         mask[14] |= 0xe0;
10626       *maskp = mask;
10627       return 1;
10628     }
10629   if (tag1 | dot1q)
10630     {
10631       if (tag1)
10632         {
10633           mask[15] = 0xff;
10634           mask[14] = 0x0f;
10635         }
10636       if (cos1)
10637         mask[14] |= 0xe0;
10638       if (proto)
10639         mask[16] = mask[17] = 0xff;
10640
10641       *maskp = mask;
10642       return 1;
10643     }
10644   if (cos2)
10645     mask[18] |= 0xe0;
10646   if (cos1)
10647     mask[14] |= 0xe0;
10648   if (proto)
10649     mask[12] = mask[13] = 0xff;
10650
10651   *maskp = mask;
10652   return 1;
10653 }
10654
10655 uword
10656 unformat_classify_mask (unformat_input_t * input, va_list * args)
10657 {
10658   u8 **maskp = va_arg (*args, u8 **);
10659   u32 *skipp = va_arg (*args, u32 *);
10660   u32 *matchp = va_arg (*args, u32 *);
10661   u32 match;
10662   u8 *mask = 0;
10663   u8 *l2 = 0;
10664   u8 *l3 = 0;
10665   u8 *l4 = 0;
10666   int i;
10667
10668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10669     {
10670       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10671         ;
10672       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10673         ;
10674       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10675         ;
10676       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10677         ;
10678       else
10679         break;
10680     }
10681
10682   if (l4 && !l3)
10683     {
10684       vec_free (mask);
10685       vec_free (l2);
10686       vec_free (l4);
10687       return 0;
10688     }
10689
10690   if (mask || l2 || l3 || l4)
10691     {
10692       if (l2 || l3 || l4)
10693         {
10694           /* "With a free Ethernet header in every package" */
10695           if (l2 == 0)
10696             vec_validate (l2, 13);
10697           mask = l2;
10698           if (vec_len (l3))
10699             {
10700               vec_append (mask, l3);
10701               vec_free (l3);
10702             }
10703           if (vec_len (l4))
10704             {
10705               vec_append (mask, l4);
10706               vec_free (l4);
10707             }
10708         }
10709
10710       /* Scan forward looking for the first significant mask octet */
10711       for (i = 0; i < vec_len (mask); i++)
10712         if (mask[i])
10713           break;
10714
10715       /* compute (skip, match) params */
10716       *skipp = i / sizeof (u32x4);
10717       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10718
10719       /* Pad mask to an even multiple of the vector size */
10720       while (vec_len (mask) % sizeof (u32x4))
10721         vec_add1 (mask, 0);
10722
10723       match = vec_len (mask) / sizeof (u32x4);
10724
10725       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10726         {
10727           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10728           if (*tmp || *(tmp + 1))
10729             break;
10730           match--;
10731         }
10732       if (match == 0)
10733         clib_warning ("BUG: match 0");
10734
10735       _vec_len (mask) = match * sizeof (u32x4);
10736
10737       *matchp = match;
10738       *maskp = mask;
10739
10740       return 1;
10741     }
10742
10743   return 0;
10744 }
10745 #endif /* VPP_API_TEST_BUILTIN */
10746
10747 #define foreach_l2_next                         \
10748 _(drop, DROP)                                   \
10749 _(ethernet, ETHERNET_INPUT)                     \
10750 _(ip4, IP4_INPUT)                               \
10751 _(ip6, IP6_INPUT)
10752
10753 uword
10754 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10755 {
10756   u32 *miss_next_indexp = va_arg (*args, u32 *);
10757   u32 next_index = 0;
10758   u32 tmp;
10759
10760 #define _(n,N) \
10761   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10762   foreach_l2_next;
10763 #undef _
10764
10765   if (unformat (input, "%d", &tmp))
10766     {
10767       next_index = tmp;
10768       goto out;
10769     }
10770
10771   return 0;
10772
10773 out:
10774   *miss_next_indexp = next_index;
10775   return 1;
10776 }
10777
10778 #define foreach_ip_next                         \
10779 _(drop, DROP)                                   \
10780 _(local, LOCAL)                                 \
10781 _(rewrite, REWRITE)
10782
10783 uword
10784 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10785 {
10786   u32 *miss_next_indexp = va_arg (*args, u32 *);
10787   u32 next_index = 0;
10788   u32 tmp;
10789
10790 #define _(n,N) \
10791   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10792   foreach_ip_next;
10793 #undef _
10794
10795   if (unformat (input, "%d", &tmp))
10796     {
10797       next_index = tmp;
10798       goto out;
10799     }
10800
10801   return 0;
10802
10803 out:
10804   *miss_next_indexp = next_index;
10805   return 1;
10806 }
10807
10808 #define foreach_acl_next                        \
10809 _(deny, DENY)
10810
10811 uword
10812 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10813 {
10814   u32 *miss_next_indexp = va_arg (*args, u32 *);
10815   u32 next_index = 0;
10816   u32 tmp;
10817
10818 #define _(n,N) \
10819   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10820   foreach_acl_next;
10821 #undef _
10822
10823   if (unformat (input, "permit"))
10824     {
10825       next_index = ~0;
10826       goto out;
10827     }
10828   else if (unformat (input, "%d", &tmp))
10829     {
10830       next_index = tmp;
10831       goto out;
10832     }
10833
10834   return 0;
10835
10836 out:
10837   *miss_next_indexp = next_index;
10838   return 1;
10839 }
10840
10841 uword
10842 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10843 {
10844   u32 *r = va_arg (*args, u32 *);
10845
10846   if (unformat (input, "conform-color"))
10847     *r = POLICE_CONFORM;
10848   else if (unformat (input, "exceed-color"))
10849     *r = POLICE_EXCEED;
10850   else
10851     return 0;
10852
10853   return 1;
10854 }
10855
10856 static int
10857 api_classify_add_del_table (vat_main_t * vam)
10858 {
10859   unformat_input_t *i = vam->input;
10860   vl_api_classify_add_del_table_t *mp;
10861
10862   u32 nbuckets = 2;
10863   u32 skip = ~0;
10864   u32 match = ~0;
10865   int is_add = 1;
10866   int del_chain = 0;
10867   u32 table_index = ~0;
10868   u32 next_table_index = ~0;
10869   u32 miss_next_index = ~0;
10870   u32 memory_size = 32 << 20;
10871   u8 *mask = 0;
10872   u32 current_data_flag = 0;
10873   int current_data_offset = 0;
10874   int ret;
10875
10876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (i, "del"))
10879         is_add = 0;
10880       else if (unformat (i, "del-chain"))
10881         {
10882           is_add = 0;
10883           del_chain = 1;
10884         }
10885       else if (unformat (i, "buckets %d", &nbuckets))
10886         ;
10887       else if (unformat (i, "memory_size %d", &memory_size))
10888         ;
10889       else if (unformat (i, "skip %d", &skip))
10890         ;
10891       else if (unformat (i, "match %d", &match))
10892         ;
10893       else if (unformat (i, "table %d", &table_index))
10894         ;
10895       else if (unformat (i, "mask %U", unformat_classify_mask,
10896                          &mask, &skip, &match))
10897         ;
10898       else if (unformat (i, "next-table %d", &next_table_index))
10899         ;
10900       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10901                          &miss_next_index))
10902         ;
10903       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10904                          &miss_next_index))
10905         ;
10906       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10907                          &miss_next_index))
10908         ;
10909       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10910         ;
10911       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10912         ;
10913       else
10914         break;
10915     }
10916
10917   if (is_add && mask == 0)
10918     {
10919       errmsg ("Mask required");
10920       return -99;
10921     }
10922
10923   if (is_add && skip == ~0)
10924     {
10925       errmsg ("skip count required");
10926       return -99;
10927     }
10928
10929   if (is_add && match == ~0)
10930     {
10931       errmsg ("match count required");
10932       return -99;
10933     }
10934
10935   if (!is_add && table_index == ~0)
10936     {
10937       errmsg ("table index required for delete");
10938       return -99;
10939     }
10940
10941   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10942
10943   mp->is_add = is_add;
10944   mp->del_chain = del_chain;
10945   mp->table_index = ntohl (table_index);
10946   mp->nbuckets = ntohl (nbuckets);
10947   mp->memory_size = ntohl (memory_size);
10948   mp->skip_n_vectors = ntohl (skip);
10949   mp->match_n_vectors = ntohl (match);
10950   mp->next_table_index = ntohl (next_table_index);
10951   mp->miss_next_index = ntohl (miss_next_index);
10952   mp->current_data_flag = ntohl (current_data_flag);
10953   mp->current_data_offset = ntohl (current_data_offset);
10954   mp->mask_len = ntohl (vec_len (mask));
10955   clib_memcpy (mp->mask, mask, vec_len (mask));
10956
10957   vec_free (mask);
10958
10959   S (mp);
10960   W (ret);
10961   return ret;
10962 }
10963
10964 #if VPP_API_TEST_BUILTIN == 0
10965 uword
10966 unformat_l4_match (unformat_input_t * input, va_list * args)
10967 {
10968   u8 **matchp = va_arg (*args, u8 **);
10969
10970   u8 *proto_header = 0;
10971   int src_port = 0;
10972   int dst_port = 0;
10973
10974   tcpudp_header_t h;
10975
10976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10977     {
10978       if (unformat (input, "src_port %d", &src_port))
10979         ;
10980       else if (unformat (input, "dst_port %d", &dst_port))
10981         ;
10982       else
10983         return 0;
10984     }
10985
10986   h.src_port = clib_host_to_net_u16 (src_port);
10987   h.dst_port = clib_host_to_net_u16 (dst_port);
10988   vec_validate (proto_header, sizeof (h) - 1);
10989   memcpy (proto_header, &h, sizeof (h));
10990
10991   *matchp = proto_header;
10992
10993   return 1;
10994 }
10995
10996 uword
10997 unformat_ip4_match (unformat_input_t * input, va_list * args)
10998 {
10999   u8 **matchp = va_arg (*args, u8 **);
11000   u8 *match = 0;
11001   ip4_header_t *ip;
11002   int version = 0;
11003   u32 version_val;
11004   int hdr_length = 0;
11005   u32 hdr_length_val;
11006   int src = 0, dst = 0;
11007   ip4_address_t src_val, dst_val;
11008   int proto = 0;
11009   u32 proto_val;
11010   int tos = 0;
11011   u32 tos_val;
11012   int length = 0;
11013   u32 length_val;
11014   int fragment_id = 0;
11015   u32 fragment_id_val;
11016   int ttl = 0;
11017   int ttl_val;
11018   int checksum = 0;
11019   u32 checksum_val;
11020
11021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11022     {
11023       if (unformat (input, "version %d", &version_val))
11024         version = 1;
11025       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11026         hdr_length = 1;
11027       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11028         src = 1;
11029       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11030         dst = 1;
11031       else if (unformat (input, "proto %d", &proto_val))
11032         proto = 1;
11033       else if (unformat (input, "tos %d", &tos_val))
11034         tos = 1;
11035       else if (unformat (input, "length %d", &length_val))
11036         length = 1;
11037       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11038         fragment_id = 1;
11039       else if (unformat (input, "ttl %d", &ttl_val))
11040         ttl = 1;
11041       else if (unformat (input, "checksum %d", &checksum_val))
11042         checksum = 1;
11043       else
11044         break;
11045     }
11046
11047   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11048       + ttl + checksum == 0)
11049     return 0;
11050
11051   /*
11052    * Aligned because we use the real comparison functions
11053    */
11054   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11055
11056   ip = (ip4_header_t *) match;
11057
11058   /* These are realistically matched in practice */
11059   if (src)
11060     ip->src_address.as_u32 = src_val.as_u32;
11061
11062   if (dst)
11063     ip->dst_address.as_u32 = dst_val.as_u32;
11064
11065   if (proto)
11066     ip->protocol = proto_val;
11067
11068
11069   /* These are not, but they're included for completeness */
11070   if (version)
11071     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11072
11073   if (hdr_length)
11074     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11075
11076   if (tos)
11077     ip->tos = tos_val;
11078
11079   if (length)
11080     ip->length = clib_host_to_net_u16 (length_val);
11081
11082   if (ttl)
11083     ip->ttl = ttl_val;
11084
11085   if (checksum)
11086     ip->checksum = clib_host_to_net_u16 (checksum_val);
11087
11088   *matchp = match;
11089   return 1;
11090 }
11091
11092 uword
11093 unformat_ip6_match (unformat_input_t * input, va_list * args)
11094 {
11095   u8 **matchp = va_arg (*args, u8 **);
11096   u8 *match = 0;
11097   ip6_header_t *ip;
11098   int version = 0;
11099   u32 version_val;
11100   u8 traffic_class = 0;
11101   u32 traffic_class_val = 0;
11102   u8 flow_label = 0;
11103   u8 flow_label_val;
11104   int src = 0, dst = 0;
11105   ip6_address_t src_val, dst_val;
11106   int proto = 0;
11107   u32 proto_val;
11108   int payload_length = 0;
11109   u32 payload_length_val;
11110   int hop_limit = 0;
11111   int hop_limit_val;
11112   u32 ip_version_traffic_class_and_flow_label;
11113
11114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11115     {
11116       if (unformat (input, "version %d", &version_val))
11117         version = 1;
11118       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11119         traffic_class = 1;
11120       else if (unformat (input, "flow_label %d", &flow_label_val))
11121         flow_label = 1;
11122       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11123         src = 1;
11124       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11125         dst = 1;
11126       else if (unformat (input, "proto %d", &proto_val))
11127         proto = 1;
11128       else if (unformat (input, "payload_length %d", &payload_length_val))
11129         payload_length = 1;
11130       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11131         hop_limit = 1;
11132       else
11133         break;
11134     }
11135
11136   if (version + traffic_class + flow_label + src + dst + proto +
11137       payload_length + hop_limit == 0)
11138     return 0;
11139
11140   /*
11141    * Aligned because we use the real comparison functions
11142    */
11143   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11144
11145   ip = (ip6_header_t *) match;
11146
11147   if (src)
11148     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11149
11150   if (dst)
11151     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11152
11153   if (proto)
11154     ip->protocol = proto_val;
11155
11156   ip_version_traffic_class_and_flow_label = 0;
11157
11158   if (version)
11159     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11160
11161   if (traffic_class)
11162     ip_version_traffic_class_and_flow_label |=
11163       (traffic_class_val & 0xFF) << 20;
11164
11165   if (flow_label)
11166     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11167
11168   ip->ip_version_traffic_class_and_flow_label =
11169     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11170
11171   if (payload_length)
11172     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11173
11174   if (hop_limit)
11175     ip->hop_limit = hop_limit_val;
11176
11177   *matchp = match;
11178   return 1;
11179 }
11180
11181 uword
11182 unformat_l3_match (unformat_input_t * input, va_list * args)
11183 {
11184   u8 **matchp = va_arg (*args, u8 **);
11185
11186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11187     {
11188       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11189         return 1;
11190       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11191         return 1;
11192       else
11193         break;
11194     }
11195   return 0;
11196 }
11197
11198 uword
11199 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11200 {
11201   u8 *tagp = va_arg (*args, u8 *);
11202   u32 tag;
11203
11204   if (unformat (input, "%d", &tag))
11205     {
11206       tagp[0] = (tag >> 8) & 0x0F;
11207       tagp[1] = tag & 0xFF;
11208       return 1;
11209     }
11210
11211   return 0;
11212 }
11213
11214 uword
11215 unformat_l2_match (unformat_input_t * input, va_list * args)
11216 {
11217   u8 **matchp = va_arg (*args, u8 **);
11218   u8 *match = 0;
11219   u8 src = 0;
11220   u8 src_val[6];
11221   u8 dst = 0;
11222   u8 dst_val[6];
11223   u8 proto = 0;
11224   u16 proto_val;
11225   u8 tag1 = 0;
11226   u8 tag1_val[2];
11227   u8 tag2 = 0;
11228   u8 tag2_val[2];
11229   int len = 14;
11230   u8 ignore_tag1 = 0;
11231   u8 ignore_tag2 = 0;
11232   u8 cos1 = 0;
11233   u8 cos2 = 0;
11234   u32 cos1_val = 0;
11235   u32 cos2_val = 0;
11236
11237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11240         src = 1;
11241       else
11242         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11243         dst = 1;
11244       else if (unformat (input, "proto %U",
11245                          unformat_ethernet_type_host_byte_order, &proto_val))
11246         proto = 1;
11247       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11248         tag1 = 1;
11249       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11250         tag2 = 1;
11251       else if (unformat (input, "ignore-tag1"))
11252         ignore_tag1 = 1;
11253       else if (unformat (input, "ignore-tag2"))
11254         ignore_tag2 = 1;
11255       else if (unformat (input, "cos1 %d", &cos1_val))
11256         cos1 = 1;
11257       else if (unformat (input, "cos2 %d", &cos2_val))
11258         cos2 = 1;
11259       else
11260         break;
11261     }
11262   if ((src + dst + proto + tag1 + tag2 +
11263        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11264     return 0;
11265
11266   if (tag1 || ignore_tag1 || cos1)
11267     len = 18;
11268   if (tag2 || ignore_tag2 || cos2)
11269     len = 22;
11270
11271   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11272
11273   if (dst)
11274     clib_memcpy (match, dst_val, 6);
11275
11276   if (src)
11277     clib_memcpy (match + 6, src_val, 6);
11278
11279   if (tag2)
11280     {
11281       /* inner vlan tag */
11282       match[19] = tag2_val[1];
11283       match[18] = tag2_val[0];
11284       if (cos2)
11285         match[18] |= (cos2_val & 0x7) << 5;
11286       if (proto)
11287         {
11288           match[21] = proto_val & 0xff;
11289           match[20] = proto_val >> 8;
11290         }
11291       if (tag1)
11292         {
11293           match[15] = tag1_val[1];
11294           match[14] = tag1_val[0];
11295         }
11296       if (cos1)
11297         match[14] |= (cos1_val & 0x7) << 5;
11298       *matchp = match;
11299       return 1;
11300     }
11301   if (tag1)
11302     {
11303       match[15] = tag1_val[1];
11304       match[14] = tag1_val[0];
11305       if (proto)
11306         {
11307           match[17] = proto_val & 0xff;
11308           match[16] = proto_val >> 8;
11309         }
11310       if (cos1)
11311         match[14] |= (cos1_val & 0x7) << 5;
11312
11313       *matchp = match;
11314       return 1;
11315     }
11316   if (cos2)
11317     match[18] |= (cos2_val & 0x7) << 5;
11318   if (cos1)
11319     match[14] |= (cos1_val & 0x7) << 5;
11320   if (proto)
11321     {
11322       match[13] = proto_val & 0xff;
11323       match[12] = proto_val >> 8;
11324     }
11325
11326   *matchp = match;
11327   return 1;
11328 }
11329
11330 uword
11331 unformat_qos_source (unformat_input_t * input, va_list * args)
11332 {
11333   int *qs = va_arg (*args, int *);
11334
11335   if (unformat (input, "ip"))
11336     *qs = QOS_SOURCE_IP;
11337   else if (unformat (input, "mpls"))
11338     *qs = QOS_SOURCE_MPLS;
11339   else if (unformat (input, "ext"))
11340     *qs = QOS_SOURCE_EXT;
11341   else if (unformat (input, "vlan"))
11342     *qs = QOS_SOURCE_VLAN;
11343   else
11344     return 0;
11345
11346   return 1;
11347 }
11348 #endif
11349
11350 uword
11351 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11352 {
11353   u8 **matchp = va_arg (*args, u8 **);
11354   u32 skip_n_vectors = va_arg (*args, u32);
11355   u32 match_n_vectors = va_arg (*args, u32);
11356
11357   u8 *match = 0;
11358   u8 *l2 = 0;
11359   u8 *l3 = 0;
11360   u8 *l4 = 0;
11361
11362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11363     {
11364       if (unformat (input, "hex %U", unformat_hex_string, &match))
11365         ;
11366       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11367         ;
11368       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11369         ;
11370       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11371         ;
11372       else
11373         break;
11374     }
11375
11376   if (l4 && !l3)
11377     {
11378       vec_free (match);
11379       vec_free (l2);
11380       vec_free (l4);
11381       return 0;
11382     }
11383
11384   if (match || l2 || l3 || l4)
11385     {
11386       if (l2 || l3 || l4)
11387         {
11388           /* "Win a free Ethernet header in every packet" */
11389           if (l2 == 0)
11390             vec_validate_aligned (l2, 13, sizeof (u32x4));
11391           match = l2;
11392           if (vec_len (l3))
11393             {
11394               vec_append_aligned (match, l3, sizeof (u32x4));
11395               vec_free (l3);
11396             }
11397           if (vec_len (l4))
11398             {
11399               vec_append_aligned (match, l4, sizeof (u32x4));
11400               vec_free (l4);
11401             }
11402         }
11403
11404       /* Make sure the vector is big enough even if key is all 0's */
11405       vec_validate_aligned
11406         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11407          sizeof (u32x4));
11408
11409       /* Set size, include skipped vectors */
11410       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11411
11412       *matchp = match;
11413
11414       return 1;
11415     }
11416
11417   return 0;
11418 }
11419
11420 static int
11421 api_classify_add_del_session (vat_main_t * vam)
11422 {
11423   unformat_input_t *i = vam->input;
11424   vl_api_classify_add_del_session_t *mp;
11425   int is_add = 1;
11426   u32 table_index = ~0;
11427   u32 hit_next_index = ~0;
11428   u32 opaque_index = ~0;
11429   u8 *match = 0;
11430   i32 advance = 0;
11431   u32 skip_n_vectors = 0;
11432   u32 match_n_vectors = 0;
11433   u32 action = 0;
11434   u32 metadata = 0;
11435   int ret;
11436
11437   /*
11438    * Warning: you have to supply skip_n and match_n
11439    * because the API client cant simply look at the classify
11440    * table object.
11441    */
11442
11443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11444     {
11445       if (unformat (i, "del"))
11446         is_add = 0;
11447       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11448                          &hit_next_index))
11449         ;
11450       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11451                          &hit_next_index))
11452         ;
11453       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11454                          &hit_next_index))
11455         ;
11456       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11457         ;
11458       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11459         ;
11460       else if (unformat (i, "opaque-index %d", &opaque_index))
11461         ;
11462       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11463         ;
11464       else if (unformat (i, "match_n %d", &match_n_vectors))
11465         ;
11466       else if (unformat (i, "match %U", api_unformat_classify_match,
11467                          &match, skip_n_vectors, match_n_vectors))
11468         ;
11469       else if (unformat (i, "advance %d", &advance))
11470         ;
11471       else if (unformat (i, "table-index %d", &table_index))
11472         ;
11473       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11474         action = 1;
11475       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11476         action = 2;
11477       else if (unformat (i, "action %d", &action))
11478         ;
11479       else if (unformat (i, "metadata %d", &metadata))
11480         ;
11481       else
11482         break;
11483     }
11484
11485   if (table_index == ~0)
11486     {
11487       errmsg ("Table index required");
11488       return -99;
11489     }
11490
11491   if (is_add && match == 0)
11492     {
11493       errmsg ("Match value required");
11494       return -99;
11495     }
11496
11497   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11498
11499   mp->is_add = is_add;
11500   mp->table_index = ntohl (table_index);
11501   mp->hit_next_index = ntohl (hit_next_index);
11502   mp->opaque_index = ntohl (opaque_index);
11503   mp->advance = ntohl (advance);
11504   mp->action = action;
11505   mp->metadata = ntohl (metadata);
11506   mp->match_len = ntohl (vec_len (match));
11507   clib_memcpy (mp->match, match, vec_len (match));
11508   vec_free (match);
11509
11510   S (mp);
11511   W (ret);
11512   return ret;
11513 }
11514
11515 static int
11516 api_classify_set_interface_ip_table (vat_main_t * vam)
11517 {
11518   unformat_input_t *i = vam->input;
11519   vl_api_classify_set_interface_ip_table_t *mp;
11520   u32 sw_if_index;
11521   int sw_if_index_set;
11522   u32 table_index = ~0;
11523   u8 is_ipv6 = 0;
11524   int ret;
11525
11526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11527     {
11528       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11529         sw_if_index_set = 1;
11530       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11531         sw_if_index_set = 1;
11532       else if (unformat (i, "table %d", &table_index))
11533         ;
11534       else
11535         {
11536           clib_warning ("parse error '%U'", format_unformat_error, i);
11537           return -99;
11538         }
11539     }
11540
11541   if (sw_if_index_set == 0)
11542     {
11543       errmsg ("missing interface name or sw_if_index");
11544       return -99;
11545     }
11546
11547
11548   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11549
11550   mp->sw_if_index = ntohl (sw_if_index);
11551   mp->table_index = ntohl (table_index);
11552   mp->is_ipv6 = is_ipv6;
11553
11554   S (mp);
11555   W (ret);
11556   return ret;
11557 }
11558
11559 static int
11560 api_classify_set_interface_l2_tables (vat_main_t * vam)
11561 {
11562   unformat_input_t *i = vam->input;
11563   vl_api_classify_set_interface_l2_tables_t *mp;
11564   u32 sw_if_index;
11565   int sw_if_index_set;
11566   u32 ip4_table_index = ~0;
11567   u32 ip6_table_index = ~0;
11568   u32 other_table_index = ~0;
11569   u32 is_input = 1;
11570   int ret;
11571
11572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11573     {
11574       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11575         sw_if_index_set = 1;
11576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11577         sw_if_index_set = 1;
11578       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11579         ;
11580       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11581         ;
11582       else if (unformat (i, "other-table %d", &other_table_index))
11583         ;
11584       else if (unformat (i, "is-input %d", &is_input))
11585         ;
11586       else
11587         {
11588           clib_warning ("parse error '%U'", format_unformat_error, i);
11589           return -99;
11590         }
11591     }
11592
11593   if (sw_if_index_set == 0)
11594     {
11595       errmsg ("missing interface name or sw_if_index");
11596       return -99;
11597     }
11598
11599
11600   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11601
11602   mp->sw_if_index = ntohl (sw_if_index);
11603   mp->ip4_table_index = ntohl (ip4_table_index);
11604   mp->ip6_table_index = ntohl (ip6_table_index);
11605   mp->other_table_index = ntohl (other_table_index);
11606   mp->is_input = (u8) is_input;
11607
11608   S (mp);
11609   W (ret);
11610   return ret;
11611 }
11612
11613 static int
11614 api_set_ipfix_exporter (vat_main_t * vam)
11615 {
11616   unformat_input_t *i = vam->input;
11617   vl_api_set_ipfix_exporter_t *mp;
11618   ip4_address_t collector_address;
11619   u8 collector_address_set = 0;
11620   u32 collector_port = ~0;
11621   ip4_address_t src_address;
11622   u8 src_address_set = 0;
11623   u32 vrf_id = ~0;
11624   u32 path_mtu = ~0;
11625   u32 template_interval = ~0;
11626   u8 udp_checksum = 0;
11627   int ret;
11628
11629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11630     {
11631       if (unformat (i, "collector_address %U", unformat_ip4_address,
11632                     &collector_address))
11633         collector_address_set = 1;
11634       else if (unformat (i, "collector_port %d", &collector_port))
11635         ;
11636       else if (unformat (i, "src_address %U", unformat_ip4_address,
11637                          &src_address))
11638         src_address_set = 1;
11639       else if (unformat (i, "vrf_id %d", &vrf_id))
11640         ;
11641       else if (unformat (i, "path_mtu %d", &path_mtu))
11642         ;
11643       else if (unformat (i, "template_interval %d", &template_interval))
11644         ;
11645       else if (unformat (i, "udp_checksum"))
11646         udp_checksum = 1;
11647       else
11648         break;
11649     }
11650
11651   if (collector_address_set == 0)
11652     {
11653       errmsg ("collector_address required");
11654       return -99;
11655     }
11656
11657   if (src_address_set == 0)
11658     {
11659       errmsg ("src_address required");
11660       return -99;
11661     }
11662
11663   M (SET_IPFIX_EXPORTER, mp);
11664
11665   memcpy (mp->collector_address, collector_address.data,
11666           sizeof (collector_address.data));
11667   mp->collector_port = htons ((u16) collector_port);
11668   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11669   mp->vrf_id = htonl (vrf_id);
11670   mp->path_mtu = htonl (path_mtu);
11671   mp->template_interval = htonl (template_interval);
11672   mp->udp_checksum = udp_checksum;
11673
11674   S (mp);
11675   W (ret);
11676   return ret;
11677 }
11678
11679 static int
11680 api_set_ipfix_classify_stream (vat_main_t * vam)
11681 {
11682   unformat_input_t *i = vam->input;
11683   vl_api_set_ipfix_classify_stream_t *mp;
11684   u32 domain_id = 0;
11685   u32 src_port = UDP_DST_PORT_ipfix;
11686   int ret;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "domain %d", &domain_id))
11691         ;
11692       else if (unformat (i, "src_port %d", &src_port))
11693         ;
11694       else
11695         {
11696           errmsg ("unknown input `%U'", format_unformat_error, i);
11697           return -99;
11698         }
11699     }
11700
11701   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11702
11703   mp->domain_id = htonl (domain_id);
11704   mp->src_port = htons ((u16) src_port);
11705
11706   S (mp);
11707   W (ret);
11708   return ret;
11709 }
11710
11711 static int
11712 api_ipfix_classify_table_add_del (vat_main_t * vam)
11713 {
11714   unformat_input_t *i = vam->input;
11715   vl_api_ipfix_classify_table_add_del_t *mp;
11716   int is_add = -1;
11717   u32 classify_table_index = ~0;
11718   u8 ip_version = 0;
11719   u8 transport_protocol = 255;
11720   int ret;
11721
11722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11723     {
11724       if (unformat (i, "add"))
11725         is_add = 1;
11726       else if (unformat (i, "del"))
11727         is_add = 0;
11728       else if (unformat (i, "table %d", &classify_table_index))
11729         ;
11730       else if (unformat (i, "ip4"))
11731         ip_version = 4;
11732       else if (unformat (i, "ip6"))
11733         ip_version = 6;
11734       else if (unformat (i, "tcp"))
11735         transport_protocol = 6;
11736       else if (unformat (i, "udp"))
11737         transport_protocol = 17;
11738       else
11739         {
11740           errmsg ("unknown input `%U'", format_unformat_error, i);
11741           return -99;
11742         }
11743     }
11744
11745   if (is_add == -1)
11746     {
11747       errmsg ("expecting: add|del");
11748       return -99;
11749     }
11750   if (classify_table_index == ~0)
11751     {
11752       errmsg ("classifier table not specified");
11753       return -99;
11754     }
11755   if (ip_version == 0)
11756     {
11757       errmsg ("IP version not specified");
11758       return -99;
11759     }
11760
11761   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11762
11763   mp->is_add = is_add;
11764   mp->table_id = htonl (classify_table_index);
11765   mp->ip_version = ip_version;
11766   mp->transport_protocol = transport_protocol;
11767
11768   S (mp);
11769   W (ret);
11770   return ret;
11771 }
11772
11773 static int
11774 api_get_node_index (vat_main_t * vam)
11775 {
11776   unformat_input_t *i = vam->input;
11777   vl_api_get_node_index_t *mp;
11778   u8 *name = 0;
11779   int ret;
11780
11781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11782     {
11783       if (unformat (i, "node %s", &name))
11784         ;
11785       else
11786         break;
11787     }
11788   if (name == 0)
11789     {
11790       errmsg ("node name required");
11791       return -99;
11792     }
11793   if (vec_len (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   M (GET_NODE_INDEX, mp);
11800   clib_memcpy (mp->node_name, name, vec_len (name));
11801   vec_free (name);
11802
11803   S (mp);
11804   W (ret);
11805   return ret;
11806 }
11807
11808 static int
11809 api_get_next_index (vat_main_t * vam)
11810 {
11811   unformat_input_t *i = vam->input;
11812   vl_api_get_next_index_t *mp;
11813   u8 *node_name = 0, *next_node_name = 0;
11814   int ret;
11815
11816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11817     {
11818       if (unformat (i, "node-name %s", &node_name))
11819         ;
11820       else if (unformat (i, "next-node-name %s", &next_node_name))
11821         break;
11822     }
11823
11824   if (node_name == 0)
11825     {
11826       errmsg ("node name required");
11827       return -99;
11828     }
11829   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11830     {
11831       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11832       return -99;
11833     }
11834
11835   if (next_node_name == 0)
11836     {
11837       errmsg ("next node name required");
11838       return -99;
11839     }
11840   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11841     {
11842       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11843       return -99;
11844     }
11845
11846   M (GET_NEXT_INDEX, mp);
11847   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11848   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11849   vec_free (node_name);
11850   vec_free (next_node_name);
11851
11852   S (mp);
11853   W (ret);
11854   return ret;
11855 }
11856
11857 static int
11858 api_add_node_next (vat_main_t * vam)
11859 {
11860   unformat_input_t *i = vam->input;
11861   vl_api_add_node_next_t *mp;
11862   u8 *name = 0;
11863   u8 *next = 0;
11864   int ret;
11865
11866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11867     {
11868       if (unformat (i, "node %s", &name))
11869         ;
11870       else if (unformat (i, "next %s", &next))
11871         ;
11872       else
11873         break;
11874     }
11875   if (name == 0)
11876     {
11877       errmsg ("node name required");
11878       return -99;
11879     }
11880   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11881     {
11882       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11883       return -99;
11884     }
11885   if (next == 0)
11886     {
11887       errmsg ("next node required");
11888       return -99;
11889     }
11890   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11891     {
11892       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11893       return -99;
11894     }
11895
11896   M (ADD_NODE_NEXT, mp);
11897   clib_memcpy (mp->node_name, name, vec_len (name));
11898   clib_memcpy (mp->next_name, next, vec_len (next));
11899   vec_free (name);
11900   vec_free (next);
11901
11902   S (mp);
11903   W (ret);
11904   return ret;
11905 }
11906
11907 static int
11908 api_l2tpv3_create_tunnel (vat_main_t * vam)
11909 {
11910   unformat_input_t *i = vam->input;
11911   ip6_address_t client_address, our_address;
11912   int client_address_set = 0;
11913   int our_address_set = 0;
11914   u32 local_session_id = 0;
11915   u32 remote_session_id = 0;
11916   u64 local_cookie = 0;
11917   u64 remote_cookie = 0;
11918   u8 l2_sublayer_present = 0;
11919   vl_api_l2tpv3_create_tunnel_t *mp;
11920   int ret;
11921
11922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11923     {
11924       if (unformat (i, "client_address %U", unformat_ip6_address,
11925                     &client_address))
11926         client_address_set = 1;
11927       else if (unformat (i, "our_address %U", unformat_ip6_address,
11928                          &our_address))
11929         our_address_set = 1;
11930       else if (unformat (i, "local_session_id %d", &local_session_id))
11931         ;
11932       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11933         ;
11934       else if (unformat (i, "local_cookie %lld", &local_cookie))
11935         ;
11936       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11937         ;
11938       else if (unformat (i, "l2-sublayer-present"))
11939         l2_sublayer_present = 1;
11940       else
11941         break;
11942     }
11943
11944   if (client_address_set == 0)
11945     {
11946       errmsg ("client_address required");
11947       return -99;
11948     }
11949
11950   if (our_address_set == 0)
11951     {
11952       errmsg ("our_address required");
11953       return -99;
11954     }
11955
11956   M (L2TPV3_CREATE_TUNNEL, mp);
11957
11958   clib_memcpy (mp->client_address, client_address.as_u8,
11959                sizeof (mp->client_address));
11960
11961   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11962
11963   mp->local_session_id = ntohl (local_session_id);
11964   mp->remote_session_id = ntohl (remote_session_id);
11965   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11966   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11967   mp->l2_sublayer_present = l2_sublayer_present;
11968   mp->is_ipv6 = 1;
11969
11970   S (mp);
11971   W (ret);
11972   return ret;
11973 }
11974
11975 static int
11976 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11977 {
11978   unformat_input_t *i = vam->input;
11979   u32 sw_if_index;
11980   u8 sw_if_index_set = 0;
11981   u64 new_local_cookie = 0;
11982   u64 new_remote_cookie = 0;
11983   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11984   int ret;
11985
11986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11987     {
11988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11989         sw_if_index_set = 1;
11990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11991         sw_if_index_set = 1;
11992       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11993         ;
11994       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11995         ;
11996       else
11997         break;
11998     }
11999
12000   if (sw_if_index_set == 0)
12001     {
12002       errmsg ("missing interface name or sw_if_index");
12003       return -99;
12004     }
12005
12006   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12007
12008   mp->sw_if_index = ntohl (sw_if_index);
12009   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12010   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12011
12012   S (mp);
12013   W (ret);
12014   return ret;
12015 }
12016
12017 static int
12018 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12019 {
12020   unformat_input_t *i = vam->input;
12021   vl_api_l2tpv3_interface_enable_disable_t *mp;
12022   u32 sw_if_index;
12023   u8 sw_if_index_set = 0;
12024   u8 enable_disable = 1;
12025   int ret;
12026
12027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12028     {
12029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12030         sw_if_index_set = 1;
12031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12032         sw_if_index_set = 1;
12033       else if (unformat (i, "enable"))
12034         enable_disable = 1;
12035       else if (unformat (i, "disable"))
12036         enable_disable = 0;
12037       else
12038         break;
12039     }
12040
12041   if (sw_if_index_set == 0)
12042     {
12043       errmsg ("missing interface name or sw_if_index");
12044       return -99;
12045     }
12046
12047   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12048
12049   mp->sw_if_index = ntohl (sw_if_index);
12050   mp->enable_disable = enable_disable;
12051
12052   S (mp);
12053   W (ret);
12054   return ret;
12055 }
12056
12057 static int
12058 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12059 {
12060   unformat_input_t *i = vam->input;
12061   vl_api_l2tpv3_set_lookup_key_t *mp;
12062   u8 key = ~0;
12063   int ret;
12064
12065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12066     {
12067       if (unformat (i, "lookup_v6_src"))
12068         key = L2T_LOOKUP_SRC_ADDRESS;
12069       else if (unformat (i, "lookup_v6_dst"))
12070         key = L2T_LOOKUP_DST_ADDRESS;
12071       else if (unformat (i, "lookup_session_id"))
12072         key = L2T_LOOKUP_SESSION_ID;
12073       else
12074         break;
12075     }
12076
12077   if (key == (u8) ~ 0)
12078     {
12079       errmsg ("l2tp session lookup key unset");
12080       return -99;
12081     }
12082
12083   M (L2TPV3_SET_LOOKUP_KEY, mp);
12084
12085   mp->key = key;
12086
12087   S (mp);
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12093   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12094 {
12095   vat_main_t *vam = &vat_main;
12096
12097   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12098          format_ip6_address, mp->our_address,
12099          format_ip6_address, mp->client_address,
12100          clib_net_to_host_u32 (mp->sw_if_index));
12101
12102   print (vam->ofp,
12103          "   local cookies %016llx %016llx remote cookie %016llx",
12104          clib_net_to_host_u64 (mp->local_cookie[0]),
12105          clib_net_to_host_u64 (mp->local_cookie[1]),
12106          clib_net_to_host_u64 (mp->remote_cookie));
12107
12108   print (vam->ofp, "   local session-id %d remote session-id %d",
12109          clib_net_to_host_u32 (mp->local_session_id),
12110          clib_net_to_host_u32 (mp->remote_session_id));
12111
12112   print (vam->ofp, "   l2 specific sublayer %s\n",
12113          mp->l2_sublayer_present ? "preset" : "absent");
12114
12115 }
12116
12117 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12118   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12119 {
12120   vat_main_t *vam = &vat_main;
12121   vat_json_node_t *node = NULL;
12122   struct in6_addr addr;
12123
12124   if (VAT_JSON_ARRAY != vam->json_tree.type)
12125     {
12126       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12127       vat_json_init_array (&vam->json_tree);
12128     }
12129   node = vat_json_array_add (&vam->json_tree);
12130
12131   vat_json_init_object (node);
12132
12133   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12134   vat_json_object_add_ip6 (node, "our_address", addr);
12135   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12136   vat_json_object_add_ip6 (node, "client_address", addr);
12137
12138   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12139   vat_json_init_array (lc);
12140   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12141   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12142   vat_json_object_add_uint (node, "remote_cookie",
12143                             clib_net_to_host_u64 (mp->remote_cookie));
12144
12145   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12146   vat_json_object_add_uint (node, "local_session_id",
12147                             clib_net_to_host_u32 (mp->local_session_id));
12148   vat_json_object_add_uint (node, "remote_session_id",
12149                             clib_net_to_host_u32 (mp->remote_session_id));
12150   vat_json_object_add_string_copy (node, "l2_sublayer",
12151                                    mp->l2_sublayer_present ? (u8 *) "present"
12152                                    : (u8 *) "absent");
12153 }
12154
12155 static int
12156 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12157 {
12158   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12159   vl_api_control_ping_t *mp_ping;
12160   int ret;
12161
12162   /* Get list of l2tpv3-tunnel interfaces */
12163   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12164   S (mp);
12165
12166   /* Use a control ping for synchronization */
12167   MPING (CONTROL_PING, mp_ping);
12168   S (mp_ping);
12169
12170   W (ret);
12171   return ret;
12172 }
12173
12174
12175 static void vl_api_sw_interface_tap_v2_details_t_handler
12176   (vl_api_sw_interface_tap_v2_details_t * mp)
12177 {
12178   vat_main_t *vam = &vat_main;
12179
12180   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12181                     mp->host_ip4_prefix_len);
12182   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12183                     mp->host_ip6_prefix_len);
12184
12185   print (vam->ofp,
12186          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
12187          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12188          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12189          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12190          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
12191
12192   vec_free (ip4);
12193   vec_free (ip6);
12194 }
12195
12196 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12197   (vl_api_sw_interface_tap_v2_details_t * mp)
12198 {
12199   vat_main_t *vam = &vat_main;
12200   vat_json_node_t *node = NULL;
12201
12202   if (VAT_JSON_ARRAY != vam->json_tree.type)
12203     {
12204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12205       vat_json_init_array (&vam->json_tree);
12206     }
12207   node = vat_json_array_add (&vam->json_tree);
12208
12209   vat_json_init_object (node);
12210   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12211   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12212   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
12213   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12214   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12215   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12216   vat_json_object_add_string_copy (node, "host_mac_addr",
12217                                    format (0, "%U", format_ethernet_address,
12218                                            &mp->host_mac_addr));
12219   vat_json_object_add_string_copy (node, "host_namespace",
12220                                    mp->host_namespace);
12221   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12222   vat_json_object_add_string_copy (node, "host_ip4_addr",
12223                                    format (0, "%U/%d", format_ip4_address,
12224                                            mp->host_ip4_addr,
12225                                            mp->host_ip4_prefix_len));
12226   vat_json_object_add_string_copy (node, "host_ip6_addr",
12227                                    format (0, "%U/%d", format_ip6_address,
12228                                            mp->host_ip6_addr,
12229                                            mp->host_ip6_prefix_len));
12230
12231 }
12232
12233 static int
12234 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12235 {
12236   vl_api_sw_interface_tap_v2_dump_t *mp;
12237   vl_api_control_ping_t *mp_ping;
12238   int ret;
12239
12240   print (vam->ofp,
12241          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12242          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12243          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12244          "host_ip6_addr");
12245
12246   /* Get list of tap interfaces */
12247   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12248   S (mp);
12249
12250   /* Use a control ping for synchronization */
12251   MPING (CONTROL_PING, mp_ping);
12252   S (mp_ping);
12253
12254   W (ret);
12255   return ret;
12256 }
12257
12258 static void vl_api_sw_interface_virtio_pci_details_t_handler
12259   (vl_api_sw_interface_virtio_pci_details_t * mp)
12260 {
12261   vat_main_t *vam = &vat_main;
12262
12263   typedef union
12264   {
12265     struct
12266     {
12267       u16 domain;
12268       u8 bus;
12269       u8 slot:5;
12270       u8 function:3;
12271     };
12272     u32 as_u32;
12273   } pci_addr_t;
12274   pci_addr_t addr;
12275   addr.as_u32 = ntohl (mp->pci_addr);
12276   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
12277                          addr.slot, addr.function);
12278
12279   print (vam->ofp,
12280          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
12281          pci_addr, ntohl (mp->sw_if_index),
12282          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12283          format_ethernet_address, mp->mac_addr,
12284          clib_net_to_host_u64 (mp->features));
12285   vec_free (pci_addr);
12286 }
12287
12288 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
12289   (vl_api_sw_interface_virtio_pci_details_t * mp)
12290 {
12291   vat_main_t *vam = &vat_main;
12292   vat_json_node_t *node = NULL;
12293
12294   if (VAT_JSON_ARRAY != vam->json_tree.type)
12295     {
12296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12297       vat_json_init_array (&vam->json_tree);
12298     }
12299   node = vat_json_array_add (&vam->json_tree);
12300
12301   vat_json_init_object (node);
12302   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
12303   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12304   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12305   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12306   vat_json_object_add_uint (node, "features",
12307                             clib_net_to_host_u64 (mp->features));
12308   vat_json_object_add_string_copy (node, "mac_addr",
12309                                    format (0, "%U", format_ethernet_address,
12310                                            &mp->mac_addr));
12311 }
12312
12313 static int
12314 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
12315 {
12316   vl_api_sw_interface_virtio_pci_dump_t *mp;
12317   vl_api_control_ping_t *mp_ping;
12318   int ret;
12319
12320   print (vam->ofp,
12321          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12322          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12323          "mac_addr", "features");
12324
12325   /* Get list of tap interfaces */
12326   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12327   S (mp);
12328
12329   /* Use a control ping for synchronization */
12330   MPING (CONTROL_PING, mp_ping);
12331   S (mp_ping);
12332
12333   W (ret);
12334   return ret;
12335 }
12336
12337 static int
12338 api_vxlan_offload_rx (vat_main_t * vam)
12339 {
12340   unformat_input_t *line_input = vam->input;
12341   vl_api_vxlan_offload_rx_t *mp;
12342   u32 hw_if_index = ~0, rx_if_index = ~0;
12343   u8 is_add = 1;
12344   int ret;
12345
12346   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12347     {
12348       if (unformat (line_input, "del"))
12349         is_add = 0;
12350       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12351                          &hw_if_index))
12352         ;
12353       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12354         ;
12355       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12356                          &rx_if_index))
12357         ;
12358       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12359         ;
12360       else
12361         {
12362           errmsg ("parse error '%U'", format_unformat_error, line_input);
12363           return -99;
12364         }
12365     }
12366
12367   if (hw_if_index == ~0)
12368     {
12369       errmsg ("no hw interface");
12370       return -99;
12371     }
12372
12373   if (rx_if_index == ~0)
12374     {
12375       errmsg ("no rx tunnel");
12376       return -99;
12377     }
12378
12379   M (VXLAN_OFFLOAD_RX, mp);
12380
12381   mp->hw_if_index = ntohl (hw_if_index);
12382   mp->sw_if_index = ntohl (rx_if_index);
12383   mp->enable = is_add;
12384
12385   S (mp);
12386   W (ret);
12387   return ret;
12388 }
12389
12390 static uword unformat_vxlan_decap_next
12391   (unformat_input_t * input, va_list * args)
12392 {
12393   u32 *result = va_arg (*args, u32 *);
12394   u32 tmp;
12395
12396   if (unformat (input, "l2"))
12397     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12398   else if (unformat (input, "%d", &tmp))
12399     *result = tmp;
12400   else
12401     return 0;
12402   return 1;
12403 }
12404
12405 static int
12406 api_vxlan_add_del_tunnel (vat_main_t * vam)
12407 {
12408   unformat_input_t *line_input = vam->input;
12409   vl_api_vxlan_add_del_tunnel_t *mp;
12410   ip46_address_t src, dst;
12411   u8 is_add = 1;
12412   u8 ipv4_set = 0, ipv6_set = 0;
12413   u8 src_set = 0;
12414   u8 dst_set = 0;
12415   u8 grp_set = 0;
12416   u32 instance = ~0;
12417   u32 mcast_sw_if_index = ~0;
12418   u32 encap_vrf_id = 0;
12419   u32 decap_next_index = ~0;
12420   u32 vni = 0;
12421   int ret;
12422
12423   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12424   clib_memset (&src, 0, sizeof src);
12425   clib_memset (&dst, 0, sizeof dst);
12426
12427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12428     {
12429       if (unformat (line_input, "del"))
12430         is_add = 0;
12431       else if (unformat (line_input, "instance %d", &instance))
12432         ;
12433       else
12434         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12435         {
12436           ipv4_set = 1;
12437           src_set = 1;
12438         }
12439       else
12440         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12441         {
12442           ipv4_set = 1;
12443           dst_set = 1;
12444         }
12445       else
12446         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12447         {
12448           ipv6_set = 1;
12449           src_set = 1;
12450         }
12451       else
12452         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12453         {
12454           ipv6_set = 1;
12455           dst_set = 1;
12456         }
12457       else if (unformat (line_input, "group %U %U",
12458                          unformat_ip4_address, &dst.ip4,
12459                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12460         {
12461           grp_set = dst_set = 1;
12462           ipv4_set = 1;
12463         }
12464       else if (unformat (line_input, "group %U",
12465                          unformat_ip4_address, &dst.ip4))
12466         {
12467           grp_set = dst_set = 1;
12468           ipv4_set = 1;
12469         }
12470       else if (unformat (line_input, "group %U %U",
12471                          unformat_ip6_address, &dst.ip6,
12472                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12473         {
12474           grp_set = dst_set = 1;
12475           ipv6_set = 1;
12476         }
12477       else if (unformat (line_input, "group %U",
12478                          unformat_ip6_address, &dst.ip6))
12479         {
12480           grp_set = dst_set = 1;
12481           ipv6_set = 1;
12482         }
12483       else
12484         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12485         ;
12486       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12487         ;
12488       else if (unformat (line_input, "decap-next %U",
12489                          unformat_vxlan_decap_next, &decap_next_index))
12490         ;
12491       else if (unformat (line_input, "vni %d", &vni))
12492         ;
12493       else
12494         {
12495           errmsg ("parse error '%U'", format_unformat_error, line_input);
12496           return -99;
12497         }
12498     }
12499
12500   if (src_set == 0)
12501     {
12502       errmsg ("tunnel src address not specified");
12503       return -99;
12504     }
12505   if (dst_set == 0)
12506     {
12507       errmsg ("tunnel dst address not specified");
12508       return -99;
12509     }
12510
12511   if (grp_set && !ip46_address_is_multicast (&dst))
12512     {
12513       errmsg ("tunnel group address not multicast");
12514       return -99;
12515     }
12516   if (grp_set && mcast_sw_if_index == ~0)
12517     {
12518       errmsg ("tunnel nonexistent multicast device");
12519       return -99;
12520     }
12521   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12522     {
12523       errmsg ("tunnel dst address must be unicast");
12524       return -99;
12525     }
12526
12527
12528   if (ipv4_set && ipv6_set)
12529     {
12530       errmsg ("both IPv4 and IPv6 addresses specified");
12531       return -99;
12532     }
12533
12534   if ((vni == 0) || (vni >> 24))
12535     {
12536       errmsg ("vni not specified or out of range");
12537       return -99;
12538     }
12539
12540   M (VXLAN_ADD_DEL_TUNNEL, mp);
12541
12542   if (ipv6_set)
12543     {
12544       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12545       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12546     }
12547   else
12548     {
12549       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12550       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12551     }
12552
12553   mp->instance = htonl (instance);
12554   mp->encap_vrf_id = ntohl (encap_vrf_id);
12555   mp->decap_next_index = ntohl (decap_next_index);
12556   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12557   mp->vni = ntohl (vni);
12558   mp->is_add = is_add;
12559   mp->is_ipv6 = ipv6_set;
12560
12561   S (mp);
12562   W (ret);
12563   return ret;
12564 }
12565
12566 static void vl_api_vxlan_tunnel_details_t_handler
12567   (vl_api_vxlan_tunnel_details_t * mp)
12568 {
12569   vat_main_t *vam = &vat_main;
12570   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12571   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12572
12573   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12574          ntohl (mp->sw_if_index),
12575          ntohl (mp->instance),
12576          format_ip46_address, &src, IP46_TYPE_ANY,
12577          format_ip46_address, &dst, IP46_TYPE_ANY,
12578          ntohl (mp->encap_vrf_id),
12579          ntohl (mp->decap_next_index), ntohl (mp->vni),
12580          ntohl (mp->mcast_sw_if_index));
12581 }
12582
12583 static void vl_api_vxlan_tunnel_details_t_handler_json
12584   (vl_api_vxlan_tunnel_details_t * mp)
12585 {
12586   vat_main_t *vam = &vat_main;
12587   vat_json_node_t *node = NULL;
12588
12589   if (VAT_JSON_ARRAY != vam->json_tree.type)
12590     {
12591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12592       vat_json_init_array (&vam->json_tree);
12593     }
12594   node = vat_json_array_add (&vam->json_tree);
12595
12596   vat_json_init_object (node);
12597   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12598
12599   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12600
12601   if (mp->is_ipv6)
12602     {
12603       struct in6_addr ip6;
12604
12605       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12606       vat_json_object_add_ip6 (node, "src_address", ip6);
12607       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12608       vat_json_object_add_ip6 (node, "dst_address", ip6);
12609     }
12610   else
12611     {
12612       struct in_addr ip4;
12613
12614       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12615       vat_json_object_add_ip4 (node, "src_address", ip4);
12616       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12617       vat_json_object_add_ip4 (node, "dst_address", ip4);
12618     }
12619   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12620   vat_json_object_add_uint (node, "decap_next_index",
12621                             ntohl (mp->decap_next_index));
12622   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12623   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12624   vat_json_object_add_uint (node, "mcast_sw_if_index",
12625                             ntohl (mp->mcast_sw_if_index));
12626 }
12627
12628 static int
12629 api_vxlan_tunnel_dump (vat_main_t * vam)
12630 {
12631   unformat_input_t *i = vam->input;
12632   vl_api_vxlan_tunnel_dump_t *mp;
12633   vl_api_control_ping_t *mp_ping;
12634   u32 sw_if_index;
12635   u8 sw_if_index_set = 0;
12636   int ret;
12637
12638   /* Parse args required to build the message */
12639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12640     {
12641       if (unformat (i, "sw_if_index %d", &sw_if_index))
12642         sw_if_index_set = 1;
12643       else
12644         break;
12645     }
12646
12647   if (sw_if_index_set == 0)
12648     {
12649       sw_if_index = ~0;
12650     }
12651
12652   if (!vam->json_output)
12653     {
12654       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12655              "sw_if_index", "instance", "src_address", "dst_address",
12656              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12657     }
12658
12659   /* Get list of vxlan-tunnel interfaces */
12660   M (VXLAN_TUNNEL_DUMP, mp);
12661
12662   mp->sw_if_index = htonl (sw_if_index);
12663
12664   S (mp);
12665
12666   /* Use a control ping for synchronization */
12667   MPING (CONTROL_PING, mp_ping);
12668   S (mp_ping);
12669
12670   W (ret);
12671   return ret;
12672 }
12673
12674 static uword unformat_geneve_decap_next
12675   (unformat_input_t * input, va_list * args)
12676 {
12677   u32 *result = va_arg (*args, u32 *);
12678   u32 tmp;
12679
12680   if (unformat (input, "l2"))
12681     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12682   else if (unformat (input, "%d", &tmp))
12683     *result = tmp;
12684   else
12685     return 0;
12686   return 1;
12687 }
12688
12689 static int
12690 api_geneve_add_del_tunnel (vat_main_t * vam)
12691 {
12692   unformat_input_t *line_input = vam->input;
12693   vl_api_geneve_add_del_tunnel_t *mp;
12694   ip46_address_t src, dst;
12695   u8 is_add = 1;
12696   u8 ipv4_set = 0, ipv6_set = 0;
12697   u8 src_set = 0;
12698   u8 dst_set = 0;
12699   u8 grp_set = 0;
12700   u32 mcast_sw_if_index = ~0;
12701   u32 encap_vrf_id = 0;
12702   u32 decap_next_index = ~0;
12703   u32 vni = 0;
12704   int ret;
12705
12706   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12707   clib_memset (&src, 0, sizeof src);
12708   clib_memset (&dst, 0, sizeof dst);
12709
12710   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12711     {
12712       if (unformat (line_input, "del"))
12713         is_add = 0;
12714       else
12715         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12716         {
12717           ipv4_set = 1;
12718           src_set = 1;
12719         }
12720       else
12721         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12722         {
12723           ipv4_set = 1;
12724           dst_set = 1;
12725         }
12726       else
12727         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12728         {
12729           ipv6_set = 1;
12730           src_set = 1;
12731         }
12732       else
12733         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12734         {
12735           ipv6_set = 1;
12736           dst_set = 1;
12737         }
12738       else if (unformat (line_input, "group %U %U",
12739                          unformat_ip4_address, &dst.ip4,
12740                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12741         {
12742           grp_set = dst_set = 1;
12743           ipv4_set = 1;
12744         }
12745       else if (unformat (line_input, "group %U",
12746                          unformat_ip4_address, &dst.ip4))
12747         {
12748           grp_set = dst_set = 1;
12749           ipv4_set = 1;
12750         }
12751       else if (unformat (line_input, "group %U %U",
12752                          unformat_ip6_address, &dst.ip6,
12753                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12754         {
12755           grp_set = dst_set = 1;
12756           ipv6_set = 1;
12757         }
12758       else if (unformat (line_input, "group %U",
12759                          unformat_ip6_address, &dst.ip6))
12760         {
12761           grp_set = dst_set = 1;
12762           ipv6_set = 1;
12763         }
12764       else
12765         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12766         ;
12767       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12768         ;
12769       else if (unformat (line_input, "decap-next %U",
12770                          unformat_geneve_decap_next, &decap_next_index))
12771         ;
12772       else if (unformat (line_input, "vni %d", &vni))
12773         ;
12774       else
12775         {
12776           errmsg ("parse error '%U'", format_unformat_error, line_input);
12777           return -99;
12778         }
12779     }
12780
12781   if (src_set == 0)
12782     {
12783       errmsg ("tunnel src address not specified");
12784       return -99;
12785     }
12786   if (dst_set == 0)
12787     {
12788       errmsg ("tunnel dst address not specified");
12789       return -99;
12790     }
12791
12792   if (grp_set && !ip46_address_is_multicast (&dst))
12793     {
12794       errmsg ("tunnel group address not multicast");
12795       return -99;
12796     }
12797   if (grp_set && mcast_sw_if_index == ~0)
12798     {
12799       errmsg ("tunnel nonexistent multicast device");
12800       return -99;
12801     }
12802   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12803     {
12804       errmsg ("tunnel dst address must be unicast");
12805       return -99;
12806     }
12807
12808
12809   if (ipv4_set && ipv6_set)
12810     {
12811       errmsg ("both IPv4 and IPv6 addresses specified");
12812       return -99;
12813     }
12814
12815   if ((vni == 0) || (vni >> 24))
12816     {
12817       errmsg ("vni not specified or out of range");
12818       return -99;
12819     }
12820
12821   M (GENEVE_ADD_DEL_TUNNEL, mp);
12822
12823   if (ipv6_set)
12824     {
12825       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12826       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12827     }
12828   else
12829     {
12830       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12831       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12832     }
12833   mp->encap_vrf_id = ntohl (encap_vrf_id);
12834   mp->decap_next_index = ntohl (decap_next_index);
12835   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12836   mp->vni = ntohl (vni);
12837   mp->is_add = is_add;
12838   mp->is_ipv6 = ipv6_set;
12839
12840   S (mp);
12841   W (ret);
12842   return ret;
12843 }
12844
12845 static void vl_api_geneve_tunnel_details_t_handler
12846   (vl_api_geneve_tunnel_details_t * mp)
12847 {
12848   vat_main_t *vam = &vat_main;
12849   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12850   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12851
12852   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12853          ntohl (mp->sw_if_index),
12854          format_ip46_address, &src, IP46_TYPE_ANY,
12855          format_ip46_address, &dst, IP46_TYPE_ANY,
12856          ntohl (mp->encap_vrf_id),
12857          ntohl (mp->decap_next_index), ntohl (mp->vni),
12858          ntohl (mp->mcast_sw_if_index));
12859 }
12860
12861 static void vl_api_geneve_tunnel_details_t_handler_json
12862   (vl_api_geneve_tunnel_details_t * mp)
12863 {
12864   vat_main_t *vam = &vat_main;
12865   vat_json_node_t *node = NULL;
12866
12867   if (VAT_JSON_ARRAY != vam->json_tree.type)
12868     {
12869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12870       vat_json_init_array (&vam->json_tree);
12871     }
12872   node = vat_json_array_add (&vam->json_tree);
12873
12874   vat_json_init_object (node);
12875   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12876   if (mp->is_ipv6)
12877     {
12878       struct in6_addr ip6;
12879
12880       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12881       vat_json_object_add_ip6 (node, "src_address", ip6);
12882       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12883       vat_json_object_add_ip6 (node, "dst_address", ip6);
12884     }
12885   else
12886     {
12887       struct in_addr ip4;
12888
12889       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12890       vat_json_object_add_ip4 (node, "src_address", ip4);
12891       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12892       vat_json_object_add_ip4 (node, "dst_address", ip4);
12893     }
12894   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12895   vat_json_object_add_uint (node, "decap_next_index",
12896                             ntohl (mp->decap_next_index));
12897   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12898   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12899   vat_json_object_add_uint (node, "mcast_sw_if_index",
12900                             ntohl (mp->mcast_sw_if_index));
12901 }
12902
12903 static int
12904 api_geneve_tunnel_dump (vat_main_t * vam)
12905 {
12906   unformat_input_t *i = vam->input;
12907   vl_api_geneve_tunnel_dump_t *mp;
12908   vl_api_control_ping_t *mp_ping;
12909   u32 sw_if_index;
12910   u8 sw_if_index_set = 0;
12911   int ret;
12912
12913   /* Parse args required to build the message */
12914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12915     {
12916       if (unformat (i, "sw_if_index %d", &sw_if_index))
12917         sw_if_index_set = 1;
12918       else
12919         break;
12920     }
12921
12922   if (sw_if_index_set == 0)
12923     {
12924       sw_if_index = ~0;
12925     }
12926
12927   if (!vam->json_output)
12928     {
12929       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12930              "sw_if_index", "local_address", "remote_address",
12931              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12932     }
12933
12934   /* Get list of geneve-tunnel interfaces */
12935   M (GENEVE_TUNNEL_DUMP, mp);
12936
12937   mp->sw_if_index = htonl (sw_if_index);
12938
12939   S (mp);
12940
12941   /* Use a control ping for synchronization */
12942   M (CONTROL_PING, mp_ping);
12943   S (mp_ping);
12944
12945   W (ret);
12946   return ret;
12947 }
12948
12949 static int
12950 api_gre_tunnel_add_del (vat_main_t * vam)
12951 {
12952   unformat_input_t *line_input = vam->input;
12953   vl_api_address_t src = { }, dst =
12954   {
12955   };
12956   vl_api_gre_tunnel_add_del_t *mp;
12957   vl_api_gre_tunnel_type_t t_type;
12958   u8 is_add = 1;
12959   u8 src_set = 0;
12960   u8 dst_set = 0;
12961   u32 outer_fib_id = 0;
12962   u32 session_id = 0;
12963   u32 instance = ~0;
12964   int ret;
12965
12966   t_type = GRE_API_TUNNEL_TYPE_L3;
12967
12968   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12969     {
12970       if (unformat (line_input, "del"))
12971         is_add = 0;
12972       else if (unformat (line_input, "instance %d", &instance))
12973         ;
12974       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12975         {
12976           src_set = 1;
12977         }
12978       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12979         {
12980           dst_set = 1;
12981         }
12982       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12983         ;
12984       else if (unformat (line_input, "teb"))
12985         t_type = GRE_API_TUNNEL_TYPE_TEB;
12986       else if (unformat (line_input, "erspan %d", &session_id))
12987         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12988       else
12989         {
12990           errmsg ("parse error '%U'", format_unformat_error, line_input);
12991           return -99;
12992         }
12993     }
12994
12995   if (src_set == 0)
12996     {
12997       errmsg ("tunnel src address not specified");
12998       return -99;
12999     }
13000   if (dst_set == 0)
13001     {
13002       errmsg ("tunnel dst address not specified");
13003       return -99;
13004     }
13005
13006   M (GRE_TUNNEL_ADD_DEL, mp);
13007
13008   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
13009   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
13010
13011   mp->tunnel.instance = htonl (instance);
13012   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
13013   mp->is_add = is_add;
13014   mp->tunnel.session_id = htons ((u16) session_id);
13015   mp->tunnel.type = htonl (t_type);
13016
13017   S (mp);
13018   W (ret);
13019   return ret;
13020 }
13021
13022 static void vl_api_gre_tunnel_details_t_handler
13023   (vl_api_gre_tunnel_details_t * mp)
13024 {
13025   vat_main_t *vam = &vat_main;
13026
13027   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13028          ntohl (mp->tunnel.sw_if_index),
13029          ntohl (mp->tunnel.instance),
13030          format_vl_api_address, &mp->tunnel.src,
13031          format_vl_api_address, &mp->tunnel.dst,
13032          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
13033          ntohl (mp->tunnel.session_id));
13034 }
13035
13036 static void vl_api_gre_tunnel_details_t_handler_json
13037   (vl_api_gre_tunnel_details_t * mp)
13038 {
13039   vat_main_t *vam = &vat_main;
13040   vat_json_node_t *node = NULL;
13041
13042   if (VAT_JSON_ARRAY != vam->json_tree.type)
13043     {
13044       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13045       vat_json_init_array (&vam->json_tree);
13046     }
13047   node = vat_json_array_add (&vam->json_tree);
13048
13049   vat_json_init_object (node);
13050   vat_json_object_add_uint (node, "sw_if_index",
13051                             ntohl (mp->tunnel.sw_if_index));
13052   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
13053
13054   vat_json_object_add_address (node, "src", &mp->tunnel.src);
13055   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
13056   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
13057   vat_json_object_add_uint (node, "outer_fib_id",
13058                             ntohl (mp->tunnel.outer_fib_id));
13059   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
13060 }
13061
13062 static int
13063 api_gre_tunnel_dump (vat_main_t * vam)
13064 {
13065   unformat_input_t *i = vam->input;
13066   vl_api_gre_tunnel_dump_t *mp;
13067   vl_api_control_ping_t *mp_ping;
13068   u32 sw_if_index;
13069   u8 sw_if_index_set = 0;
13070   int ret;
13071
13072   /* Parse args required to build the message */
13073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13074     {
13075       if (unformat (i, "sw_if_index %d", &sw_if_index))
13076         sw_if_index_set = 1;
13077       else
13078         break;
13079     }
13080
13081   if (sw_if_index_set == 0)
13082     {
13083       sw_if_index = ~0;
13084     }
13085
13086   if (!vam->json_output)
13087     {
13088       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13089              "sw_if_index", "instance", "src_address", "dst_address",
13090              "tunnel_type", "outer_fib_id", "session_id");
13091     }
13092
13093   /* Get list of gre-tunnel interfaces */
13094   M (GRE_TUNNEL_DUMP, mp);
13095
13096   mp->sw_if_index = htonl (sw_if_index);
13097
13098   S (mp);
13099
13100   /* Use a control ping for synchronization */
13101   MPING (CONTROL_PING, mp_ping);
13102   S (mp_ping);
13103
13104   W (ret);
13105   return ret;
13106 }
13107
13108 static int
13109 api_l2_fib_clear_table (vat_main_t * vam)
13110 {
13111 //  unformat_input_t * i = vam->input;
13112   vl_api_l2_fib_clear_table_t *mp;
13113   int ret;
13114
13115   M (L2_FIB_CLEAR_TABLE, mp);
13116
13117   S (mp);
13118   W (ret);
13119   return ret;
13120 }
13121
13122 static int
13123 api_l2_interface_efp_filter (vat_main_t * vam)
13124 {
13125   unformat_input_t *i = vam->input;
13126   vl_api_l2_interface_efp_filter_t *mp;
13127   u32 sw_if_index;
13128   u8 enable = 1;
13129   u8 sw_if_index_set = 0;
13130   int ret;
13131
13132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13133     {
13134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13135         sw_if_index_set = 1;
13136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13137         sw_if_index_set = 1;
13138       else if (unformat (i, "enable"))
13139         enable = 1;
13140       else if (unformat (i, "disable"))
13141         enable = 0;
13142       else
13143         {
13144           clib_warning ("parse error '%U'", format_unformat_error, i);
13145           return -99;
13146         }
13147     }
13148
13149   if (sw_if_index_set == 0)
13150     {
13151       errmsg ("missing sw_if_index");
13152       return -99;
13153     }
13154
13155   M (L2_INTERFACE_EFP_FILTER, mp);
13156
13157   mp->sw_if_index = ntohl (sw_if_index);
13158   mp->enable_disable = enable;
13159
13160   S (mp);
13161   W (ret);
13162   return ret;
13163 }
13164
13165 #define foreach_vtr_op                          \
13166 _("disable",  L2_VTR_DISABLED)                  \
13167 _("push-1",  L2_VTR_PUSH_1)                     \
13168 _("push-2",  L2_VTR_PUSH_2)                     \
13169 _("pop-1",  L2_VTR_POP_1)                       \
13170 _("pop-2",  L2_VTR_POP_2)                       \
13171 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13172 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13173 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13174 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13175
13176 static int
13177 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13178 {
13179   unformat_input_t *i = vam->input;
13180   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13181   u32 sw_if_index;
13182   u8 sw_if_index_set = 0;
13183   u8 vtr_op_set = 0;
13184   u32 vtr_op = 0;
13185   u32 push_dot1q = 1;
13186   u32 tag1 = ~0;
13187   u32 tag2 = ~0;
13188   int ret;
13189
13190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13191     {
13192       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13193         sw_if_index_set = 1;
13194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13195         sw_if_index_set = 1;
13196       else if (unformat (i, "vtr_op %d", &vtr_op))
13197         vtr_op_set = 1;
13198 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13199       foreach_vtr_op
13200 #undef _
13201         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13202         ;
13203       else if (unformat (i, "tag1 %d", &tag1))
13204         ;
13205       else if (unformat (i, "tag2 %d", &tag2))
13206         ;
13207       else
13208         {
13209           clib_warning ("parse error '%U'", format_unformat_error, i);
13210           return -99;
13211         }
13212     }
13213
13214   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13215     {
13216       errmsg ("missing vtr operation or sw_if_index");
13217       return -99;
13218     }
13219
13220   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13221   mp->sw_if_index = ntohl (sw_if_index);
13222   mp->vtr_op = ntohl (vtr_op);
13223   mp->push_dot1q = ntohl (push_dot1q);
13224   mp->tag1 = ntohl (tag1);
13225   mp->tag2 = ntohl (tag2);
13226
13227   S (mp);
13228   W (ret);
13229   return ret;
13230 }
13231
13232 static int
13233 api_create_vhost_user_if (vat_main_t * vam)
13234 {
13235   unformat_input_t *i = vam->input;
13236   vl_api_create_vhost_user_if_t *mp;
13237   u8 *file_name;
13238   u8 is_server = 0;
13239   u8 file_name_set = 0;
13240   u32 custom_dev_instance = ~0;
13241   u8 hwaddr[6];
13242   u8 use_custom_mac = 0;
13243   u8 disable_mrg_rxbuf = 0;
13244   u8 disable_indirect_desc = 0;
13245   u8 *tag = 0;
13246   u8 enable_gso = 0;
13247   int ret;
13248
13249   /* Shut up coverity */
13250   clib_memset (hwaddr, 0, sizeof (hwaddr));
13251
13252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13253     {
13254       if (unformat (i, "socket %s", &file_name))
13255         {
13256           file_name_set = 1;
13257         }
13258       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13259         ;
13260       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13261         use_custom_mac = 1;
13262       else if (unformat (i, "server"))
13263         is_server = 1;
13264       else if (unformat (i, "disable_mrg_rxbuf"))
13265         disable_mrg_rxbuf = 1;
13266       else if (unformat (i, "disable_indirect_desc"))
13267         disable_indirect_desc = 1;
13268       else if (unformat (i, "gso"))
13269         enable_gso = 1;
13270       else if (unformat (i, "tag %s", &tag))
13271         ;
13272       else
13273         break;
13274     }
13275
13276   if (file_name_set == 0)
13277     {
13278       errmsg ("missing socket file name");
13279       return -99;
13280     }
13281
13282   if (vec_len (file_name) > 255)
13283     {
13284       errmsg ("socket file name too long");
13285       return -99;
13286     }
13287   vec_add1 (file_name, 0);
13288
13289   M (CREATE_VHOST_USER_IF, mp);
13290
13291   mp->is_server = is_server;
13292   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13293   mp->disable_indirect_desc = disable_indirect_desc;
13294   mp->enable_gso = enable_gso;
13295   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13296   vec_free (file_name);
13297   if (custom_dev_instance != ~0)
13298     {
13299       mp->renumber = 1;
13300       mp->custom_dev_instance = ntohl (custom_dev_instance);
13301     }
13302
13303   mp->use_custom_mac = use_custom_mac;
13304   clib_memcpy (mp->mac_address, hwaddr, 6);
13305   if (tag)
13306     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13307   vec_free (tag);
13308
13309   S (mp);
13310   W (ret);
13311   return ret;
13312 }
13313
13314 static int
13315 api_modify_vhost_user_if (vat_main_t * vam)
13316 {
13317   unformat_input_t *i = vam->input;
13318   vl_api_modify_vhost_user_if_t *mp;
13319   u8 *file_name;
13320   u8 is_server = 0;
13321   u8 file_name_set = 0;
13322   u32 custom_dev_instance = ~0;
13323   u8 sw_if_index_set = 0;
13324   u32 sw_if_index = (u32) ~ 0;
13325   u8 enable_gso = 0;
13326   int ret;
13327
13328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13329     {
13330       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13331         sw_if_index_set = 1;
13332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13333         sw_if_index_set = 1;
13334       else if (unformat (i, "socket %s", &file_name))
13335         {
13336           file_name_set = 1;
13337         }
13338       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13339         ;
13340       else if (unformat (i, "server"))
13341         is_server = 1;
13342       else if (unformat (i, "gso"))
13343         enable_gso = 1;
13344       else
13345         break;
13346     }
13347
13348   if (sw_if_index_set == 0)
13349     {
13350       errmsg ("missing sw_if_index or interface name");
13351       return -99;
13352     }
13353
13354   if (file_name_set == 0)
13355     {
13356       errmsg ("missing socket file name");
13357       return -99;
13358     }
13359
13360   if (vec_len (file_name) > 255)
13361     {
13362       errmsg ("socket file name too long");
13363       return -99;
13364     }
13365   vec_add1 (file_name, 0);
13366
13367   M (MODIFY_VHOST_USER_IF, mp);
13368
13369   mp->sw_if_index = ntohl (sw_if_index);
13370   mp->is_server = is_server;
13371   mp->enable_gso = enable_gso;
13372   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13373   vec_free (file_name);
13374   if (custom_dev_instance != ~0)
13375     {
13376       mp->renumber = 1;
13377       mp->custom_dev_instance = ntohl (custom_dev_instance);
13378     }
13379
13380   S (mp);
13381   W (ret);
13382   return ret;
13383 }
13384
13385 static int
13386 api_delete_vhost_user_if (vat_main_t * vam)
13387 {
13388   unformat_input_t *i = vam->input;
13389   vl_api_delete_vhost_user_if_t *mp;
13390   u32 sw_if_index = ~0;
13391   u8 sw_if_index_set = 0;
13392   int ret;
13393
13394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13395     {
13396       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13397         sw_if_index_set = 1;
13398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13399         sw_if_index_set = 1;
13400       else
13401         break;
13402     }
13403
13404   if (sw_if_index_set == 0)
13405     {
13406       errmsg ("missing sw_if_index or interface name");
13407       return -99;
13408     }
13409
13410
13411   M (DELETE_VHOST_USER_IF, mp);
13412
13413   mp->sw_if_index = ntohl (sw_if_index);
13414
13415   S (mp);
13416   W (ret);
13417   return ret;
13418 }
13419
13420 static void vl_api_sw_interface_vhost_user_details_t_handler
13421   (vl_api_sw_interface_vhost_user_details_t * mp)
13422 {
13423   vat_main_t *vam = &vat_main;
13424
13425   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13426          (char *) mp->interface_name,
13427          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13428          clib_net_to_host_u64 (mp->features), mp->is_server,
13429          ntohl (mp->num_regions), (char *) mp->sock_filename);
13430   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13431 }
13432
13433 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13434   (vl_api_sw_interface_vhost_user_details_t * mp)
13435 {
13436   vat_main_t *vam = &vat_main;
13437   vat_json_node_t *node = NULL;
13438
13439   if (VAT_JSON_ARRAY != vam->json_tree.type)
13440     {
13441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13442       vat_json_init_array (&vam->json_tree);
13443     }
13444   node = vat_json_array_add (&vam->json_tree);
13445
13446   vat_json_init_object (node);
13447   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13448   vat_json_object_add_string_copy (node, "interface_name",
13449                                    mp->interface_name);
13450   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13451                             ntohl (mp->virtio_net_hdr_sz));
13452   vat_json_object_add_uint (node, "features",
13453                             clib_net_to_host_u64 (mp->features));
13454   vat_json_object_add_uint (node, "is_server", mp->is_server);
13455   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13456   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13457   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13458 }
13459
13460 static int
13461 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13462 {
13463   vl_api_sw_interface_vhost_user_dump_t *mp;
13464   vl_api_control_ping_t *mp_ping;
13465   int ret;
13466   print (vam->ofp,
13467          "Interface name            idx hdr_sz features server regions filename");
13468
13469   /* Get list of vhost-user interfaces */
13470   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13471   S (mp);
13472
13473   /* Use a control ping for synchronization */
13474   MPING (CONTROL_PING, mp_ping);
13475   S (mp_ping);
13476
13477   W (ret);
13478   return ret;
13479 }
13480
13481 static int
13482 api_show_version (vat_main_t * vam)
13483 {
13484   vl_api_show_version_t *mp;
13485   int ret;
13486
13487   M (SHOW_VERSION, mp);
13488
13489   S (mp);
13490   W (ret);
13491   return ret;
13492 }
13493
13494
13495 static int
13496 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13497 {
13498   unformat_input_t *line_input = vam->input;
13499   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13500   ip4_address_t local4, remote4;
13501   ip6_address_t local6, remote6;
13502   u8 is_add = 1;
13503   u8 ipv4_set = 0, ipv6_set = 0;
13504   u8 local_set = 0;
13505   u8 remote_set = 0;
13506   u8 grp_set = 0;
13507   u32 mcast_sw_if_index = ~0;
13508   u32 encap_vrf_id = 0;
13509   u32 decap_vrf_id = 0;
13510   u8 protocol = ~0;
13511   u32 vni;
13512   u8 vni_set = 0;
13513   int ret;
13514
13515   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13516   clib_memset (&local4, 0, sizeof local4);
13517   clib_memset (&remote4, 0, sizeof remote4);
13518   clib_memset (&local6, 0, sizeof local6);
13519   clib_memset (&remote6, 0, sizeof remote6);
13520
13521   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13522     {
13523       if (unformat (line_input, "del"))
13524         is_add = 0;
13525       else if (unformat (line_input, "local %U",
13526                          unformat_ip4_address, &local4))
13527         {
13528           local_set = 1;
13529           ipv4_set = 1;
13530         }
13531       else if (unformat (line_input, "remote %U",
13532                          unformat_ip4_address, &remote4))
13533         {
13534           remote_set = 1;
13535           ipv4_set = 1;
13536         }
13537       else if (unformat (line_input, "local %U",
13538                          unformat_ip6_address, &local6))
13539         {
13540           local_set = 1;
13541           ipv6_set = 1;
13542         }
13543       else if (unformat (line_input, "remote %U",
13544                          unformat_ip6_address, &remote6))
13545         {
13546           remote_set = 1;
13547           ipv6_set = 1;
13548         }
13549       else if (unformat (line_input, "group %U %U",
13550                          unformat_ip4_address, &remote4,
13551                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13552         {
13553           grp_set = remote_set = 1;
13554           ipv4_set = 1;
13555         }
13556       else if (unformat (line_input, "group %U",
13557                          unformat_ip4_address, &remote4))
13558         {
13559           grp_set = remote_set = 1;
13560           ipv4_set = 1;
13561         }
13562       else if (unformat (line_input, "group %U %U",
13563                          unformat_ip6_address, &remote6,
13564                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13565         {
13566           grp_set = remote_set = 1;
13567           ipv6_set = 1;
13568         }
13569       else if (unformat (line_input, "group %U",
13570                          unformat_ip6_address, &remote6))
13571         {
13572           grp_set = remote_set = 1;
13573           ipv6_set = 1;
13574         }
13575       else
13576         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13577         ;
13578       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13579         ;
13580       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13581         ;
13582       else if (unformat (line_input, "vni %d", &vni))
13583         vni_set = 1;
13584       else if (unformat (line_input, "next-ip4"))
13585         protocol = 1;
13586       else if (unformat (line_input, "next-ip6"))
13587         protocol = 2;
13588       else if (unformat (line_input, "next-ethernet"))
13589         protocol = 3;
13590       else if (unformat (line_input, "next-nsh"))
13591         protocol = 4;
13592       else
13593         {
13594           errmsg ("parse error '%U'", format_unformat_error, line_input);
13595           return -99;
13596         }
13597     }
13598
13599   if (local_set == 0)
13600     {
13601       errmsg ("tunnel local address not specified");
13602       return -99;
13603     }
13604   if (remote_set == 0)
13605     {
13606       errmsg ("tunnel remote address not specified");
13607       return -99;
13608     }
13609   if (grp_set && mcast_sw_if_index == ~0)
13610     {
13611       errmsg ("tunnel nonexistent multicast device");
13612       return -99;
13613     }
13614   if (ipv4_set && ipv6_set)
13615     {
13616       errmsg ("both IPv4 and IPv6 addresses specified");
13617       return -99;
13618     }
13619
13620   if (vni_set == 0)
13621     {
13622       errmsg ("vni not specified");
13623       return -99;
13624     }
13625
13626   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13627
13628
13629   if (ipv6_set)
13630     {
13631       clib_memcpy (&mp->local, &local6, sizeof (local6));
13632       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13633     }
13634   else
13635     {
13636       clib_memcpy (&mp->local, &local4, sizeof (local4));
13637       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13638     }
13639
13640   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13641   mp->encap_vrf_id = ntohl (encap_vrf_id);
13642   mp->decap_vrf_id = ntohl (decap_vrf_id);
13643   mp->protocol = protocol;
13644   mp->vni = ntohl (vni);
13645   mp->is_add = is_add;
13646   mp->is_ipv6 = ipv6_set;
13647
13648   S (mp);
13649   W (ret);
13650   return ret;
13651 }
13652
13653 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13654   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13655 {
13656   vat_main_t *vam = &vat_main;
13657   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13658   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13659
13660   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13661          ntohl (mp->sw_if_index),
13662          format_ip46_address, &local, IP46_TYPE_ANY,
13663          format_ip46_address, &remote, IP46_TYPE_ANY,
13664          ntohl (mp->vni), mp->protocol,
13665          ntohl (mp->mcast_sw_if_index),
13666          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13667 }
13668
13669
13670 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13671   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13672 {
13673   vat_main_t *vam = &vat_main;
13674   vat_json_node_t *node = NULL;
13675   struct in_addr ip4;
13676   struct in6_addr ip6;
13677
13678   if (VAT_JSON_ARRAY != vam->json_tree.type)
13679     {
13680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13681       vat_json_init_array (&vam->json_tree);
13682     }
13683   node = vat_json_array_add (&vam->json_tree);
13684
13685   vat_json_init_object (node);
13686   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13687   if (mp->is_ipv6)
13688     {
13689       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13690       vat_json_object_add_ip6 (node, "local", ip6);
13691       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13692       vat_json_object_add_ip6 (node, "remote", ip6);
13693     }
13694   else
13695     {
13696       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13697       vat_json_object_add_ip4 (node, "local", ip4);
13698       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13699       vat_json_object_add_ip4 (node, "remote", ip4);
13700     }
13701   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13702   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13703   vat_json_object_add_uint (node, "mcast_sw_if_index",
13704                             ntohl (mp->mcast_sw_if_index));
13705   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13706   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13707   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13708 }
13709
13710 static int
13711 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13712 {
13713   unformat_input_t *i = vam->input;
13714   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13715   vl_api_control_ping_t *mp_ping;
13716   u32 sw_if_index;
13717   u8 sw_if_index_set = 0;
13718   int ret;
13719
13720   /* Parse args required to build the message */
13721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13722     {
13723       if (unformat (i, "sw_if_index %d", &sw_if_index))
13724         sw_if_index_set = 1;
13725       else
13726         break;
13727     }
13728
13729   if (sw_if_index_set == 0)
13730     {
13731       sw_if_index = ~0;
13732     }
13733
13734   if (!vam->json_output)
13735     {
13736       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13737              "sw_if_index", "local", "remote", "vni",
13738              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13739     }
13740
13741   /* Get list of vxlan-tunnel interfaces */
13742   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13743
13744   mp->sw_if_index = htonl (sw_if_index);
13745
13746   S (mp);
13747
13748   /* Use a control ping for synchronization */
13749   MPING (CONTROL_PING, mp_ping);
13750   S (mp_ping);
13751
13752   W (ret);
13753   return ret;
13754 }
13755
13756 static void vl_api_l2_fib_table_details_t_handler
13757   (vl_api_l2_fib_table_details_t * mp)
13758 {
13759   vat_main_t *vam = &vat_main;
13760
13761   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13762          "       %d       %d     %d",
13763          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13764          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13765          mp->bvi_mac);
13766 }
13767
13768 static void vl_api_l2_fib_table_details_t_handler_json
13769   (vl_api_l2_fib_table_details_t * mp)
13770 {
13771   vat_main_t *vam = &vat_main;
13772   vat_json_node_t *node = NULL;
13773
13774   if (VAT_JSON_ARRAY != vam->json_tree.type)
13775     {
13776       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13777       vat_json_init_array (&vam->json_tree);
13778     }
13779   node = vat_json_array_add (&vam->json_tree);
13780
13781   vat_json_init_object (node);
13782   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13783   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13784   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13785   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13786   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13787   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13788 }
13789
13790 static int
13791 api_l2_fib_table_dump (vat_main_t * vam)
13792 {
13793   unformat_input_t *i = vam->input;
13794   vl_api_l2_fib_table_dump_t *mp;
13795   vl_api_control_ping_t *mp_ping;
13796   u32 bd_id;
13797   u8 bd_id_set = 0;
13798   int ret;
13799
13800   /* Parse args required to build the message */
13801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13802     {
13803       if (unformat (i, "bd_id %d", &bd_id))
13804         bd_id_set = 1;
13805       else
13806         break;
13807     }
13808
13809   if (bd_id_set == 0)
13810     {
13811       errmsg ("missing bridge domain");
13812       return -99;
13813     }
13814
13815   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13816
13817   /* Get list of l2 fib entries */
13818   M (L2_FIB_TABLE_DUMP, mp);
13819
13820   mp->bd_id = ntohl (bd_id);
13821   S (mp);
13822
13823   /* Use a control ping for synchronization */
13824   MPING (CONTROL_PING, mp_ping);
13825   S (mp_ping);
13826
13827   W (ret);
13828   return ret;
13829 }
13830
13831
13832 static int
13833 api_interface_name_renumber (vat_main_t * vam)
13834 {
13835   unformat_input_t *line_input = vam->input;
13836   vl_api_interface_name_renumber_t *mp;
13837   u32 sw_if_index = ~0;
13838   u32 new_show_dev_instance = ~0;
13839   int ret;
13840
13841   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13842     {
13843       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13844                     &sw_if_index))
13845         ;
13846       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13847         ;
13848       else if (unformat (line_input, "new_show_dev_instance %d",
13849                          &new_show_dev_instance))
13850         ;
13851       else
13852         break;
13853     }
13854
13855   if (sw_if_index == ~0)
13856     {
13857       errmsg ("missing interface name or sw_if_index");
13858       return -99;
13859     }
13860
13861   if (new_show_dev_instance == ~0)
13862     {
13863       errmsg ("missing new_show_dev_instance");
13864       return -99;
13865     }
13866
13867   M (INTERFACE_NAME_RENUMBER, mp);
13868
13869   mp->sw_if_index = ntohl (sw_if_index);
13870   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13871
13872   S (mp);
13873   W (ret);
13874   return ret;
13875 }
13876
13877 static int
13878 api_ip_probe_neighbor (vat_main_t * vam)
13879 {
13880   unformat_input_t *i = vam->input;
13881   vl_api_ip_probe_neighbor_t *mp;
13882   vl_api_address_t dst_adr = { };
13883   u8 int_set = 0;
13884   u8 adr_set = 0;
13885   u32 sw_if_index;
13886   int ret;
13887
13888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13889     {
13890       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13891         int_set = 1;
13892       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13893         int_set = 1;
13894       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13895         adr_set = 1;
13896       else
13897         break;
13898     }
13899
13900   if (int_set == 0)
13901     {
13902       errmsg ("missing interface");
13903       return -99;
13904     }
13905
13906   if (adr_set == 0)
13907     {
13908       errmsg ("missing addresses");
13909       return -99;
13910     }
13911
13912   M (IP_PROBE_NEIGHBOR, mp);
13913
13914   mp->sw_if_index = ntohl (sw_if_index);
13915   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13916
13917   S (mp);
13918   W (ret);
13919   return ret;
13920 }
13921
13922 static int
13923 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13924 {
13925   unformat_input_t *i = vam->input;
13926   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13927   u8 mode = IP_SCAN_V46_NEIGHBORS;
13928   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13929   int ret;
13930
13931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13932     {
13933       if (unformat (i, "ip4"))
13934         mode = IP_SCAN_V4_NEIGHBORS;
13935       else if (unformat (i, "ip6"))
13936         mode = IP_SCAN_V6_NEIGHBORS;
13937       if (unformat (i, "both"))
13938         mode = IP_SCAN_V46_NEIGHBORS;
13939       else if (unformat (i, "disable"))
13940         mode = IP_SCAN_DISABLED;
13941       else if (unformat (i, "interval %d", &interval))
13942         ;
13943       else if (unformat (i, "max-time %d", &time))
13944         ;
13945       else if (unformat (i, "max-update %d", &update))
13946         ;
13947       else if (unformat (i, "delay %d", &delay))
13948         ;
13949       else if (unformat (i, "stale %d", &stale))
13950         ;
13951       else
13952         break;
13953     }
13954
13955   if (interval > 255)
13956     {
13957       errmsg ("interval cannot exceed 255 minutes.");
13958       return -99;
13959     }
13960   if (time > 255)
13961     {
13962       errmsg ("max-time cannot exceed 255 usec.");
13963       return -99;
13964     }
13965   if (update > 255)
13966     {
13967       errmsg ("max-update cannot exceed 255.");
13968       return -99;
13969     }
13970   if (delay > 255)
13971     {
13972       errmsg ("delay cannot exceed 255 msec.");
13973       return -99;
13974     }
13975   if (stale > 255)
13976     {
13977       errmsg ("stale cannot exceed 255 minutes.");
13978       return -99;
13979     }
13980
13981   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13982   mp->mode = mode;
13983   mp->scan_interval = interval;
13984   mp->max_proc_time = time;
13985   mp->max_update = update;
13986   mp->scan_int_delay = delay;
13987   mp->stale_threshold = stale;
13988
13989   S (mp);
13990   W (ret);
13991   return ret;
13992 }
13993
13994 static int
13995 api_want_ip4_arp_events (vat_main_t * vam)
13996 {
13997   unformat_input_t *line_input = vam->input;
13998   vl_api_want_ip4_arp_events_t *mp;
13999   ip4_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 (line_input, "address %U", unformat_ip4_address, &address))
14007         address_set = 1;
14008       else if (unformat (line_input, "del"))
14009         enable_disable = 0;
14010       else
14011         break;
14012     }
14013
14014   if (address_set == 0)
14015     {
14016       errmsg ("missing addresses");
14017       return -99;
14018     }
14019
14020   M (WANT_IP4_ARP_EVENTS, mp);
14021   mp->enable_disable = enable_disable;
14022   mp->pid = htonl (getpid ());
14023   clib_memcpy (mp->ip, &address, sizeof (address));
14024
14025   S (mp);
14026   W (ret);
14027   return ret;
14028 }
14029
14030 static int
14031 api_want_ip6_nd_events (vat_main_t * vam)
14032 {
14033   unformat_input_t *line_input = vam->input;
14034   vl_api_want_ip6_nd_events_t *mp;
14035   vl_api_ip6_address_t address;
14036   int address_set = 0;
14037   u32 enable_disable = 1;
14038   int ret;
14039
14040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14041     {
14042       if (unformat
14043           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
14044         address_set = 1;
14045       else if (unformat (line_input, "del"))
14046         enable_disable = 0;
14047       else
14048         break;
14049     }
14050
14051   if (address_set == 0)
14052     {
14053       errmsg ("missing addresses");
14054       return -99;
14055     }
14056
14057   M (WANT_IP6_ND_EVENTS, mp);
14058   mp->enable_disable = enable_disable;
14059   mp->pid = htonl (getpid ());
14060   clib_memcpy (&mp->ip, &address, sizeof (address));
14061
14062   S (mp);
14063   W (ret);
14064   return ret;
14065 }
14066
14067 static int
14068 api_want_l2_macs_events (vat_main_t * vam)
14069 {
14070   unformat_input_t *line_input = vam->input;
14071   vl_api_want_l2_macs_events_t *mp;
14072   u8 enable_disable = 1;
14073   u32 scan_delay = 0;
14074   u32 max_macs_in_event = 0;
14075   u32 learn_limit = 0;
14076   int ret;
14077
14078   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14079     {
14080       if (unformat (line_input, "learn-limit %d", &learn_limit))
14081         ;
14082       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14083         ;
14084       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14085         ;
14086       else if (unformat (line_input, "disable"))
14087         enable_disable = 0;
14088       else
14089         break;
14090     }
14091
14092   M (WANT_L2_MACS_EVENTS, mp);
14093   mp->enable_disable = enable_disable;
14094   mp->pid = htonl (getpid ());
14095   mp->learn_limit = htonl (learn_limit);
14096   mp->scan_delay = (u8) scan_delay;
14097   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14098   S (mp);
14099   W (ret);
14100   return ret;
14101 }
14102
14103 static int
14104 api_input_acl_set_interface (vat_main_t * vam)
14105 {
14106   unformat_input_t *i = vam->input;
14107   vl_api_input_acl_set_interface_t *mp;
14108   u32 sw_if_index;
14109   int sw_if_index_set;
14110   u32 ip4_table_index = ~0;
14111   u32 ip6_table_index = ~0;
14112   u32 l2_table_index = ~0;
14113   u8 is_add = 1;
14114   int ret;
14115
14116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14117     {
14118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14119         sw_if_index_set = 1;
14120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14121         sw_if_index_set = 1;
14122       else if (unformat (i, "del"))
14123         is_add = 0;
14124       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14125         ;
14126       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14127         ;
14128       else if (unformat (i, "l2-table %d", &l2_table_index))
14129         ;
14130       else
14131         {
14132           clib_warning ("parse error '%U'", format_unformat_error, i);
14133           return -99;
14134         }
14135     }
14136
14137   if (sw_if_index_set == 0)
14138     {
14139       errmsg ("missing interface name or sw_if_index");
14140       return -99;
14141     }
14142
14143   M (INPUT_ACL_SET_INTERFACE, mp);
14144
14145   mp->sw_if_index = ntohl (sw_if_index);
14146   mp->ip4_table_index = ntohl (ip4_table_index);
14147   mp->ip6_table_index = ntohl (ip6_table_index);
14148   mp->l2_table_index = ntohl (l2_table_index);
14149   mp->is_add = is_add;
14150
14151   S (mp);
14152   W (ret);
14153   return ret;
14154 }
14155
14156 static int
14157 api_output_acl_set_interface (vat_main_t * vam)
14158 {
14159   unformat_input_t *i = vam->input;
14160   vl_api_output_acl_set_interface_t *mp;
14161   u32 sw_if_index;
14162   int sw_if_index_set;
14163   u32 ip4_table_index = ~0;
14164   u32 ip6_table_index = ~0;
14165   u32 l2_table_index = ~0;
14166   u8 is_add = 1;
14167   int ret;
14168
14169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14170     {
14171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14172         sw_if_index_set = 1;
14173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14174         sw_if_index_set = 1;
14175       else if (unformat (i, "del"))
14176         is_add = 0;
14177       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14178         ;
14179       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14180         ;
14181       else if (unformat (i, "l2-table %d", &l2_table_index))
14182         ;
14183       else
14184         {
14185           clib_warning ("parse error '%U'", format_unformat_error, i);
14186           return -99;
14187         }
14188     }
14189
14190   if (sw_if_index_set == 0)
14191     {
14192       errmsg ("missing interface name or sw_if_index");
14193       return -99;
14194     }
14195
14196   M (OUTPUT_ACL_SET_INTERFACE, mp);
14197
14198   mp->sw_if_index = ntohl (sw_if_index);
14199   mp->ip4_table_index = ntohl (ip4_table_index);
14200   mp->ip6_table_index = ntohl (ip6_table_index);
14201   mp->l2_table_index = ntohl (l2_table_index);
14202   mp->is_add = is_add;
14203
14204   S (mp);
14205   W (ret);
14206   return ret;
14207 }
14208
14209 static int
14210 api_ip_address_dump (vat_main_t * vam)
14211 {
14212   unformat_input_t *i = vam->input;
14213   vl_api_ip_address_dump_t *mp;
14214   vl_api_control_ping_t *mp_ping;
14215   u32 sw_if_index = ~0;
14216   u8 sw_if_index_set = 0;
14217   u8 ipv4_set = 0;
14218   u8 ipv6_set = 0;
14219   int ret;
14220
14221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (i, "sw_if_index %d", &sw_if_index))
14224         sw_if_index_set = 1;
14225       else
14226         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14227         sw_if_index_set = 1;
14228       else if (unformat (i, "ipv4"))
14229         ipv4_set = 1;
14230       else if (unformat (i, "ipv6"))
14231         ipv6_set = 1;
14232       else
14233         break;
14234     }
14235
14236   if (ipv4_set && ipv6_set)
14237     {
14238       errmsg ("ipv4 and ipv6 flags cannot be both set");
14239       return -99;
14240     }
14241
14242   if ((!ipv4_set) && (!ipv6_set))
14243     {
14244       errmsg ("no ipv4 nor ipv6 flag set");
14245       return -99;
14246     }
14247
14248   if (sw_if_index_set == 0)
14249     {
14250       errmsg ("missing interface name or sw_if_index");
14251       return -99;
14252     }
14253
14254   vam->current_sw_if_index = sw_if_index;
14255   vam->is_ipv6 = ipv6_set;
14256
14257   M (IP_ADDRESS_DUMP, mp);
14258   mp->sw_if_index = ntohl (sw_if_index);
14259   mp->is_ipv6 = ipv6_set;
14260   S (mp);
14261
14262   /* Use a control ping for synchronization */
14263   MPING (CONTROL_PING, mp_ping);
14264   S (mp_ping);
14265
14266   W (ret);
14267   return ret;
14268 }
14269
14270 static int
14271 api_ip_dump (vat_main_t * vam)
14272 {
14273   vl_api_ip_dump_t *mp;
14274   vl_api_control_ping_t *mp_ping;
14275   unformat_input_t *in = vam->input;
14276   int ipv4_set = 0;
14277   int ipv6_set = 0;
14278   int is_ipv6;
14279   int i;
14280   int ret;
14281
14282   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14283     {
14284       if (unformat (in, "ipv4"))
14285         ipv4_set = 1;
14286       else if (unformat (in, "ipv6"))
14287         ipv6_set = 1;
14288       else
14289         break;
14290     }
14291
14292   if (ipv4_set && ipv6_set)
14293     {
14294       errmsg ("ipv4 and ipv6 flags cannot be both set");
14295       return -99;
14296     }
14297
14298   if ((!ipv4_set) && (!ipv6_set))
14299     {
14300       errmsg ("no ipv4 nor ipv6 flag set");
14301       return -99;
14302     }
14303
14304   is_ipv6 = ipv6_set;
14305   vam->is_ipv6 = is_ipv6;
14306
14307   /* free old data */
14308   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14309     {
14310       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14311     }
14312   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14313
14314   M (IP_DUMP, mp);
14315   mp->is_ipv6 = ipv6_set;
14316   S (mp);
14317
14318   /* Use a control ping for synchronization */
14319   MPING (CONTROL_PING, mp_ping);
14320   S (mp_ping);
14321
14322   W (ret);
14323   return ret;
14324 }
14325
14326 static int
14327 api_ipsec_spd_add_del (vat_main_t * vam)
14328 {
14329   unformat_input_t *i = vam->input;
14330   vl_api_ipsec_spd_add_del_t *mp;
14331   u32 spd_id = ~0;
14332   u8 is_add = 1;
14333   int ret;
14334
14335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14336     {
14337       if (unformat (i, "spd_id %d", &spd_id))
14338         ;
14339       else if (unformat (i, "del"))
14340         is_add = 0;
14341       else
14342         {
14343           clib_warning ("parse error '%U'", format_unformat_error, i);
14344           return -99;
14345         }
14346     }
14347   if (spd_id == ~0)
14348     {
14349       errmsg ("spd_id must be set");
14350       return -99;
14351     }
14352
14353   M (IPSEC_SPD_ADD_DEL, mp);
14354
14355   mp->spd_id = ntohl (spd_id);
14356   mp->is_add = is_add;
14357
14358   S (mp);
14359   W (ret);
14360   return ret;
14361 }
14362
14363 static int
14364 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14365 {
14366   unformat_input_t *i = vam->input;
14367   vl_api_ipsec_interface_add_del_spd_t *mp;
14368   u32 sw_if_index;
14369   u8 sw_if_index_set = 0;
14370   u32 spd_id = (u32) ~ 0;
14371   u8 is_add = 1;
14372   int ret;
14373
14374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14375     {
14376       if (unformat (i, "del"))
14377         is_add = 0;
14378       else if (unformat (i, "spd_id %d", &spd_id))
14379         ;
14380       else
14381         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14382         sw_if_index_set = 1;
14383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14384         sw_if_index_set = 1;
14385       else
14386         {
14387           clib_warning ("parse error '%U'", format_unformat_error, i);
14388           return -99;
14389         }
14390
14391     }
14392
14393   if (spd_id == (u32) ~ 0)
14394     {
14395       errmsg ("spd_id must be set");
14396       return -99;
14397     }
14398
14399   if (sw_if_index_set == 0)
14400     {
14401       errmsg ("missing interface name or sw_if_index");
14402       return -99;
14403     }
14404
14405   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14406
14407   mp->spd_id = ntohl (spd_id);
14408   mp->sw_if_index = ntohl (sw_if_index);
14409   mp->is_add = is_add;
14410
14411   S (mp);
14412   W (ret);
14413   return ret;
14414 }
14415
14416 static int
14417 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14418 {
14419   unformat_input_t *i = vam->input;
14420   vl_api_ipsec_spd_entry_add_del_t *mp;
14421   u8 is_add = 1, is_outbound = 0;
14422   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14423   i32 priority = 0;
14424   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14425   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14426   vl_api_address_t laddr_start = { }, laddr_stop =
14427   {
14428   }, raddr_start =
14429   {
14430   }, raddr_stop =
14431   {
14432   };
14433   int ret;
14434
14435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14436     {
14437       if (unformat (i, "del"))
14438         is_add = 0;
14439       if (unformat (i, "outbound"))
14440         is_outbound = 1;
14441       if (unformat (i, "inbound"))
14442         is_outbound = 0;
14443       else if (unformat (i, "spd_id %d", &spd_id))
14444         ;
14445       else if (unformat (i, "sa_id %d", &sa_id))
14446         ;
14447       else if (unformat (i, "priority %d", &priority))
14448         ;
14449       else if (unformat (i, "protocol %d", &protocol))
14450         ;
14451       else if (unformat (i, "lport_start %d", &lport_start))
14452         ;
14453       else if (unformat (i, "lport_stop %d", &lport_stop))
14454         ;
14455       else if (unformat (i, "rport_start %d", &rport_start))
14456         ;
14457       else if (unformat (i, "rport_stop %d", &rport_stop))
14458         ;
14459       else if (unformat (i, "laddr_start %U",
14460                          unformat_vl_api_address, &laddr_start))
14461         ;
14462       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14463                          &laddr_stop))
14464         ;
14465       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14466                          &raddr_start))
14467         ;
14468       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14469                          &raddr_stop))
14470         ;
14471       else
14472         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14473         {
14474           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14475             {
14476               clib_warning ("unsupported action: 'resolve'");
14477               return -99;
14478             }
14479         }
14480       else
14481         {
14482           clib_warning ("parse error '%U'", format_unformat_error, i);
14483           return -99;
14484         }
14485
14486     }
14487
14488   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14489
14490   mp->is_add = is_add;
14491
14492   mp->entry.spd_id = ntohl (spd_id);
14493   mp->entry.priority = ntohl (priority);
14494   mp->entry.is_outbound = is_outbound;
14495
14496   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14497                sizeof (vl_api_address_t));
14498   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14499                sizeof (vl_api_address_t));
14500   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14501                sizeof (vl_api_address_t));
14502   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14503                sizeof (vl_api_address_t));
14504
14505   mp->entry.protocol = (u8) protocol;
14506   mp->entry.local_port_start = ntohs ((u16) lport_start);
14507   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14508   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14509   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14510   mp->entry.policy = (u8) policy;
14511   mp->entry.sa_id = ntohl (sa_id);
14512
14513   S (mp);
14514   W (ret);
14515   return ret;
14516 }
14517
14518 static int
14519 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_ipsec_sad_entry_add_del_t *mp;
14523   u32 sad_id = 0, spi = 0;
14524   u8 *ck = 0, *ik = 0;
14525   u8 is_add = 1;
14526
14527   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14528   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14529   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14530   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14531   vl_api_address_t tun_src, tun_dst;
14532   int ret;
14533
14534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14535     {
14536       if (unformat (i, "del"))
14537         is_add = 0;
14538       else if (unformat (i, "sad_id %d", &sad_id))
14539         ;
14540       else if (unformat (i, "spi %d", &spi))
14541         ;
14542       else if (unformat (i, "esp"))
14543         protocol = IPSEC_API_PROTO_ESP;
14544       else
14545         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14546         {
14547           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14548           if (ADDRESS_IP6 == tun_src.af)
14549             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14550         }
14551       else
14552         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14553         {
14554           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14555           if (ADDRESS_IP6 == tun_src.af)
14556             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14557         }
14558       else
14559         if (unformat (i, "crypto_alg %U",
14560                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14561         ;
14562       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14563         ;
14564       else if (unformat (i, "integ_alg %U",
14565                          unformat_ipsec_api_integ_alg, &integ_alg))
14566         ;
14567       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14568         ;
14569       else
14570         {
14571           clib_warning ("parse error '%U'", format_unformat_error, i);
14572           return -99;
14573         }
14574
14575     }
14576
14577   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14578
14579   mp->is_add = is_add;
14580   mp->entry.sad_id = ntohl (sad_id);
14581   mp->entry.protocol = protocol;
14582   mp->entry.spi = ntohl (spi);
14583   mp->entry.flags = flags;
14584
14585   mp->entry.crypto_algorithm = crypto_alg;
14586   mp->entry.integrity_algorithm = integ_alg;
14587   mp->entry.crypto_key.length = vec_len (ck);
14588   mp->entry.integrity_key.length = vec_len (ik);
14589
14590   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14591     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14592
14593   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14594     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14595
14596   if (ck)
14597     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14598   if (ik)
14599     clib_memcpy (mp->entry.integrity_key.data, ik,
14600                  mp->entry.integrity_key.length);
14601
14602   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14603     {
14604       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14605                    sizeof (mp->entry.tunnel_src));
14606       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14607                    sizeof (mp->entry.tunnel_dst));
14608     }
14609
14610   S (mp);
14611   W (ret);
14612   return ret;
14613 }
14614
14615 static int
14616 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14617 {
14618   unformat_input_t *i = vam->input;
14619   vl_api_ipsec_tunnel_if_add_del_t *mp;
14620   u32 local_spi = 0, remote_spi = 0;
14621   u32 crypto_alg = 0, integ_alg = 0;
14622   u8 *lck = NULL, *rck = NULL;
14623   u8 *lik = NULL, *rik = NULL;
14624   vl_api_address_t local_ip = { 0 };
14625   vl_api_address_t remote_ip = { 0 };
14626   f64 before = 0;
14627   u8 is_add = 1;
14628   u8 esn = 0;
14629   u8 anti_replay = 0;
14630   u8 renumber = 0;
14631   u32 instance = ~0;
14632   u32 count = 1, jj;
14633   int ret = -1;
14634
14635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14636     {
14637       if (unformat (i, "del"))
14638         is_add = 0;
14639       else if (unformat (i, "esn"))
14640         esn = 1;
14641       else if (unformat (i, "anti-replay"))
14642         anti_replay = 1;
14643       else if (unformat (i, "count %d", &count))
14644         ;
14645       else if (unformat (i, "local_spi %d", &local_spi))
14646         ;
14647       else if (unformat (i, "remote_spi %d", &remote_spi))
14648         ;
14649       else
14650         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14651         ;
14652       else
14653         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14654         ;
14655       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14656         ;
14657       else
14658         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14659         ;
14660       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14661         ;
14662       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14663         ;
14664       else
14665         if (unformat
14666             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14667         {
14668           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14669             {
14670               errmsg ("unsupported crypto-alg: '%U'\n",
14671                       format_ipsec_crypto_alg, crypto_alg);
14672               return -99;
14673             }
14674         }
14675       else
14676         if (unformat
14677             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14678         {
14679           if (integ_alg >= IPSEC_INTEG_N_ALG)
14680             {
14681               errmsg ("unsupported integ-alg: '%U'\n",
14682                       format_ipsec_integ_alg, integ_alg);
14683               return -99;
14684             }
14685         }
14686       else if (unformat (i, "instance %u", &instance))
14687         renumber = 1;
14688       else
14689         {
14690           errmsg ("parse error '%U'\n", format_unformat_error, i);
14691           return -99;
14692         }
14693     }
14694
14695   if (count > 1)
14696     {
14697       /* Turn on async mode */
14698       vam->async_mode = 1;
14699       vam->async_errors = 0;
14700       before = vat_time_now (vam);
14701     }
14702
14703   for (jj = 0; jj < count; jj++)
14704     {
14705       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14706
14707       mp->is_add = is_add;
14708       mp->esn = esn;
14709       mp->anti_replay = anti_replay;
14710
14711       if (jj > 0)
14712         increment_address (&remote_ip);
14713
14714       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14715       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14716
14717       mp->local_spi = htonl (local_spi + jj);
14718       mp->remote_spi = htonl (remote_spi + jj);
14719       mp->crypto_alg = (u8) crypto_alg;
14720
14721       mp->local_crypto_key_len = 0;
14722       if (lck)
14723         {
14724           mp->local_crypto_key_len = vec_len (lck);
14725           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14726             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14727           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14728         }
14729
14730       mp->remote_crypto_key_len = 0;
14731       if (rck)
14732         {
14733           mp->remote_crypto_key_len = vec_len (rck);
14734           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14735             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14736           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14737         }
14738
14739       mp->integ_alg = (u8) integ_alg;
14740
14741       mp->local_integ_key_len = 0;
14742       if (lik)
14743         {
14744           mp->local_integ_key_len = vec_len (lik);
14745           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14746             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14747           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14748         }
14749
14750       mp->remote_integ_key_len = 0;
14751       if (rik)
14752         {
14753           mp->remote_integ_key_len = vec_len (rik);
14754           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14755             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14756           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14757         }
14758
14759       if (renumber)
14760         {
14761           mp->renumber = renumber;
14762           mp->show_instance = ntohl (instance);
14763         }
14764       S (mp);
14765     }
14766
14767   /* When testing multiple add/del ops, use a control-ping to sync */
14768   if (count > 1)
14769     {
14770       vl_api_control_ping_t *mp_ping;
14771       f64 after;
14772       f64 timeout;
14773
14774       /* Shut off async mode */
14775       vam->async_mode = 0;
14776
14777       MPING (CONTROL_PING, mp_ping);
14778       S (mp_ping);
14779
14780       timeout = vat_time_now (vam) + 1.0;
14781       while (vat_time_now (vam) < timeout)
14782         if (vam->result_ready == 1)
14783           goto out;
14784       vam->retval = -99;
14785
14786     out:
14787       if (vam->retval == -99)
14788         errmsg ("timeout");
14789
14790       if (vam->async_errors > 0)
14791         {
14792           errmsg ("%d asynchronous errors", vam->async_errors);
14793           vam->retval = -98;
14794         }
14795       vam->async_errors = 0;
14796       after = vat_time_now (vam);
14797
14798       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14799       if (jj > 0)
14800         count = jj;
14801
14802       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14803              count, after - before, count / (after - before));
14804     }
14805   else
14806     {
14807       /* Wait for a reply... */
14808       W (ret);
14809       return ret;
14810     }
14811
14812   return ret;
14813 }
14814
14815 static void
14816 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14817 {
14818   vat_main_t *vam = &vat_main;
14819
14820   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14821          "crypto_key %U integ_alg %u integ_key %U flags %x "
14822          "tunnel_src_addr %U tunnel_dst_addr %U "
14823          "salt %u seq_outbound %lu last_seq_inbound %lu "
14824          "replay_window %lu\n",
14825          ntohl (mp->entry.sad_id),
14826          ntohl (mp->sw_if_index),
14827          ntohl (mp->entry.spi),
14828          ntohl (mp->entry.protocol),
14829          ntohl (mp->entry.crypto_algorithm),
14830          format_hex_bytes, mp->entry.crypto_key.data,
14831          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14832          format_hex_bytes, mp->entry.integrity_key.data,
14833          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14834          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14835          &mp->entry.tunnel_dst, ntohl (mp->salt),
14836          clib_net_to_host_u64 (mp->seq_outbound),
14837          clib_net_to_host_u64 (mp->last_seq_inbound),
14838          clib_net_to_host_u64 (mp->replay_window));
14839 }
14840
14841 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14842 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14843
14844 static void vl_api_ipsec_sa_details_t_handler_json
14845   (vl_api_ipsec_sa_details_t * mp)
14846 {
14847   vat_main_t *vam = &vat_main;
14848   vat_json_node_t *node = NULL;
14849   vl_api_ipsec_sad_flags_t flags;
14850
14851   if (VAT_JSON_ARRAY != vam->json_tree.type)
14852     {
14853       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14854       vat_json_init_array (&vam->json_tree);
14855     }
14856   node = vat_json_array_add (&vam->json_tree);
14857
14858   vat_json_init_object (node);
14859   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14860   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14861   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14862   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14863   vat_json_object_add_uint (node, "crypto_alg",
14864                             ntohl (mp->entry.crypto_algorithm));
14865   vat_json_object_add_uint (node, "integ_alg",
14866                             ntohl (mp->entry.integrity_algorithm));
14867   flags = ntohl (mp->entry.flags);
14868   vat_json_object_add_uint (node, "use_esn",
14869                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14870   vat_json_object_add_uint (node, "use_anti_replay",
14871                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14872   vat_json_object_add_uint (node, "is_tunnel",
14873                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14874   vat_json_object_add_uint (node, "is_tunnel_ip6",
14875                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14876   vat_json_object_add_uint (node, "udp_encap",
14877                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14878   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14879                              mp->entry.crypto_key.length);
14880   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14881                              mp->entry.integrity_key.length);
14882   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14883   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14884   vat_json_object_add_uint (node, "replay_window",
14885                             clib_net_to_host_u64 (mp->replay_window));
14886 }
14887
14888 static int
14889 api_ipsec_sa_dump (vat_main_t * vam)
14890 {
14891   unformat_input_t *i = vam->input;
14892   vl_api_ipsec_sa_dump_t *mp;
14893   vl_api_control_ping_t *mp_ping;
14894   u32 sa_id = ~0;
14895   int ret;
14896
14897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14898     {
14899       if (unformat (i, "sa_id %d", &sa_id))
14900         ;
14901       else
14902         {
14903           clib_warning ("parse error '%U'", format_unformat_error, i);
14904           return -99;
14905         }
14906     }
14907
14908   M (IPSEC_SA_DUMP, mp);
14909
14910   mp->sa_id = ntohl (sa_id);
14911
14912   S (mp);
14913
14914   /* Use a control ping for synchronization */
14915   M (CONTROL_PING, mp_ping);
14916   S (mp_ping);
14917
14918   W (ret);
14919   return ret;
14920 }
14921
14922 static int
14923 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14924 {
14925   unformat_input_t *i = vam->input;
14926   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14927   u32 sw_if_index = ~0;
14928   u32 sa_id = ~0;
14929   u8 is_outbound = (u8) ~ 0;
14930   int ret;
14931
14932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14933     {
14934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14935         ;
14936       else if (unformat (i, "sa_id %d", &sa_id))
14937         ;
14938       else if (unformat (i, "outbound"))
14939         is_outbound = 1;
14940       else if (unformat (i, "inbound"))
14941         is_outbound = 0;
14942       else
14943         {
14944           clib_warning ("parse error '%U'", format_unformat_error, i);
14945           return -99;
14946         }
14947     }
14948
14949   if (sw_if_index == ~0)
14950     {
14951       errmsg ("interface must be specified");
14952       return -99;
14953     }
14954
14955   if (sa_id == ~0)
14956     {
14957       errmsg ("SA ID must be specified");
14958       return -99;
14959     }
14960
14961   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14962
14963   mp->sw_if_index = htonl (sw_if_index);
14964   mp->sa_id = htonl (sa_id);
14965   mp->is_outbound = is_outbound;
14966
14967   S (mp);
14968   W (ret);
14969
14970   return ret;
14971 }
14972
14973 static int
14974 api_get_first_msg_id (vat_main_t * vam)
14975 {
14976   vl_api_get_first_msg_id_t *mp;
14977   unformat_input_t *i = vam->input;
14978   u8 *name;
14979   u8 name_set = 0;
14980   int ret;
14981
14982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14983     {
14984       if (unformat (i, "client %s", &name))
14985         name_set = 1;
14986       else
14987         break;
14988     }
14989
14990   if (name_set == 0)
14991     {
14992       errmsg ("missing client name");
14993       return -99;
14994     }
14995   vec_add1 (name, 0);
14996
14997   if (vec_len (name) > 63)
14998     {
14999       errmsg ("client name too long");
15000       return -99;
15001     }
15002
15003   M (GET_FIRST_MSG_ID, mp);
15004   clib_memcpy (mp->name, name, vec_len (name));
15005   S (mp);
15006   W (ret);
15007   return ret;
15008 }
15009
15010 static int
15011 api_cop_interface_enable_disable (vat_main_t * vam)
15012 {
15013   unformat_input_t *line_input = vam->input;
15014   vl_api_cop_interface_enable_disable_t *mp;
15015   u32 sw_if_index = ~0;
15016   u8 enable_disable = 1;
15017   int ret;
15018
15019   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15020     {
15021       if (unformat (line_input, "disable"))
15022         enable_disable = 0;
15023       if (unformat (line_input, "enable"))
15024         enable_disable = 1;
15025       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15026                          vam, &sw_if_index))
15027         ;
15028       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15029         ;
15030       else
15031         break;
15032     }
15033
15034   if (sw_if_index == ~0)
15035     {
15036       errmsg ("missing interface name or sw_if_index");
15037       return -99;
15038     }
15039
15040   /* Construct the API message */
15041   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15042   mp->sw_if_index = ntohl (sw_if_index);
15043   mp->enable_disable = enable_disable;
15044
15045   /* send it... */
15046   S (mp);
15047   /* Wait for the reply */
15048   W (ret);
15049   return ret;
15050 }
15051
15052 static int
15053 api_cop_whitelist_enable_disable (vat_main_t * vam)
15054 {
15055   unformat_input_t *line_input = vam->input;
15056   vl_api_cop_whitelist_enable_disable_t *mp;
15057   u32 sw_if_index = ~0;
15058   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15059   u32 fib_id = 0;
15060   int ret;
15061
15062   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15063     {
15064       if (unformat (line_input, "ip4"))
15065         ip4 = 1;
15066       else if (unformat (line_input, "ip6"))
15067         ip6 = 1;
15068       else if (unformat (line_input, "default"))
15069         default_cop = 1;
15070       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15071                          vam, &sw_if_index))
15072         ;
15073       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15074         ;
15075       else if (unformat (line_input, "fib-id %d", &fib_id))
15076         ;
15077       else
15078         break;
15079     }
15080
15081   if (sw_if_index == ~0)
15082     {
15083       errmsg ("missing interface name or sw_if_index");
15084       return -99;
15085     }
15086
15087   /* Construct the API message */
15088   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15089   mp->sw_if_index = ntohl (sw_if_index);
15090   mp->fib_id = ntohl (fib_id);
15091   mp->ip4 = ip4;
15092   mp->ip6 = ip6;
15093   mp->default_cop = default_cop;
15094
15095   /* send it... */
15096   S (mp);
15097   /* Wait for the reply */
15098   W (ret);
15099   return ret;
15100 }
15101
15102 static int
15103 api_get_node_graph (vat_main_t * vam)
15104 {
15105   vl_api_get_node_graph_t *mp;
15106   int ret;
15107
15108   M (GET_NODE_GRAPH, mp);
15109
15110   /* send it... */
15111   S (mp);
15112   /* Wait for the reply */
15113   W (ret);
15114   return ret;
15115 }
15116
15117 /* *INDENT-OFF* */
15118 /** Used for parsing LISP eids */
15119 typedef CLIB_PACKED(struct{
15120   u8 addr[16];   /**< eid address */
15121   u32 len;       /**< prefix length if IP */
15122   u8 type;      /**< type of eid */
15123 }) lisp_eid_vat_t;
15124 /* *INDENT-ON* */
15125
15126 static uword
15127 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15128 {
15129   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15130
15131   clib_memset (a, 0, sizeof (a[0]));
15132
15133   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15134     {
15135       a->type = 0;              /* ipv4 type */
15136     }
15137   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15138     {
15139       a->type = 1;              /* ipv6 type */
15140     }
15141   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15142     {
15143       a->type = 2;              /* mac type */
15144     }
15145   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15146     {
15147       a->type = 3;              /* NSH type */
15148       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15149       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15150     }
15151   else
15152     {
15153       return 0;
15154     }
15155
15156   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15157     {
15158       return 0;
15159     }
15160
15161   return 1;
15162 }
15163
15164 static int
15165 lisp_eid_size_vat (u8 type)
15166 {
15167   switch (type)
15168     {
15169     case 0:
15170       return 4;
15171     case 1:
15172       return 16;
15173     case 2:
15174       return 6;
15175     case 3:
15176       return 5;
15177     }
15178   return 0;
15179 }
15180
15181 static void
15182 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15183 {
15184   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15185 }
15186
15187 static int
15188 api_one_add_del_locator_set (vat_main_t * vam)
15189 {
15190   unformat_input_t *input = vam->input;
15191   vl_api_one_add_del_locator_set_t *mp;
15192   u8 is_add = 1;
15193   u8 *locator_set_name = NULL;
15194   u8 locator_set_name_set = 0;
15195   vl_api_local_locator_t locator, *locators = 0;
15196   u32 sw_if_index, priority, weight;
15197   u32 data_len = 0;
15198
15199   int ret;
15200   /* Parse args required to build the message */
15201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15202     {
15203       if (unformat (input, "del"))
15204         {
15205           is_add = 0;
15206         }
15207       else if (unformat (input, "locator-set %s", &locator_set_name))
15208         {
15209           locator_set_name_set = 1;
15210         }
15211       else if (unformat (input, "sw_if_index %u p %u w %u",
15212                          &sw_if_index, &priority, &weight))
15213         {
15214           locator.sw_if_index = htonl (sw_if_index);
15215           locator.priority = priority;
15216           locator.weight = weight;
15217           vec_add1 (locators, locator);
15218         }
15219       else
15220         if (unformat
15221             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15222              &sw_if_index, &priority, &weight))
15223         {
15224           locator.sw_if_index = htonl (sw_if_index);
15225           locator.priority = priority;
15226           locator.weight = weight;
15227           vec_add1 (locators, locator);
15228         }
15229       else
15230         break;
15231     }
15232
15233   if (locator_set_name_set == 0)
15234     {
15235       errmsg ("missing locator-set name");
15236       vec_free (locators);
15237       return -99;
15238     }
15239
15240   if (vec_len (locator_set_name) > 64)
15241     {
15242       errmsg ("locator-set name too long");
15243       vec_free (locator_set_name);
15244       vec_free (locators);
15245       return -99;
15246     }
15247   vec_add1 (locator_set_name, 0);
15248
15249   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15250
15251   /* Construct the API message */
15252   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15253
15254   mp->is_add = is_add;
15255   clib_memcpy (mp->locator_set_name, locator_set_name,
15256                vec_len (locator_set_name));
15257   vec_free (locator_set_name);
15258
15259   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15260   if (locators)
15261     clib_memcpy (mp->locators, locators, data_len);
15262   vec_free (locators);
15263
15264   /* send it... */
15265   S (mp);
15266
15267   /* Wait for a reply... */
15268   W (ret);
15269   return ret;
15270 }
15271
15272 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15273
15274 static int
15275 api_one_add_del_locator (vat_main_t * vam)
15276 {
15277   unformat_input_t *input = vam->input;
15278   vl_api_one_add_del_locator_t *mp;
15279   u32 tmp_if_index = ~0;
15280   u32 sw_if_index = ~0;
15281   u8 sw_if_index_set = 0;
15282   u8 sw_if_index_if_name_set = 0;
15283   u32 priority = ~0;
15284   u8 priority_set = 0;
15285   u32 weight = ~0;
15286   u8 weight_set = 0;
15287   u8 is_add = 1;
15288   u8 *locator_set_name = NULL;
15289   u8 locator_set_name_set = 0;
15290   int ret;
15291
15292   /* Parse args required to build the message */
15293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15294     {
15295       if (unformat (input, "del"))
15296         {
15297           is_add = 0;
15298         }
15299       else if (unformat (input, "locator-set %s", &locator_set_name))
15300         {
15301           locator_set_name_set = 1;
15302         }
15303       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15304                          &tmp_if_index))
15305         {
15306           sw_if_index_if_name_set = 1;
15307           sw_if_index = tmp_if_index;
15308         }
15309       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15310         {
15311           sw_if_index_set = 1;
15312           sw_if_index = tmp_if_index;
15313         }
15314       else if (unformat (input, "p %d", &priority))
15315         {
15316           priority_set = 1;
15317         }
15318       else if (unformat (input, "w %d", &weight))
15319         {
15320           weight_set = 1;
15321         }
15322       else
15323         break;
15324     }
15325
15326   if (locator_set_name_set == 0)
15327     {
15328       errmsg ("missing locator-set name");
15329       return -99;
15330     }
15331
15332   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15333     {
15334       errmsg ("missing sw_if_index");
15335       vec_free (locator_set_name);
15336       return -99;
15337     }
15338
15339   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15340     {
15341       errmsg ("cannot use both params interface name and sw_if_index");
15342       vec_free (locator_set_name);
15343       return -99;
15344     }
15345
15346   if (priority_set == 0)
15347     {
15348       errmsg ("missing locator-set priority");
15349       vec_free (locator_set_name);
15350       return -99;
15351     }
15352
15353   if (weight_set == 0)
15354     {
15355       errmsg ("missing locator-set weight");
15356       vec_free (locator_set_name);
15357       return -99;
15358     }
15359
15360   if (vec_len (locator_set_name) > 64)
15361     {
15362       errmsg ("locator-set name too long");
15363       vec_free (locator_set_name);
15364       return -99;
15365     }
15366   vec_add1 (locator_set_name, 0);
15367
15368   /* Construct the API message */
15369   M (ONE_ADD_DEL_LOCATOR, mp);
15370
15371   mp->is_add = is_add;
15372   mp->sw_if_index = ntohl (sw_if_index);
15373   mp->priority = priority;
15374   mp->weight = weight;
15375   clib_memcpy (mp->locator_set_name, locator_set_name,
15376                vec_len (locator_set_name));
15377   vec_free (locator_set_name);
15378
15379   /* send it... */
15380   S (mp);
15381
15382   /* Wait for a reply... */
15383   W (ret);
15384   return ret;
15385 }
15386
15387 #define api_lisp_add_del_locator api_one_add_del_locator
15388
15389 uword
15390 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15391 {
15392   u32 *key_id = va_arg (*args, u32 *);
15393   u8 *s = 0;
15394
15395   if (unformat (input, "%s", &s))
15396     {
15397       if (!strcmp ((char *) s, "sha1"))
15398         key_id[0] = HMAC_SHA_1_96;
15399       else if (!strcmp ((char *) s, "sha256"))
15400         key_id[0] = HMAC_SHA_256_128;
15401       else
15402         {
15403           clib_warning ("invalid key_id: '%s'", s);
15404           key_id[0] = HMAC_NO_KEY;
15405         }
15406     }
15407   else
15408     return 0;
15409
15410   vec_free (s);
15411   return 1;
15412 }
15413
15414 static int
15415 api_one_add_del_local_eid (vat_main_t * vam)
15416 {
15417   unformat_input_t *input = vam->input;
15418   vl_api_one_add_del_local_eid_t *mp;
15419   u8 is_add = 1;
15420   u8 eid_set = 0;
15421   lisp_eid_vat_t _eid, *eid = &_eid;
15422   u8 *locator_set_name = 0;
15423   u8 locator_set_name_set = 0;
15424   u32 vni = 0;
15425   u16 key_id = 0;
15426   u8 *key = 0;
15427   int ret;
15428
15429   /* Parse args required to build the message */
15430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15431     {
15432       if (unformat (input, "del"))
15433         {
15434           is_add = 0;
15435         }
15436       else if (unformat (input, "vni %d", &vni))
15437         {
15438           ;
15439         }
15440       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15441         {
15442           eid_set = 1;
15443         }
15444       else if (unformat (input, "locator-set %s", &locator_set_name))
15445         {
15446           locator_set_name_set = 1;
15447         }
15448       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15449         ;
15450       else if (unformat (input, "secret-key %_%v%_", &key))
15451         ;
15452       else
15453         break;
15454     }
15455
15456   if (locator_set_name_set == 0)
15457     {
15458       errmsg ("missing locator-set name");
15459       return -99;
15460     }
15461
15462   if (0 == eid_set)
15463     {
15464       errmsg ("EID address not set!");
15465       vec_free (locator_set_name);
15466       return -99;
15467     }
15468
15469   if (key && (0 == key_id))
15470     {
15471       errmsg ("invalid key_id!");
15472       return -99;
15473     }
15474
15475   if (vec_len (key) > 64)
15476     {
15477       errmsg ("key too long");
15478       vec_free (key);
15479       return -99;
15480     }
15481
15482   if (vec_len (locator_set_name) > 64)
15483     {
15484       errmsg ("locator-set name too long");
15485       vec_free (locator_set_name);
15486       return -99;
15487     }
15488   vec_add1 (locator_set_name, 0);
15489
15490   /* Construct the API message */
15491   M (ONE_ADD_DEL_LOCAL_EID, mp);
15492
15493   mp->is_add = is_add;
15494   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15495   mp->eid_type = eid->type;
15496   mp->prefix_len = eid->len;
15497   mp->vni = clib_host_to_net_u32 (vni);
15498   mp->key_id = clib_host_to_net_u16 (key_id);
15499   clib_memcpy (mp->locator_set_name, locator_set_name,
15500                vec_len (locator_set_name));
15501   clib_memcpy (mp->key, key, vec_len (key));
15502
15503   vec_free (locator_set_name);
15504   vec_free (key);
15505
15506   /* send it... */
15507   S (mp);
15508
15509   /* Wait for a reply... */
15510   W (ret);
15511   return ret;
15512 }
15513
15514 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15515
15516 static int
15517 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15518 {
15519   u32 dp_table = 0, vni = 0;;
15520   unformat_input_t *input = vam->input;
15521   vl_api_gpe_add_del_fwd_entry_t *mp;
15522   u8 is_add = 1;
15523   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15524   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15525   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15526   u32 action = ~0, w;
15527   ip4_address_t rmt_rloc4, lcl_rloc4;
15528   ip6_address_t rmt_rloc6, lcl_rloc6;
15529   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15530   int ret;
15531
15532   clib_memset (&rloc, 0, sizeof (rloc));
15533
15534   /* Parse args required to build the message */
15535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15536     {
15537       if (unformat (input, "del"))
15538         is_add = 0;
15539       else if (unformat (input, "add"))
15540         is_add = 1;
15541       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15542         {
15543           rmt_eid_set = 1;
15544         }
15545       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15546         {
15547           lcl_eid_set = 1;
15548         }
15549       else if (unformat (input, "vrf %d", &dp_table))
15550         ;
15551       else if (unformat (input, "bd %d", &dp_table))
15552         ;
15553       else if (unformat (input, "vni %d", &vni))
15554         ;
15555       else if (unformat (input, "w %d", &w))
15556         {
15557           if (!curr_rloc)
15558             {
15559               errmsg ("No RLOC configured for setting priority/weight!");
15560               return -99;
15561             }
15562           curr_rloc->weight = w;
15563         }
15564       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15565                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15566         {
15567           rloc.is_ip4 = 1;
15568
15569           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15570           rloc.weight = 0;
15571           vec_add1 (lcl_locs, rloc);
15572
15573           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15574           vec_add1 (rmt_locs, rloc);
15575           /* weight saved in rmt loc */
15576           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15577         }
15578       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15579                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15580         {
15581           rloc.is_ip4 = 0;
15582           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15583           rloc.weight = 0;
15584           vec_add1 (lcl_locs, rloc);
15585
15586           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15587           vec_add1 (rmt_locs, rloc);
15588           /* weight saved in rmt loc */
15589           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15590         }
15591       else if (unformat (input, "action %d", &action))
15592         {
15593           ;
15594         }
15595       else
15596         {
15597           clib_warning ("parse error '%U'", format_unformat_error, input);
15598           return -99;
15599         }
15600     }
15601
15602   if (!rmt_eid_set)
15603     {
15604       errmsg ("remote eid addresses not set");
15605       return -99;
15606     }
15607
15608   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15609     {
15610       errmsg ("eid types don't match");
15611       return -99;
15612     }
15613
15614   if (0 == rmt_locs && (u32) ~ 0 == action)
15615     {
15616       errmsg ("action not set for negative mapping");
15617       return -99;
15618     }
15619
15620   /* Construct the API message */
15621   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15622       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15623
15624   mp->is_add = is_add;
15625   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15626   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15627   mp->eid_type = rmt_eid->type;
15628   mp->dp_table = clib_host_to_net_u32 (dp_table);
15629   mp->vni = clib_host_to_net_u32 (vni);
15630   mp->rmt_len = rmt_eid->len;
15631   mp->lcl_len = lcl_eid->len;
15632   mp->action = action;
15633
15634   if (0 != rmt_locs && 0 != lcl_locs)
15635     {
15636       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15637       clib_memcpy (mp->locs, lcl_locs,
15638                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15639
15640       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15641       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15642                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15643     }
15644   vec_free (lcl_locs);
15645   vec_free (rmt_locs);
15646
15647   /* send it... */
15648   S (mp);
15649
15650   /* Wait for a reply... */
15651   W (ret);
15652   return ret;
15653 }
15654
15655 static int
15656 api_one_add_del_map_server (vat_main_t * vam)
15657 {
15658   unformat_input_t *input = vam->input;
15659   vl_api_one_add_del_map_server_t *mp;
15660   u8 is_add = 1;
15661   u8 ipv4_set = 0;
15662   u8 ipv6_set = 0;
15663   ip4_address_t ipv4;
15664   ip6_address_t ipv6;
15665   int ret;
15666
15667   /* Parse args required to build the message */
15668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15669     {
15670       if (unformat (input, "del"))
15671         {
15672           is_add = 0;
15673         }
15674       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15675         {
15676           ipv4_set = 1;
15677         }
15678       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15679         {
15680           ipv6_set = 1;
15681         }
15682       else
15683         break;
15684     }
15685
15686   if (ipv4_set && ipv6_set)
15687     {
15688       errmsg ("both eid v4 and v6 addresses set");
15689       return -99;
15690     }
15691
15692   if (!ipv4_set && !ipv6_set)
15693     {
15694       errmsg ("eid addresses not set");
15695       return -99;
15696     }
15697
15698   /* Construct the API message */
15699   M (ONE_ADD_DEL_MAP_SERVER, mp);
15700
15701   mp->is_add = is_add;
15702   if (ipv6_set)
15703     {
15704       mp->is_ipv6 = 1;
15705       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15706     }
15707   else
15708     {
15709       mp->is_ipv6 = 0;
15710       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15711     }
15712
15713   /* send it... */
15714   S (mp);
15715
15716   /* Wait for a reply... */
15717   W (ret);
15718   return ret;
15719 }
15720
15721 #define api_lisp_add_del_map_server api_one_add_del_map_server
15722
15723 static int
15724 api_one_add_del_map_resolver (vat_main_t * vam)
15725 {
15726   unformat_input_t *input = vam->input;
15727   vl_api_one_add_del_map_resolver_t *mp;
15728   u8 is_add = 1;
15729   u8 ipv4_set = 0;
15730   u8 ipv6_set = 0;
15731   ip4_address_t ipv4;
15732   ip6_address_t ipv6;
15733   int ret;
15734
15735   /* Parse args required to build the message */
15736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15737     {
15738       if (unformat (input, "del"))
15739         {
15740           is_add = 0;
15741         }
15742       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15743         {
15744           ipv4_set = 1;
15745         }
15746       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15747         {
15748           ipv6_set = 1;
15749         }
15750       else
15751         break;
15752     }
15753
15754   if (ipv4_set && ipv6_set)
15755     {
15756       errmsg ("both eid v4 and v6 addresses set");
15757       return -99;
15758     }
15759
15760   if (!ipv4_set && !ipv6_set)
15761     {
15762       errmsg ("eid addresses not set");
15763       return -99;
15764     }
15765
15766   /* Construct the API message */
15767   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15768
15769   mp->is_add = is_add;
15770   if (ipv6_set)
15771     {
15772       mp->is_ipv6 = 1;
15773       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15774     }
15775   else
15776     {
15777       mp->is_ipv6 = 0;
15778       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15779     }
15780
15781   /* send it... */
15782   S (mp);
15783
15784   /* Wait for a reply... */
15785   W (ret);
15786   return ret;
15787 }
15788
15789 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15790
15791 static int
15792 api_lisp_gpe_enable_disable (vat_main_t * vam)
15793 {
15794   unformat_input_t *input = vam->input;
15795   vl_api_gpe_enable_disable_t *mp;
15796   u8 is_set = 0;
15797   u8 is_en = 1;
15798   int ret;
15799
15800   /* Parse args required to build the message */
15801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15802     {
15803       if (unformat (input, "enable"))
15804         {
15805           is_set = 1;
15806           is_en = 1;
15807         }
15808       else if (unformat (input, "disable"))
15809         {
15810           is_set = 1;
15811           is_en = 0;
15812         }
15813       else
15814         break;
15815     }
15816
15817   if (is_set == 0)
15818     {
15819       errmsg ("Value not set");
15820       return -99;
15821     }
15822
15823   /* Construct the API message */
15824   M (GPE_ENABLE_DISABLE, mp);
15825
15826   mp->is_en = is_en;
15827
15828   /* send it... */
15829   S (mp);
15830
15831   /* Wait for a reply... */
15832   W (ret);
15833   return ret;
15834 }
15835
15836 static int
15837 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15838 {
15839   unformat_input_t *input = vam->input;
15840   vl_api_one_rloc_probe_enable_disable_t *mp;
15841   u8 is_set = 0;
15842   u8 is_en = 0;
15843   int ret;
15844
15845   /* Parse args required to build the message */
15846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15847     {
15848       if (unformat (input, "enable"))
15849         {
15850           is_set = 1;
15851           is_en = 1;
15852         }
15853       else if (unformat (input, "disable"))
15854         is_set = 1;
15855       else
15856         break;
15857     }
15858
15859   if (!is_set)
15860     {
15861       errmsg ("Value not set");
15862       return -99;
15863     }
15864
15865   /* Construct the API message */
15866   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15867
15868   mp->is_enabled = is_en;
15869
15870   /* send it... */
15871   S (mp);
15872
15873   /* Wait for a reply... */
15874   W (ret);
15875   return ret;
15876 }
15877
15878 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15879
15880 static int
15881 api_one_map_register_enable_disable (vat_main_t * vam)
15882 {
15883   unformat_input_t *input = vam->input;
15884   vl_api_one_map_register_enable_disable_t *mp;
15885   u8 is_set = 0;
15886   u8 is_en = 0;
15887   int ret;
15888
15889   /* Parse args required to build the message */
15890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15891     {
15892       if (unformat (input, "enable"))
15893         {
15894           is_set = 1;
15895           is_en = 1;
15896         }
15897       else if (unformat (input, "disable"))
15898         is_set = 1;
15899       else
15900         break;
15901     }
15902
15903   if (!is_set)
15904     {
15905       errmsg ("Value not set");
15906       return -99;
15907     }
15908
15909   /* Construct the API message */
15910   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15911
15912   mp->is_enabled = is_en;
15913
15914   /* send it... */
15915   S (mp);
15916
15917   /* Wait for a reply... */
15918   W (ret);
15919   return ret;
15920 }
15921
15922 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15923
15924 static int
15925 api_one_enable_disable (vat_main_t * vam)
15926 {
15927   unformat_input_t *input = vam->input;
15928   vl_api_one_enable_disable_t *mp;
15929   u8 is_set = 0;
15930   u8 is_en = 0;
15931   int ret;
15932
15933   /* Parse args required to build the message */
15934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15935     {
15936       if (unformat (input, "enable"))
15937         {
15938           is_set = 1;
15939           is_en = 1;
15940         }
15941       else if (unformat (input, "disable"))
15942         {
15943           is_set = 1;
15944         }
15945       else
15946         break;
15947     }
15948
15949   if (!is_set)
15950     {
15951       errmsg ("Value not set");
15952       return -99;
15953     }
15954
15955   /* Construct the API message */
15956   M (ONE_ENABLE_DISABLE, mp);
15957
15958   mp->is_en = is_en;
15959
15960   /* send it... */
15961   S (mp);
15962
15963   /* Wait for a reply... */
15964   W (ret);
15965   return ret;
15966 }
15967
15968 #define api_lisp_enable_disable api_one_enable_disable
15969
15970 static int
15971 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15972 {
15973   unformat_input_t *input = vam->input;
15974   vl_api_one_enable_disable_xtr_mode_t *mp;
15975   u8 is_set = 0;
15976   u8 is_en = 0;
15977   int ret;
15978
15979   /* Parse args required to build the message */
15980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15981     {
15982       if (unformat (input, "enable"))
15983         {
15984           is_set = 1;
15985           is_en = 1;
15986         }
15987       else if (unformat (input, "disable"))
15988         {
15989           is_set = 1;
15990         }
15991       else
15992         break;
15993     }
15994
15995   if (!is_set)
15996     {
15997       errmsg ("Value not set");
15998       return -99;
15999     }
16000
16001   /* Construct the API message */
16002   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16003
16004   mp->is_en = is_en;
16005
16006   /* send it... */
16007   S (mp);
16008
16009   /* Wait for a reply... */
16010   W (ret);
16011   return ret;
16012 }
16013
16014 static int
16015 api_one_show_xtr_mode (vat_main_t * vam)
16016 {
16017   vl_api_one_show_xtr_mode_t *mp;
16018   int ret;
16019
16020   /* Construct the API message */
16021   M (ONE_SHOW_XTR_MODE, mp);
16022
16023   /* send it... */
16024   S (mp);
16025
16026   /* Wait for a reply... */
16027   W (ret);
16028   return ret;
16029 }
16030
16031 static int
16032 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16033 {
16034   unformat_input_t *input = vam->input;
16035   vl_api_one_enable_disable_pitr_mode_t *mp;
16036   u8 is_set = 0;
16037   u8 is_en = 0;
16038   int ret;
16039
16040   /* Parse args required to build the message */
16041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16042     {
16043       if (unformat (input, "enable"))
16044         {
16045           is_set = 1;
16046           is_en = 1;
16047         }
16048       else if (unformat (input, "disable"))
16049         {
16050           is_set = 1;
16051         }
16052       else
16053         break;
16054     }
16055
16056   if (!is_set)
16057     {
16058       errmsg ("Value not set");
16059       return -99;
16060     }
16061
16062   /* Construct the API message */
16063   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16064
16065   mp->is_en = is_en;
16066
16067   /* send it... */
16068   S (mp);
16069
16070   /* Wait for a reply... */
16071   W (ret);
16072   return ret;
16073 }
16074
16075 static int
16076 api_one_show_pitr_mode (vat_main_t * vam)
16077 {
16078   vl_api_one_show_pitr_mode_t *mp;
16079   int ret;
16080
16081   /* Construct the API message */
16082   M (ONE_SHOW_PITR_MODE, mp);
16083
16084   /* send it... */
16085   S (mp);
16086
16087   /* Wait for a reply... */
16088   W (ret);
16089   return ret;
16090 }
16091
16092 static int
16093 api_one_enable_disable_petr_mode (vat_main_t * vam)
16094 {
16095   unformat_input_t *input = vam->input;
16096   vl_api_one_enable_disable_petr_mode_t *mp;
16097   u8 is_set = 0;
16098   u8 is_en = 0;
16099   int ret;
16100
16101   /* Parse args required to build the message */
16102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16103     {
16104       if (unformat (input, "enable"))
16105         {
16106           is_set = 1;
16107           is_en = 1;
16108         }
16109       else if (unformat (input, "disable"))
16110         {
16111           is_set = 1;
16112         }
16113       else
16114         break;
16115     }
16116
16117   if (!is_set)
16118     {
16119       errmsg ("Value not set");
16120       return -99;
16121     }
16122
16123   /* Construct the API message */
16124   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16125
16126   mp->is_en = is_en;
16127
16128   /* send it... */
16129   S (mp);
16130
16131   /* Wait for a reply... */
16132   W (ret);
16133   return ret;
16134 }
16135
16136 static int
16137 api_one_show_petr_mode (vat_main_t * vam)
16138 {
16139   vl_api_one_show_petr_mode_t *mp;
16140   int ret;
16141
16142   /* Construct the API message */
16143   M (ONE_SHOW_PETR_MODE, mp);
16144
16145   /* send it... */
16146   S (mp);
16147
16148   /* Wait for a reply... */
16149   W (ret);
16150   return ret;
16151 }
16152
16153 static int
16154 api_show_one_map_register_state (vat_main_t * vam)
16155 {
16156   vl_api_show_one_map_register_state_t *mp;
16157   int ret;
16158
16159   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16160
16161   /* send */
16162   S (mp);
16163
16164   /* wait for reply */
16165   W (ret);
16166   return ret;
16167 }
16168
16169 #define api_show_lisp_map_register_state api_show_one_map_register_state
16170
16171 static int
16172 api_show_one_rloc_probe_state (vat_main_t * vam)
16173 {
16174   vl_api_show_one_rloc_probe_state_t *mp;
16175   int ret;
16176
16177   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16178
16179   /* send */
16180   S (mp);
16181
16182   /* wait for reply */
16183   W (ret);
16184   return ret;
16185 }
16186
16187 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16188
16189 static int
16190 api_one_add_del_ndp_entry (vat_main_t * vam)
16191 {
16192   vl_api_one_add_del_ndp_entry_t *mp;
16193   unformat_input_t *input = vam->input;
16194   u8 is_add = 1;
16195   u8 mac_set = 0;
16196   u8 bd_set = 0;
16197   u8 ip_set = 0;
16198   u8 mac[6] = { 0, };
16199   u8 ip6[16] = { 0, };
16200   u32 bd = ~0;
16201   int ret;
16202
16203   /* Parse args required to build the message */
16204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16205     {
16206       if (unformat (input, "del"))
16207         is_add = 0;
16208       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16209         mac_set = 1;
16210       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16211         ip_set = 1;
16212       else if (unformat (input, "bd %d", &bd))
16213         bd_set = 1;
16214       else
16215         {
16216           errmsg ("parse error '%U'", format_unformat_error, input);
16217           return -99;
16218         }
16219     }
16220
16221   if (!bd_set || !ip_set || (!mac_set && is_add))
16222     {
16223       errmsg ("Missing BD, IP or MAC!");
16224       return -99;
16225     }
16226
16227   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16228   mp->is_add = is_add;
16229   clib_memcpy (mp->mac, mac, 6);
16230   mp->bd = clib_host_to_net_u32 (bd);
16231   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16232
16233   /* send */
16234   S (mp);
16235
16236   /* wait for reply */
16237   W (ret);
16238   return ret;
16239 }
16240
16241 static int
16242 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16243 {
16244   vl_api_one_add_del_l2_arp_entry_t *mp;
16245   unformat_input_t *input = vam->input;
16246   u8 is_add = 1;
16247   u8 mac_set = 0;
16248   u8 bd_set = 0;
16249   u8 ip_set = 0;
16250   u8 mac[6] = { 0, };
16251   u32 ip4 = 0, bd = ~0;
16252   int ret;
16253
16254   /* Parse args required to build the message */
16255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16256     {
16257       if (unformat (input, "del"))
16258         is_add = 0;
16259       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16260         mac_set = 1;
16261       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16262         ip_set = 1;
16263       else if (unformat (input, "bd %d", &bd))
16264         bd_set = 1;
16265       else
16266         {
16267           errmsg ("parse error '%U'", format_unformat_error, input);
16268           return -99;
16269         }
16270     }
16271
16272   if (!bd_set || !ip_set || (!mac_set && is_add))
16273     {
16274       errmsg ("Missing BD, IP or MAC!");
16275       return -99;
16276     }
16277
16278   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16279   mp->is_add = is_add;
16280   clib_memcpy (mp->mac, mac, 6);
16281   mp->bd = clib_host_to_net_u32 (bd);
16282   mp->ip4 = ip4;
16283
16284   /* send */
16285   S (mp);
16286
16287   /* wait for reply */
16288   W (ret);
16289   return ret;
16290 }
16291
16292 static int
16293 api_one_ndp_bd_get (vat_main_t * vam)
16294 {
16295   vl_api_one_ndp_bd_get_t *mp;
16296   int ret;
16297
16298   M (ONE_NDP_BD_GET, mp);
16299
16300   /* send */
16301   S (mp);
16302
16303   /* wait for reply */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 static int
16309 api_one_ndp_entries_get (vat_main_t * vam)
16310 {
16311   vl_api_one_ndp_entries_get_t *mp;
16312   unformat_input_t *input = vam->input;
16313   u8 bd_set = 0;
16314   u32 bd = ~0;
16315   int ret;
16316
16317   /* Parse args required to build the message */
16318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16319     {
16320       if (unformat (input, "bd %d", &bd))
16321         bd_set = 1;
16322       else
16323         {
16324           errmsg ("parse error '%U'", format_unformat_error, input);
16325           return -99;
16326         }
16327     }
16328
16329   if (!bd_set)
16330     {
16331       errmsg ("Expected bridge domain!");
16332       return -99;
16333     }
16334
16335   M (ONE_NDP_ENTRIES_GET, mp);
16336   mp->bd = clib_host_to_net_u32 (bd);
16337
16338   /* send */
16339   S (mp);
16340
16341   /* wait for reply */
16342   W (ret);
16343   return ret;
16344 }
16345
16346 static int
16347 api_one_l2_arp_bd_get (vat_main_t * vam)
16348 {
16349   vl_api_one_l2_arp_bd_get_t *mp;
16350   int ret;
16351
16352   M (ONE_L2_ARP_BD_GET, mp);
16353
16354   /* send */
16355   S (mp);
16356
16357   /* wait for reply */
16358   W (ret);
16359   return ret;
16360 }
16361
16362 static int
16363 api_one_l2_arp_entries_get (vat_main_t * vam)
16364 {
16365   vl_api_one_l2_arp_entries_get_t *mp;
16366   unformat_input_t *input = vam->input;
16367   u8 bd_set = 0;
16368   u32 bd = ~0;
16369   int ret;
16370
16371   /* Parse args required to build the message */
16372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (input, "bd %d", &bd))
16375         bd_set = 1;
16376       else
16377         {
16378           errmsg ("parse error '%U'", format_unformat_error, input);
16379           return -99;
16380         }
16381     }
16382
16383   if (!bd_set)
16384     {
16385       errmsg ("Expected bridge domain!");
16386       return -99;
16387     }
16388
16389   M (ONE_L2_ARP_ENTRIES_GET, mp);
16390   mp->bd = clib_host_to_net_u32 (bd);
16391
16392   /* send */
16393   S (mp);
16394
16395   /* wait for reply */
16396   W (ret);
16397   return ret;
16398 }
16399
16400 static int
16401 api_one_stats_enable_disable (vat_main_t * vam)
16402 {
16403   vl_api_one_stats_enable_disable_t *mp;
16404   unformat_input_t *input = vam->input;
16405   u8 is_set = 0;
16406   u8 is_en = 0;
16407   int ret;
16408
16409   /* Parse args required to build the message */
16410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16411     {
16412       if (unformat (input, "enable"))
16413         {
16414           is_set = 1;
16415           is_en = 1;
16416         }
16417       else if (unformat (input, "disable"))
16418         {
16419           is_set = 1;
16420         }
16421       else
16422         break;
16423     }
16424
16425   if (!is_set)
16426     {
16427       errmsg ("Value not set");
16428       return -99;
16429     }
16430
16431   M (ONE_STATS_ENABLE_DISABLE, mp);
16432   mp->is_en = is_en;
16433
16434   /* send */
16435   S (mp);
16436
16437   /* wait for reply */
16438   W (ret);
16439   return ret;
16440 }
16441
16442 static int
16443 api_show_one_stats_enable_disable (vat_main_t * vam)
16444 {
16445   vl_api_show_one_stats_enable_disable_t *mp;
16446   int ret;
16447
16448   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16449
16450   /* send */
16451   S (mp);
16452
16453   /* wait for reply */
16454   W (ret);
16455   return ret;
16456 }
16457
16458 static int
16459 api_show_one_map_request_mode (vat_main_t * vam)
16460 {
16461   vl_api_show_one_map_request_mode_t *mp;
16462   int ret;
16463
16464   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16465
16466   /* send */
16467   S (mp);
16468
16469   /* wait for reply */
16470   W (ret);
16471   return ret;
16472 }
16473
16474 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16475
16476 static int
16477 api_one_map_request_mode (vat_main_t * vam)
16478 {
16479   unformat_input_t *input = vam->input;
16480   vl_api_one_map_request_mode_t *mp;
16481   u8 mode = 0;
16482   int ret;
16483
16484   /* Parse args required to build the message */
16485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16486     {
16487       if (unformat (input, "dst-only"))
16488         mode = 0;
16489       else if (unformat (input, "src-dst"))
16490         mode = 1;
16491       else
16492         {
16493           errmsg ("parse error '%U'", format_unformat_error, input);
16494           return -99;
16495         }
16496     }
16497
16498   M (ONE_MAP_REQUEST_MODE, mp);
16499
16500   mp->mode = mode;
16501
16502   /* send */
16503   S (mp);
16504
16505   /* wait for reply */
16506   W (ret);
16507   return ret;
16508 }
16509
16510 #define api_lisp_map_request_mode api_one_map_request_mode
16511
16512 /**
16513  * Enable/disable ONE proxy ITR.
16514  *
16515  * @param vam vpp API test context
16516  * @return return code
16517  */
16518 static int
16519 api_one_pitr_set_locator_set (vat_main_t * vam)
16520 {
16521   u8 ls_name_set = 0;
16522   unformat_input_t *input = vam->input;
16523   vl_api_one_pitr_set_locator_set_t *mp;
16524   u8 is_add = 1;
16525   u8 *ls_name = 0;
16526   int ret;
16527
16528   /* Parse args required to build the message */
16529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16530     {
16531       if (unformat (input, "del"))
16532         is_add = 0;
16533       else if (unformat (input, "locator-set %s", &ls_name))
16534         ls_name_set = 1;
16535       else
16536         {
16537           errmsg ("parse error '%U'", format_unformat_error, input);
16538           return -99;
16539         }
16540     }
16541
16542   if (!ls_name_set)
16543     {
16544       errmsg ("locator-set name not set!");
16545       return -99;
16546     }
16547
16548   M (ONE_PITR_SET_LOCATOR_SET, mp);
16549
16550   mp->is_add = is_add;
16551   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16552   vec_free (ls_name);
16553
16554   /* send */
16555   S (mp);
16556
16557   /* wait for reply */
16558   W (ret);
16559   return ret;
16560 }
16561
16562 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16563
16564 static int
16565 api_one_nsh_set_locator_set (vat_main_t * vam)
16566 {
16567   u8 ls_name_set = 0;
16568   unformat_input_t *input = vam->input;
16569   vl_api_one_nsh_set_locator_set_t *mp;
16570   u8 is_add = 1;
16571   u8 *ls_name = 0;
16572   int ret;
16573
16574   /* Parse args required to build the message */
16575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16576     {
16577       if (unformat (input, "del"))
16578         is_add = 0;
16579       else if (unformat (input, "ls %s", &ls_name))
16580         ls_name_set = 1;
16581       else
16582         {
16583           errmsg ("parse error '%U'", format_unformat_error, input);
16584           return -99;
16585         }
16586     }
16587
16588   if (!ls_name_set && is_add)
16589     {
16590       errmsg ("locator-set name not set!");
16591       return -99;
16592     }
16593
16594   M (ONE_NSH_SET_LOCATOR_SET, mp);
16595
16596   mp->is_add = is_add;
16597   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16598   vec_free (ls_name);
16599
16600   /* send */
16601   S (mp);
16602
16603   /* wait for reply */
16604   W (ret);
16605   return ret;
16606 }
16607
16608 static int
16609 api_show_one_pitr (vat_main_t * vam)
16610 {
16611   vl_api_show_one_pitr_t *mp;
16612   int ret;
16613
16614   if (!vam->json_output)
16615     {
16616       print (vam->ofp, "%=20s", "lisp status:");
16617     }
16618
16619   M (SHOW_ONE_PITR, mp);
16620   /* send it... */
16621   S (mp);
16622
16623   /* Wait for a reply... */
16624   W (ret);
16625   return ret;
16626 }
16627
16628 #define api_show_lisp_pitr api_show_one_pitr
16629
16630 static int
16631 api_one_use_petr (vat_main_t * vam)
16632 {
16633   unformat_input_t *input = vam->input;
16634   vl_api_one_use_petr_t *mp;
16635   u8 is_add = 0;
16636   ip_address_t ip;
16637   int ret;
16638
16639   clib_memset (&ip, 0, sizeof (ip));
16640
16641   /* Parse args required to build the message */
16642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16643     {
16644       if (unformat (input, "disable"))
16645         is_add = 0;
16646       else
16647         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16648         {
16649           is_add = 1;
16650           ip_addr_version (&ip) = IP4;
16651         }
16652       else
16653         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16654         {
16655           is_add = 1;
16656           ip_addr_version (&ip) = IP6;
16657         }
16658       else
16659         {
16660           errmsg ("parse error '%U'", format_unformat_error, input);
16661           return -99;
16662         }
16663     }
16664
16665   M (ONE_USE_PETR, mp);
16666
16667   mp->is_add = is_add;
16668   if (is_add)
16669     {
16670       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16671       if (mp->is_ip4)
16672         clib_memcpy (mp->address, &ip, 4);
16673       else
16674         clib_memcpy (mp->address, &ip, 16);
16675     }
16676
16677   /* send */
16678   S (mp);
16679
16680   /* wait for reply */
16681   W (ret);
16682   return ret;
16683 }
16684
16685 #define api_lisp_use_petr api_one_use_petr
16686
16687 static int
16688 api_show_one_nsh_mapping (vat_main_t * vam)
16689 {
16690   vl_api_show_one_use_petr_t *mp;
16691   int ret;
16692
16693   if (!vam->json_output)
16694     {
16695       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16696     }
16697
16698   M (SHOW_ONE_NSH_MAPPING, mp);
16699   /* send it... */
16700   S (mp);
16701
16702   /* Wait for a reply... */
16703   W (ret);
16704   return ret;
16705 }
16706
16707 static int
16708 api_show_one_use_petr (vat_main_t * vam)
16709 {
16710   vl_api_show_one_use_petr_t *mp;
16711   int ret;
16712
16713   if (!vam->json_output)
16714     {
16715       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16716     }
16717
16718   M (SHOW_ONE_USE_PETR, mp);
16719   /* send it... */
16720   S (mp);
16721
16722   /* Wait for a reply... */
16723   W (ret);
16724   return ret;
16725 }
16726
16727 #define api_show_lisp_use_petr api_show_one_use_petr
16728
16729 /**
16730  * Add/delete mapping between vni and vrf
16731  */
16732 static int
16733 api_one_eid_table_add_del_map (vat_main_t * vam)
16734 {
16735   unformat_input_t *input = vam->input;
16736   vl_api_one_eid_table_add_del_map_t *mp;
16737   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16738   u32 vni, vrf, bd_index;
16739   int ret;
16740
16741   /* Parse args required to build the message */
16742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16743     {
16744       if (unformat (input, "del"))
16745         is_add = 0;
16746       else if (unformat (input, "vrf %d", &vrf))
16747         vrf_set = 1;
16748       else if (unformat (input, "bd_index %d", &bd_index))
16749         bd_index_set = 1;
16750       else if (unformat (input, "vni %d", &vni))
16751         vni_set = 1;
16752       else
16753         break;
16754     }
16755
16756   if (!vni_set || (!vrf_set && !bd_index_set))
16757     {
16758       errmsg ("missing arguments!");
16759       return -99;
16760     }
16761
16762   if (vrf_set && bd_index_set)
16763     {
16764       errmsg ("error: both vrf and bd entered!");
16765       return -99;
16766     }
16767
16768   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16769
16770   mp->is_add = is_add;
16771   mp->vni = htonl (vni);
16772   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16773   mp->is_l2 = bd_index_set;
16774
16775   /* send */
16776   S (mp);
16777
16778   /* wait for reply */
16779   W (ret);
16780   return ret;
16781 }
16782
16783 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16784
16785 uword
16786 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16787 {
16788   u32 *action = va_arg (*args, u32 *);
16789   u8 *s = 0;
16790
16791   if (unformat (input, "%s", &s))
16792     {
16793       if (!strcmp ((char *) s, "no-action"))
16794         action[0] = 0;
16795       else if (!strcmp ((char *) s, "natively-forward"))
16796         action[0] = 1;
16797       else if (!strcmp ((char *) s, "send-map-request"))
16798         action[0] = 2;
16799       else if (!strcmp ((char *) s, "drop"))
16800         action[0] = 3;
16801       else
16802         {
16803           clib_warning ("invalid action: '%s'", s);
16804           action[0] = 3;
16805         }
16806     }
16807   else
16808     return 0;
16809
16810   vec_free (s);
16811   return 1;
16812 }
16813
16814 /**
16815  * Add/del remote mapping to/from ONE control plane
16816  *
16817  * @param vam vpp API test context
16818  * @return return code
16819  */
16820 static int
16821 api_one_add_del_remote_mapping (vat_main_t * vam)
16822 {
16823   unformat_input_t *input = vam->input;
16824   vl_api_one_add_del_remote_mapping_t *mp;
16825   u32 vni = 0;
16826   lisp_eid_vat_t _eid, *eid = &_eid;
16827   lisp_eid_vat_t _seid, *seid = &_seid;
16828   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16829   u32 action = ~0, p, w, data_len;
16830   ip4_address_t rloc4;
16831   ip6_address_t rloc6;
16832   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16833   int ret;
16834
16835   clib_memset (&rloc, 0, sizeof (rloc));
16836
16837   /* Parse args required to build the message */
16838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16839     {
16840       if (unformat (input, "del-all"))
16841         {
16842           del_all = 1;
16843         }
16844       else if (unformat (input, "del"))
16845         {
16846           is_add = 0;
16847         }
16848       else if (unformat (input, "add"))
16849         {
16850           is_add = 1;
16851         }
16852       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16853         {
16854           eid_set = 1;
16855         }
16856       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16857         {
16858           seid_set = 1;
16859         }
16860       else if (unformat (input, "vni %d", &vni))
16861         {
16862           ;
16863         }
16864       else if (unformat (input, "p %d w %d", &p, &w))
16865         {
16866           if (!curr_rloc)
16867             {
16868               errmsg ("No RLOC configured for setting priority/weight!");
16869               return -99;
16870             }
16871           curr_rloc->priority = p;
16872           curr_rloc->weight = w;
16873         }
16874       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16875         {
16876           rloc.is_ip4 = 1;
16877           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16878           vec_add1 (rlocs, rloc);
16879           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16880         }
16881       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16882         {
16883           rloc.is_ip4 = 0;
16884           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16885           vec_add1 (rlocs, rloc);
16886           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16887         }
16888       else if (unformat (input, "action %U",
16889                          unformat_negative_mapping_action, &action))
16890         {
16891           ;
16892         }
16893       else
16894         {
16895           clib_warning ("parse error '%U'", format_unformat_error, input);
16896           return -99;
16897         }
16898     }
16899
16900   if (0 == eid_set)
16901     {
16902       errmsg ("missing params!");
16903       return -99;
16904     }
16905
16906   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16907     {
16908       errmsg ("no action set for negative map-reply!");
16909       return -99;
16910     }
16911
16912   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16913
16914   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16915   mp->is_add = is_add;
16916   mp->vni = htonl (vni);
16917   mp->action = (u8) action;
16918   mp->is_src_dst = seid_set;
16919   mp->eid_len = eid->len;
16920   mp->seid_len = seid->len;
16921   mp->del_all = del_all;
16922   mp->eid_type = eid->type;
16923   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16924   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16925
16926   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16927   clib_memcpy (mp->rlocs, rlocs, data_len);
16928   vec_free (rlocs);
16929
16930   /* send it... */
16931   S (mp);
16932
16933   /* Wait for a reply... */
16934   W (ret);
16935   return ret;
16936 }
16937
16938 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16939
16940 /**
16941  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16942  * forwarding entries in data-plane accordingly.
16943  *
16944  * @param vam vpp API test context
16945  * @return return code
16946  */
16947 static int
16948 api_one_add_del_adjacency (vat_main_t * vam)
16949 {
16950   unformat_input_t *input = vam->input;
16951   vl_api_one_add_del_adjacency_t *mp;
16952   u32 vni = 0;
16953   ip4_address_t leid4, reid4;
16954   ip6_address_t leid6, reid6;
16955   u8 reid_mac[6] = { 0 };
16956   u8 leid_mac[6] = { 0 };
16957   u8 reid_type, leid_type;
16958   u32 leid_len = 0, reid_len = 0, len;
16959   u8 is_add = 1;
16960   int ret;
16961
16962   leid_type = reid_type = (u8) ~ 0;
16963
16964   /* Parse args required to build the message */
16965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16966     {
16967       if (unformat (input, "del"))
16968         {
16969           is_add = 0;
16970         }
16971       else if (unformat (input, "add"))
16972         {
16973           is_add = 1;
16974         }
16975       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16976                          &reid4, &len))
16977         {
16978           reid_type = 0;        /* ipv4 */
16979           reid_len = len;
16980         }
16981       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16982                          &reid6, &len))
16983         {
16984           reid_type = 1;        /* ipv6 */
16985           reid_len = len;
16986         }
16987       else if (unformat (input, "reid %U", unformat_ethernet_address,
16988                          reid_mac))
16989         {
16990           reid_type = 2;        /* mac */
16991         }
16992       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16993                          &leid4, &len))
16994         {
16995           leid_type = 0;        /* ipv4 */
16996           leid_len = len;
16997         }
16998       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16999                          &leid6, &len))
17000         {
17001           leid_type = 1;        /* ipv6 */
17002           leid_len = len;
17003         }
17004       else if (unformat (input, "leid %U", unformat_ethernet_address,
17005                          leid_mac))
17006         {
17007           leid_type = 2;        /* mac */
17008         }
17009       else if (unformat (input, "vni %d", &vni))
17010         {
17011           ;
17012         }
17013       else
17014         {
17015           errmsg ("parse error '%U'", format_unformat_error, input);
17016           return -99;
17017         }
17018     }
17019
17020   if ((u8) ~ 0 == reid_type)
17021     {
17022       errmsg ("missing params!");
17023       return -99;
17024     }
17025
17026   if (leid_type != reid_type)
17027     {
17028       errmsg ("remote and local EIDs are of different types!");
17029       return -99;
17030     }
17031
17032   M (ONE_ADD_DEL_ADJACENCY, mp);
17033   mp->is_add = is_add;
17034   mp->vni = htonl (vni);
17035   mp->leid_len = leid_len;
17036   mp->reid_len = reid_len;
17037   mp->eid_type = reid_type;
17038
17039   switch (mp->eid_type)
17040     {
17041     case 0:
17042       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17043       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17044       break;
17045     case 1:
17046       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17047       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17048       break;
17049     case 2:
17050       clib_memcpy (mp->leid, leid_mac, 6);
17051       clib_memcpy (mp->reid, reid_mac, 6);
17052       break;
17053     default:
17054       errmsg ("unknown EID type %d!", mp->eid_type);
17055       return 0;
17056     }
17057
17058   /* send it... */
17059   S (mp);
17060
17061   /* Wait for a reply... */
17062   W (ret);
17063   return ret;
17064 }
17065
17066 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17067
17068 uword
17069 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17070 {
17071   u32 *mode = va_arg (*args, u32 *);
17072
17073   if (unformat (input, "lisp"))
17074     *mode = 0;
17075   else if (unformat (input, "vxlan"))
17076     *mode = 1;
17077   else
17078     return 0;
17079
17080   return 1;
17081 }
17082
17083 static int
17084 api_gpe_get_encap_mode (vat_main_t * vam)
17085 {
17086   vl_api_gpe_get_encap_mode_t *mp;
17087   int ret;
17088
17089   /* Construct the API message */
17090   M (GPE_GET_ENCAP_MODE, mp);
17091
17092   /* send it... */
17093   S (mp);
17094
17095   /* Wait for a reply... */
17096   W (ret);
17097   return ret;
17098 }
17099
17100 static int
17101 api_gpe_set_encap_mode (vat_main_t * vam)
17102 {
17103   unformat_input_t *input = vam->input;
17104   vl_api_gpe_set_encap_mode_t *mp;
17105   int ret;
17106   u32 mode = 0;
17107
17108   /* Parse args required to build the message */
17109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17110     {
17111       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17112         ;
17113       else
17114         break;
17115     }
17116
17117   /* Construct the API message */
17118   M (GPE_SET_ENCAP_MODE, mp);
17119
17120   mp->mode = mode;
17121
17122   /* send it... */
17123   S (mp);
17124
17125   /* Wait for a reply... */
17126   W (ret);
17127   return ret;
17128 }
17129
17130 static int
17131 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17132 {
17133   unformat_input_t *input = vam->input;
17134   vl_api_gpe_add_del_iface_t *mp;
17135   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17136   u32 dp_table = 0, vni = 0;
17137   int ret;
17138
17139   /* Parse args required to build the message */
17140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17141     {
17142       if (unformat (input, "up"))
17143         {
17144           action_set = 1;
17145           is_add = 1;
17146         }
17147       else if (unformat (input, "down"))
17148         {
17149           action_set = 1;
17150           is_add = 0;
17151         }
17152       else if (unformat (input, "table_id %d", &dp_table))
17153         {
17154           dp_table_set = 1;
17155         }
17156       else if (unformat (input, "bd_id %d", &dp_table))
17157         {
17158           dp_table_set = 1;
17159           is_l2 = 1;
17160         }
17161       else if (unformat (input, "vni %d", &vni))
17162         {
17163           vni_set = 1;
17164         }
17165       else
17166         break;
17167     }
17168
17169   if (action_set == 0)
17170     {
17171       errmsg ("Action not set");
17172       return -99;
17173     }
17174   if (dp_table_set == 0 || vni_set == 0)
17175     {
17176       errmsg ("vni and dp_table must be set");
17177       return -99;
17178     }
17179
17180   /* Construct the API message */
17181   M (GPE_ADD_DEL_IFACE, mp);
17182
17183   mp->is_add = is_add;
17184   mp->dp_table = clib_host_to_net_u32 (dp_table);
17185   mp->is_l2 = is_l2;
17186   mp->vni = clib_host_to_net_u32 (vni);
17187
17188   /* send it... */
17189   S (mp);
17190
17191   /* Wait for a reply... */
17192   W (ret);
17193   return ret;
17194 }
17195
17196 static int
17197 api_one_map_register_fallback_threshold (vat_main_t * vam)
17198 {
17199   unformat_input_t *input = vam->input;
17200   vl_api_one_map_register_fallback_threshold_t *mp;
17201   u32 value = 0;
17202   u8 is_set = 0;
17203   int ret;
17204
17205   /* Parse args required to build the message */
17206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17207     {
17208       if (unformat (input, "%u", &value))
17209         is_set = 1;
17210       else
17211         {
17212           clib_warning ("parse error '%U'", format_unformat_error, input);
17213           return -99;
17214         }
17215     }
17216
17217   if (!is_set)
17218     {
17219       errmsg ("fallback threshold value is missing!");
17220       return -99;
17221     }
17222
17223   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17224   mp->value = clib_host_to_net_u32 (value);
17225
17226   /* send it... */
17227   S (mp);
17228
17229   /* Wait for a reply... */
17230   W (ret);
17231   return ret;
17232 }
17233
17234 static int
17235 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17236 {
17237   vl_api_show_one_map_register_fallback_threshold_t *mp;
17238   int ret;
17239
17240   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17241
17242   /* send it... */
17243   S (mp);
17244
17245   /* Wait for a reply... */
17246   W (ret);
17247   return ret;
17248 }
17249
17250 uword
17251 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17252 {
17253   u32 *proto = va_arg (*args, u32 *);
17254
17255   if (unformat (input, "udp"))
17256     *proto = 1;
17257   else if (unformat (input, "api"))
17258     *proto = 2;
17259   else
17260     return 0;
17261
17262   return 1;
17263 }
17264
17265 static int
17266 api_one_set_transport_protocol (vat_main_t * vam)
17267 {
17268   unformat_input_t *input = vam->input;
17269   vl_api_one_set_transport_protocol_t *mp;
17270   u8 is_set = 0;
17271   u32 protocol = 0;
17272   int ret;
17273
17274   /* Parse args required to build the message */
17275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17276     {
17277       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17278         is_set = 1;
17279       else
17280         {
17281           clib_warning ("parse error '%U'", format_unformat_error, input);
17282           return -99;
17283         }
17284     }
17285
17286   if (!is_set)
17287     {
17288       errmsg ("Transport protocol missing!");
17289       return -99;
17290     }
17291
17292   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17293   mp->protocol = (u8) protocol;
17294
17295   /* send it... */
17296   S (mp);
17297
17298   /* Wait for a reply... */
17299   W (ret);
17300   return ret;
17301 }
17302
17303 static int
17304 api_one_get_transport_protocol (vat_main_t * vam)
17305 {
17306   vl_api_one_get_transport_protocol_t *mp;
17307   int ret;
17308
17309   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17310
17311   /* send it... */
17312   S (mp);
17313
17314   /* Wait for a reply... */
17315   W (ret);
17316   return ret;
17317 }
17318
17319 static int
17320 api_one_map_register_set_ttl (vat_main_t * vam)
17321 {
17322   unformat_input_t *input = vam->input;
17323   vl_api_one_map_register_set_ttl_t *mp;
17324   u32 ttl = 0;
17325   u8 is_set = 0;
17326   int ret;
17327
17328   /* Parse args required to build the message */
17329   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17330     {
17331       if (unformat (input, "%u", &ttl))
17332         is_set = 1;
17333       else
17334         {
17335           clib_warning ("parse error '%U'", format_unformat_error, input);
17336           return -99;
17337         }
17338     }
17339
17340   if (!is_set)
17341     {
17342       errmsg ("TTL value missing!");
17343       return -99;
17344     }
17345
17346   M (ONE_MAP_REGISTER_SET_TTL, mp);
17347   mp->ttl = clib_host_to_net_u32 (ttl);
17348
17349   /* send it... */
17350   S (mp);
17351
17352   /* Wait for a reply... */
17353   W (ret);
17354   return ret;
17355 }
17356
17357 static int
17358 api_show_one_map_register_ttl (vat_main_t * vam)
17359 {
17360   vl_api_show_one_map_register_ttl_t *mp;
17361   int ret;
17362
17363   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17364
17365   /* send it... */
17366   S (mp);
17367
17368   /* Wait for a reply... */
17369   W (ret);
17370   return ret;
17371 }
17372
17373 /**
17374  * Add/del map request itr rlocs from ONE control plane and updates
17375  *
17376  * @param vam vpp API test context
17377  * @return return code
17378  */
17379 static int
17380 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17381 {
17382   unformat_input_t *input = vam->input;
17383   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17384   u8 *locator_set_name = 0;
17385   u8 locator_set_name_set = 0;
17386   u8 is_add = 1;
17387   int ret;
17388
17389   /* Parse args required to build the message */
17390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17391     {
17392       if (unformat (input, "del"))
17393         {
17394           is_add = 0;
17395         }
17396       else if (unformat (input, "%_%v%_", &locator_set_name))
17397         {
17398           locator_set_name_set = 1;
17399         }
17400       else
17401         {
17402           clib_warning ("parse error '%U'", format_unformat_error, input);
17403           return -99;
17404         }
17405     }
17406
17407   if (is_add && !locator_set_name_set)
17408     {
17409       errmsg ("itr-rloc is not set!");
17410       return -99;
17411     }
17412
17413   if (is_add && vec_len (locator_set_name) > 64)
17414     {
17415       errmsg ("itr-rloc locator-set name too long");
17416       vec_free (locator_set_name);
17417       return -99;
17418     }
17419
17420   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17421   mp->is_add = is_add;
17422   if (is_add)
17423     {
17424       clib_memcpy (mp->locator_set_name, locator_set_name,
17425                    vec_len (locator_set_name));
17426     }
17427   else
17428     {
17429       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17430     }
17431   vec_free (locator_set_name);
17432
17433   /* send it... */
17434   S (mp);
17435
17436   /* Wait for a reply... */
17437   W (ret);
17438   return ret;
17439 }
17440
17441 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17442
17443 static int
17444 api_one_locator_dump (vat_main_t * vam)
17445 {
17446   unformat_input_t *input = vam->input;
17447   vl_api_one_locator_dump_t *mp;
17448   vl_api_control_ping_t *mp_ping;
17449   u8 is_index_set = 0, is_name_set = 0;
17450   u8 *ls_name = 0;
17451   u32 ls_index = ~0;
17452   int ret;
17453
17454   /* Parse args required to build the message */
17455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17456     {
17457       if (unformat (input, "ls_name %_%v%_", &ls_name))
17458         {
17459           is_name_set = 1;
17460         }
17461       else if (unformat (input, "ls_index %d", &ls_index))
17462         {
17463           is_index_set = 1;
17464         }
17465       else
17466         {
17467           errmsg ("parse error '%U'", format_unformat_error, input);
17468           return -99;
17469         }
17470     }
17471
17472   if (!is_index_set && !is_name_set)
17473     {
17474       errmsg ("error: expected one of index or name!");
17475       return -99;
17476     }
17477
17478   if (is_index_set && is_name_set)
17479     {
17480       errmsg ("error: only one param expected!");
17481       return -99;
17482     }
17483
17484   if (vec_len (ls_name) > 62)
17485     {
17486       errmsg ("error: locator set name too long!");
17487       return -99;
17488     }
17489
17490   if (!vam->json_output)
17491     {
17492       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17493     }
17494
17495   M (ONE_LOCATOR_DUMP, mp);
17496   mp->is_index_set = is_index_set;
17497
17498   if (is_index_set)
17499     mp->ls_index = clib_host_to_net_u32 (ls_index);
17500   else
17501     {
17502       vec_add1 (ls_name, 0);
17503       strncpy ((char *) mp->ls_name, (char *) ls_name,
17504                sizeof (mp->ls_name) - 1);
17505     }
17506
17507   /* send it... */
17508   S (mp);
17509
17510   /* Use a control ping for synchronization */
17511   MPING (CONTROL_PING, mp_ping);
17512   S (mp_ping);
17513
17514   /* Wait for a reply... */
17515   W (ret);
17516   return ret;
17517 }
17518
17519 #define api_lisp_locator_dump api_one_locator_dump
17520
17521 static int
17522 api_one_locator_set_dump (vat_main_t * vam)
17523 {
17524   vl_api_one_locator_set_dump_t *mp;
17525   vl_api_control_ping_t *mp_ping;
17526   unformat_input_t *input = vam->input;
17527   u8 filter = 0;
17528   int ret;
17529
17530   /* Parse args required to build the message */
17531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17532     {
17533       if (unformat (input, "local"))
17534         {
17535           filter = 1;
17536         }
17537       else if (unformat (input, "remote"))
17538         {
17539           filter = 2;
17540         }
17541       else
17542         {
17543           errmsg ("parse error '%U'", format_unformat_error, input);
17544           return -99;
17545         }
17546     }
17547
17548   if (!vam->json_output)
17549     {
17550       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17551     }
17552
17553   M (ONE_LOCATOR_SET_DUMP, mp);
17554
17555   mp->filter = filter;
17556
17557   /* send it... */
17558   S (mp);
17559
17560   /* Use a control ping for synchronization */
17561   MPING (CONTROL_PING, mp_ping);
17562   S (mp_ping);
17563
17564   /* Wait for a reply... */
17565   W (ret);
17566   return ret;
17567 }
17568
17569 #define api_lisp_locator_set_dump api_one_locator_set_dump
17570
17571 static int
17572 api_one_eid_table_map_dump (vat_main_t * vam)
17573 {
17574   u8 is_l2 = 0;
17575   u8 mode_set = 0;
17576   unformat_input_t *input = vam->input;
17577   vl_api_one_eid_table_map_dump_t *mp;
17578   vl_api_control_ping_t *mp_ping;
17579   int ret;
17580
17581   /* Parse args required to build the message */
17582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17583     {
17584       if (unformat (input, "l2"))
17585         {
17586           is_l2 = 1;
17587           mode_set = 1;
17588         }
17589       else if (unformat (input, "l3"))
17590         {
17591           is_l2 = 0;
17592           mode_set = 1;
17593         }
17594       else
17595         {
17596           errmsg ("parse error '%U'", format_unformat_error, input);
17597           return -99;
17598         }
17599     }
17600
17601   if (!mode_set)
17602     {
17603       errmsg ("expected one of 'l2' or 'l3' parameter!");
17604       return -99;
17605     }
17606
17607   if (!vam->json_output)
17608     {
17609       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17610     }
17611
17612   M (ONE_EID_TABLE_MAP_DUMP, mp);
17613   mp->is_l2 = is_l2;
17614
17615   /* send it... */
17616   S (mp);
17617
17618   /* Use a control ping for synchronization */
17619   MPING (CONTROL_PING, mp_ping);
17620   S (mp_ping);
17621
17622   /* Wait for a reply... */
17623   W (ret);
17624   return ret;
17625 }
17626
17627 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17628
17629 static int
17630 api_one_eid_table_vni_dump (vat_main_t * vam)
17631 {
17632   vl_api_one_eid_table_vni_dump_t *mp;
17633   vl_api_control_ping_t *mp_ping;
17634   int ret;
17635
17636   if (!vam->json_output)
17637     {
17638       print (vam->ofp, "VNI");
17639     }
17640
17641   M (ONE_EID_TABLE_VNI_DUMP, mp);
17642
17643   /* send it... */
17644   S (mp);
17645
17646   /* Use a control ping for synchronization */
17647   MPING (CONTROL_PING, mp_ping);
17648   S (mp_ping);
17649
17650   /* Wait for a reply... */
17651   W (ret);
17652   return ret;
17653 }
17654
17655 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17656
17657 static int
17658 api_one_eid_table_dump (vat_main_t * vam)
17659 {
17660   unformat_input_t *i = vam->input;
17661   vl_api_one_eid_table_dump_t *mp;
17662   vl_api_control_ping_t *mp_ping;
17663   struct in_addr ip4;
17664   struct in6_addr ip6;
17665   u8 mac[6];
17666   u8 eid_type = ~0, eid_set = 0;
17667   u32 prefix_length = ~0, t, vni = 0;
17668   u8 filter = 0;
17669   int ret;
17670   lisp_nsh_api_t nsh;
17671
17672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17673     {
17674       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17675         {
17676           eid_set = 1;
17677           eid_type = 0;
17678           prefix_length = t;
17679         }
17680       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17681         {
17682           eid_set = 1;
17683           eid_type = 1;
17684           prefix_length = t;
17685         }
17686       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17687         {
17688           eid_set = 1;
17689           eid_type = 2;
17690         }
17691       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17692         {
17693           eid_set = 1;
17694           eid_type = 3;
17695         }
17696       else if (unformat (i, "vni %d", &t))
17697         {
17698           vni = t;
17699         }
17700       else if (unformat (i, "local"))
17701         {
17702           filter = 1;
17703         }
17704       else if (unformat (i, "remote"))
17705         {
17706           filter = 2;
17707         }
17708       else
17709         {
17710           errmsg ("parse error '%U'", format_unformat_error, i);
17711           return -99;
17712         }
17713     }
17714
17715   if (!vam->json_output)
17716     {
17717       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17718              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17719     }
17720
17721   M (ONE_EID_TABLE_DUMP, mp);
17722
17723   mp->filter = filter;
17724   if (eid_set)
17725     {
17726       mp->eid_set = 1;
17727       mp->vni = htonl (vni);
17728       mp->eid_type = eid_type;
17729       switch (eid_type)
17730         {
17731         case 0:
17732           mp->prefix_length = prefix_length;
17733           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17734           break;
17735         case 1:
17736           mp->prefix_length = prefix_length;
17737           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17738           break;
17739         case 2:
17740           clib_memcpy (mp->eid, mac, sizeof (mac));
17741           break;
17742         case 3:
17743           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17744           break;
17745         default:
17746           errmsg ("unknown EID type %d!", eid_type);
17747           return -99;
17748         }
17749     }
17750
17751   /* send it... */
17752   S (mp);
17753
17754   /* Use a control ping for synchronization */
17755   MPING (CONTROL_PING, mp_ping);
17756   S (mp_ping);
17757
17758   /* Wait for a reply... */
17759   W (ret);
17760   return ret;
17761 }
17762
17763 #define api_lisp_eid_table_dump api_one_eid_table_dump
17764
17765 static int
17766 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17767 {
17768   unformat_input_t *i = vam->input;
17769   vl_api_gpe_fwd_entries_get_t *mp;
17770   u8 vni_set = 0;
17771   u32 vni = ~0;
17772   int ret;
17773
17774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17775     {
17776       if (unformat (i, "vni %d", &vni))
17777         {
17778           vni_set = 1;
17779         }
17780       else
17781         {
17782           errmsg ("parse error '%U'", format_unformat_error, i);
17783           return -99;
17784         }
17785     }
17786
17787   if (!vni_set)
17788     {
17789       errmsg ("vni not set!");
17790       return -99;
17791     }
17792
17793   if (!vam->json_output)
17794     {
17795       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17796              "leid", "reid");
17797     }
17798
17799   M (GPE_FWD_ENTRIES_GET, mp);
17800   mp->vni = clib_host_to_net_u32 (vni);
17801
17802   /* send it... */
17803   S (mp);
17804
17805   /* Wait for a reply... */
17806   W (ret);
17807   return ret;
17808 }
17809
17810 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17811 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17812 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17813 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17814 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17815 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17816 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17817 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17818
17819 static int
17820 api_one_adjacencies_get (vat_main_t * vam)
17821 {
17822   unformat_input_t *i = vam->input;
17823   vl_api_one_adjacencies_get_t *mp;
17824   u8 vni_set = 0;
17825   u32 vni = ~0;
17826   int ret;
17827
17828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17829     {
17830       if (unformat (i, "vni %d", &vni))
17831         {
17832           vni_set = 1;
17833         }
17834       else
17835         {
17836           errmsg ("parse error '%U'", format_unformat_error, i);
17837           return -99;
17838         }
17839     }
17840
17841   if (!vni_set)
17842     {
17843       errmsg ("vni not set!");
17844       return -99;
17845     }
17846
17847   if (!vam->json_output)
17848     {
17849       print (vam->ofp, "%s %40s", "leid", "reid");
17850     }
17851
17852   M (ONE_ADJACENCIES_GET, mp);
17853   mp->vni = clib_host_to_net_u32 (vni);
17854
17855   /* send it... */
17856   S (mp);
17857
17858   /* Wait for a reply... */
17859   W (ret);
17860   return ret;
17861 }
17862
17863 #define api_lisp_adjacencies_get api_one_adjacencies_get
17864
17865 static int
17866 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17867 {
17868   unformat_input_t *i = vam->input;
17869   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17870   int ret;
17871   u8 ip_family_set = 0, is_ip4 = 1;
17872
17873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17874     {
17875       if (unformat (i, "ip4"))
17876         {
17877           ip_family_set = 1;
17878           is_ip4 = 1;
17879         }
17880       else if (unformat (i, "ip6"))
17881         {
17882           ip_family_set = 1;
17883           is_ip4 = 0;
17884         }
17885       else
17886         {
17887           errmsg ("parse error '%U'", format_unformat_error, i);
17888           return -99;
17889         }
17890     }
17891
17892   if (!ip_family_set)
17893     {
17894       errmsg ("ip family not set!");
17895       return -99;
17896     }
17897
17898   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17899   mp->is_ip4 = is_ip4;
17900
17901   /* send it... */
17902   S (mp);
17903
17904   /* Wait for a reply... */
17905   W (ret);
17906   return ret;
17907 }
17908
17909 static int
17910 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17911 {
17912   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17913   int ret;
17914
17915   if (!vam->json_output)
17916     {
17917       print (vam->ofp, "VNIs");
17918     }
17919
17920   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17921
17922   /* send it... */
17923   S (mp);
17924
17925   /* Wait for a reply... */
17926   W (ret);
17927   return ret;
17928 }
17929
17930 static int
17931 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17932 {
17933   unformat_input_t *i = vam->input;
17934   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17935   int ret = 0;
17936   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17937   struct in_addr ip4;
17938   struct in6_addr ip6;
17939   u32 table_id = 0, nh_sw_if_index = ~0;
17940
17941   clib_memset (&ip4, 0, sizeof (ip4));
17942   clib_memset (&ip6, 0, sizeof (ip6));
17943
17944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17945     {
17946       if (unformat (i, "del"))
17947         is_add = 0;
17948       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17949                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17950         {
17951           ip_set = 1;
17952           is_ip4 = 1;
17953         }
17954       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17955                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17956         {
17957           ip_set = 1;
17958           is_ip4 = 0;
17959         }
17960       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17961         {
17962           ip_set = 1;
17963           is_ip4 = 1;
17964           nh_sw_if_index = ~0;
17965         }
17966       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17967         {
17968           ip_set = 1;
17969           is_ip4 = 0;
17970           nh_sw_if_index = ~0;
17971         }
17972       else if (unformat (i, "table %d", &table_id))
17973         ;
17974       else
17975         {
17976           errmsg ("parse error '%U'", format_unformat_error, i);
17977           return -99;
17978         }
17979     }
17980
17981   if (!ip_set)
17982     {
17983       errmsg ("nh addr not set!");
17984       return -99;
17985     }
17986
17987   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17988   mp->is_add = is_add;
17989   mp->table_id = clib_host_to_net_u32 (table_id);
17990   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17991   mp->is_ip4 = is_ip4;
17992   if (is_ip4)
17993     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17994   else
17995     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17996
17997   /* send it... */
17998   S (mp);
17999
18000   /* Wait for a reply... */
18001   W (ret);
18002   return ret;
18003 }
18004
18005 static int
18006 api_one_map_server_dump (vat_main_t * vam)
18007 {
18008   vl_api_one_map_server_dump_t *mp;
18009   vl_api_control_ping_t *mp_ping;
18010   int ret;
18011
18012   if (!vam->json_output)
18013     {
18014       print (vam->ofp, "%=20s", "Map server");
18015     }
18016
18017   M (ONE_MAP_SERVER_DUMP, mp);
18018   /* send it... */
18019   S (mp);
18020
18021   /* Use a control ping for synchronization */
18022   MPING (CONTROL_PING, mp_ping);
18023   S (mp_ping);
18024
18025   /* Wait for a reply... */
18026   W (ret);
18027   return ret;
18028 }
18029
18030 #define api_lisp_map_server_dump api_one_map_server_dump
18031
18032 static int
18033 api_one_map_resolver_dump (vat_main_t * vam)
18034 {
18035   vl_api_one_map_resolver_dump_t *mp;
18036   vl_api_control_ping_t *mp_ping;
18037   int ret;
18038
18039   if (!vam->json_output)
18040     {
18041       print (vam->ofp, "%=20s", "Map resolver");
18042     }
18043
18044   M (ONE_MAP_RESOLVER_DUMP, mp);
18045   /* send it... */
18046   S (mp);
18047
18048   /* Use a control ping for synchronization */
18049   MPING (CONTROL_PING, mp_ping);
18050   S (mp_ping);
18051
18052   /* Wait for a reply... */
18053   W (ret);
18054   return ret;
18055 }
18056
18057 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18058
18059 static int
18060 api_one_stats_flush (vat_main_t * vam)
18061 {
18062   vl_api_one_stats_flush_t *mp;
18063   int ret = 0;
18064
18065   M (ONE_STATS_FLUSH, mp);
18066   S (mp);
18067   W (ret);
18068   return ret;
18069 }
18070
18071 static int
18072 api_one_stats_dump (vat_main_t * vam)
18073 {
18074   vl_api_one_stats_dump_t *mp;
18075   vl_api_control_ping_t *mp_ping;
18076   int ret;
18077
18078   M (ONE_STATS_DUMP, mp);
18079   /* send it... */
18080   S (mp);
18081
18082   /* Use a control ping for synchronization */
18083   MPING (CONTROL_PING, mp_ping);
18084   S (mp_ping);
18085
18086   /* Wait for a reply... */
18087   W (ret);
18088   return ret;
18089 }
18090
18091 static int
18092 api_show_one_status (vat_main_t * vam)
18093 {
18094   vl_api_show_one_status_t *mp;
18095   int ret;
18096
18097   if (!vam->json_output)
18098     {
18099       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18100     }
18101
18102   M (SHOW_ONE_STATUS, mp);
18103   /* send it... */
18104   S (mp);
18105   /* Wait for a reply... */
18106   W (ret);
18107   return ret;
18108 }
18109
18110 #define api_show_lisp_status api_show_one_status
18111
18112 static int
18113 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18114 {
18115   vl_api_gpe_fwd_entry_path_dump_t *mp;
18116   vl_api_control_ping_t *mp_ping;
18117   unformat_input_t *i = vam->input;
18118   u32 fwd_entry_index = ~0;
18119   int ret;
18120
18121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18122     {
18123       if (unformat (i, "index %d", &fwd_entry_index))
18124         ;
18125       else
18126         break;
18127     }
18128
18129   if (~0 == fwd_entry_index)
18130     {
18131       errmsg ("no index specified!");
18132       return -99;
18133     }
18134
18135   if (!vam->json_output)
18136     {
18137       print (vam->ofp, "first line");
18138     }
18139
18140   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18141
18142   /* send it... */
18143   S (mp);
18144   /* Use a control ping for synchronization */
18145   MPING (CONTROL_PING, mp_ping);
18146   S (mp_ping);
18147
18148   /* Wait for a reply... */
18149   W (ret);
18150   return ret;
18151 }
18152
18153 static int
18154 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18155 {
18156   vl_api_one_get_map_request_itr_rlocs_t *mp;
18157   int ret;
18158
18159   if (!vam->json_output)
18160     {
18161       print (vam->ofp, "%=20s", "itr-rlocs:");
18162     }
18163
18164   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18165   /* send it... */
18166   S (mp);
18167   /* Wait for a reply... */
18168   W (ret);
18169   return ret;
18170 }
18171
18172 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18173
18174 static int
18175 api_af_packet_create (vat_main_t * vam)
18176 {
18177   unformat_input_t *i = vam->input;
18178   vl_api_af_packet_create_t *mp;
18179   u8 *host_if_name = 0;
18180   u8 hw_addr[6];
18181   u8 random_hw_addr = 1;
18182   int ret;
18183
18184   clib_memset (hw_addr, 0, sizeof (hw_addr));
18185
18186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18187     {
18188       if (unformat (i, "name %s", &host_if_name))
18189         vec_add1 (host_if_name, 0);
18190       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18191         random_hw_addr = 0;
18192       else
18193         break;
18194     }
18195
18196   if (!vec_len (host_if_name))
18197     {
18198       errmsg ("host-interface name must be specified");
18199       return -99;
18200     }
18201
18202   if (vec_len (host_if_name) > 64)
18203     {
18204       errmsg ("host-interface name too long");
18205       return -99;
18206     }
18207
18208   M (AF_PACKET_CREATE, mp);
18209
18210   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18211   clib_memcpy (mp->hw_addr, hw_addr, 6);
18212   mp->use_random_hw_addr = random_hw_addr;
18213   vec_free (host_if_name);
18214
18215   S (mp);
18216
18217   /* *INDENT-OFF* */
18218   W2 (ret,
18219       ({
18220         if (ret == 0)
18221           fprintf (vam->ofp ? vam->ofp : stderr,
18222                    " new sw_if_index = %d\n", vam->sw_if_index);
18223       }));
18224   /* *INDENT-ON* */
18225   return ret;
18226 }
18227
18228 static int
18229 api_af_packet_delete (vat_main_t * vam)
18230 {
18231   unformat_input_t *i = vam->input;
18232   vl_api_af_packet_delete_t *mp;
18233   u8 *host_if_name = 0;
18234   int ret;
18235
18236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18237     {
18238       if (unformat (i, "name %s", &host_if_name))
18239         vec_add1 (host_if_name, 0);
18240       else
18241         break;
18242     }
18243
18244   if (!vec_len (host_if_name))
18245     {
18246       errmsg ("host-interface name must be specified");
18247       return -99;
18248     }
18249
18250   if (vec_len (host_if_name) > 64)
18251     {
18252       errmsg ("host-interface name too long");
18253       return -99;
18254     }
18255
18256   M (AF_PACKET_DELETE, mp);
18257
18258   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18259   vec_free (host_if_name);
18260
18261   S (mp);
18262   W (ret);
18263   return ret;
18264 }
18265
18266 static void vl_api_af_packet_details_t_handler
18267   (vl_api_af_packet_details_t * mp)
18268 {
18269   vat_main_t *vam = &vat_main;
18270
18271   print (vam->ofp, "%-16s %d",
18272          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
18273 }
18274
18275 static void vl_api_af_packet_details_t_handler_json
18276   (vl_api_af_packet_details_t * mp)
18277 {
18278   vat_main_t *vam = &vat_main;
18279   vat_json_node_t *node = NULL;
18280
18281   if (VAT_JSON_ARRAY != vam->json_tree.type)
18282     {
18283       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18284       vat_json_init_array (&vam->json_tree);
18285     }
18286   node = vat_json_array_add (&vam->json_tree);
18287
18288   vat_json_init_object (node);
18289   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18290   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
18291 }
18292
18293 static int
18294 api_af_packet_dump (vat_main_t * vam)
18295 {
18296   vl_api_af_packet_dump_t *mp;
18297   vl_api_control_ping_t *mp_ping;
18298   int ret;
18299
18300   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18301   /* Get list of tap interfaces */
18302   M (AF_PACKET_DUMP, mp);
18303   S (mp);
18304
18305   /* Use a control ping for synchronization */
18306   MPING (CONTROL_PING, mp_ping);
18307   S (mp_ping);
18308
18309   W (ret);
18310   return ret;
18311 }
18312
18313 static int
18314 api_policer_add_del (vat_main_t * vam)
18315 {
18316   unformat_input_t *i = vam->input;
18317   vl_api_policer_add_del_t *mp;
18318   u8 is_add = 1;
18319   u8 *name = 0;
18320   u32 cir = 0;
18321   u32 eir = 0;
18322   u64 cb = 0;
18323   u64 eb = 0;
18324   u8 rate_type = 0;
18325   u8 round_type = 0;
18326   u8 type = 0;
18327   u8 color_aware = 0;
18328   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18329   int ret;
18330
18331   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18332   conform_action.dscp = 0;
18333   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18334   exceed_action.dscp = 0;
18335   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18336   violate_action.dscp = 0;
18337
18338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18339     {
18340       if (unformat (i, "del"))
18341         is_add = 0;
18342       else if (unformat (i, "name %s", &name))
18343         vec_add1 (name, 0);
18344       else if (unformat (i, "cir %u", &cir))
18345         ;
18346       else if (unformat (i, "eir %u", &eir))
18347         ;
18348       else if (unformat (i, "cb %u", &cb))
18349         ;
18350       else if (unformat (i, "eb %u", &eb))
18351         ;
18352       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18353                          &rate_type))
18354         ;
18355       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18356                          &round_type))
18357         ;
18358       else if (unformat (i, "type %U", unformat_policer_type, &type))
18359         ;
18360       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18361                          &conform_action))
18362         ;
18363       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18364                          &exceed_action))
18365         ;
18366       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18367                          &violate_action))
18368         ;
18369       else if (unformat (i, "color-aware"))
18370         color_aware = 1;
18371       else
18372         break;
18373     }
18374
18375   if (!vec_len (name))
18376     {
18377       errmsg ("policer name must be specified");
18378       return -99;
18379     }
18380
18381   if (vec_len (name) > 64)
18382     {
18383       errmsg ("policer name too long");
18384       return -99;
18385     }
18386
18387   M (POLICER_ADD_DEL, mp);
18388
18389   clib_memcpy (mp->name, name, vec_len (name));
18390   vec_free (name);
18391   mp->is_add = is_add;
18392   mp->cir = ntohl (cir);
18393   mp->eir = ntohl (eir);
18394   mp->cb = clib_net_to_host_u64 (cb);
18395   mp->eb = clib_net_to_host_u64 (eb);
18396   mp->rate_type = rate_type;
18397   mp->round_type = round_type;
18398   mp->type = type;
18399   mp->conform_action_type = conform_action.action_type;
18400   mp->conform_dscp = conform_action.dscp;
18401   mp->exceed_action_type = exceed_action.action_type;
18402   mp->exceed_dscp = exceed_action.dscp;
18403   mp->violate_action_type = violate_action.action_type;
18404   mp->violate_dscp = violate_action.dscp;
18405   mp->color_aware = color_aware;
18406
18407   S (mp);
18408   W (ret);
18409   return ret;
18410 }
18411
18412 static int
18413 api_policer_dump (vat_main_t * vam)
18414 {
18415   unformat_input_t *i = vam->input;
18416   vl_api_policer_dump_t *mp;
18417   vl_api_control_ping_t *mp_ping;
18418   u8 *match_name = 0;
18419   u8 match_name_valid = 0;
18420   int ret;
18421
18422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18423     {
18424       if (unformat (i, "name %s", &match_name))
18425         {
18426           vec_add1 (match_name, 0);
18427           match_name_valid = 1;
18428         }
18429       else
18430         break;
18431     }
18432
18433   M (POLICER_DUMP, mp);
18434   mp->match_name_valid = match_name_valid;
18435   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18436   vec_free (match_name);
18437   /* send it... */
18438   S (mp);
18439
18440   /* Use a control ping for synchronization */
18441   MPING (CONTROL_PING, mp_ping);
18442   S (mp_ping);
18443
18444   /* Wait for a reply... */
18445   W (ret);
18446   return ret;
18447 }
18448
18449 static int
18450 api_policer_classify_set_interface (vat_main_t * vam)
18451 {
18452   unformat_input_t *i = vam->input;
18453   vl_api_policer_classify_set_interface_t *mp;
18454   u32 sw_if_index;
18455   int sw_if_index_set;
18456   u32 ip4_table_index = ~0;
18457   u32 ip6_table_index = ~0;
18458   u32 l2_table_index = ~0;
18459   u8 is_add = 1;
18460   int ret;
18461
18462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18463     {
18464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18465         sw_if_index_set = 1;
18466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18467         sw_if_index_set = 1;
18468       else if (unformat (i, "del"))
18469         is_add = 0;
18470       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18471         ;
18472       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18473         ;
18474       else if (unformat (i, "l2-table %d", &l2_table_index))
18475         ;
18476       else
18477         {
18478           clib_warning ("parse error '%U'", format_unformat_error, i);
18479           return -99;
18480         }
18481     }
18482
18483   if (sw_if_index_set == 0)
18484     {
18485       errmsg ("missing interface name or sw_if_index");
18486       return -99;
18487     }
18488
18489   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18490
18491   mp->sw_if_index = ntohl (sw_if_index);
18492   mp->ip4_table_index = ntohl (ip4_table_index);
18493   mp->ip6_table_index = ntohl (ip6_table_index);
18494   mp->l2_table_index = ntohl (l2_table_index);
18495   mp->is_add = is_add;
18496
18497   S (mp);
18498   W (ret);
18499   return ret;
18500 }
18501
18502 static int
18503 api_policer_classify_dump (vat_main_t * vam)
18504 {
18505   unformat_input_t *i = vam->input;
18506   vl_api_policer_classify_dump_t *mp;
18507   vl_api_control_ping_t *mp_ping;
18508   u8 type = POLICER_CLASSIFY_N_TABLES;
18509   int ret;
18510
18511   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18512     ;
18513   else
18514     {
18515       errmsg ("classify table type must be specified");
18516       return -99;
18517     }
18518
18519   if (!vam->json_output)
18520     {
18521       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18522     }
18523
18524   M (POLICER_CLASSIFY_DUMP, mp);
18525   mp->type = type;
18526   /* send it... */
18527   S (mp);
18528
18529   /* Use a control ping for synchronization */
18530   MPING (CONTROL_PING, mp_ping);
18531   S (mp_ping);
18532
18533   /* Wait for a reply... */
18534   W (ret);
18535   return ret;
18536 }
18537
18538 static int
18539 api_netmap_create (vat_main_t * vam)
18540 {
18541   unformat_input_t *i = vam->input;
18542   vl_api_netmap_create_t *mp;
18543   u8 *if_name = 0;
18544   u8 hw_addr[6];
18545   u8 random_hw_addr = 1;
18546   u8 is_pipe = 0;
18547   u8 is_master = 0;
18548   int ret;
18549
18550   clib_memset (hw_addr, 0, sizeof (hw_addr));
18551
18552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18553     {
18554       if (unformat (i, "name %s", &if_name))
18555         vec_add1 (if_name, 0);
18556       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18557         random_hw_addr = 0;
18558       else if (unformat (i, "pipe"))
18559         is_pipe = 1;
18560       else if (unformat (i, "master"))
18561         is_master = 1;
18562       else if (unformat (i, "slave"))
18563         is_master = 0;
18564       else
18565         break;
18566     }
18567
18568   if (!vec_len (if_name))
18569     {
18570       errmsg ("interface name must be specified");
18571       return -99;
18572     }
18573
18574   if (vec_len (if_name) > 64)
18575     {
18576       errmsg ("interface name too long");
18577       return -99;
18578     }
18579
18580   M (NETMAP_CREATE, mp);
18581
18582   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18583   clib_memcpy (mp->hw_addr, hw_addr, 6);
18584   mp->use_random_hw_addr = random_hw_addr;
18585   mp->is_pipe = is_pipe;
18586   mp->is_master = is_master;
18587   vec_free (if_name);
18588
18589   S (mp);
18590   W (ret);
18591   return ret;
18592 }
18593
18594 static int
18595 api_netmap_delete (vat_main_t * vam)
18596 {
18597   unformat_input_t *i = vam->input;
18598   vl_api_netmap_delete_t *mp;
18599   u8 *if_name = 0;
18600   int ret;
18601
18602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18603     {
18604       if (unformat (i, "name %s", &if_name))
18605         vec_add1 (if_name, 0);
18606       else
18607         break;
18608     }
18609
18610   if (!vec_len (if_name))
18611     {
18612       errmsg ("interface name must be specified");
18613       return -99;
18614     }
18615
18616   if (vec_len (if_name) > 64)
18617     {
18618       errmsg ("interface name too long");
18619       return -99;
18620     }
18621
18622   M (NETMAP_DELETE, mp);
18623
18624   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18625   vec_free (if_name);
18626
18627   S (mp);
18628   W (ret);
18629   return ret;
18630 }
18631
18632 static u8 *
18633 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18634 {
18635   vl_api_fib_path_nh_proto_t proto =
18636     va_arg (*args, vl_api_fib_path_nh_proto_t);
18637
18638   switch (proto)
18639     {
18640     case FIB_API_PATH_NH_PROTO_IP4:
18641       s = format (s, "ip4");
18642       break;
18643     case FIB_API_PATH_NH_PROTO_IP6:
18644       s = format (s, "ip6");
18645       break;
18646     case FIB_API_PATH_NH_PROTO_MPLS:
18647       s = format (s, "mpls");
18648       break;
18649     case FIB_API_PATH_NH_PROTO_BIER:
18650       s = format (s, "bier");
18651       break;
18652     case FIB_API_PATH_NH_PROTO_ETHERNET:
18653       s = format (s, "ethernet");
18654       break;
18655     }
18656
18657   return (s);
18658 }
18659
18660 static u8 *
18661 format_vl_api_ip_address_union (u8 * s, va_list * args)
18662 {
18663   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18664   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18665
18666   switch (af)
18667     {
18668     case ADDRESS_IP4:
18669       s = format (s, "%U", format_ip4_address, u->ip4);
18670       break;
18671     case ADDRESS_IP6:
18672       s = format (s, "%U", format_ip6_address, u->ip6);
18673       break;
18674     }
18675   return (s);
18676 }
18677
18678 static u8 *
18679 format_vl_api_fib_path_type (u8 * s, va_list * args)
18680 {
18681   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18682
18683   switch (t)
18684     {
18685     case FIB_API_PATH_TYPE_NORMAL:
18686       s = format (s, "normal");
18687       break;
18688     case FIB_API_PATH_TYPE_LOCAL:
18689       s = format (s, "local");
18690       break;
18691     case FIB_API_PATH_TYPE_DROP:
18692       s = format (s, "drop");
18693       break;
18694     case FIB_API_PATH_TYPE_UDP_ENCAP:
18695       s = format (s, "udp-encap");
18696       break;
18697     case FIB_API_PATH_TYPE_BIER_IMP:
18698       s = format (s, "bier-imp");
18699       break;
18700     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18701       s = format (s, "unreach");
18702       break;
18703     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18704       s = format (s, "prohibit");
18705       break;
18706     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18707       s = format (s, "src-lookup");
18708       break;
18709     case FIB_API_PATH_TYPE_DVR:
18710       s = format (s, "dvr");
18711       break;
18712     case FIB_API_PATH_TYPE_INTERFACE_RX:
18713       s = format (s, "interface-rx");
18714       break;
18715     case FIB_API_PATH_TYPE_CLASSIFY:
18716       s = format (s, "classify");
18717       break;
18718     }
18719
18720   return (s);
18721 }
18722
18723 static void
18724 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18725 {
18726   print (vam->ofp,
18727          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18728          ntohl (fp->weight), ntohl (fp->sw_if_index),
18729          format_vl_api_fib_path_type, fp->type,
18730          format_fib_api_path_nh_proto, fp->proto,
18731          format_vl_api_ip_address_union, &fp->nh.address);
18732 }
18733
18734 static void
18735 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18736                                  vl_api_fib_path_t * fp)
18737 {
18738   struct in_addr ip4;
18739   struct in6_addr ip6;
18740
18741   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18742   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18743   vat_json_object_add_uint (node, "type", fp->type);
18744   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18745   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18746     {
18747       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18748       vat_json_object_add_ip4 (node, "next_hop", ip4);
18749     }
18750   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18751     {
18752       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18753       vat_json_object_add_ip6 (node, "next_hop", ip6);
18754     }
18755 }
18756
18757 static void
18758 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18759 {
18760   vat_main_t *vam = &vat_main;
18761   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18762   vl_api_fib_path_t *fp;
18763   i32 i;
18764
18765   print (vam->ofp, "sw_if_index %d via:",
18766          ntohl (mp->mt_tunnel.mt_sw_if_index));
18767   fp = mp->mt_tunnel.mt_paths;
18768   for (i = 0; i < count; i++)
18769     {
18770       vl_api_fib_path_print (vam, fp);
18771       fp++;
18772     }
18773
18774   print (vam->ofp, "");
18775 }
18776
18777 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18778 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18779
18780 static void
18781 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18782 {
18783   vat_main_t *vam = &vat_main;
18784   vat_json_node_t *node = NULL;
18785   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18786   vl_api_fib_path_t *fp;
18787   i32 i;
18788
18789   if (VAT_JSON_ARRAY != vam->json_tree.type)
18790     {
18791       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18792       vat_json_init_array (&vam->json_tree);
18793     }
18794   node = vat_json_array_add (&vam->json_tree);
18795
18796   vat_json_init_object (node);
18797   vat_json_object_add_uint (node, "sw_if_index",
18798                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18799
18800   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18801
18802   fp = mp->mt_tunnel.mt_paths;
18803   for (i = 0; i < count; i++)
18804     {
18805       vl_api_mpls_fib_path_json_print (node, fp);
18806       fp++;
18807     }
18808 }
18809
18810 static int
18811 api_mpls_tunnel_dump (vat_main_t * vam)
18812 {
18813   vl_api_mpls_tunnel_dump_t *mp;
18814   vl_api_control_ping_t *mp_ping;
18815   int ret;
18816
18817   M (MPLS_TUNNEL_DUMP, mp);
18818
18819   S (mp);
18820
18821   /* Use a control ping for synchronization */
18822   MPING (CONTROL_PING, mp_ping);
18823   S (mp_ping);
18824
18825   W (ret);
18826   return ret;
18827 }
18828
18829 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18830 #define vl_api_mpls_table_details_t_print vl_noop_handler
18831
18832
18833 static void
18834 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18835 {
18836   vat_main_t *vam = &vat_main;
18837
18838   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18839 }
18840
18841 static void vl_api_mpls_table_details_t_handler_json
18842   (vl_api_mpls_table_details_t * mp)
18843 {
18844   vat_main_t *vam = &vat_main;
18845   vat_json_node_t *node = NULL;
18846
18847   if (VAT_JSON_ARRAY != vam->json_tree.type)
18848     {
18849       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18850       vat_json_init_array (&vam->json_tree);
18851     }
18852   node = vat_json_array_add (&vam->json_tree);
18853
18854   vat_json_init_object (node);
18855   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18856 }
18857
18858 static int
18859 api_mpls_table_dump (vat_main_t * vam)
18860 {
18861   vl_api_mpls_table_dump_t *mp;
18862   vl_api_control_ping_t *mp_ping;
18863   int ret;
18864
18865   M (MPLS_TABLE_DUMP, mp);
18866   S (mp);
18867
18868   /* Use a control ping for synchronization */
18869   MPING (CONTROL_PING, mp_ping);
18870   S (mp_ping);
18871
18872   W (ret);
18873   return ret;
18874 }
18875
18876 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18877 #define vl_api_mpls_route_details_t_print vl_noop_handler
18878
18879 static void
18880 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18881 {
18882   vat_main_t *vam = &vat_main;
18883   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18884   vl_api_fib_path_t *fp;
18885   int i;
18886
18887   print (vam->ofp,
18888          "table-id %d, label %u, ess_bit %u",
18889          ntohl (mp->mr_route.mr_table_id),
18890          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18891   fp = mp->mr_route.mr_paths;
18892   for (i = 0; i < count; i++)
18893     {
18894       vl_api_fib_path_print (vam, fp);
18895       fp++;
18896     }
18897 }
18898
18899 static void vl_api_mpls_route_details_t_handler_json
18900   (vl_api_mpls_route_details_t * mp)
18901 {
18902   vat_main_t *vam = &vat_main;
18903   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18904   vat_json_node_t *node = NULL;
18905   vl_api_fib_path_t *fp;
18906   int i;
18907
18908   if (VAT_JSON_ARRAY != vam->json_tree.type)
18909     {
18910       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18911       vat_json_init_array (&vam->json_tree);
18912     }
18913   node = vat_json_array_add (&vam->json_tree);
18914
18915   vat_json_init_object (node);
18916   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18917   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18918   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18919   vat_json_object_add_uint (node, "path_count", count);
18920   fp = mp->mr_route.mr_paths;
18921   for (i = 0; i < count; i++)
18922     {
18923       vl_api_mpls_fib_path_json_print (node, fp);
18924       fp++;
18925     }
18926 }
18927
18928 static int
18929 api_mpls_route_dump (vat_main_t * vam)
18930 {
18931   unformat_input_t *input = vam->input;
18932   vl_api_mpls_route_dump_t *mp;
18933   vl_api_control_ping_t *mp_ping;
18934   u32 table_id;
18935   int ret;
18936
18937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18938     {
18939       if (unformat (input, "table_id %d", &table_id))
18940         ;
18941       else
18942         break;
18943     }
18944   if (table_id == ~0)
18945     {
18946       errmsg ("missing table id");
18947       return -99;
18948     }
18949
18950   M (MPLS_ROUTE_DUMP, mp);
18951
18952   mp->table.mt_table_id = ntohl (table_id);
18953   S (mp);
18954
18955   /* Use a control ping for synchronization */
18956   MPING (CONTROL_PING, mp_ping);
18957   S (mp_ping);
18958
18959   W (ret);
18960   return ret;
18961 }
18962
18963 #define vl_api_ip_table_details_t_endian vl_noop_handler
18964 #define vl_api_ip_table_details_t_print vl_noop_handler
18965
18966 static void
18967 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18968 {
18969   vat_main_t *vam = &vat_main;
18970
18971   print (vam->ofp,
18972          "%s; table-id %d, prefix %U/%d",
18973          mp->table.name, ntohl (mp->table.table_id));
18974 }
18975
18976
18977 static void vl_api_ip_table_details_t_handler_json
18978   (vl_api_ip_table_details_t * mp)
18979 {
18980   vat_main_t *vam = &vat_main;
18981   vat_json_node_t *node = NULL;
18982
18983   if (VAT_JSON_ARRAY != vam->json_tree.type)
18984     {
18985       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18986       vat_json_init_array (&vam->json_tree);
18987     }
18988   node = vat_json_array_add (&vam->json_tree);
18989
18990   vat_json_init_object (node);
18991   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18992 }
18993
18994 static int
18995 api_ip_table_dump (vat_main_t * vam)
18996 {
18997   vl_api_ip_table_dump_t *mp;
18998   vl_api_control_ping_t *mp_ping;
18999   int ret;
19000
19001   M (IP_TABLE_DUMP, mp);
19002   S (mp);
19003
19004   /* Use a control ping for synchronization */
19005   MPING (CONTROL_PING, mp_ping);
19006   S (mp_ping);
19007
19008   W (ret);
19009   return ret;
19010 }
19011
19012 static int
19013 api_ip_mtable_dump (vat_main_t * vam)
19014 {
19015   vl_api_ip_mtable_dump_t *mp;
19016   vl_api_control_ping_t *mp_ping;
19017   int ret;
19018
19019   M (IP_MTABLE_DUMP, mp);
19020   S (mp);
19021
19022   /* Use a control ping for synchronization */
19023   MPING (CONTROL_PING, mp_ping);
19024   S (mp_ping);
19025
19026   W (ret);
19027   return ret;
19028 }
19029
19030 static int
19031 api_ip_mroute_dump (vat_main_t * vam)
19032 {
19033   unformat_input_t *input = vam->input;
19034   vl_api_control_ping_t *mp_ping;
19035   vl_api_ip_mroute_dump_t *mp;
19036   int ret, is_ip6;
19037   u32 table_id;
19038
19039   is_ip6 = 0;
19040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19041     {
19042       if (unformat (input, "table_id %d", &table_id))
19043         ;
19044       else if (unformat (input, "ip6"))
19045         is_ip6 = 1;
19046       else if (unformat (input, "ip4"))
19047         is_ip6 = 0;
19048       else
19049         break;
19050     }
19051   if (table_id == ~0)
19052     {
19053       errmsg ("missing table id");
19054       return -99;
19055     }
19056
19057   M (IP_MROUTE_DUMP, mp);
19058   mp->table.table_id = table_id;
19059   mp->table.is_ip6 = is_ip6;
19060   S (mp);
19061
19062   /* Use a control ping for synchronization */
19063   MPING (CONTROL_PING, mp_ping);
19064   S (mp_ping);
19065
19066   W (ret);
19067   return ret;
19068 }
19069
19070 static void vl_api_ip_neighbor_details_t_handler
19071   (vl_api_ip_neighbor_details_t * mp)
19072 {
19073   vat_main_t *vam = &vat_main;
19074
19075   print (vam->ofp, "%c %U %U",
19076          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
19077          format_vl_api_mac_address, &mp->neighbor.mac_address,
19078          format_vl_api_address, &mp->neighbor.ip_address);
19079 }
19080
19081 static void vl_api_ip_neighbor_details_t_handler_json
19082   (vl_api_ip_neighbor_details_t * mp)
19083 {
19084
19085   vat_main_t *vam = &vat_main;
19086   vat_json_node_t *node;
19087
19088   if (VAT_JSON_ARRAY != vam->json_tree.type)
19089     {
19090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19091       vat_json_init_array (&vam->json_tree);
19092     }
19093   node = vat_json_array_add (&vam->json_tree);
19094
19095   vat_json_init_object (node);
19096   vat_json_object_add_string_copy
19097     (node, "flag",
19098      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
19099       (u8 *) "static" : (u8 *) "dynamic"));
19100
19101   vat_json_object_add_string_copy (node, "link_layer",
19102                                    format (0, "%U", format_vl_api_mac_address,
19103                                            &mp->neighbor.mac_address));
19104   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
19105 }
19106
19107 static int
19108 api_ip_neighbor_dump (vat_main_t * vam)
19109 {
19110   unformat_input_t *i = vam->input;
19111   vl_api_ip_neighbor_dump_t *mp;
19112   vl_api_control_ping_t *mp_ping;
19113   u8 is_ipv6 = 0;
19114   u32 sw_if_index = ~0;
19115   int ret;
19116
19117   /* Parse args required to build the message */
19118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19119     {
19120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19121         ;
19122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19123         ;
19124       else if (unformat (i, "ip6"))
19125         is_ipv6 = 1;
19126       else
19127         break;
19128     }
19129
19130   if (sw_if_index == ~0)
19131     {
19132       errmsg ("missing interface name or sw_if_index");
19133       return -99;
19134     }
19135
19136   M (IP_NEIGHBOR_DUMP, mp);
19137   mp->is_ipv6 = (u8) is_ipv6;
19138   mp->sw_if_index = ntohl (sw_if_index);
19139   S (mp);
19140
19141   /* Use a control ping for synchronization */
19142   MPING (CONTROL_PING, mp_ping);
19143   S (mp_ping);
19144
19145   W (ret);
19146   return ret;
19147 }
19148
19149 #define vl_api_ip_route_details_t_endian vl_noop_handler
19150 #define vl_api_ip_route_details_t_print vl_noop_handler
19151
19152 static void
19153 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
19154 {
19155   vat_main_t *vam = &vat_main;
19156   u8 count = mp->route.n_paths;
19157   vl_api_fib_path_t *fp;
19158   int i;
19159
19160   print (vam->ofp,
19161          "table-id %d, prefix %U/%d",
19162          ntohl (mp->route.table_id),
19163          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
19164   for (i = 0; i < count; i++)
19165     {
19166       fp = &mp->route.paths[i];
19167
19168       vl_api_fib_path_print (vam, fp);
19169       fp++;
19170     }
19171 }
19172
19173 static void vl_api_ip_route_details_t_handler_json
19174   (vl_api_ip_route_details_t * mp)
19175 {
19176   vat_main_t *vam = &vat_main;
19177   u8 count = mp->route.n_paths;
19178   vat_json_node_t *node = NULL;
19179   struct in_addr ip4;
19180   struct in6_addr ip6;
19181   vl_api_fib_path_t *fp;
19182   int i;
19183
19184   if (VAT_JSON_ARRAY != vam->json_tree.type)
19185     {
19186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19187       vat_json_init_array (&vam->json_tree);
19188     }
19189   node = vat_json_array_add (&vam->json_tree);
19190
19191   vat_json_init_object (node);
19192   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
19193   if (ADDRESS_IP6 == mp->route.prefix.address.af)
19194     {
19195       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
19196       vat_json_object_add_ip6 (node, "prefix", ip6);
19197     }
19198   else
19199     {
19200       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
19201       vat_json_object_add_ip4 (node, "prefix", ip4);
19202     }
19203   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
19204   vat_json_object_add_uint (node, "path_count", count);
19205   for (i = 0; i < count; i++)
19206     {
19207       fp = &mp->route.paths[i];
19208       vl_api_mpls_fib_path_json_print (node, fp);
19209     }
19210 }
19211
19212 static int
19213 api_ip_route_dump (vat_main_t * vam)
19214 {
19215   unformat_input_t *input = vam->input;
19216   vl_api_ip_route_dump_t *mp;
19217   vl_api_control_ping_t *mp_ping;
19218   u32 table_id;
19219   u8 is_ip6;
19220   int ret;
19221
19222   is_ip6 = 0;
19223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19224     {
19225       if (unformat (input, "table_id %d", &table_id))
19226         ;
19227       else if (unformat (input, "ip6"))
19228         is_ip6 = 1;
19229       else if (unformat (input, "ip4"))
19230         is_ip6 = 0;
19231       else
19232         break;
19233     }
19234   if (table_id == ~0)
19235     {
19236       errmsg ("missing table id");
19237       return -99;
19238     }
19239
19240   M (IP_ROUTE_DUMP, mp);
19241
19242   mp->table.table_id = table_id;
19243   mp->table.is_ip6 = is_ip6;
19244
19245   S (mp);
19246
19247   /* Use a control ping for synchronization */
19248   MPING (CONTROL_PING, mp_ping);
19249   S (mp_ping);
19250
19251   W (ret);
19252   return ret;
19253 }
19254
19255 int
19256 api_classify_table_ids (vat_main_t * vam)
19257 {
19258   vl_api_classify_table_ids_t *mp;
19259   int ret;
19260
19261   /* Construct the API message */
19262   M (CLASSIFY_TABLE_IDS, mp);
19263   mp->context = 0;
19264
19265   S (mp);
19266   W (ret);
19267   return ret;
19268 }
19269
19270 int
19271 api_classify_table_by_interface (vat_main_t * vam)
19272 {
19273   unformat_input_t *input = vam->input;
19274   vl_api_classify_table_by_interface_t *mp;
19275
19276   u32 sw_if_index = ~0;
19277   int ret;
19278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19279     {
19280       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19281         ;
19282       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19283         ;
19284       else
19285         break;
19286     }
19287   if (sw_if_index == ~0)
19288     {
19289       errmsg ("missing interface name or sw_if_index");
19290       return -99;
19291     }
19292
19293   /* Construct the API message */
19294   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19295   mp->context = 0;
19296   mp->sw_if_index = ntohl (sw_if_index);
19297
19298   S (mp);
19299   W (ret);
19300   return ret;
19301 }
19302
19303 int
19304 api_classify_table_info (vat_main_t * vam)
19305 {
19306   unformat_input_t *input = vam->input;
19307   vl_api_classify_table_info_t *mp;
19308
19309   u32 table_id = ~0;
19310   int ret;
19311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19312     {
19313       if (unformat (input, "table_id %d", &table_id))
19314         ;
19315       else
19316         break;
19317     }
19318   if (table_id == ~0)
19319     {
19320       errmsg ("missing table id");
19321       return -99;
19322     }
19323
19324   /* Construct the API message */
19325   M (CLASSIFY_TABLE_INFO, mp);
19326   mp->context = 0;
19327   mp->table_id = ntohl (table_id);
19328
19329   S (mp);
19330   W (ret);
19331   return ret;
19332 }
19333
19334 int
19335 api_classify_session_dump (vat_main_t * vam)
19336 {
19337   unformat_input_t *input = vam->input;
19338   vl_api_classify_session_dump_t *mp;
19339   vl_api_control_ping_t *mp_ping;
19340
19341   u32 table_id = ~0;
19342   int ret;
19343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19344     {
19345       if (unformat (input, "table_id %d", &table_id))
19346         ;
19347       else
19348         break;
19349     }
19350   if (table_id == ~0)
19351     {
19352       errmsg ("missing table id");
19353       return -99;
19354     }
19355
19356   /* Construct the API message */
19357   M (CLASSIFY_SESSION_DUMP, mp);
19358   mp->context = 0;
19359   mp->table_id = ntohl (table_id);
19360   S (mp);
19361
19362   /* Use a control ping for synchronization */
19363   MPING (CONTROL_PING, mp_ping);
19364   S (mp_ping);
19365
19366   W (ret);
19367   return ret;
19368 }
19369
19370 static void
19371 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19372 {
19373   vat_main_t *vam = &vat_main;
19374
19375   print (vam->ofp, "collector_address %U, collector_port %d, "
19376          "src_address %U, vrf_id %d, path_mtu %u, "
19377          "template_interval %u, udp_checksum %d",
19378          format_ip4_address, mp->collector_address,
19379          ntohs (mp->collector_port),
19380          format_ip4_address, mp->src_address,
19381          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19382          ntohl (mp->template_interval), mp->udp_checksum);
19383
19384   vam->retval = 0;
19385   vam->result_ready = 1;
19386 }
19387
19388 static void
19389   vl_api_ipfix_exporter_details_t_handler_json
19390   (vl_api_ipfix_exporter_details_t * mp)
19391 {
19392   vat_main_t *vam = &vat_main;
19393   vat_json_node_t node;
19394   struct in_addr collector_address;
19395   struct in_addr src_address;
19396
19397   vat_json_init_object (&node);
19398   clib_memcpy (&collector_address, &mp->collector_address,
19399                sizeof (collector_address));
19400   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19401   vat_json_object_add_uint (&node, "collector_port",
19402                             ntohs (mp->collector_port));
19403   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19404   vat_json_object_add_ip4 (&node, "src_address", src_address);
19405   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19406   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19407   vat_json_object_add_uint (&node, "template_interval",
19408                             ntohl (mp->template_interval));
19409   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19410
19411   vat_json_print (vam->ofp, &node);
19412   vat_json_free (&node);
19413   vam->retval = 0;
19414   vam->result_ready = 1;
19415 }
19416
19417 int
19418 api_ipfix_exporter_dump (vat_main_t * vam)
19419 {
19420   vl_api_ipfix_exporter_dump_t *mp;
19421   int ret;
19422
19423   /* Construct the API message */
19424   M (IPFIX_EXPORTER_DUMP, mp);
19425   mp->context = 0;
19426
19427   S (mp);
19428   W (ret);
19429   return ret;
19430 }
19431
19432 static int
19433 api_ipfix_classify_stream_dump (vat_main_t * vam)
19434 {
19435   vl_api_ipfix_classify_stream_dump_t *mp;
19436   int ret;
19437
19438   /* Construct the API message */
19439   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19440   mp->context = 0;
19441
19442   S (mp);
19443   W (ret);
19444   return ret;
19445   /* NOTREACHED */
19446   return 0;
19447 }
19448
19449 static void
19450   vl_api_ipfix_classify_stream_details_t_handler
19451   (vl_api_ipfix_classify_stream_details_t * mp)
19452 {
19453   vat_main_t *vam = &vat_main;
19454   print (vam->ofp, "domain_id %d, src_port %d",
19455          ntohl (mp->domain_id), ntohs (mp->src_port));
19456   vam->retval = 0;
19457   vam->result_ready = 1;
19458 }
19459
19460 static void
19461   vl_api_ipfix_classify_stream_details_t_handler_json
19462   (vl_api_ipfix_classify_stream_details_t * mp)
19463 {
19464   vat_main_t *vam = &vat_main;
19465   vat_json_node_t node;
19466
19467   vat_json_init_object (&node);
19468   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19469   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19470
19471   vat_json_print (vam->ofp, &node);
19472   vat_json_free (&node);
19473   vam->retval = 0;
19474   vam->result_ready = 1;
19475 }
19476
19477 static int
19478 api_ipfix_classify_table_dump (vat_main_t * vam)
19479 {
19480   vl_api_ipfix_classify_table_dump_t *mp;
19481   vl_api_control_ping_t *mp_ping;
19482   int ret;
19483
19484   if (!vam->json_output)
19485     {
19486       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19487              "transport_protocol");
19488     }
19489
19490   /* Construct the API message */
19491   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19492
19493   /* send it... */
19494   S (mp);
19495
19496   /* Use a control ping for synchronization */
19497   MPING (CONTROL_PING, mp_ping);
19498   S (mp_ping);
19499
19500   W (ret);
19501   return ret;
19502 }
19503
19504 static void
19505   vl_api_ipfix_classify_table_details_t_handler
19506   (vl_api_ipfix_classify_table_details_t * mp)
19507 {
19508   vat_main_t *vam = &vat_main;
19509   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19510          mp->transport_protocol);
19511 }
19512
19513 static void
19514   vl_api_ipfix_classify_table_details_t_handler_json
19515   (vl_api_ipfix_classify_table_details_t * mp)
19516 {
19517   vat_json_node_t *node = NULL;
19518   vat_main_t *vam = &vat_main;
19519
19520   if (VAT_JSON_ARRAY != vam->json_tree.type)
19521     {
19522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19523       vat_json_init_array (&vam->json_tree);
19524     }
19525
19526   node = vat_json_array_add (&vam->json_tree);
19527   vat_json_init_object (node);
19528
19529   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19530   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19531   vat_json_object_add_uint (node, "transport_protocol",
19532                             mp->transport_protocol);
19533 }
19534
19535 static int
19536 api_sw_interface_span_enable_disable (vat_main_t * vam)
19537 {
19538   unformat_input_t *i = vam->input;
19539   vl_api_sw_interface_span_enable_disable_t *mp;
19540   u32 src_sw_if_index = ~0;
19541   u32 dst_sw_if_index = ~0;
19542   u8 state = 3;
19543   int ret;
19544   u8 is_l2 = 0;
19545
19546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19547     {
19548       if (unformat
19549           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19550         ;
19551       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19552         ;
19553       else
19554         if (unformat
19555             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19556         ;
19557       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19558         ;
19559       else if (unformat (i, "disable"))
19560         state = 0;
19561       else if (unformat (i, "rx"))
19562         state = 1;
19563       else if (unformat (i, "tx"))
19564         state = 2;
19565       else if (unformat (i, "both"))
19566         state = 3;
19567       else if (unformat (i, "l2"))
19568         is_l2 = 1;
19569       else
19570         break;
19571     }
19572
19573   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19574
19575   mp->sw_if_index_from = htonl (src_sw_if_index);
19576   mp->sw_if_index_to = htonl (dst_sw_if_index);
19577   mp->state = state;
19578   mp->is_l2 = is_l2;
19579
19580   S (mp);
19581   W (ret);
19582   return ret;
19583 }
19584
19585 static void
19586 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19587                                             * mp)
19588 {
19589   vat_main_t *vam = &vat_main;
19590   u8 *sw_if_from_name = 0;
19591   u8 *sw_if_to_name = 0;
19592   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19593   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19594   char *states[] = { "none", "rx", "tx", "both" };
19595   hash_pair_t *p;
19596
19597   /* *INDENT-OFF* */
19598   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19599   ({
19600     if ((u32) p->value[0] == sw_if_index_from)
19601       {
19602         sw_if_from_name = (u8 *)(p->key);
19603         if (sw_if_to_name)
19604           break;
19605       }
19606     if ((u32) p->value[0] == sw_if_index_to)
19607       {
19608         sw_if_to_name = (u8 *)(p->key);
19609         if (sw_if_from_name)
19610           break;
19611       }
19612   }));
19613   /* *INDENT-ON* */
19614   print (vam->ofp, "%20s => %20s (%s) %s",
19615          sw_if_from_name, sw_if_to_name, states[mp->state],
19616          mp->is_l2 ? "l2" : "device");
19617 }
19618
19619 static void
19620   vl_api_sw_interface_span_details_t_handler_json
19621   (vl_api_sw_interface_span_details_t * mp)
19622 {
19623   vat_main_t *vam = &vat_main;
19624   vat_json_node_t *node = NULL;
19625   u8 *sw_if_from_name = 0;
19626   u8 *sw_if_to_name = 0;
19627   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19628   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19629   hash_pair_t *p;
19630
19631   /* *INDENT-OFF* */
19632   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19633   ({
19634     if ((u32) p->value[0] == sw_if_index_from)
19635       {
19636         sw_if_from_name = (u8 *)(p->key);
19637         if (sw_if_to_name)
19638           break;
19639       }
19640     if ((u32) p->value[0] == sw_if_index_to)
19641       {
19642         sw_if_to_name = (u8 *)(p->key);
19643         if (sw_if_from_name)
19644           break;
19645       }
19646   }));
19647   /* *INDENT-ON* */
19648
19649   if (VAT_JSON_ARRAY != vam->json_tree.type)
19650     {
19651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19652       vat_json_init_array (&vam->json_tree);
19653     }
19654   node = vat_json_array_add (&vam->json_tree);
19655
19656   vat_json_init_object (node);
19657   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19658   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19659   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19660   if (0 != sw_if_to_name)
19661     {
19662       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19663     }
19664   vat_json_object_add_uint (node, "state", mp->state);
19665   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19666 }
19667
19668 static int
19669 api_sw_interface_span_dump (vat_main_t * vam)
19670 {
19671   unformat_input_t *input = vam->input;
19672   vl_api_sw_interface_span_dump_t *mp;
19673   vl_api_control_ping_t *mp_ping;
19674   u8 is_l2 = 0;
19675   int ret;
19676
19677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19678     {
19679       if (unformat (input, "l2"))
19680         is_l2 = 1;
19681       else
19682         break;
19683     }
19684
19685   M (SW_INTERFACE_SPAN_DUMP, mp);
19686   mp->is_l2 = is_l2;
19687   S (mp);
19688
19689   /* Use a control ping for synchronization */
19690   MPING (CONTROL_PING, mp_ping);
19691   S (mp_ping);
19692
19693   W (ret);
19694   return ret;
19695 }
19696
19697 int
19698 api_pg_create_interface (vat_main_t * vam)
19699 {
19700   unformat_input_t *input = vam->input;
19701   vl_api_pg_create_interface_t *mp;
19702
19703   u32 if_id = ~0, gso_size = 0;
19704   u8 gso_enabled = 0;
19705   int ret;
19706   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19707     {
19708       if (unformat (input, "if_id %d", &if_id))
19709         ;
19710       else if (unformat (input, "gso-enabled"))
19711         {
19712           gso_enabled = 1;
19713           if (unformat (input, "gso-size %u", &gso_size))
19714             ;
19715           else
19716             {
19717               errmsg ("missing gso-size");
19718               return -99;
19719             }
19720         }
19721       else
19722         break;
19723     }
19724   if (if_id == ~0)
19725     {
19726       errmsg ("missing pg interface index");
19727       return -99;
19728     }
19729
19730   /* Construct the API message */
19731   M (PG_CREATE_INTERFACE, mp);
19732   mp->context = 0;
19733   mp->interface_id = ntohl (if_id);
19734   mp->gso_enabled = gso_enabled;
19735
19736   S (mp);
19737   W (ret);
19738   return ret;
19739 }
19740
19741 int
19742 api_pg_capture (vat_main_t * vam)
19743 {
19744   unformat_input_t *input = vam->input;
19745   vl_api_pg_capture_t *mp;
19746
19747   u32 if_id = ~0;
19748   u8 enable = 1;
19749   u32 count = 1;
19750   u8 pcap_file_set = 0;
19751   u8 *pcap_file = 0;
19752   int ret;
19753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19754     {
19755       if (unformat (input, "if_id %d", &if_id))
19756         ;
19757       else if (unformat (input, "pcap %s", &pcap_file))
19758         pcap_file_set = 1;
19759       else if (unformat (input, "count %d", &count))
19760         ;
19761       else if (unformat (input, "disable"))
19762         enable = 0;
19763       else
19764         break;
19765     }
19766   if (if_id == ~0)
19767     {
19768       errmsg ("missing pg interface index");
19769       return -99;
19770     }
19771   if (pcap_file_set > 0)
19772     {
19773       if (vec_len (pcap_file) > 255)
19774         {
19775           errmsg ("pcap file name is too long");
19776           return -99;
19777         }
19778     }
19779
19780   u32 name_len = vec_len (pcap_file);
19781   /* Construct the API message */
19782   M (PG_CAPTURE, mp);
19783   mp->context = 0;
19784   mp->interface_id = ntohl (if_id);
19785   mp->is_enabled = enable;
19786   mp->count = ntohl (count);
19787   mp->pcap_name_length = ntohl (name_len);
19788   if (pcap_file_set != 0)
19789     {
19790       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19791     }
19792   vec_free (pcap_file);
19793
19794   S (mp);
19795   W (ret);
19796   return ret;
19797 }
19798
19799 int
19800 api_pg_enable_disable (vat_main_t * vam)
19801 {
19802   unformat_input_t *input = vam->input;
19803   vl_api_pg_enable_disable_t *mp;
19804
19805   u8 enable = 1;
19806   u8 stream_name_set = 0;
19807   u8 *stream_name = 0;
19808   int ret;
19809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19810     {
19811       if (unformat (input, "stream %s", &stream_name))
19812         stream_name_set = 1;
19813       else if (unformat (input, "disable"))
19814         enable = 0;
19815       else
19816         break;
19817     }
19818
19819   if (stream_name_set > 0)
19820     {
19821       if (vec_len (stream_name) > 255)
19822         {
19823           errmsg ("stream name too long");
19824           return -99;
19825         }
19826     }
19827
19828   u32 name_len = vec_len (stream_name);
19829   /* Construct the API message */
19830   M (PG_ENABLE_DISABLE, mp);
19831   mp->context = 0;
19832   mp->is_enabled = enable;
19833   if (stream_name_set != 0)
19834     {
19835       mp->stream_name_length = ntohl (name_len);
19836       clib_memcpy (mp->stream_name, stream_name, name_len);
19837     }
19838   vec_free (stream_name);
19839
19840   S (mp);
19841   W (ret);
19842   return ret;
19843 }
19844
19845 int
19846 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19847 {
19848   unformat_input_t *input = vam->input;
19849   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19850
19851   u16 *low_ports = 0;
19852   u16 *high_ports = 0;
19853   u16 this_low;
19854   u16 this_hi;
19855   vl_api_prefix_t prefix;
19856   u32 tmp, tmp2;
19857   u8 prefix_set = 0;
19858   u32 vrf_id = ~0;
19859   u8 is_add = 1;
19860   int ret;
19861
19862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19863     {
19864       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19865         prefix_set = 1;
19866       else if (unformat (input, "vrf %d", &vrf_id))
19867         ;
19868       else if (unformat (input, "del"))
19869         is_add = 0;
19870       else if (unformat (input, "port %d", &tmp))
19871         {
19872           if (tmp == 0 || tmp > 65535)
19873             {
19874               errmsg ("port %d out of range", tmp);
19875               return -99;
19876             }
19877           this_low = tmp;
19878           this_hi = this_low + 1;
19879           vec_add1 (low_ports, this_low);
19880           vec_add1 (high_ports, this_hi);
19881         }
19882       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19883         {
19884           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19885             {
19886               errmsg ("incorrect range parameters");
19887               return -99;
19888             }
19889           this_low = tmp;
19890           /* Note: in debug CLI +1 is added to high before
19891              passing to real fn that does "the work"
19892              (ip_source_and_port_range_check_add_del).
19893              This fn is a wrapper around the binary API fn a
19894              control plane will call, which expects this increment
19895              to have occurred. Hence letting the binary API control
19896              plane fn do the increment for consistency between VAT
19897              and other control planes.
19898            */
19899           this_hi = tmp2;
19900           vec_add1 (low_ports, this_low);
19901           vec_add1 (high_ports, this_hi);
19902         }
19903       else
19904         break;
19905     }
19906
19907   if (prefix_set == 0)
19908     {
19909       errmsg ("<address>/<mask> not specified");
19910       return -99;
19911     }
19912
19913   if (vrf_id == ~0)
19914     {
19915       errmsg ("VRF ID required, not specified");
19916       return -99;
19917     }
19918
19919   if (vrf_id == 0)
19920     {
19921       errmsg
19922         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19923       return -99;
19924     }
19925
19926   if (vec_len (low_ports) == 0)
19927     {
19928       errmsg ("At least one port or port range required");
19929       return -99;
19930     }
19931
19932   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19933
19934   mp->is_add = is_add;
19935
19936   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19937
19938   mp->number_of_ranges = vec_len (low_ports);
19939
19940   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19941   vec_free (low_ports);
19942
19943   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19944   vec_free (high_ports);
19945
19946   mp->vrf_id = ntohl (vrf_id);
19947
19948   S (mp);
19949   W (ret);
19950   return ret;
19951 }
19952
19953 int
19954 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19955 {
19956   unformat_input_t *input = vam->input;
19957   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19958   u32 sw_if_index = ~0;
19959   int vrf_set = 0;
19960   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19961   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19962   u8 is_add = 1;
19963   int ret;
19964
19965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19966     {
19967       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19968         ;
19969       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19970         ;
19971       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19972         vrf_set = 1;
19973       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19974         vrf_set = 1;
19975       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19976         vrf_set = 1;
19977       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19978         vrf_set = 1;
19979       else if (unformat (input, "del"))
19980         is_add = 0;
19981       else
19982         break;
19983     }
19984
19985   if (sw_if_index == ~0)
19986     {
19987       errmsg ("Interface required but not specified");
19988       return -99;
19989     }
19990
19991   if (vrf_set == 0)
19992     {
19993       errmsg ("VRF ID required but not specified");
19994       return -99;
19995     }
19996
19997   if (tcp_out_vrf_id == 0
19998       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19999     {
20000       errmsg
20001         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20002       return -99;
20003     }
20004
20005   /* Construct the API message */
20006   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20007
20008   mp->sw_if_index = ntohl (sw_if_index);
20009   mp->is_add = is_add;
20010   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20011   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20012   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20013   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20014
20015   /* send it... */
20016   S (mp);
20017
20018   /* Wait for a reply... */
20019   W (ret);
20020   return ret;
20021 }
20022
20023 static int
20024 api_set_punt (vat_main_t * vam)
20025 {
20026   unformat_input_t *i = vam->input;
20027   vl_api_address_family_t af;
20028   vl_api_set_punt_t *mp;
20029   u32 protocol = ~0;
20030   u32 port = ~0;
20031   int is_add = 1;
20032   int ret;
20033
20034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20035     {
20036       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
20037         ;
20038       else if (unformat (i, "protocol %d", &protocol))
20039         ;
20040       else if (unformat (i, "port %d", &port))
20041         ;
20042       else if (unformat (i, "del"))
20043         is_add = 0;
20044       else
20045         {
20046           clib_warning ("parse error '%U'", format_unformat_error, i);
20047           return -99;
20048         }
20049     }
20050
20051   M (SET_PUNT, mp);
20052
20053   mp->is_add = (u8) is_add;
20054   mp->punt.type = PUNT_API_TYPE_L4;
20055   mp->punt.punt.l4.af = af;
20056   mp->punt.punt.l4.protocol = (u8) protocol;
20057   mp->punt.punt.l4.port = htons ((u16) port);
20058
20059   S (mp);
20060   W (ret);
20061   return ret;
20062 }
20063
20064 static int
20065 api_delete_subif (vat_main_t * vam)
20066 {
20067   unformat_input_t *i = vam->input;
20068   vl_api_delete_subif_t *mp;
20069   u32 sw_if_index = ~0;
20070   int ret;
20071
20072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20073     {
20074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20075         ;
20076       if (unformat (i, "sw_if_index %d", &sw_if_index))
20077         ;
20078       else
20079         break;
20080     }
20081
20082   if (sw_if_index == ~0)
20083     {
20084       errmsg ("missing sw_if_index");
20085       return -99;
20086     }
20087
20088   /* Construct the API message */
20089   M (DELETE_SUBIF, mp);
20090   mp->sw_if_index = ntohl (sw_if_index);
20091
20092   S (mp);
20093   W (ret);
20094   return ret;
20095 }
20096
20097 #define foreach_pbb_vtr_op      \
20098 _("disable",  L2_VTR_DISABLED)  \
20099 _("pop",  L2_VTR_POP_2)         \
20100 _("push",  L2_VTR_PUSH_2)
20101
20102 static int
20103 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20104 {
20105   unformat_input_t *i = vam->input;
20106   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20107   u32 sw_if_index = ~0, vtr_op = ~0;
20108   u16 outer_tag = ~0;
20109   u8 dmac[6], smac[6];
20110   u8 dmac_set = 0, smac_set = 0;
20111   u16 vlanid = 0;
20112   u32 sid = ~0;
20113   u32 tmp;
20114   int ret;
20115
20116   /* Shut up coverity */
20117   clib_memset (dmac, 0, sizeof (dmac));
20118   clib_memset (smac, 0, sizeof (smac));
20119
20120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20121     {
20122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20123         ;
20124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20125         ;
20126       else if (unformat (i, "vtr_op %d", &vtr_op))
20127         ;
20128 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20129       foreach_pbb_vtr_op
20130 #undef _
20131         else if (unformat (i, "translate_pbb_stag"))
20132         {
20133           if (unformat (i, "%d", &tmp))
20134             {
20135               vtr_op = L2_VTR_TRANSLATE_2_1;
20136               outer_tag = tmp;
20137             }
20138           else
20139             {
20140               errmsg
20141                 ("translate_pbb_stag operation requires outer tag definition");
20142               return -99;
20143             }
20144         }
20145       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20146         dmac_set++;
20147       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20148         smac_set++;
20149       else if (unformat (i, "sid %d", &sid))
20150         ;
20151       else if (unformat (i, "vlanid %d", &tmp))
20152         vlanid = tmp;
20153       else
20154         {
20155           clib_warning ("parse error '%U'", format_unformat_error, i);
20156           return -99;
20157         }
20158     }
20159
20160   if ((sw_if_index == ~0) || (vtr_op == ~0))
20161     {
20162       errmsg ("missing sw_if_index or vtr operation");
20163       return -99;
20164     }
20165   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20166       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20167     {
20168       errmsg
20169         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20170       return -99;
20171     }
20172
20173   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20174   mp->sw_if_index = ntohl (sw_if_index);
20175   mp->vtr_op = ntohl (vtr_op);
20176   mp->outer_tag = ntohs (outer_tag);
20177   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20178   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20179   mp->b_vlanid = ntohs (vlanid);
20180   mp->i_sid = ntohl (sid);
20181
20182   S (mp);
20183   W (ret);
20184   return ret;
20185 }
20186
20187 static int
20188 api_flow_classify_set_interface (vat_main_t * vam)
20189 {
20190   unformat_input_t *i = vam->input;
20191   vl_api_flow_classify_set_interface_t *mp;
20192   u32 sw_if_index;
20193   int sw_if_index_set;
20194   u32 ip4_table_index = ~0;
20195   u32 ip6_table_index = ~0;
20196   u8 is_add = 1;
20197   int ret;
20198
20199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20200     {
20201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20202         sw_if_index_set = 1;
20203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20204         sw_if_index_set = 1;
20205       else if (unformat (i, "del"))
20206         is_add = 0;
20207       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20208         ;
20209       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20210         ;
20211       else
20212         {
20213           clib_warning ("parse error '%U'", format_unformat_error, i);
20214           return -99;
20215         }
20216     }
20217
20218   if (sw_if_index_set == 0)
20219     {
20220       errmsg ("missing interface name or sw_if_index");
20221       return -99;
20222     }
20223
20224   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20225
20226   mp->sw_if_index = ntohl (sw_if_index);
20227   mp->ip4_table_index = ntohl (ip4_table_index);
20228   mp->ip6_table_index = ntohl (ip6_table_index);
20229   mp->is_add = is_add;
20230
20231   S (mp);
20232   W (ret);
20233   return ret;
20234 }
20235
20236 static int
20237 api_flow_classify_dump (vat_main_t * vam)
20238 {
20239   unformat_input_t *i = vam->input;
20240   vl_api_flow_classify_dump_t *mp;
20241   vl_api_control_ping_t *mp_ping;
20242   u8 type = FLOW_CLASSIFY_N_TABLES;
20243   int ret;
20244
20245   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20246     ;
20247   else
20248     {
20249       errmsg ("classify table type must be specified");
20250       return -99;
20251     }
20252
20253   if (!vam->json_output)
20254     {
20255       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20256     }
20257
20258   M (FLOW_CLASSIFY_DUMP, mp);
20259   mp->type = type;
20260   /* send it... */
20261   S (mp);
20262
20263   /* Use a control ping for synchronization */
20264   MPING (CONTROL_PING, mp_ping);
20265   S (mp_ping);
20266
20267   /* Wait for a reply... */
20268   W (ret);
20269   return ret;
20270 }
20271
20272 static int
20273 api_feature_enable_disable (vat_main_t * vam)
20274 {
20275   unformat_input_t *i = vam->input;
20276   vl_api_feature_enable_disable_t *mp;
20277   u8 *arc_name = 0;
20278   u8 *feature_name = 0;
20279   u32 sw_if_index = ~0;
20280   u8 enable = 1;
20281   int ret;
20282
20283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20284     {
20285       if (unformat (i, "arc_name %s", &arc_name))
20286         ;
20287       else if (unformat (i, "feature_name %s", &feature_name))
20288         ;
20289       else
20290         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20291         ;
20292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20293         ;
20294       else if (unformat (i, "disable"))
20295         enable = 0;
20296       else
20297         break;
20298     }
20299
20300   if (arc_name == 0)
20301     {
20302       errmsg ("missing arc name");
20303       return -99;
20304     }
20305   if (vec_len (arc_name) > 63)
20306     {
20307       errmsg ("arc name too long");
20308     }
20309
20310   if (feature_name == 0)
20311     {
20312       errmsg ("missing feature name");
20313       return -99;
20314     }
20315   if (vec_len (feature_name) > 63)
20316     {
20317       errmsg ("feature name too long");
20318     }
20319
20320   if (sw_if_index == ~0)
20321     {
20322       errmsg ("missing interface name or sw_if_index");
20323       return -99;
20324     }
20325
20326   /* Construct the API message */
20327   M (FEATURE_ENABLE_DISABLE, mp);
20328   mp->sw_if_index = ntohl (sw_if_index);
20329   mp->enable = enable;
20330   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20331   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20332   vec_free (arc_name);
20333   vec_free (feature_name);
20334
20335   S (mp);
20336   W (ret);
20337   return ret;
20338 }
20339
20340 static int
20341 api_sw_interface_tag_add_del (vat_main_t * vam)
20342 {
20343   unformat_input_t *i = vam->input;
20344   vl_api_sw_interface_tag_add_del_t *mp;
20345   u32 sw_if_index = ~0;
20346   u8 *tag = 0;
20347   u8 enable = 1;
20348   int ret;
20349
20350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20351     {
20352       if (unformat (i, "tag %s", &tag))
20353         ;
20354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20355         ;
20356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20357         ;
20358       else if (unformat (i, "del"))
20359         enable = 0;
20360       else
20361         break;
20362     }
20363
20364   if (sw_if_index == ~0)
20365     {
20366       errmsg ("missing interface name or sw_if_index");
20367       return -99;
20368     }
20369
20370   if (enable && (tag == 0))
20371     {
20372       errmsg ("no tag specified");
20373       return -99;
20374     }
20375
20376   /* Construct the API message */
20377   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20378   mp->sw_if_index = ntohl (sw_if_index);
20379   mp->is_add = enable;
20380   if (enable)
20381     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20382   vec_free (tag);
20383
20384   S (mp);
20385   W (ret);
20386   return ret;
20387 }
20388
20389 static void vl_api_l2_xconnect_details_t_handler
20390   (vl_api_l2_xconnect_details_t * mp)
20391 {
20392   vat_main_t *vam = &vat_main;
20393
20394   print (vam->ofp, "%15d%15d",
20395          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20396 }
20397
20398 static void vl_api_l2_xconnect_details_t_handler_json
20399   (vl_api_l2_xconnect_details_t * mp)
20400 {
20401   vat_main_t *vam = &vat_main;
20402   vat_json_node_t *node = NULL;
20403
20404   if (VAT_JSON_ARRAY != vam->json_tree.type)
20405     {
20406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20407       vat_json_init_array (&vam->json_tree);
20408     }
20409   node = vat_json_array_add (&vam->json_tree);
20410
20411   vat_json_init_object (node);
20412   vat_json_object_add_uint (node, "rx_sw_if_index",
20413                             ntohl (mp->rx_sw_if_index));
20414   vat_json_object_add_uint (node, "tx_sw_if_index",
20415                             ntohl (mp->tx_sw_if_index));
20416 }
20417
20418 static int
20419 api_l2_xconnect_dump (vat_main_t * vam)
20420 {
20421   vl_api_l2_xconnect_dump_t *mp;
20422   vl_api_control_ping_t *mp_ping;
20423   int ret;
20424
20425   if (!vam->json_output)
20426     {
20427       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20428     }
20429
20430   M (L2_XCONNECT_DUMP, mp);
20431
20432   S (mp);
20433
20434   /* Use a control ping for synchronization */
20435   MPING (CONTROL_PING, mp_ping);
20436   S (mp_ping);
20437
20438   W (ret);
20439   return ret;
20440 }
20441
20442 static int
20443 api_hw_interface_set_mtu (vat_main_t * vam)
20444 {
20445   unformat_input_t *i = vam->input;
20446   vl_api_hw_interface_set_mtu_t *mp;
20447   u32 sw_if_index = ~0;
20448   u32 mtu = 0;
20449   int ret;
20450
20451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20452     {
20453       if (unformat (i, "mtu %d", &mtu))
20454         ;
20455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20456         ;
20457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20458         ;
20459       else
20460         break;
20461     }
20462
20463   if (sw_if_index == ~0)
20464     {
20465       errmsg ("missing interface name or sw_if_index");
20466       return -99;
20467     }
20468
20469   if (mtu == 0)
20470     {
20471       errmsg ("no mtu specified");
20472       return -99;
20473     }
20474
20475   /* Construct the API message */
20476   M (HW_INTERFACE_SET_MTU, mp);
20477   mp->sw_if_index = ntohl (sw_if_index);
20478   mp->mtu = ntohs ((u16) mtu);
20479
20480   S (mp);
20481   W (ret);
20482   return ret;
20483 }
20484
20485 static int
20486 api_p2p_ethernet_add (vat_main_t * vam)
20487 {
20488   unformat_input_t *i = vam->input;
20489   vl_api_p2p_ethernet_add_t *mp;
20490   u32 parent_if_index = ~0;
20491   u32 sub_id = ~0;
20492   u8 remote_mac[6];
20493   u8 mac_set = 0;
20494   int ret;
20495
20496   clib_memset (remote_mac, 0, sizeof (remote_mac));
20497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20498     {
20499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20500         ;
20501       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20502         ;
20503       else
20504         if (unformat
20505             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20506         mac_set++;
20507       else if (unformat (i, "sub_id %d", &sub_id))
20508         ;
20509       else
20510         {
20511           clib_warning ("parse error '%U'", format_unformat_error, i);
20512           return -99;
20513         }
20514     }
20515
20516   if (parent_if_index == ~0)
20517     {
20518       errmsg ("missing interface name or sw_if_index");
20519       return -99;
20520     }
20521   if (mac_set == 0)
20522     {
20523       errmsg ("missing remote mac address");
20524       return -99;
20525     }
20526   if (sub_id == ~0)
20527     {
20528       errmsg ("missing sub-interface id");
20529       return -99;
20530     }
20531
20532   M (P2P_ETHERNET_ADD, mp);
20533   mp->parent_if_index = ntohl (parent_if_index);
20534   mp->subif_id = ntohl (sub_id);
20535   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20536
20537   S (mp);
20538   W (ret);
20539   return ret;
20540 }
20541
20542 static int
20543 api_p2p_ethernet_del (vat_main_t * vam)
20544 {
20545   unformat_input_t *i = vam->input;
20546   vl_api_p2p_ethernet_del_t *mp;
20547   u32 parent_if_index = ~0;
20548   u8 remote_mac[6];
20549   u8 mac_set = 0;
20550   int ret;
20551
20552   clib_memset (remote_mac, 0, sizeof (remote_mac));
20553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20554     {
20555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20556         ;
20557       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20558         ;
20559       else
20560         if (unformat
20561             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20562         mac_set++;
20563       else
20564         {
20565           clib_warning ("parse error '%U'", format_unformat_error, i);
20566           return -99;
20567         }
20568     }
20569
20570   if (parent_if_index == ~0)
20571     {
20572       errmsg ("missing interface name or sw_if_index");
20573       return -99;
20574     }
20575   if (mac_set == 0)
20576     {
20577       errmsg ("missing remote mac address");
20578       return -99;
20579     }
20580
20581   M (P2P_ETHERNET_DEL, mp);
20582   mp->parent_if_index = ntohl (parent_if_index);
20583   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20584
20585   S (mp);
20586   W (ret);
20587   return ret;
20588 }
20589
20590 static int
20591 api_lldp_config (vat_main_t * vam)
20592 {
20593   unformat_input_t *i = vam->input;
20594   vl_api_lldp_config_t *mp;
20595   int tx_hold = 0;
20596   int tx_interval = 0;
20597   u8 *sys_name = NULL;
20598   int ret;
20599
20600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20601     {
20602       if (unformat (i, "system-name %s", &sys_name))
20603         ;
20604       else if (unformat (i, "tx-hold %d", &tx_hold))
20605         ;
20606       else if (unformat (i, "tx-interval %d", &tx_interval))
20607         ;
20608       else
20609         {
20610           clib_warning ("parse error '%U'", format_unformat_error, i);
20611           return -99;
20612         }
20613     }
20614
20615   vec_add1 (sys_name, 0);
20616
20617   M (LLDP_CONFIG, mp);
20618   mp->tx_hold = htonl (tx_hold);
20619   mp->tx_interval = htonl (tx_interval);
20620   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20621   vec_free (sys_name);
20622
20623   S (mp);
20624   W (ret);
20625   return ret;
20626 }
20627
20628 static int
20629 api_sw_interface_set_lldp (vat_main_t * vam)
20630 {
20631   unformat_input_t *i = vam->input;
20632   vl_api_sw_interface_set_lldp_t *mp;
20633   u32 sw_if_index = ~0;
20634   u32 enable = 1;
20635   u8 *port_desc = NULL, *mgmt_oid = NULL;
20636   ip4_address_t ip4_addr;
20637   ip6_address_t ip6_addr;
20638   int ret;
20639
20640   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20641   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20642
20643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20644     {
20645       if (unformat (i, "disable"))
20646         enable = 0;
20647       else
20648         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20649         ;
20650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20651         ;
20652       else if (unformat (i, "port-desc %s", &port_desc))
20653         ;
20654       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20655         ;
20656       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20657         ;
20658       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20659         ;
20660       else
20661         break;
20662     }
20663
20664   if (sw_if_index == ~0)
20665     {
20666       errmsg ("missing interface name or sw_if_index");
20667       return -99;
20668     }
20669
20670   /* Construct the API message */
20671   vec_add1 (port_desc, 0);
20672   vec_add1 (mgmt_oid, 0);
20673   M (SW_INTERFACE_SET_LLDP, mp);
20674   mp->sw_if_index = ntohl (sw_if_index);
20675   mp->enable = enable;
20676   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20677   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20678   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20679   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20680   vec_free (port_desc);
20681   vec_free (mgmt_oid);
20682
20683   S (mp);
20684   W (ret);
20685   return ret;
20686 }
20687
20688 static int
20689 api_tcp_configure_src_addresses (vat_main_t * vam)
20690 {
20691   vl_api_tcp_configure_src_addresses_t *mp;
20692   unformat_input_t *i = vam->input;
20693   ip4_address_t v4first, v4last;
20694   ip6_address_t v6first, v6last;
20695   u8 range_set = 0;
20696   u32 vrf_id = 0;
20697   int ret;
20698
20699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20700     {
20701       if (unformat (i, "%U - %U",
20702                     unformat_ip4_address, &v4first,
20703                     unformat_ip4_address, &v4last))
20704         {
20705           if (range_set)
20706             {
20707               errmsg ("one range per message (range already set)");
20708               return -99;
20709             }
20710           range_set = 1;
20711         }
20712       else if (unformat (i, "%U - %U",
20713                          unformat_ip6_address, &v6first,
20714                          unformat_ip6_address, &v6last))
20715         {
20716           if (range_set)
20717             {
20718               errmsg ("one range per message (range already set)");
20719               return -99;
20720             }
20721           range_set = 2;
20722         }
20723       else if (unformat (i, "vrf %d", &vrf_id))
20724         ;
20725       else
20726         break;
20727     }
20728
20729   if (range_set == 0)
20730     {
20731       errmsg ("address range not set");
20732       return -99;
20733     }
20734
20735   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20736   mp->vrf_id = ntohl (vrf_id);
20737   /* ipv6? */
20738   if (range_set == 2)
20739     {
20740       mp->is_ipv6 = 1;
20741       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20742       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20743     }
20744   else
20745     {
20746       mp->is_ipv6 = 0;
20747       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20748       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20749     }
20750   S (mp);
20751   W (ret);
20752   return ret;
20753 }
20754
20755 static void vl_api_app_namespace_add_del_reply_t_handler
20756   (vl_api_app_namespace_add_del_reply_t * mp)
20757 {
20758   vat_main_t *vam = &vat_main;
20759   i32 retval = ntohl (mp->retval);
20760   if (vam->async_mode)
20761     {
20762       vam->async_errors += (retval < 0);
20763     }
20764   else
20765     {
20766       vam->retval = retval;
20767       if (retval == 0)
20768         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20769       vam->result_ready = 1;
20770     }
20771 }
20772
20773 static void vl_api_app_namespace_add_del_reply_t_handler_json
20774   (vl_api_app_namespace_add_del_reply_t * mp)
20775 {
20776   vat_main_t *vam = &vat_main;
20777   vat_json_node_t node;
20778
20779   vat_json_init_object (&node);
20780   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20781   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20782
20783   vat_json_print (vam->ofp, &node);
20784   vat_json_free (&node);
20785
20786   vam->retval = ntohl (mp->retval);
20787   vam->result_ready = 1;
20788 }
20789
20790 static int
20791 api_app_namespace_add_del (vat_main_t * vam)
20792 {
20793   vl_api_app_namespace_add_del_t *mp;
20794   unformat_input_t *i = vam->input;
20795   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20796   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20797   u64 secret;
20798   int ret;
20799
20800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20801     {
20802       if (unformat (i, "id %_%v%_", &ns_id))
20803         ;
20804       else if (unformat (i, "secret %lu", &secret))
20805         secret_set = 1;
20806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20807         sw_if_index_set = 1;
20808       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20809         ;
20810       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20811         ;
20812       else
20813         break;
20814     }
20815   if (!ns_id || !secret_set || !sw_if_index_set)
20816     {
20817       errmsg ("namespace id, secret and sw_if_index must be set");
20818       return -99;
20819     }
20820   if (vec_len (ns_id) > 64)
20821     {
20822       errmsg ("namespace id too long");
20823       return -99;
20824     }
20825   M (APP_NAMESPACE_ADD_DEL, mp);
20826
20827   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20828   mp->namespace_id_len = vec_len (ns_id);
20829   mp->secret = clib_host_to_net_u64 (secret);
20830   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20831   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20832   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20833   vec_free (ns_id);
20834   S (mp);
20835   W (ret);
20836   return ret;
20837 }
20838
20839 static int
20840 api_sock_init_shm (vat_main_t * vam)
20841 {
20842 #if VPP_API_TEST_BUILTIN == 0
20843   unformat_input_t *i = vam->input;
20844   vl_api_shm_elem_config_t *config = 0;
20845   u64 size = 64 << 20;
20846   int rv;
20847
20848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20849     {
20850       if (unformat (i, "size %U", unformat_memory_size, &size))
20851         ;
20852       else
20853         break;
20854     }
20855
20856   /*
20857    * Canned custom ring allocator config.
20858    * Should probably parse all of this
20859    */
20860   vec_validate (config, 6);
20861   config[0].type = VL_API_VLIB_RING;
20862   config[0].size = 256;
20863   config[0].count = 32;
20864
20865   config[1].type = VL_API_VLIB_RING;
20866   config[1].size = 1024;
20867   config[1].count = 16;
20868
20869   config[2].type = VL_API_VLIB_RING;
20870   config[2].size = 4096;
20871   config[2].count = 2;
20872
20873   config[3].type = VL_API_CLIENT_RING;
20874   config[3].size = 256;
20875   config[3].count = 32;
20876
20877   config[4].type = VL_API_CLIENT_RING;
20878   config[4].size = 1024;
20879   config[4].count = 16;
20880
20881   config[5].type = VL_API_CLIENT_RING;
20882   config[5].size = 4096;
20883   config[5].count = 2;
20884
20885   config[6].type = VL_API_QUEUE;
20886   config[6].count = 128;
20887   config[6].size = sizeof (uword);
20888
20889   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20890   if (!rv)
20891     vam->client_index_invalid = 1;
20892   return rv;
20893 #else
20894   return -99;
20895 #endif
20896 }
20897
20898 static void
20899 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20900 {
20901   vat_main_t *vam = &vat_main;
20902
20903   if (mp->is_ip4)
20904     {
20905       print (vam->ofp,
20906              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20907              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20908              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20909              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20910              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20911              clib_net_to_host_u32 (mp->action_index), mp->tag);
20912     }
20913   else
20914     {
20915       print (vam->ofp,
20916              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20917              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20918              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20919              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20920              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20921              clib_net_to_host_u32 (mp->action_index), mp->tag);
20922     }
20923 }
20924
20925 static void
20926 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20927                                              mp)
20928 {
20929   vat_main_t *vam = &vat_main;
20930   vat_json_node_t *node = NULL;
20931   struct in6_addr ip6;
20932   struct in_addr ip4;
20933
20934   if (VAT_JSON_ARRAY != vam->json_tree.type)
20935     {
20936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20937       vat_json_init_array (&vam->json_tree);
20938     }
20939   node = vat_json_array_add (&vam->json_tree);
20940   vat_json_init_object (node);
20941
20942   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20943   vat_json_object_add_uint (node, "appns_index",
20944                             clib_net_to_host_u32 (mp->appns_index));
20945   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20946   vat_json_object_add_uint (node, "scope", mp->scope);
20947   vat_json_object_add_uint (node, "action_index",
20948                             clib_net_to_host_u32 (mp->action_index));
20949   vat_json_object_add_uint (node, "lcl_port",
20950                             clib_net_to_host_u16 (mp->lcl_port));
20951   vat_json_object_add_uint (node, "rmt_port",
20952                             clib_net_to_host_u16 (mp->rmt_port));
20953   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20954   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20955   vat_json_object_add_string_copy (node, "tag", mp->tag);
20956   if (mp->is_ip4)
20957     {
20958       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20959       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20960       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20961       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20962     }
20963   else
20964     {
20965       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20966       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20967       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20968       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20969     }
20970 }
20971
20972 static int
20973 api_session_rule_add_del (vat_main_t * vam)
20974 {
20975   vl_api_session_rule_add_del_t *mp;
20976   unformat_input_t *i = vam->input;
20977   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20978   u32 appns_index = 0, scope = 0;
20979   ip4_address_t lcl_ip4, rmt_ip4;
20980   ip6_address_t lcl_ip6, rmt_ip6;
20981   u8 is_ip4 = 1, conn_set = 0;
20982   u8 is_add = 1, *tag = 0;
20983   int ret;
20984
20985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20986     {
20987       if (unformat (i, "del"))
20988         is_add = 0;
20989       else if (unformat (i, "add"))
20990         ;
20991       else if (unformat (i, "proto tcp"))
20992         proto = 0;
20993       else if (unformat (i, "proto udp"))
20994         proto = 1;
20995       else if (unformat (i, "appns %d", &appns_index))
20996         ;
20997       else if (unformat (i, "scope %d", &scope))
20998         ;
20999       else if (unformat (i, "tag %_%v%_", &tag))
21000         ;
21001       else
21002         if (unformat
21003             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21004              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21005              &rmt_port))
21006         {
21007           is_ip4 = 1;
21008           conn_set = 1;
21009         }
21010       else
21011         if (unformat
21012             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21013              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21014              &rmt_port))
21015         {
21016           is_ip4 = 0;
21017           conn_set = 1;
21018         }
21019       else if (unformat (i, "action %d", &action))
21020         ;
21021       else
21022         break;
21023     }
21024   if (proto == ~0 || !conn_set || action == ~0)
21025     {
21026       errmsg ("transport proto, connection and action must be set");
21027       return -99;
21028     }
21029
21030   if (scope > 3)
21031     {
21032       errmsg ("scope should be 0-3");
21033       return -99;
21034     }
21035
21036   M (SESSION_RULE_ADD_DEL, mp);
21037
21038   mp->is_ip4 = is_ip4;
21039   mp->transport_proto = proto;
21040   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21041   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21042   mp->lcl_plen = lcl_plen;
21043   mp->rmt_plen = rmt_plen;
21044   mp->action_index = clib_host_to_net_u32 (action);
21045   mp->appns_index = clib_host_to_net_u32 (appns_index);
21046   mp->scope = scope;
21047   mp->is_add = is_add;
21048   if (is_ip4)
21049     {
21050       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21051       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21052     }
21053   else
21054     {
21055       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21056       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21057     }
21058   if (tag)
21059     {
21060       clib_memcpy (mp->tag, tag, vec_len (tag));
21061       vec_free (tag);
21062     }
21063
21064   S (mp);
21065   W (ret);
21066   return ret;
21067 }
21068
21069 static int
21070 api_session_rules_dump (vat_main_t * vam)
21071 {
21072   vl_api_session_rules_dump_t *mp;
21073   vl_api_control_ping_t *mp_ping;
21074   int ret;
21075
21076   if (!vam->json_output)
21077     {
21078       print (vam->ofp, "%=20s", "Session Rules");
21079     }
21080
21081   M (SESSION_RULES_DUMP, mp);
21082   /* send it... */
21083   S (mp);
21084
21085   /* Use a control ping for synchronization */
21086   MPING (CONTROL_PING, mp_ping);
21087   S (mp_ping);
21088
21089   /* Wait for a reply... */
21090   W (ret);
21091   return ret;
21092 }
21093
21094 static int
21095 api_ip_container_proxy_add_del (vat_main_t * vam)
21096 {
21097   vl_api_ip_container_proxy_add_del_t *mp;
21098   unformat_input_t *i = vam->input;
21099   u32 sw_if_index = ~0;
21100   vl_api_prefix_t pfx = { };
21101   u8 is_add = 1;
21102   int ret;
21103
21104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21105     {
21106       if (unformat (i, "del"))
21107         is_add = 0;
21108       else if (unformat (i, "add"))
21109         ;
21110       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
21111         ;
21112       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21113         ;
21114       else
21115         break;
21116     }
21117   if (sw_if_index == ~0 || pfx.len == 0)
21118     {
21119       errmsg ("address and sw_if_index must be set");
21120       return -99;
21121     }
21122
21123   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21124
21125   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21126   mp->is_add = is_add;
21127   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
21128
21129   S (mp);
21130   W (ret);
21131   return ret;
21132 }
21133
21134 static int
21135 api_qos_record_enable_disable (vat_main_t * vam)
21136 {
21137   unformat_input_t *i = vam->input;
21138   vl_api_qos_record_enable_disable_t *mp;
21139   u32 sw_if_index, qs = 0xff;
21140   u8 sw_if_index_set = 0;
21141   u8 enable = 1;
21142   int ret;
21143
21144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21145     {
21146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21147         sw_if_index_set = 1;
21148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21149         sw_if_index_set = 1;
21150       else if (unformat (i, "%U", unformat_qos_source, &qs))
21151         ;
21152       else if (unformat (i, "disable"))
21153         enable = 0;
21154       else
21155         {
21156           clib_warning ("parse error '%U'", format_unformat_error, i);
21157           return -99;
21158         }
21159     }
21160
21161   if (sw_if_index_set == 0)
21162     {
21163       errmsg ("missing interface name or sw_if_index");
21164       return -99;
21165     }
21166   if (qs == 0xff)
21167     {
21168       errmsg ("input location must be specified");
21169       return -99;
21170     }
21171
21172   M (QOS_RECORD_ENABLE_DISABLE, mp);
21173
21174   mp->record.sw_if_index = ntohl (sw_if_index);
21175   mp->record.input_source = qs;
21176   mp->enable = enable;
21177
21178   S (mp);
21179   W (ret);
21180   return ret;
21181 }
21182
21183
21184 static int
21185 q_or_quit (vat_main_t * vam)
21186 {
21187 #if VPP_API_TEST_BUILTIN == 0
21188   longjmp (vam->jump_buf, 1);
21189 #endif
21190   return 0;                     /* not so much */
21191 }
21192
21193 static int
21194 q (vat_main_t * vam)
21195 {
21196   return q_or_quit (vam);
21197 }
21198
21199 static int
21200 quit (vat_main_t * vam)
21201 {
21202   return q_or_quit (vam);
21203 }
21204
21205 static int
21206 comment (vat_main_t * vam)
21207 {
21208   return 0;
21209 }
21210
21211 static int
21212 elog_save (vat_main_t * vam)
21213 {
21214 #if VPP_API_TEST_BUILTIN == 0
21215   elog_main_t *em = &vam->elog_main;
21216   unformat_input_t *i = vam->input;
21217   char *file, *chroot_file;
21218   clib_error_t *error;
21219
21220   if (!unformat (i, "%s", &file))
21221     {
21222       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21223       return 0;
21224     }
21225
21226   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21227   if (strstr (file, "..") || index (file, '/'))
21228     {
21229       errmsg ("illegal characters in filename '%s'", file);
21230       return 0;
21231     }
21232
21233   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21234
21235   vec_free (file);
21236
21237   errmsg ("Saving %wd of %wd events to %s",
21238           elog_n_events_in_buffer (em),
21239           elog_buffer_capacity (em), chroot_file);
21240
21241   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21242   vec_free (chroot_file);
21243
21244   if (error)
21245     clib_error_report (error);
21246 #else
21247   errmsg ("Use the vpp event loger...");
21248 #endif
21249
21250   return 0;
21251 }
21252
21253 static int
21254 elog_setup (vat_main_t * vam)
21255 {
21256 #if VPP_API_TEST_BUILTIN == 0
21257   elog_main_t *em = &vam->elog_main;
21258   unformat_input_t *i = vam->input;
21259   u32 nevents = 128 << 10;
21260
21261   (void) unformat (i, "nevents %d", &nevents);
21262
21263   elog_init (em, nevents);
21264   vl_api_set_elog_main (em);
21265   vl_api_set_elog_trace_api_messages (1);
21266   errmsg ("Event logger initialized with %u events", nevents);
21267 #else
21268   errmsg ("Use the vpp event loger...");
21269 #endif
21270   return 0;
21271 }
21272
21273 static int
21274 elog_enable (vat_main_t * vam)
21275 {
21276 #if VPP_API_TEST_BUILTIN == 0
21277   elog_main_t *em = &vam->elog_main;
21278
21279   elog_enable_disable (em, 1 /* enable */ );
21280   vl_api_set_elog_trace_api_messages (1);
21281   errmsg ("Event logger enabled...");
21282 #else
21283   errmsg ("Use the vpp event loger...");
21284 #endif
21285   return 0;
21286 }
21287
21288 static int
21289 elog_disable (vat_main_t * vam)
21290 {
21291 #if VPP_API_TEST_BUILTIN == 0
21292   elog_main_t *em = &vam->elog_main;
21293
21294   elog_enable_disable (em, 0 /* enable */ );
21295   vl_api_set_elog_trace_api_messages (1);
21296   errmsg ("Event logger disabled...");
21297 #else
21298   errmsg ("Use the vpp event loger...");
21299 #endif
21300   return 0;
21301 }
21302
21303 static int
21304 statseg (vat_main_t * vam)
21305 {
21306   ssvm_private_t *ssvmp = &vam->stat_segment;
21307   ssvm_shared_header_t *shared_header = ssvmp->sh;
21308   vlib_counter_t **counters;
21309   u64 thread0_index1_packets;
21310   u64 thread0_index1_bytes;
21311   f64 vector_rate, input_rate;
21312   uword *p;
21313
21314   uword *counter_vector_by_name;
21315   if (vam->stat_segment_lockp == 0)
21316     {
21317       errmsg ("Stat segment not mapped...");
21318       return -99;
21319     }
21320
21321   /* look up "/if/rx for sw_if_index 1 as a test */
21322
21323   clib_spinlock_lock (vam->stat_segment_lockp);
21324
21325   counter_vector_by_name = (uword *) shared_header->opaque[1];
21326
21327   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21328   if (p == 0)
21329     {
21330       clib_spinlock_unlock (vam->stat_segment_lockp);
21331       errmsg ("/if/tx not found?");
21332       return -99;
21333     }
21334
21335   /* Fish per-thread vector of combined counters from shared memory */
21336   counters = (vlib_counter_t **) p[0];
21337
21338   if (vec_len (counters[0]) < 2)
21339     {
21340       clib_spinlock_unlock (vam->stat_segment_lockp);
21341       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21342       return -99;
21343     }
21344
21345   /* Read thread 0 sw_if_index 1 counter */
21346   thread0_index1_packets = counters[0][1].packets;
21347   thread0_index1_bytes = counters[0][1].bytes;
21348
21349   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21350   if (p == 0)
21351     {
21352       clib_spinlock_unlock (vam->stat_segment_lockp);
21353       errmsg ("vector_rate not found?");
21354       return -99;
21355     }
21356
21357   vector_rate = *(f64 *) (p[0]);
21358   p = hash_get_mem (counter_vector_by_name, "input_rate");
21359   if (p == 0)
21360     {
21361       clib_spinlock_unlock (vam->stat_segment_lockp);
21362       errmsg ("input_rate not found?");
21363       return -99;
21364     }
21365   input_rate = *(f64 *) (p[0]);
21366
21367   clib_spinlock_unlock (vam->stat_segment_lockp);
21368
21369   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21370          vector_rate, input_rate);
21371   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21372          thread0_index1_packets, thread0_index1_bytes);
21373
21374   return 0;
21375 }
21376
21377 static int
21378 cmd_cmp (void *a1, void *a2)
21379 {
21380   u8 **c1 = a1;
21381   u8 **c2 = a2;
21382
21383   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21384 }
21385
21386 static int
21387 help (vat_main_t * vam)
21388 {
21389   u8 **cmds = 0;
21390   u8 *name = 0;
21391   hash_pair_t *p;
21392   unformat_input_t *i = vam->input;
21393   int j;
21394
21395   if (unformat (i, "%s", &name))
21396     {
21397       uword *hs;
21398
21399       vec_add1 (name, 0);
21400
21401       hs = hash_get_mem (vam->help_by_name, name);
21402       if (hs)
21403         print (vam->ofp, "usage: %s %s", name, hs[0]);
21404       else
21405         print (vam->ofp, "No such msg / command '%s'", name);
21406       vec_free (name);
21407       return 0;
21408     }
21409
21410   print (vam->ofp, "Help is available for the following:");
21411
21412     /* *INDENT-OFF* */
21413     hash_foreach_pair (p, vam->function_by_name,
21414     ({
21415       vec_add1 (cmds, (u8 *)(p->key));
21416     }));
21417     /* *INDENT-ON* */
21418
21419   vec_sort_with_function (cmds, cmd_cmp);
21420
21421   for (j = 0; j < vec_len (cmds); j++)
21422     print (vam->ofp, "%s", cmds[j]);
21423
21424   vec_free (cmds);
21425   return 0;
21426 }
21427
21428 static int
21429 set (vat_main_t * vam)
21430 {
21431   u8 *name = 0, *value = 0;
21432   unformat_input_t *i = vam->input;
21433
21434   if (unformat (i, "%s", &name))
21435     {
21436       /* The input buffer is a vector, not a string. */
21437       value = vec_dup (i->buffer);
21438       vec_delete (value, i->index, 0);
21439       /* Almost certainly has a trailing newline */
21440       if (value[vec_len (value) - 1] == '\n')
21441         value[vec_len (value) - 1] = 0;
21442       /* Make sure it's a proper string, one way or the other */
21443       vec_add1 (value, 0);
21444       (void) clib_macro_set_value (&vam->macro_main,
21445                                    (char *) name, (char *) value);
21446     }
21447   else
21448     errmsg ("usage: set <name> <value>");
21449
21450   vec_free (name);
21451   vec_free (value);
21452   return 0;
21453 }
21454
21455 static int
21456 unset (vat_main_t * vam)
21457 {
21458   u8 *name = 0;
21459
21460   if (unformat (vam->input, "%s", &name))
21461     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21462       errmsg ("unset: %s wasn't set", name);
21463   vec_free (name);
21464   return 0;
21465 }
21466
21467 typedef struct
21468 {
21469   u8 *name;
21470   u8 *value;
21471 } macro_sort_t;
21472
21473
21474 static int
21475 macro_sort_cmp (void *a1, void *a2)
21476 {
21477   macro_sort_t *s1 = a1;
21478   macro_sort_t *s2 = a2;
21479
21480   return strcmp ((char *) (s1->name), (char *) (s2->name));
21481 }
21482
21483 static int
21484 dump_macro_table (vat_main_t * vam)
21485 {
21486   macro_sort_t *sort_me = 0, *sm;
21487   int i;
21488   hash_pair_t *p;
21489
21490     /* *INDENT-OFF* */
21491     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21492     ({
21493       vec_add2 (sort_me, sm, 1);
21494       sm->name = (u8 *)(p->key);
21495       sm->value = (u8 *) (p->value[0]);
21496     }));
21497     /* *INDENT-ON* */
21498
21499   vec_sort_with_function (sort_me, macro_sort_cmp);
21500
21501   if (vec_len (sort_me))
21502     print (vam->ofp, "%-15s%s", "Name", "Value");
21503   else
21504     print (vam->ofp, "The macro table is empty...");
21505
21506   for (i = 0; i < vec_len (sort_me); i++)
21507     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21508   return 0;
21509 }
21510
21511 static int
21512 dump_node_table (vat_main_t * vam)
21513 {
21514   int i, j;
21515   vlib_node_t *node, *next_node;
21516
21517   if (vec_len (vam->graph_nodes) == 0)
21518     {
21519       print (vam->ofp, "Node table empty, issue get_node_graph...");
21520       return 0;
21521     }
21522
21523   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21524     {
21525       node = vam->graph_nodes[0][i];
21526       print (vam->ofp, "[%d] %s", i, node->name);
21527       for (j = 0; j < vec_len (node->next_nodes); j++)
21528         {
21529           if (node->next_nodes[j] != ~0)
21530             {
21531               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21532               print (vam->ofp, "  [%d] %s", j, next_node->name);
21533             }
21534         }
21535     }
21536   return 0;
21537 }
21538
21539 static int
21540 value_sort_cmp (void *a1, void *a2)
21541 {
21542   name_sort_t *n1 = a1;
21543   name_sort_t *n2 = a2;
21544
21545   if (n1->value < n2->value)
21546     return -1;
21547   if (n1->value > n2->value)
21548     return 1;
21549   return 0;
21550 }
21551
21552
21553 static int
21554 dump_msg_api_table (vat_main_t * vam)
21555 {
21556   api_main_t *am = &api_main;
21557   name_sort_t *nses = 0, *ns;
21558   hash_pair_t *hp;
21559   int i;
21560
21561   /* *INDENT-OFF* */
21562   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21563   ({
21564     vec_add2 (nses, ns, 1);
21565     ns->name = (u8 *)(hp->key);
21566     ns->value = (u32) hp->value[0];
21567   }));
21568   /* *INDENT-ON* */
21569
21570   vec_sort_with_function (nses, value_sort_cmp);
21571
21572   for (i = 0; i < vec_len (nses); i++)
21573     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21574   vec_free (nses);
21575   return 0;
21576 }
21577
21578 static int
21579 get_msg_id (vat_main_t * vam)
21580 {
21581   u8 *name_and_crc;
21582   u32 message_index;
21583
21584   if (unformat (vam->input, "%s", &name_and_crc))
21585     {
21586       message_index = vl_msg_api_get_msg_index (name_and_crc);
21587       if (message_index == ~0)
21588         {
21589           print (vam->ofp, " '%s' not found", name_and_crc);
21590           return 0;
21591         }
21592       print (vam->ofp, " '%s' has message index %d",
21593              name_and_crc, message_index);
21594       return 0;
21595     }
21596   errmsg ("name_and_crc required...");
21597   return 0;
21598 }
21599
21600 static int
21601 search_node_table (vat_main_t * vam)
21602 {
21603   unformat_input_t *line_input = vam->input;
21604   u8 *node_to_find;
21605   int j;
21606   vlib_node_t *node, *next_node;
21607   uword *p;
21608
21609   if (vam->graph_node_index_by_name == 0)
21610     {
21611       print (vam->ofp, "Node table empty, issue get_node_graph...");
21612       return 0;
21613     }
21614
21615   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21616     {
21617       if (unformat (line_input, "%s", &node_to_find))
21618         {
21619           vec_add1 (node_to_find, 0);
21620           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21621           if (p == 0)
21622             {
21623               print (vam->ofp, "%s not found...", node_to_find);
21624               goto out;
21625             }
21626           node = vam->graph_nodes[0][p[0]];
21627           print (vam->ofp, "[%d] %s", p[0], node->name);
21628           for (j = 0; j < vec_len (node->next_nodes); j++)
21629             {
21630               if (node->next_nodes[j] != ~0)
21631                 {
21632                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21633                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21634                 }
21635             }
21636         }
21637
21638       else
21639         {
21640           clib_warning ("parse error '%U'", format_unformat_error,
21641                         line_input);
21642           return -99;
21643         }
21644
21645     out:
21646       vec_free (node_to_find);
21647
21648     }
21649
21650   return 0;
21651 }
21652
21653
21654 static int
21655 script (vat_main_t * vam)
21656 {
21657 #if (VPP_API_TEST_BUILTIN==0)
21658   u8 *s = 0;
21659   char *save_current_file;
21660   unformat_input_t save_input;
21661   jmp_buf save_jump_buf;
21662   u32 save_line_number;
21663
21664   FILE *new_fp, *save_ifp;
21665
21666   if (unformat (vam->input, "%s", &s))
21667     {
21668       new_fp = fopen ((char *) s, "r");
21669       if (new_fp == 0)
21670         {
21671           errmsg ("Couldn't open script file %s", s);
21672           vec_free (s);
21673           return -99;
21674         }
21675     }
21676   else
21677     {
21678       errmsg ("Missing script name");
21679       return -99;
21680     }
21681
21682   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21683   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21684   save_ifp = vam->ifp;
21685   save_line_number = vam->input_line_number;
21686   save_current_file = (char *) vam->current_file;
21687
21688   vam->input_line_number = 0;
21689   vam->ifp = new_fp;
21690   vam->current_file = s;
21691   do_one_file (vam);
21692
21693   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21694   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21695   vam->ifp = save_ifp;
21696   vam->input_line_number = save_line_number;
21697   vam->current_file = (u8 *) save_current_file;
21698   vec_free (s);
21699
21700   return 0;
21701 #else
21702   clib_warning ("use the exec command...");
21703   return -99;
21704 #endif
21705 }
21706
21707 static int
21708 echo (vat_main_t * vam)
21709 {
21710   print (vam->ofp, "%v", vam->input->buffer);
21711   return 0;
21712 }
21713
21714 /* List of API message constructors, CLI names map to api_xxx */
21715 #define foreach_vpe_api_msg                                             \
21716 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21717 _(sw_interface_dump,"")                                                 \
21718 _(sw_interface_set_flags,                                               \
21719   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21720 _(sw_interface_add_del_address,                                         \
21721   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21722 _(sw_interface_set_rx_mode,                                             \
21723   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21724 _(sw_interface_set_rx_placement,                                        \
21725   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21726 _(sw_interface_rx_placement_dump,                                       \
21727   "[<intfc> | sw_if_index <id>]")                                         \
21728 _(sw_interface_set_table,                                               \
21729   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21730 _(sw_interface_set_mpls_enable,                                         \
21731   "<intfc> | sw_if_index [disable | dis]")                              \
21732 _(sw_interface_set_vpath,                                               \
21733   "<intfc> | sw_if_index <id> enable | disable")                        \
21734 _(sw_interface_set_vxlan_bypass,                                        \
21735   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21736 _(sw_interface_set_geneve_bypass,                                       \
21737   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21738 _(sw_interface_set_l2_xconnect,                                         \
21739   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21740   "enable | disable")                                                   \
21741 _(sw_interface_set_l2_bridge,                                           \
21742   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21743   "[shg <split-horizon-group>] [bvi]\n"                                 \
21744   "enable | disable")                                                   \
21745 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21746 _(bridge_domain_add_del,                                                \
21747   "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") \
21748 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21749 _(l2fib_add_del,                                                        \
21750   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21751 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21752 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21753 _(l2_flags,                                                             \
21754   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21755 _(bridge_flags,                                                         \
21756   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21757 _(tap_create_v2,                                                        \
21758   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21759 _(tap_delete_v2,                                                        \
21760   "<vpp-if-name> | sw_if_index <id>")                                   \
21761 _(sw_interface_tap_v2_dump, "")                                         \
21762 _(virtio_pci_create,                                                    \
21763   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21764 _(virtio_pci_delete,                                                    \
21765   "<vpp-if-name> | sw_if_index <id>")                                   \
21766 _(sw_interface_virtio_pci_dump, "")                                     \
21767 _(bond_create,                                                          \
21768   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21769   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21770   "[id <if-id>]")                                                       \
21771 _(bond_delete,                                                          \
21772   "<vpp-if-name> | sw_if_index <id>")                                   \
21773 _(bond_enslave,                                                         \
21774   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21775 _(bond_detach_slave,                                                    \
21776   "sw_if_index <n>")                                                    \
21777  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21778 _(sw_interface_bond_dump, "")                                           \
21779 _(sw_interface_slave_dump,                                              \
21780   "<vpp-if-name> | sw_if_index <id>")                                   \
21781 _(ip_table_add_del,                                                     \
21782   "table <n> [ipv6] [add | del]\n")                                     \
21783 _(ip_route_add_del,                                                     \
21784   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21785   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21786   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21787   "[multipath] [count <n>] [del]")                                      \
21788 _(ip_mroute_add_del,                                                    \
21789   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21790   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21791 _(mpls_table_add_del,                                                   \
21792   "table <n> [add | del]\n")                                            \
21793 _(mpls_route_add_del,                                                   \
21794   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21795   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21796   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21797   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21798   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21799   "[count <n>] [del]")                                                  \
21800 _(mpls_ip_bind_unbind,                                                  \
21801   "<label> <addr/len>")                                                 \
21802 _(mpls_tunnel_add_del,                                                  \
21803   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21804   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21805   "[l2-only]  [out-label <n>]")                                         \
21806 _(sr_mpls_policy_add,                                                   \
21807   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21808 _(sr_mpls_policy_del,                                                   \
21809   "bsid <id>")                                                          \
21810 _(bier_table_add_del,                                                   \
21811   "<label> <sub-domain> <set> <bsl> [del]")                             \
21812 _(bier_route_add_del,                                                   \
21813   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21814   "[<intfc> | sw_if_index <id>]"                                        \
21815   "[weight <n>] [del] [multipath]")                                     \
21816 _(proxy_arp_add_del,                                                    \
21817   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21818 _(proxy_arp_intfc_enable_disable,                                       \
21819   "<intfc> | sw_if_index <id> enable | disable")                        \
21820 _(sw_interface_set_unnumbered,                                          \
21821   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21822 _(ip_neighbor_add_del,                                                  \
21823   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21824   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21825 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21826 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21827   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21828   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21829   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21830 _(reset_fib, "vrf <n> [ipv6]")                                          \
21831 _(dhcp_proxy_config,                                                    \
21832   "svr <v46-address> src <v46-address>\n"                               \
21833    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21834 _(dhcp_proxy_set_vss,                                                   \
21835   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
21836 _(dhcp_proxy_dump, "ip6")                                               \
21837 _(dhcp_client_config,                                                   \
21838   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21839 _(set_ip_flow_hash,                                                     \
21840   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21841 _(sw_interface_ip6_enable_disable,                                      \
21842   "<intfc> | sw_if_index <id> enable | disable")                        \
21843 _(ip6nd_proxy_add_del,                                                  \
21844   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21845 _(ip6nd_proxy_dump, "")                                                 \
21846 _(sw_interface_ip6nd_ra_prefix,                                         \
21847   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21848   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21849   "[nolink] [isno]")                                                    \
21850 _(sw_interface_ip6nd_ra_config,                                         \
21851   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21852   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21853   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21854 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21855 _(l2_patch_add_del,                                                     \
21856   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21857   "enable | disable")                                                   \
21858 _(sr_localsid_add_del,                                                  \
21859   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21860   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21861 _(classify_add_del_table,                                               \
21862   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21863   " [del] [del-chain] mask <mask-value>\n"                              \
21864   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21865   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21866 _(classify_add_del_session,                                             \
21867   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21868   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21869   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21870   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21871 _(classify_set_interface_ip_table,                                      \
21872   "<intfc> | sw_if_index <nn> table <nn>")                              \
21873 _(classify_set_interface_l2_tables,                                     \
21874   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21875   "  [other-table <nn>]")                                               \
21876 _(get_node_index, "node <node-name")                                    \
21877 _(add_node_next, "node <node-name> next <next-node-name>")              \
21878 _(l2tpv3_create_tunnel,                                                 \
21879   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21880   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21881   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21882 _(l2tpv3_set_tunnel_cookies,                                            \
21883   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21884   "[new_remote_cookie <nn>]\n")                                         \
21885 _(l2tpv3_interface_enable_disable,                                      \
21886   "<intfc> | sw_if_index <nn> enable | disable")                        \
21887 _(l2tpv3_set_lookup_key,                                                \
21888   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21889 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21890 _(vxlan_offload_rx,                                                     \
21891   "hw { <interface name> | hw_if_index <nn>} "                          \
21892   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21893 _(vxlan_add_del_tunnel,                                                 \
21894   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21895   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21896   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21897 _(geneve_add_del_tunnel,                                                \
21898   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21899   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21900   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21901 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21902 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21903 _(gre_tunnel_add_del,                                                   \
21904   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21905   "[teb | erspan <session-id>] [del]")                                  \
21906 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21907 _(l2_fib_clear_table, "")                                               \
21908 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21909 _(l2_interface_vlan_tag_rewrite,                                        \
21910   "<intfc> | sw_if_index <nn> \n"                                       \
21911   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21912   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21913 _(create_vhost_user_if,                                                 \
21914         "socket <filename> [server] [renumber <dev_instance>] "         \
21915         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21916         "[mac <mac_address>]")                                          \
21917 _(modify_vhost_user_if,                                                 \
21918         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21919         "[server] [renumber <dev_instance>] [gso]")                     \
21920 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21921 _(sw_interface_vhost_user_dump, "")                                     \
21922 _(show_version, "")                                                     \
21923 _(show_threads, "")                                                     \
21924 _(vxlan_gpe_add_del_tunnel,                                             \
21925   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21926   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21927   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21928   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21929 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21930 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21931 _(interface_name_renumber,                                              \
21932   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21933 _(input_acl_set_interface,                                              \
21934   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21935   "  [l2-table <nn>] [del]")                                            \
21936 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21937 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21938   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21939 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21940 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21941 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21942 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21943 _(ip_dump, "ipv4 | ipv6")                                               \
21944 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21945 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21946   "  spid_id <n> ")                                                     \
21947 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21948   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21949   "  integ_alg <alg> integ_key <hex>")                                  \
21950 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21951   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21952   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21953   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21954 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21955   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21956   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21957   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21958   "  [instance <n>]")     \
21959 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21960 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21961 _(delete_loopback,"sw_if_index <nn>")                                   \
21962 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21963 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21964 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21965 _(want_interface_events,  "enable|disable")                             \
21966 _(get_first_msg_id, "client <name>")                                    \
21967 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21968 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21969   "fib-id <nn> [ip4][ip6][default]")                                    \
21970 _(get_node_graph, " ")                                                  \
21971 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21972 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21973 _(ioam_disable, "")                                                     \
21974 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21975                             " sw_if_index <sw_if_index> p <priority> "  \
21976                             "w <weight>] [del]")                        \
21977 _(one_add_del_locator, "locator-set <locator_name> "                    \
21978                         "iface <intf> | sw_if_index <sw_if_index> "     \
21979                         "p <priority> w <weight> [del]")                \
21980 _(one_add_del_local_eid,"vni <vni> eid "                                \
21981                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21982                          "locator-set <locator_name> [del]"             \
21983                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21984 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21985 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21986 _(one_enable_disable, "enable|disable")                                 \
21987 _(one_map_register_enable_disable, "enable|disable")                    \
21988 _(one_map_register_fallback_threshold, "<value>")                       \
21989 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21990 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21991                                "[seid <seid>] "                         \
21992                                "rloc <locator> p <prio> "               \
21993                                "w <weight> [rloc <loc> ... ] "          \
21994                                "action <action> [del-all]")             \
21995 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21996                           "<local-eid>")                                \
21997 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21998 _(one_use_petr, "ip-address> | disable")                                \
21999 _(one_map_request_mode, "src-dst|dst-only")                             \
22000 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22001 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22002 _(one_locator_set_dump, "[local | remote]")                             \
22003 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22004 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22005                        "[local] | [remote]")                            \
22006 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22007 _(one_ndp_bd_get, "")                                                   \
22008 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22009 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22010 _(one_l2_arp_bd_get, "")                                                \
22011 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22012 _(one_stats_enable_disable, "enable|disable")                           \
22013 _(show_one_stats_enable_disable, "")                                    \
22014 _(one_eid_table_vni_dump, "")                                           \
22015 _(one_eid_table_map_dump, "l2|l3")                                      \
22016 _(one_map_resolver_dump, "")                                            \
22017 _(one_map_server_dump, "")                                              \
22018 _(one_adjacencies_get, "vni <vni>")                                     \
22019 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22020 _(show_one_rloc_probe_state, "")                                        \
22021 _(show_one_map_register_state, "")                                      \
22022 _(show_one_status, "")                                                  \
22023 _(one_stats_dump, "")                                                   \
22024 _(one_stats_flush, "")                                                  \
22025 _(one_get_map_request_itr_rlocs, "")                                    \
22026 _(one_map_register_set_ttl, "<ttl>")                                    \
22027 _(one_set_transport_protocol, "udp|api")                                \
22028 _(one_get_transport_protocol, "")                                       \
22029 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22030 _(one_show_xtr_mode, "")                                                \
22031 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22032 _(one_show_pitr_mode, "")                                               \
22033 _(one_enable_disable_petr_mode, "enable|disable")                       \
22034 _(one_show_petr_mode, "")                                               \
22035 _(show_one_nsh_mapping, "")                                             \
22036 _(show_one_pitr, "")                                                    \
22037 _(show_one_use_petr, "")                                                \
22038 _(show_one_map_request_mode, "")                                        \
22039 _(show_one_map_register_ttl, "")                                        \
22040 _(show_one_map_register_fallback_threshold, "")                         \
22041 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22042                             " sw_if_index <sw_if_index> p <priority> "  \
22043                             "w <weight>] [del]")                        \
22044 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22045                         "iface <intf> | sw_if_index <sw_if_index> "     \
22046                         "p <priority> w <weight> [del]")                \
22047 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22048                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22049                          "locator-set <locator_name> [del]"             \
22050                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22051 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22052 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22053 _(lisp_enable_disable, "enable|disable")                                \
22054 _(lisp_map_register_enable_disable, "enable|disable")                   \
22055 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22056 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22057                                "[seid <seid>] "                         \
22058                                "rloc <locator> p <prio> "               \
22059                                "w <weight> [rloc <loc> ... ] "          \
22060                                "action <action> [del-all]")             \
22061 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22062                           "<local-eid>")                                \
22063 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22064 _(lisp_use_petr, "<ip-address> | disable")                              \
22065 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22066 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22067 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22068 _(lisp_locator_set_dump, "[local | remote]")                            \
22069 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22070 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22071                        "[local] | [remote]")                            \
22072 _(lisp_eid_table_vni_dump, "")                                          \
22073 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22074 _(lisp_map_resolver_dump, "")                                           \
22075 _(lisp_map_server_dump, "")                                             \
22076 _(lisp_adjacencies_get, "vni <vni>")                                    \
22077 _(gpe_fwd_entry_vnis_get, "")                                           \
22078 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22079 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22080                                 "[table <table-id>]")                   \
22081 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22082 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22083 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22084 _(gpe_get_encap_mode, "")                                               \
22085 _(lisp_gpe_add_del_iface, "up|down")                                    \
22086 _(lisp_gpe_enable_disable, "enable|disable")                            \
22087 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22088   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22089 _(show_lisp_rloc_probe_state, "")                                       \
22090 _(show_lisp_map_register_state, "")                                     \
22091 _(show_lisp_status, "")                                                 \
22092 _(lisp_get_map_request_itr_rlocs, "")                                   \
22093 _(show_lisp_pitr, "")                                                   \
22094 _(show_lisp_use_petr, "")                                               \
22095 _(show_lisp_map_request_mode, "")                                       \
22096 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22097 _(af_packet_delete, "name <host interface name>")                       \
22098 _(af_packet_dump, "")                                                   \
22099 _(policer_add_del, "name <policer name> <params> [del]")                \
22100 _(policer_dump, "[name <policer name>]")                                \
22101 _(policer_classify_set_interface,                                       \
22102   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22103   "  [l2-table <nn>] [del]")                                            \
22104 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22105 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22106     "[master|slave]")                                                   \
22107 _(netmap_delete, "name <interface name>")                               \
22108 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22109 _(mpls_table_dump, "")                                                  \
22110 _(mpls_route_dump, "table-id <ID>")                                     \
22111 _(classify_table_ids, "")                                               \
22112 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22113 _(classify_table_info, "table_id <nn>")                                 \
22114 _(classify_session_dump, "table_id <nn>")                               \
22115 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22116     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22117     "[template_interval <nn>] [udp_checksum]")                          \
22118 _(ipfix_exporter_dump, "")                                              \
22119 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22120 _(ipfix_classify_stream_dump, "")                                       \
22121 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22122 _(ipfix_classify_table_dump, "")                                        \
22123 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22124 _(sw_interface_span_dump, "[l2]")                                           \
22125 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22126 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
22127 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22128 _(pg_enable_disable, "[stream <id>] disable")                           \
22129 _(ip_source_and_port_range_check_add_del,                               \
22130   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22131 _(ip_source_and_port_range_check_interface_add_del,                     \
22132   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22133   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22134 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22135 _(l2_interface_pbb_tag_rewrite,                                         \
22136   "<intfc> | sw_if_index <nn> \n"                                       \
22137   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22138   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22139 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22140 _(flow_classify_set_interface,                                          \
22141   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22142 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22143 _(ip_table_dump, "")                                                    \
22144 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
22145 _(ip_mtable_dump, "")                                                   \
22146 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
22147 _(feature_enable_disable, "arc_name <arc_name> "                        \
22148   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22149 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22150 "[disable]")                                                            \
22151 _(l2_xconnect_dump, "")                                                 \
22152 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
22153 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22154 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22155 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22156 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22157 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22158 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22159   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22160 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22161 _(sock_init_shm, "size <nnn>")                                          \
22162 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22163 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22164   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22165 _(session_rules_dump, "")                                               \
22166 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22167 _(output_acl_set_interface,                                             \
22168   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22169   "  [l2-table <nn>] [del]")                                            \
22170 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
22171
22172 /* List of command functions, CLI names map directly to functions */
22173 #define foreach_cli_function                                    \
22174 _(comment, "usage: comment <ignore-rest-of-line>")              \
22175 _(dump_interface_table, "usage: dump_interface_table")          \
22176 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22177 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22178 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22179 _(dump_macro_table, "usage: dump_macro_table ")                 \
22180 _(dump_node_table, "usage: dump_node_table")                    \
22181 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22182 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
22183 _(elog_disable, "usage: elog_disable")                          \
22184 _(elog_enable, "usage: elog_enable")                            \
22185 _(elog_save, "usage: elog_save <filename>")                     \
22186 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22187 _(echo, "usage: echo <message>")                                \
22188 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22189 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22190 _(help, "usage: help")                                          \
22191 _(q, "usage: quit")                                             \
22192 _(quit, "usage: quit")                                          \
22193 _(search_node_table, "usage: search_node_table <name>...")      \
22194 _(set, "usage: set <variable-name> <value>")                    \
22195 _(script, "usage: script <file-name>")                          \
22196 _(statseg, "usage: statseg")                                    \
22197 _(unset, "usage: unset <variable-name>")
22198
22199 #define _(N,n)                                  \
22200     static void vl_api_##n##_t_handler_uni      \
22201     (vl_api_##n##_t * mp)                       \
22202     {                                           \
22203         vat_main_t * vam = &vat_main;           \
22204         if (vam->json_output) {                 \
22205             vl_api_##n##_t_handler_json(mp);    \
22206         } else {                                \
22207             vl_api_##n##_t_handler(mp);         \
22208         }                                       \
22209     }
22210 foreach_vpe_api_reply_msg;
22211 #if VPP_API_TEST_BUILTIN == 0
22212 foreach_standalone_reply_msg;
22213 #endif
22214 #undef _
22215
22216 void
22217 vat_api_hookup (vat_main_t * vam)
22218 {
22219 #define _(N,n)                                                  \
22220     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22221                            vl_api_##n##_t_handler_uni,          \
22222                            vl_noop_handler,                     \
22223                            vl_api_##n##_t_endian,               \
22224                            vl_api_##n##_t_print,                \
22225                            sizeof(vl_api_##n##_t), 1);
22226   foreach_vpe_api_reply_msg;
22227 #if VPP_API_TEST_BUILTIN == 0
22228   foreach_standalone_reply_msg;
22229 #endif
22230 #undef _
22231
22232 #if (VPP_API_TEST_BUILTIN==0)
22233   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22234
22235   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22236
22237   vam->function_by_name = hash_create_string (0, sizeof (uword));
22238
22239   vam->help_by_name = hash_create_string (0, sizeof (uword));
22240 #endif
22241
22242   /* API messages we can send */
22243 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22244   foreach_vpe_api_msg;
22245 #undef _
22246
22247   /* Help strings */
22248 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22249   foreach_vpe_api_msg;
22250 #undef _
22251
22252   /* CLI functions */
22253 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22254   foreach_cli_function;
22255 #undef _
22256
22257   /* Help strings */
22258 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22259   foreach_cli_function;
22260 #undef _
22261 }
22262
22263 #if VPP_API_TEST_BUILTIN
22264 static clib_error_t *
22265 vat_api_hookup_shim (vlib_main_t * vm)
22266 {
22267   vat_api_hookup (&vat_main);
22268   return 0;
22269 }
22270
22271 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22272 #endif
22273
22274 /*
22275  * fd.io coding-style-patch-verification: ON
22276  *
22277  * Local Variables:
22278  * eval: (c-set-style "gnu")
22279  * End:
22280  */