PAPI: Add MACAddress object wrapper for vl_api_mac_address_t
[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 <vpp/api/types.h>
22 #include <vppinfra/socket.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/ip/ip_neighbor.h>
27 #include <vnet/l2/l2_input.h>
28 #include <vnet/l2tp/l2tp.h>
29 #include <vnet/vxlan/vxlan.h>
30 #include <vnet/geneve/geneve.h>
31 #include <vnet/gre/gre.h>
32 #include <vnet/vxlan-gpe/vxlan_gpe.h>
33 #include <vnet/lisp-gpe/lisp_gpe.h>
34
35 #include <vpp/api/vpe_msg_enum.h>
36 #include <vnet/l2/l2_classify.h>
37 #include <vnet/l2/l2_vtr.h>
38 #include <vnet/classify/in_out_acl.h>
39 #include <vnet/classify/policer_classify.h>
40 #include <vnet/classify/flow_classify.h>
41 #include <vnet/mpls/mpls.h>
42 #include <vnet/ipsec/ipsec.h>
43 #include <vnet/ipsec/ikev2.h>
44 #include <inttypes.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53 #include <vnet/dhcp/dhcp_proxy.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include "vat/json_format.h"
57 #include <vnet/ip/ip_types_api.h>
58 #include <vnet/ethernet/ethernet_types_api.h>
59
60 #include <inttypes.h>
61 #include <sys/stat.h>
62
63 #define vl_typedefs             /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_typedefs
66
67 /* declare message handlers for each api */
68
69 #define vl_endianfun            /* define message structures */
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_endianfun
72
73 /* instantiate all the print functions we know about */
74 #define vl_print(handle, ...)
75 #define vl_printfun
76 #include <vpp/api/vpe_all_api_h.h>
77 #undef vl_printfun
78
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
81
82 #if VPP_API_TEST_BUILTIN == 0
83 #include <netdb.h>
84
85 u32
86 vl (void *p)
87 {
88   return vec_len (p);
89 }
90
91 int
92 vat_socket_connect (vat_main_t * vam)
93 {
94   vam->socket_client_main = &socket_client_main;
95   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
96                                    0 /* default socket rx, tx buffer */ );
97 }
98 #else /* vpp built-in case, we don't do sockets... */
99 int
100 vat_socket_connect (vat_main_t * vam)
101 {
102   return 0;
103 }
104
105 int
106 vl_socket_client_read (int wait)
107 {
108   return -1;
109 };
110
111 int
112 vl_socket_client_write ()
113 {
114   return -1;
115 };
116
117 void *
118 vl_socket_client_msg_alloc (int nbytes)
119 {
120   return 0;
121 }
122 #endif
123
124
125 f64
126 vat_time_now (vat_main_t * vam)
127 {
128 #if VPP_API_TEST_BUILTIN
129   return vlib_time_now (vam->vlib_main);
130 #else
131   return clib_time_now (&vam->clib_time);
132 #endif
133 }
134
135 void
136 errmsg (char *fmt, ...)
137 {
138   vat_main_t *vam = &vat_main;
139   va_list va;
140   u8 *s;
141
142   va_start (va, fmt);
143   s = va_format (0, fmt, &va);
144   va_end (va);
145
146   vec_add1 (s, 0);
147
148 #if VPP_API_TEST_BUILTIN
149   vlib_cli_output (vam->vlib_main, (char *) s);
150 #else
151   {
152     if (vam->ifp != stdin)
153       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
154                vam->input_line_number);
155     fformat (vam->ofp, (char *) s);
156     fflush (vam->ofp);
157   }
158 #endif
159
160   vec_free (s);
161 }
162
163 #if VPP_API_TEST_BUILTIN == 0
164 static uword
165 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
166 {
167   vat_main_t *vam = va_arg (*args, vat_main_t *);
168   u32 *result = va_arg (*args, u32 *);
169   u8 *if_name;
170   uword *p;
171
172   if (!unformat (input, "%s", &if_name))
173     return 0;
174
175   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
176   if (p == 0)
177     return 0;
178   *result = p[0];
179   return 1;
180 }
181
182 static uword
183 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
184 {
185   return 0;
186 }
187
188 /* Parse an IP4 address %d.%d.%d.%d. */
189 uword
190 unformat_ip4_address (unformat_input_t * input, va_list * args)
191 {
192   u8 *result = va_arg (*args, u8 *);
193   unsigned a[4];
194
195   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
196     return 0;
197
198   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
199     return 0;
200
201   result[0] = a[0];
202   result[1] = a[1];
203   result[2] = a[2];
204   result[3] = a[3];
205
206   return 1;
207 }
208
209 uword
210 unformat_ethernet_address (unformat_input_t * input, va_list * args)
211 {
212   u8 *result = va_arg (*args, u8 *);
213   u32 i, a[6];
214
215   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
216                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
217     return 0;
218
219   /* Check range. */
220   for (i = 0; i < 6; i++)
221     if (a[i] >= (1 << 8))
222       return 0;
223
224   for (i = 0; i < 6; i++)
225     result[i] = a[i];
226
227   return 1;
228 }
229
230 /* Returns ethernet type as an int in host byte order. */
231 uword
232 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
233                                         va_list * args)
234 {
235   u16 *result = va_arg (*args, u16 *);
236   int type;
237
238   /* Numeric type. */
239   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
240     {
241       if (type >= (1 << 16))
242         return 0;
243       *result = type;
244       return 1;
245     }
246   return 0;
247 }
248
249 /* Parse an IP6 address. */
250 uword
251 unformat_ip6_address (unformat_input_t * input, va_list * args)
252 {
253   ip6_address_t *result = va_arg (*args, ip6_address_t *);
254   u16 hex_quads[8];
255   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
256   uword c, n_colon, double_colon_index;
257
258   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
259   double_colon_index = ARRAY_LEN (hex_quads);
260   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
261     {
262       hex_digit = 16;
263       if (c >= '0' && c <= '9')
264         hex_digit = c - '0';
265       else if (c >= 'a' && c <= 'f')
266         hex_digit = c + 10 - 'a';
267       else if (c >= 'A' && c <= 'F')
268         hex_digit = c + 10 - 'A';
269       else if (c == ':' && n_colon < 2)
270         n_colon++;
271       else
272         {
273           unformat_put_input (input);
274           break;
275         }
276
277       /* Too many hex quads. */
278       if (n_hex_quads >= ARRAY_LEN (hex_quads))
279         return 0;
280
281       if (hex_digit < 16)
282         {
283           hex_quad = (hex_quad << 4) | hex_digit;
284
285           /* Hex quad must fit in 16 bits. */
286           if (n_hex_digits >= 4)
287             return 0;
288
289           n_colon = 0;
290           n_hex_digits++;
291         }
292
293       /* Save position of :: */
294       if (n_colon == 2)
295         {
296           /* More than one :: ? */
297           if (double_colon_index < ARRAY_LEN (hex_quads))
298             return 0;
299           double_colon_index = n_hex_quads;
300         }
301
302       if (n_colon > 0 && n_hex_digits > 0)
303         {
304           hex_quads[n_hex_quads++] = hex_quad;
305           hex_quad = 0;
306           n_hex_digits = 0;
307         }
308     }
309
310   if (n_hex_digits > 0)
311     hex_quads[n_hex_quads++] = hex_quad;
312
313   {
314     word i;
315
316     /* Expand :: to appropriate number of zero hex quads. */
317     if (double_colon_index < ARRAY_LEN (hex_quads))
318       {
319         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
320
321         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
322           hex_quads[n_zero + i] = hex_quads[i];
323
324         for (i = 0; i < n_zero; i++)
325           hex_quads[double_colon_index + i] = 0;
326
327         n_hex_quads = ARRAY_LEN (hex_quads);
328       }
329
330     /* Too few hex quads given. */
331     if (n_hex_quads < ARRAY_LEN (hex_quads))
332       return 0;
333
334     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
335       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
336
337     return 1;
338   }
339 }
340
341 uword
342 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
343 {
344   u32 *r = va_arg (*args, u32 *);
345
346   if (0);
347 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
348   foreach_ipsec_policy_action
349 #undef _
350     else
351     return 0;
352   return 1;
353 }
354
355 uword
356 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
357 {
358   u32 *r = va_arg (*args, u32 *);
359
360   if (0);
361 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
362   foreach_ipsec_crypto_alg
363 #undef _
364     else
365     return 0;
366   return 1;
367 }
368
369 u8 *
370 format_ipsec_crypto_alg (u8 * s, va_list * args)
371 {
372   u32 i = va_arg (*args, u32);
373   u8 *t = 0;
374
375   switch (i)
376     {
377 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
378       foreach_ipsec_crypto_alg
379 #undef _
380     default:
381       return format (s, "unknown");
382     }
383   return format (s, "%s", t);
384 }
385
386 uword
387 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
388 {
389   u32 *r = va_arg (*args, u32 *);
390
391   if (0);
392 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
393   foreach_ipsec_integ_alg
394 #undef _
395     else
396     return 0;
397   return 1;
398 }
399
400 u8 *
401 format_ipsec_integ_alg (u8 * s, va_list * args)
402 {
403   u32 i = va_arg (*args, u32);
404   u8 *t = 0;
405
406   switch (i)
407     {
408 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
409       foreach_ipsec_integ_alg
410 #undef _
411     default:
412       return format (s, "unknown");
413     }
414   return format (s, "%s", t);
415 }
416
417 uword
418 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
419 {
420   u32 *r = va_arg (*args, u32 *);
421
422   if (0);
423 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
424   foreach_ikev2_auth_method
425 #undef _
426     else
427     return 0;
428   return 1;
429 }
430
431 uword
432 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
433 {
434   u32 *r = va_arg (*args, u32 *);
435
436   if (0);
437 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
438   foreach_ikev2_id_type
439 #undef _
440     else
441     return 0;
442   return 1;
443 }
444 #else /* VPP_API_TEST_BUILTIN == 1 */
445 static uword
446 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
447 {
448   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
449   vnet_main_t *vnm = vnet_get_main ();
450   u32 *result = va_arg (*args, u32 *);
451
452   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
453 }
454
455 static uword
456 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
457 {
458   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
459   vnet_main_t *vnm = vnet_get_main ();
460   u32 *result = va_arg (*args, u32 *);
461
462   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
463 }
464
465 #endif /* VPP_API_TEST_BUILTIN */
466
467 static uword
468 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
469 {
470   u8 *r = va_arg (*args, u8 *);
471
472   if (unformat (input, "kbps"))
473     *r = SSE2_QOS_RATE_KBPS;
474   else if (unformat (input, "pps"))
475     *r = SSE2_QOS_RATE_PPS;
476   else
477     return 0;
478   return 1;
479 }
480
481 static uword
482 unformat_policer_round_type (unformat_input_t * input, va_list * args)
483 {
484   u8 *r = va_arg (*args, u8 *);
485
486   if (unformat (input, "closest"))
487     *r = SSE2_QOS_ROUND_TO_CLOSEST;
488   else if (unformat (input, "up"))
489     *r = SSE2_QOS_ROUND_TO_UP;
490   else if (unformat (input, "down"))
491     *r = SSE2_QOS_ROUND_TO_DOWN;
492   else
493     return 0;
494   return 1;
495 }
496
497 static uword
498 unformat_policer_type (unformat_input_t * input, va_list * args)
499 {
500   u8 *r = va_arg (*args, u8 *);
501
502   if (unformat (input, "1r2c"))
503     *r = SSE2_QOS_POLICER_TYPE_1R2C;
504   else if (unformat (input, "1r3c"))
505     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
506   else if (unformat (input, "2r3c-2698"))
507     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
508   else if (unformat (input, "2r3c-4115"))
509     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
510   else if (unformat (input, "2r3c-mef5cf1"))
511     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
512   else
513     return 0;
514   return 1;
515 }
516
517 static uword
518 unformat_dscp (unformat_input_t * input, va_list * va)
519 {
520   u8 *r = va_arg (*va, u8 *);
521
522   if (0);
523 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
524   foreach_vnet_dscp
525 #undef _
526     else
527     return 0;
528   return 1;
529 }
530
531 static uword
532 unformat_policer_action_type (unformat_input_t * input, va_list * va)
533 {
534   sse2_qos_pol_action_params_st *a
535     = va_arg (*va, sse2_qos_pol_action_params_st *);
536
537   if (unformat (input, "drop"))
538     a->action_type = SSE2_QOS_ACTION_DROP;
539   else if (unformat (input, "transmit"))
540     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
541   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
542     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
543   else
544     return 0;
545   return 1;
546 }
547
548 static uword
549 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
550 {
551   u32 *r = va_arg (*va, u32 *);
552   u32 tid;
553
554   if (unformat (input, "ip4"))
555     tid = POLICER_CLASSIFY_TABLE_IP4;
556   else if (unformat (input, "ip6"))
557     tid = POLICER_CLASSIFY_TABLE_IP6;
558   else if (unformat (input, "l2"))
559     tid = POLICER_CLASSIFY_TABLE_L2;
560   else
561     return 0;
562
563   *r = tid;
564   return 1;
565 }
566
567 static uword
568 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
569 {
570   u32 *r = va_arg (*va, u32 *);
571   u32 tid;
572
573   if (unformat (input, "ip4"))
574     tid = FLOW_CLASSIFY_TABLE_IP4;
575   else if (unformat (input, "ip6"))
576     tid = FLOW_CLASSIFY_TABLE_IP6;
577   else
578     return 0;
579
580   *r = tid;
581   return 1;
582 }
583
584 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
585 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
586 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
587 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
588
589 #if (VPP_API_TEST_BUILTIN==0)
590 uword
591 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
592 {
593   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
594   mfib_itf_attribute_t attr;
595
596   old = *iflags;
597   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
598   {
599     if (unformat (input, mfib_itf_flag_long_names[attr]))
600       *iflags |= (1 << attr);
601   }
602   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_itf_flag_names[attr]))
605       *iflags |= (1 << attr);
606   }
607
608   return (old == *iflags ? 0 : 1);
609 }
610
611 uword
612 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
613 {
614   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
615   mfib_entry_attribute_t attr;
616
617   old = *eflags;
618   FOR_EACH_MFIB_ATTRIBUTE (attr)
619   {
620     if (unformat (input, mfib_flag_long_names[attr]))
621       *eflags |= (1 << attr);
622   }
623   FOR_EACH_MFIB_ATTRIBUTE (attr)
624   {
625     if (unformat (input, mfib_flag_names[attr]))
626       *eflags |= (1 << attr);
627   }
628
629   return (old == *eflags ? 0 : 1);
630 }
631
632 u8 *
633 format_ip4_address (u8 * s, va_list * args)
634 {
635   u8 *a = va_arg (*args, u8 *);
636   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
637 }
638
639 u8 *
640 format_ip6_address (u8 * s, va_list * args)
641 {
642   ip6_address_t *a = va_arg (*args, ip6_address_t *);
643   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
644
645   i_max_n_zero = ARRAY_LEN (a->as_u16);
646   max_n_zeros = 0;
647   i_first_zero = i_max_n_zero;
648   n_zeros = 0;
649   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
650     {
651       u32 is_zero = a->as_u16[i] == 0;
652       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
653         {
654           i_first_zero = i;
655           n_zeros = 0;
656         }
657       n_zeros += is_zero;
658       if ((!is_zero && n_zeros > max_n_zeros)
659           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
660         {
661           i_max_n_zero = i_first_zero;
662           max_n_zeros = n_zeros;
663           i_first_zero = ARRAY_LEN (a->as_u16);
664           n_zeros = 0;
665         }
666     }
667
668   last_double_colon = 0;
669   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
670     {
671       if (i == i_max_n_zero && max_n_zeros > 1)
672         {
673           s = format (s, "::");
674           i += max_n_zeros - 1;
675           last_double_colon = 1;
676         }
677       else
678         {
679           s = format (s, "%s%x",
680                       (last_double_colon || i == 0) ? "" : ":",
681                       clib_net_to_host_u16 (a->as_u16[i]));
682           last_double_colon = 0;
683         }
684     }
685
686   return s;
687 }
688
689 /* Format an IP46 address. */
690 u8 *
691 format_ip46_address (u8 * s, va_list * args)
692 {
693   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
694   ip46_type_t type = va_arg (*args, ip46_type_t);
695   int is_ip4 = 1;
696
697   switch (type)
698     {
699     case IP46_TYPE_ANY:
700       is_ip4 = ip46_address_is_ip4 (ip46);
701       break;
702     case IP46_TYPE_IP4:
703       is_ip4 = 1;
704       break;
705     case IP46_TYPE_IP6:
706       is_ip4 = 0;
707       break;
708     }
709
710   return is_ip4 ?
711     format (s, "%U", format_ip4_address, &ip46->ip4) :
712     format (s, "%U", format_ip6_address, &ip46->ip6);
713 }
714
715 u8 *
716 format_ethernet_address (u8 * s, va_list * args)
717 {
718   u8 *a = va_arg (*args, u8 *);
719
720   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
721                  a[0], a[1], a[2], a[3], a[4], a[5]);
722 }
723 #endif
724
725 static void
726 increment_v4_address (ip4_address_t * a)
727 {
728   u32 v;
729
730   v = ntohl (a->as_u32) + 1;
731   a->as_u32 = ntohl (v);
732 }
733
734 static void
735 increment_v6_address (ip6_address_t * a)
736 {
737   u64 v0, v1;
738
739   v0 = clib_net_to_host_u64 (a->as_u64[0]);
740   v1 = clib_net_to_host_u64 (a->as_u64[1]);
741
742   v1 += 1;
743   if (v1 == 0)
744     v0 += 1;
745   a->as_u64[0] = clib_net_to_host_u64 (v0);
746   a->as_u64[1] = clib_net_to_host_u64 (v1);
747 }
748
749 static void
750 increment_mac_address (u8 * mac)
751 {
752   u64 tmp = *((u64 *) mac);
753   tmp = clib_net_to_host_u64 (tmp);
754   tmp += 1 << 16;               /* skip unused (least significant) octets */
755   tmp = clib_host_to_net_u64 (tmp);
756
757   clib_memcpy (mac, &tmp, 6);
758 }
759
760 static void vl_api_create_loopback_reply_t_handler
761   (vl_api_create_loopback_reply_t * mp)
762 {
763   vat_main_t *vam = &vat_main;
764   i32 retval = ntohl (mp->retval);
765
766   vam->retval = retval;
767   vam->regenerate_interface_table = 1;
768   vam->sw_if_index = ntohl (mp->sw_if_index);
769   vam->result_ready = 1;
770 }
771
772 static void vl_api_create_loopback_reply_t_handler_json
773   (vl_api_create_loopback_reply_t * mp)
774 {
775   vat_main_t *vam = &vat_main;
776   vat_json_node_t node;
777
778   vat_json_init_object (&node);
779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
780   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
781
782   vat_json_print (vam->ofp, &node);
783   vat_json_free (&node);
784   vam->retval = ntohl (mp->retval);
785   vam->result_ready = 1;
786 }
787
788 static void vl_api_create_loopback_instance_reply_t_handler
789   (vl_api_create_loopback_instance_reply_t * mp)
790 {
791   vat_main_t *vam = &vat_main;
792   i32 retval = ntohl (mp->retval);
793
794   vam->retval = retval;
795   vam->regenerate_interface_table = 1;
796   vam->sw_if_index = ntohl (mp->sw_if_index);
797   vam->result_ready = 1;
798 }
799
800 static void vl_api_create_loopback_instance_reply_t_handler_json
801   (vl_api_create_loopback_instance_reply_t * mp)
802 {
803   vat_main_t *vam = &vat_main;
804   vat_json_node_t node;
805
806   vat_json_init_object (&node);
807   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
808   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
809
810   vat_json_print (vam->ofp, &node);
811   vat_json_free (&node);
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_af_packet_create_reply_t_handler
817   (vl_api_af_packet_create_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_af_packet_create_reply_t_handler_json
829   (vl_api_af_packet_create_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_vlan_subif_reply_t_handler
846   (vl_api_create_vlan_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_vlan_subif_reply_t_handler_json
858   (vl_api_create_vlan_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_create_subif_reply_t_handler
875   (vl_api_create_subif_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->sw_if_index = ntohl (mp->sw_if_index);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_subif_reply_t_handler_json
887   (vl_api_create_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   vat_json_node_t node;
891
892   vat_json_init_object (&node);
893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
894   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
895
896   vat_json_print (vam->ofp, &node);
897   vat_json_free (&node);
898
899   vam->retval = ntohl (mp->retval);
900   vam->result_ready = 1;
901 }
902
903 static void vl_api_interface_name_renumber_reply_t_handler
904   (vl_api_interface_name_renumber_reply_t * mp)
905 {
906   vat_main_t *vam = &vat_main;
907   i32 retval = ntohl (mp->retval);
908
909   vam->retval = retval;
910   vam->regenerate_interface_table = 1;
911   vam->result_ready = 1;
912 }
913
914 static void vl_api_interface_name_renumber_reply_t_handler_json
915   (vl_api_interface_name_renumber_reply_t * mp)
916 {
917   vat_main_t *vam = &vat_main;
918   vat_json_node_t node;
919
920   vat_json_init_object (&node);
921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
922
923   vat_json_print (vam->ofp, &node);
924   vat_json_free (&node);
925
926   vam->retval = ntohl (mp->retval);
927   vam->result_ready = 1;
928 }
929
930 /*
931  * Special-case: build the interface table, maintain
932  * the next loopback sw_if_index vbl.
933  */
934 static void vl_api_sw_interface_details_t_handler
935   (vl_api_sw_interface_details_t * mp)
936 {
937   vat_main_t *vam = &vat_main;
938   u8 *s = format (0, "%s%c", mp->interface_name, 0);
939
940   hash_set_mem (vam->sw_if_index_by_interface_name, s,
941                 ntohl (mp->sw_if_index));
942
943   /* In sub interface case, fill the sub interface table entry */
944   if (mp->sw_if_index != mp->sup_sw_if_index)
945     {
946       sw_interface_subif_t *sub = NULL;
947
948       vec_add2 (vam->sw_if_subif_table, sub, 1);
949
950       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
951       strncpy ((char *) sub->interface_name, (char *) s,
952                vec_len (sub->interface_name));
953       sub->sw_if_index = ntohl (mp->sw_if_index);
954       sub->sub_id = ntohl (mp->sub_id);
955
956       sub->sub_dot1ad = mp->sub_dot1ad;
957       sub->sub_number_of_tags = mp->sub_number_of_tags;
958       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
959       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
960       sub->sub_exact_match = mp->sub_exact_match;
961       sub->sub_default = mp->sub_default;
962       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
963       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
964
965       /* vlan tag rewrite */
966       sub->vtr_op = ntohl (mp->vtr_op);
967       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
968       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
969       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
970     }
971 }
972
973 static void vl_api_sw_interface_details_t_handler_json
974   (vl_api_sw_interface_details_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   vat_json_node_t *node = NULL;
978
979   if (VAT_JSON_ARRAY != vam->json_tree.type)
980     {
981       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
982       vat_json_init_array (&vam->json_tree);
983     }
984   node = vat_json_array_add (&vam->json_tree);
985
986   vat_json_init_object (node);
987   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
988   vat_json_object_add_uint (node, "sup_sw_if_index",
989                             ntohl (mp->sup_sw_if_index));
990   vat_json_object_add_uint (node, "l2_address_length",
991                             ntohl (mp->l2_address_length));
992   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
993                              sizeof (mp->l2_address));
994   vat_json_object_add_string_copy (node, "interface_name",
995                                    mp->interface_name);
996   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
997   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
998   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
999   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1000   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1001   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1002   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1003   vat_json_object_add_uint (node, "sub_number_of_tags",
1004                             mp->sub_number_of_tags);
1005   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1006                             ntohs (mp->sub_outer_vlan_id));
1007   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1008                             ntohs (mp->sub_inner_vlan_id));
1009   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1010   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1011   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1012                             mp->sub_outer_vlan_id_any);
1013   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1014                             mp->sub_inner_vlan_id_any);
1015   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1016   vat_json_object_add_uint (node, "vtr_push_dot1q",
1017                             ntohl (mp->vtr_push_dot1q));
1018   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1019   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1020   if (mp->sub_dot1ah)
1021     {
1022       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1023                                        format (0, "%U",
1024                                                format_ethernet_address,
1025                                                &mp->b_dmac));
1026       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1027                                        format (0, "%U",
1028                                                format_ethernet_address,
1029                                                &mp->b_smac));
1030       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1031       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1032     }
1033 }
1034
1035 #if VPP_API_TEST_BUILTIN == 0
1036 static void vl_api_sw_interface_event_t_handler
1037   (vl_api_sw_interface_event_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   if (vam->interface_event_display)
1041     errmsg ("interface flags: sw_if_index %d %s %s",
1042             ntohl (mp->sw_if_index),
1043             mp->admin_up_down ? "admin-up" : "admin-down",
1044             mp->link_up_down ? "link-up" : "link-down");
1045 }
1046 #endif
1047
1048 static void vl_api_sw_interface_event_t_handler_json
1049   (vl_api_sw_interface_event_t * mp)
1050 {
1051   /* JSON output not supported */
1052 }
1053
1054 static void
1055 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1056 {
1057   vat_main_t *vam = &vat_main;
1058   i32 retval = ntohl (mp->retval);
1059
1060   vam->retval = retval;
1061   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1062   vam->result_ready = 1;
1063 }
1064
1065 static void
1066 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070   api_main_t *am = &api_main;
1071   void *oldheap;
1072   u8 *reply;
1073
1074   vat_json_init_object (&node);
1075   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1076   vat_json_object_add_uint (&node, "reply_in_shmem",
1077                             ntohl (mp->reply_in_shmem));
1078   /* Toss the shared-memory original... */
1079   pthread_mutex_lock (&am->vlib_rp->mutex);
1080   oldheap = svm_push_data_heap (am->vlib_rp);
1081
1082   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1083   vec_free (reply);
1084
1085   svm_pop_heap (oldheap);
1086   pthread_mutex_unlock (&am->vlib_rp->mutex);
1087
1088   vat_json_print (vam->ofp, &node);
1089   vat_json_free (&node);
1090
1091   vam->retval = ntohl (mp->retval);
1092   vam->result_ready = 1;
1093 }
1094
1095 static void
1096 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1097 {
1098   vat_main_t *vam = &vat_main;
1099   i32 retval = ntohl (mp->retval);
1100   u32 length = vl_api_string_len (&mp->reply);
1101
1102   vec_reset_length (vam->cmd_reply);
1103
1104   vam->retval = retval;
1105   if (retval == 0)
1106     {
1107       vec_validate (vam->cmd_reply, length);
1108       clib_memcpy ((char *) (vam->cmd_reply),
1109                    vl_api_from_api_string (&mp->reply), length);
1110       vam->cmd_reply[length] = 0;
1111     }
1112   vam->result_ready = 1;
1113 }
1114
1115 static void
1116 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1117 {
1118   vat_main_t *vam = &vat_main;
1119   vat_json_node_t node;
1120
1121   vec_reset_length (vam->cmd_reply);
1122
1123   vat_json_init_object (&node);
1124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1125   vat_json_object_add_string_copy (&node, "reply",
1126                                    vl_api_from_api_string (&mp->reply));
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void vl_api_classify_add_del_table_reply_t_handler
1136   (vl_api_classify_add_del_table_reply_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   i32 retval = ntohl (mp->retval);
1140   if (vam->async_mode)
1141     {
1142       vam->async_errors += (retval < 0);
1143     }
1144   else
1145     {
1146       vam->retval = retval;
1147       if (retval == 0 &&
1148           ((mp->new_table_index != 0xFFFFFFFF) ||
1149            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1150            (mp->match_n_vectors != 0xFFFFFFFF)))
1151         /*
1152          * Note: this is just barely thread-safe, depends on
1153          * the main thread spinning waiting for an answer...
1154          */
1155         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1156                 ntohl (mp->new_table_index),
1157                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1158       vam->result_ready = 1;
1159     }
1160 }
1161
1162 static void vl_api_classify_add_del_table_reply_t_handler_json
1163   (vl_api_classify_add_del_table_reply_t * mp)
1164 {
1165   vat_main_t *vam = &vat_main;
1166   vat_json_node_t node;
1167
1168   vat_json_init_object (&node);
1169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1170   vat_json_object_add_uint (&node, "new_table_index",
1171                             ntohl (mp->new_table_index));
1172   vat_json_object_add_uint (&node, "skip_n_vectors",
1173                             ntohl (mp->skip_n_vectors));
1174   vat_json_object_add_uint (&node, "match_n_vectors",
1175                             ntohl (mp->match_n_vectors));
1176
1177   vat_json_print (vam->ofp, &node);
1178   vat_json_free (&node);
1179
1180   vam->retval = ntohl (mp->retval);
1181   vam->result_ready = 1;
1182 }
1183
1184 static void vl_api_get_node_index_reply_t_handler
1185   (vl_api_get_node_index_reply_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   i32 retval = ntohl (mp->retval);
1189   if (vam->async_mode)
1190     {
1191       vam->async_errors += (retval < 0);
1192     }
1193   else
1194     {
1195       vam->retval = retval;
1196       if (retval == 0)
1197         errmsg ("node index %d", ntohl (mp->node_index));
1198       vam->result_ready = 1;
1199     }
1200 }
1201
1202 static void vl_api_get_node_index_reply_t_handler_json
1203   (vl_api_get_node_index_reply_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   vat_json_node_t node;
1207
1208   vat_json_init_object (&node);
1209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1210   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1211
1212   vat_json_print (vam->ofp, &node);
1213   vat_json_free (&node);
1214
1215   vam->retval = ntohl (mp->retval);
1216   vam->result_ready = 1;
1217 }
1218
1219 static void vl_api_get_next_index_reply_t_handler
1220   (vl_api_get_next_index_reply_t * mp)
1221 {
1222   vat_main_t *vam = &vat_main;
1223   i32 retval = ntohl (mp->retval);
1224   if (vam->async_mode)
1225     {
1226       vam->async_errors += (retval < 0);
1227     }
1228   else
1229     {
1230       vam->retval = retval;
1231       if (retval == 0)
1232         errmsg ("next node index %d", ntohl (mp->next_index));
1233       vam->result_ready = 1;
1234     }
1235 }
1236
1237 static void vl_api_get_next_index_reply_t_handler_json
1238   (vl_api_get_next_index_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   vat_json_node_t node;
1242
1243   vat_json_init_object (&node);
1244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1245   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void vl_api_add_node_next_reply_t_handler
1255   (vl_api_add_node_next_reply_t * mp)
1256 {
1257   vat_main_t *vam = &vat_main;
1258   i32 retval = ntohl (mp->retval);
1259   if (vam->async_mode)
1260     {
1261       vam->async_errors += (retval < 0);
1262     }
1263   else
1264     {
1265       vam->retval = retval;
1266       if (retval == 0)
1267         errmsg ("next index %d", ntohl (mp->next_index));
1268       vam->result_ready = 1;
1269     }
1270 }
1271
1272 static void vl_api_add_node_next_reply_t_handler_json
1273   (vl_api_add_node_next_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   vat_json_node_t node;
1277
1278   vat_json_init_object (&node);
1279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1280   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1281
1282   vat_json_print (vam->ofp, &node);
1283   vat_json_free (&node);
1284
1285   vam->retval = ntohl (mp->retval);
1286   vam->result_ready = 1;
1287 }
1288
1289 static void vl_api_show_version_reply_t_handler
1290   (vl_api_show_version_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (retval >= 0)
1296     {
1297       char *s;
1298       char *p = (char *) &mp->program;
1299
1300       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1301       errmsg ("        program: %s\n", s);
1302       free (s);
1303
1304       p +=
1305         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1306       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1307       errmsg ("        version: %s\n", s);
1308       free (s);
1309
1310       p +=
1311         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1312       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1313       errmsg ("     build date: %s\n", s);
1314       free (s);
1315
1316       p +=
1317         vl_api_string_len ((vl_api_string_t *) p) + sizeof (vl_api_string_t);
1318       s = vl_api_from_api_string_c ((vl_api_string_t *) p);
1319       errmsg ("build directory: %s\n", s);
1320       free (s);
1321     }
1322   vam->retval = retval;
1323   vam->result_ready = 1;
1324 }
1325
1326 static void vl_api_show_version_reply_t_handler_json
1327   (vl_api_show_version_reply_t * mp)
1328 {
1329   vat_main_t *vam = &vat_main;
1330   vat_json_node_t node;
1331
1332   vat_json_init_object (&node);
1333   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1334   char *p = (char *) &mp->program;
1335   vat_json_object_add_string_copy (&node, "program",
1336                                    vl_api_from_api_string ((vl_api_string_t *)
1337                                                            p));
1338   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1339   vat_json_object_add_string_copy (&node, "version",
1340                                    vl_api_from_api_string ((vl_api_string_t *)
1341                                                            p));
1342   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1343   vat_json_object_add_string_copy (&node, "build_date",
1344                                    vl_api_from_api_string ((vl_api_string_t *)
1345                                                            p));
1346   p += vl_api_string_len ((vl_api_string_t *) p) + sizeof (u32);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    vl_api_from_api_string ((vl_api_string_t *)
1349                                                            p));
1350
1351   vat_json_print (vam->ofp, &node);
1352   vat_json_free (&node);
1353
1354   vam->retval = ntohl (mp->retval);
1355   vam->result_ready = 1;
1356 }
1357
1358 static void vl_api_show_threads_reply_t_handler
1359   (vl_api_show_threads_reply_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   i32 retval = ntohl (mp->retval);
1363   int i, count = 0;
1364
1365   if (retval >= 0)
1366     count = ntohl (mp->count);
1367
1368   for (i = 0; i < count; i++)
1369     print (vam->ofp,
1370            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1371            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1372            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1373            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1374            ntohl (mp->thread_data[i].cpu_socket));
1375
1376   vam->retval = retval;
1377   vam->result_ready = 1;
1378 }
1379
1380 static void vl_api_show_threads_reply_t_handler_json
1381   (vl_api_show_threads_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   vat_json_node_t node;
1385   vl_api_thread_data_t *td;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", retval);
1394   vat_json_object_add_uint (&node, "count", count);
1395
1396   for (i = 0; i < count; i++)
1397     {
1398       td = &mp->thread_data[i];
1399       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1400       vat_json_object_add_string_copy (&node, "name", td->name);
1401       vat_json_object_add_string_copy (&node, "type", td->type);
1402       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1403       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1404       vat_json_object_add_int (&node, "core", ntohl (td->id));
1405       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1406     }
1407
1408   vat_json_print (vam->ofp, &node);
1409   vat_json_free (&node);
1410
1411   vam->retval = retval;
1412   vam->result_ready = 1;
1413 }
1414
1415 static int
1416 api_show_threads (vat_main_t * vam)
1417 {
1418   vl_api_show_threads_t *mp;
1419   int ret;
1420
1421   print (vam->ofp,
1422          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1423          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1424
1425   M (SHOW_THREADS, mp);
1426
1427   S (mp);
1428   W (ret);
1429   return ret;
1430 }
1431
1432 static void
1433 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1434 {
1435   u32 sw_if_index = ntohl (mp->sw_if_index);
1436   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1437           mp->mac_ip ? "mac/ip binding" : "address resolution",
1438           ntohl (mp->pid), format_ip4_address, &mp->address,
1439           format_ethernet_address, mp->new_mac, sw_if_index);
1440 }
1441
1442 static void
1443 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1444 {
1445   /* JSON output not supported */
1446 }
1447
1448 static void
1449 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1450 {
1451   u32 sw_if_index = ntohl (mp->sw_if_index);
1452   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1453           mp->mac_ip ? "mac/ip binding" : "address resolution",
1454           ntohl (mp->pid), format_ip6_address, mp->address,
1455           format_ethernet_address, mp->new_mac, sw_if_index);
1456 }
1457
1458 static void
1459 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1460 {
1461   /* JSON output not supported */
1462 }
1463
1464 static void
1465 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1466 {
1467   u32 n_macs = ntohl (mp->n_macs);
1468   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1469           ntohl (mp->pid), mp->client_index, n_macs);
1470   int i;
1471   for (i = 0; i < n_macs; i++)
1472     {
1473       vl_api_mac_entry_t *mac = &mp->mac[i];
1474       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1475               i + 1, ntohl (mac->sw_if_index),
1476               format_ethernet_address, mac->mac_addr, mac->action);
1477       if (i == 1000)
1478         break;
1479     }
1480 }
1481
1482 static void
1483 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1484 {
1485   /* JSON output not supported */
1486 }
1487
1488 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1489 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1490
1491 /*
1492  * Special-case: build the bridge domain table, maintain
1493  * the next bd id vbl.
1494  */
1495 static void vl_api_bridge_domain_details_t_handler
1496   (vl_api_bridge_domain_details_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1500   int i;
1501
1502   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1503          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1504
1505   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1506          ntohl (mp->bd_id), mp->learn, mp->forward,
1507          mp->flood, ntohl (mp->bvi_sw_if_index),
1508          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1509
1510   if (n_sw_ifs)
1511     {
1512       vl_api_bridge_domain_sw_if_t *sw_ifs;
1513       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1514              "Interface Name");
1515
1516       sw_ifs = mp->sw_if_details;
1517       for (i = 0; i < n_sw_ifs; i++)
1518         {
1519           u8 *sw_if_name = 0;
1520           u32 sw_if_index;
1521           hash_pair_t *p;
1522
1523           sw_if_index = ntohl (sw_ifs->sw_if_index);
1524
1525           /* *INDENT-OFF* */
1526           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1527                              ({
1528                                if ((u32) p->value[0] == sw_if_index)
1529                                  {
1530                                    sw_if_name = (u8 *)(p->key);
1531                                    break;
1532                                  }
1533                              }));
1534           /* *INDENT-ON* */
1535           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1536                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1537                  "sw_if_index not found!");
1538
1539           sw_ifs++;
1540         }
1541     }
1542 }
1543
1544 static void vl_api_bridge_domain_details_t_handler_json
1545   (vl_api_bridge_domain_details_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t *node, *array = NULL;
1549   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1550
1551   if (VAT_JSON_ARRAY != vam->json_tree.type)
1552     {
1553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1554       vat_json_init_array (&vam->json_tree);
1555     }
1556   node = vat_json_array_add (&vam->json_tree);
1557
1558   vat_json_init_object (node);
1559   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1560   vat_json_object_add_uint (node, "flood", mp->flood);
1561   vat_json_object_add_uint (node, "forward", mp->forward);
1562   vat_json_object_add_uint (node, "learn", mp->learn);
1563   vat_json_object_add_uint (node, "bvi_sw_if_index",
1564                             ntohl (mp->bvi_sw_if_index));
1565   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1566   array = vat_json_object_add (node, "sw_if");
1567   vat_json_init_array (array);
1568
1569
1570
1571   if (n_sw_ifs)
1572     {
1573       vl_api_bridge_domain_sw_if_t *sw_ifs;
1574       int i;
1575
1576       sw_ifs = mp->sw_if_details;
1577       for (i = 0; i < n_sw_ifs; i++)
1578         {
1579           node = vat_json_array_add (array);
1580           vat_json_init_object (node);
1581           vat_json_object_add_uint (node, "sw_if_index",
1582                                     ntohl (sw_ifs->sw_if_index));
1583           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1584           sw_ifs++;
1585         }
1586     }
1587 }
1588
1589 static void vl_api_control_ping_reply_t_handler
1590   (vl_api_control_ping_reply_t * mp)
1591 {
1592   vat_main_t *vam = &vat_main;
1593   i32 retval = ntohl (mp->retval);
1594   if (vam->async_mode)
1595     {
1596       vam->async_errors += (retval < 0);
1597     }
1598   else
1599     {
1600       vam->retval = retval;
1601       vam->result_ready = 1;
1602     }
1603   if (vam->socket_client_main)
1604     vam->socket_client_main->control_pings_outstanding--;
1605 }
1606
1607 static void vl_api_control_ping_reply_t_handler_json
1608   (vl_api_control_ping_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612
1613   if (VAT_JSON_NONE != vam->json_tree.type)
1614     {
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vat_json_free (&vam->json_tree);
1617       vam->json_tree.type = VAT_JSON_NONE;
1618     }
1619   else
1620     {
1621       /* just print [] */
1622       vat_json_init_array (&vam->json_tree);
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vam->json_tree.type = VAT_JSON_NONE;
1625     }
1626
1627   vam->retval = retval;
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632   vl_api_bridge_domain_set_mac_age_reply_t_handler
1633   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1649   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2_flags_reply_t_handler_json
1681   (vl_api_l2_flags_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1689                             ntohl (mp->resulting_feature_bitmap));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_bridge_flags_reply_t_handler
1699   (vl_api_bridge_flags_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_bridge_flags_reply_t_handler_json
1715   (vl_api_bridge_flags_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1723                             ntohl (mp->resulting_feature_bitmap));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732 static void vl_api_tap_connect_reply_t_handler
1733   (vl_api_tap_connect_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747
1748 }
1749
1750 static void vl_api_tap_connect_reply_t_handler_json
1751   (vl_api_tap_connect_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765
1766 }
1767
1768 static void
1769 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->sw_if_index = ntohl (mp->sw_if_index);
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_tap_modify_reply_t_handler_json
1786   (vl_api_tap_modify_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800 }
1801
1802 static void
1803 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1804 {
1805   vat_main_t *vam = &vat_main;
1806   i32 retval = ntohl (mp->retval);
1807   if (vam->async_mode)
1808     {
1809       vam->async_errors += (retval < 0);
1810     }
1811   else
1812     {
1813       vam->retval = retval;
1814       vam->result_ready = 1;
1815     }
1816 }
1817
1818 static void vl_api_tap_delete_reply_t_handler_json
1819   (vl_api_tap_delete_reply_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   vat_json_node_t node;
1823
1824   vat_json_init_object (&node);
1825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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 static void
1835 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   i32 retval = ntohl (mp->retval);
1839   if (vam->async_mode)
1840     {
1841       vam->async_errors += (retval < 0);
1842     }
1843   else
1844     {
1845       vam->retval = retval;
1846       vam->sw_if_index = ntohl (mp->sw_if_index);
1847       vam->result_ready = 1;
1848     }
1849
1850 }
1851
1852 static void vl_api_tap_create_v2_reply_t_handler_json
1853   (vl_api_tap_create_v2_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1861
1862   vat_json_print (vam->ofp, &node);
1863   vat_json_free (&node);
1864
1865   vam->retval = ntohl (mp->retval);
1866   vam->result_ready = 1;
1867
1868 }
1869
1870 static void
1871 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874   i32 retval = ntohl (mp->retval);
1875   if (vam->async_mode)
1876     {
1877       vam->async_errors += (retval < 0);
1878     }
1879   else
1880     {
1881       vam->retval = retval;
1882       vam->result_ready = 1;
1883     }
1884 }
1885
1886 static void vl_api_tap_delete_v2_reply_t_handler_json
1887   (vl_api_tap_delete_v2_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
1895   vat_json_print (vam->ofp, &node);
1896   vat_json_free (&node);
1897
1898   vam->retval = ntohl (mp->retval);
1899   vam->result_ready = 1;
1900 }
1901
1902 static void
1903 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1904 {
1905   vat_main_t *vam = &vat_main;
1906   i32 retval = ntohl (mp->retval);
1907
1908   if (vam->async_mode)
1909     {
1910       vam->async_errors += (retval < 0);
1911     }
1912   else
1913     {
1914       vam->retval = retval;
1915       vam->sw_if_index = ntohl (mp->sw_if_index);
1916       vam->result_ready = 1;
1917     }
1918 }
1919
1920 static void vl_api_bond_create_reply_t_handler_json
1921   (vl_api_bond_create_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   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1939 {
1940   vat_main_t *vam = &vat_main;
1941   i32 retval = ntohl (mp->retval);
1942
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_bond_delete_reply_t_handler_json
1955   (vl_api_bond_delete_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962
1963   vat_json_print (vam->ofp, &node);
1964   vat_json_free (&node);
1965
1966   vam->retval = ntohl (mp->retval);
1967   vam->result_ready = 1;
1968 }
1969
1970 static void
1971 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * 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_enslave_reply_t_handler_json
1988   (vl_api_bond_enslave_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 void
2004 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
2005                                           mp)
2006 {
2007   vat_main_t *vam = &vat_main;
2008   i32 retval = ntohl (mp->retval);
2009
2010   if (vam->async_mode)
2011     {
2012       vam->async_errors += (retval < 0);
2013     }
2014   else
2015     {
2016       vam->retval = retval;
2017       vam->result_ready = 1;
2018     }
2019 }
2020
2021 static void vl_api_bond_detach_slave_reply_t_handler_json
2022   (vl_api_bond_detach_slave_reply_t * mp)
2023 {
2024   vat_main_t *vam = &vat_main;
2025   vat_json_node_t node;
2026
2027   vat_json_init_object (&node);
2028   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2029
2030   vat_json_print (vam->ofp, &node);
2031   vat_json_free (&node);
2032
2033   vam->retval = ntohl (mp->retval);
2034   vam->result_ready = 1;
2035 }
2036
2037 static void vl_api_sw_interface_bond_details_t_handler
2038   (vl_api_sw_interface_bond_details_t * mp)
2039 {
2040   vat_main_t *vam = &vat_main;
2041
2042   print (vam->ofp,
2043          "%-16s %-12d %-12U %-13U %-14u %-14u",
2044          mp->interface_name, ntohl (mp->sw_if_index),
2045          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2046          ntohl (mp->active_slaves), ntohl (mp->slaves));
2047 }
2048
2049 static void vl_api_sw_interface_bond_details_t_handler_json
2050   (vl_api_sw_interface_bond_details_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053   vat_json_node_t *node = NULL;
2054
2055   if (VAT_JSON_ARRAY != vam->json_tree.type)
2056     {
2057       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2058       vat_json_init_array (&vam->json_tree);
2059     }
2060   node = vat_json_array_add (&vam->json_tree);
2061
2062   vat_json_init_object (node);
2063   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2064   vat_json_object_add_string_copy (node, "interface_name",
2065                                    mp->interface_name);
2066   vat_json_object_add_uint (node, "mode", mp->mode);
2067   vat_json_object_add_uint (node, "load_balance", mp->lb);
2068   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2069   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2070 }
2071
2072 static int
2073 api_sw_interface_bond_dump (vat_main_t * vam)
2074 {
2075   vl_api_sw_interface_bond_dump_t *mp;
2076   vl_api_control_ping_t *mp_ping;
2077   int ret;
2078
2079   print (vam->ofp,
2080          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2081          "interface name", "sw_if_index", "mode", "load balance",
2082          "active slaves", "slaves");
2083
2084   /* Get list of bond interfaces */
2085   M (SW_INTERFACE_BOND_DUMP, mp);
2086   S (mp);
2087
2088   /* Use a control ping for synchronization */
2089   MPING (CONTROL_PING, mp_ping);
2090   S (mp_ping);
2091
2092   W (ret);
2093   return ret;
2094 }
2095
2096 static void vl_api_sw_interface_slave_details_t_handler
2097   (vl_api_sw_interface_slave_details_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100
2101   print (vam->ofp,
2102          "%-25s %-12d %-12d %d", mp->interface_name,
2103          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2104 }
2105
2106 static void vl_api_sw_interface_slave_details_t_handler_json
2107   (vl_api_sw_interface_slave_details_t * mp)
2108 {
2109   vat_main_t *vam = &vat_main;
2110   vat_json_node_t *node = NULL;
2111
2112   if (VAT_JSON_ARRAY != vam->json_tree.type)
2113     {
2114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2115       vat_json_init_array (&vam->json_tree);
2116     }
2117   node = vat_json_array_add (&vam->json_tree);
2118
2119   vat_json_init_object (node);
2120   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2121   vat_json_object_add_string_copy (node, "interface_name",
2122                                    mp->interface_name);
2123   vat_json_object_add_uint (node, "passive", mp->is_passive);
2124   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2125 }
2126
2127 static int
2128 api_sw_interface_slave_dump (vat_main_t * vam)
2129 {
2130   unformat_input_t *i = vam->input;
2131   vl_api_sw_interface_slave_dump_t *mp;
2132   vl_api_control_ping_t *mp_ping;
2133   u32 sw_if_index = ~0;
2134   u8 sw_if_index_set = 0;
2135   int ret;
2136
2137   /* Parse args required to build the message */
2138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2139     {
2140       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2141         sw_if_index_set = 1;
2142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2143         sw_if_index_set = 1;
2144       else
2145         break;
2146     }
2147
2148   if (sw_if_index_set == 0)
2149     {
2150       errmsg ("missing vpp interface name. ");
2151       return -99;
2152     }
2153
2154   print (vam->ofp,
2155          "\n%-25s %-12s %-12s %s",
2156          "slave interface name", "sw_if_index", "passive", "long_timeout");
2157
2158   /* Get list of bond interfaces */
2159   M (SW_INTERFACE_SLAVE_DUMP, mp);
2160   mp->sw_if_index = ntohl (sw_if_index);
2161   S (mp);
2162
2163   /* Use a control ping for synchronization */
2164   MPING (CONTROL_PING, mp_ping);
2165   S (mp_ping);
2166
2167   W (ret);
2168   return ret;
2169 }
2170
2171 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2172   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2173 {
2174   vat_main_t *vam = &vat_main;
2175   i32 retval = ntohl (mp->retval);
2176   if (vam->async_mode)
2177     {
2178       vam->async_errors += (retval < 0);
2179     }
2180   else
2181     {
2182       vam->retval = retval;
2183       vam->sw_if_index = ntohl (mp->sw_if_index);
2184       vam->result_ready = 1;
2185     }
2186   vam->regenerate_interface_table = 1;
2187 }
2188
2189 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2190   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2191 {
2192   vat_main_t *vam = &vat_main;
2193   vat_json_node_t node;
2194
2195   vat_json_init_object (&node);
2196   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2197   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2198                             ntohl (mp->sw_if_index));
2199
2200   vat_json_print (vam->ofp, &node);
2201   vat_json_free (&node);
2202
2203   vam->retval = ntohl (mp->retval);
2204   vam->result_ready = 1;
2205 }
2206
2207 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2208   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2209 {
2210   vat_main_t *vam = &vat_main;
2211   i32 retval = ntohl (mp->retval);
2212   if (vam->async_mode)
2213     {
2214       vam->async_errors += (retval < 0);
2215     }
2216   else
2217     {
2218       vam->retval = retval;
2219       vam->sw_if_index = ntohl (mp->sw_if_index);
2220       vam->result_ready = 1;
2221     }
2222 }
2223
2224 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2225   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2226 {
2227   vat_main_t *vam = &vat_main;
2228   vat_json_node_t node;
2229
2230   vat_json_init_object (&node);
2231   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2232   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2233
2234   vat_json_print (vam->ofp, &node);
2235   vat_json_free (&node);
2236
2237   vam->retval = ntohl (mp->retval);
2238   vam->result_ready = 1;
2239 }
2240
2241 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2242   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2243 {
2244   vat_main_t *vam = &vat_main;
2245   i32 retval = ntohl (mp->retval);
2246   if (vam->async_mode)
2247     {
2248       vam->async_errors += (retval < 0);
2249     }
2250   else
2251     {
2252       vam->retval = retval;
2253       vam->result_ready = 1;
2254     }
2255 }
2256
2257 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2258   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2259 {
2260   vat_main_t *vam = &vat_main;
2261   vat_json_node_t node;
2262
2263   vat_json_init_object (&node);
2264   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2265   vat_json_object_add_uint (&node, "fwd_entry_index",
2266                             clib_net_to_host_u32 (mp->fwd_entry_index));
2267
2268   vat_json_print (vam->ofp, &node);
2269   vat_json_free (&node);
2270
2271   vam->retval = ntohl (mp->retval);
2272   vam->result_ready = 1;
2273 }
2274
2275 u8 *
2276 format_lisp_transport_protocol (u8 * s, va_list * args)
2277 {
2278   u32 proto = va_arg (*args, u32);
2279
2280   switch (proto)
2281     {
2282     case 1:
2283       return format (s, "udp");
2284     case 2:
2285       return format (s, "api");
2286     default:
2287       return 0;
2288     }
2289   return 0;
2290 }
2291
2292 static void vl_api_one_get_transport_protocol_reply_t_handler
2293   (vl_api_one_get_transport_protocol_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   i32 retval = ntohl (mp->retval);
2297   if (vam->async_mode)
2298     {
2299       vam->async_errors += (retval < 0);
2300     }
2301   else
2302     {
2303       u32 proto = mp->protocol;
2304       print (vam->ofp, "Transport protocol: %U",
2305              format_lisp_transport_protocol, proto);
2306       vam->retval = retval;
2307       vam->result_ready = 1;
2308     }
2309 }
2310
2311 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2312   (vl_api_one_get_transport_protocol_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   vat_json_node_t node;
2316   u8 *s;
2317
2318   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2319   vec_add1 (s, 0);
2320
2321   vat_json_init_object (&node);
2322   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2323   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2324
2325   vec_free (s);
2326   vat_json_print (vam->ofp, &node);
2327   vat_json_free (&node);
2328
2329   vam->retval = ntohl (mp->retval);
2330   vam->result_ready = 1;
2331 }
2332
2333 static void vl_api_one_add_del_locator_set_reply_t_handler
2334   (vl_api_one_add_del_locator_set_reply_t * mp)
2335 {
2336   vat_main_t *vam = &vat_main;
2337   i32 retval = ntohl (mp->retval);
2338   if (vam->async_mode)
2339     {
2340       vam->async_errors += (retval < 0);
2341     }
2342   else
2343     {
2344       vam->retval = retval;
2345       vam->result_ready = 1;
2346     }
2347 }
2348
2349 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2350   (vl_api_one_add_del_locator_set_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   vat_json_node_t node;
2354
2355   vat_json_init_object (&node);
2356   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2357   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2358
2359   vat_json_print (vam->ofp, &node);
2360   vat_json_free (&node);
2361
2362   vam->retval = ntohl (mp->retval);
2363   vam->result_ready = 1;
2364 }
2365
2366 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2367   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2368 {
2369   vat_main_t *vam = &vat_main;
2370   i32 retval = ntohl (mp->retval);
2371   if (vam->async_mode)
2372     {
2373       vam->async_errors += (retval < 0);
2374     }
2375   else
2376     {
2377       vam->retval = retval;
2378       vam->sw_if_index = ntohl (mp->sw_if_index);
2379       vam->result_ready = 1;
2380     }
2381   vam->regenerate_interface_table = 1;
2382 }
2383
2384 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2385   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2386 {
2387   vat_main_t *vam = &vat_main;
2388   vat_json_node_t node;
2389
2390   vat_json_init_object (&node);
2391   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2392   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2393
2394   vat_json_print (vam->ofp, &node);
2395   vat_json_free (&node);
2396
2397   vam->retval = ntohl (mp->retval);
2398   vam->result_ready = 1;
2399 }
2400
2401 static void vl_api_vxlan_offload_rx_reply_t_handler
2402   (vl_api_vxlan_offload_rx_reply_t * mp)
2403 {
2404   vat_main_t *vam = &vat_main;
2405   i32 retval = ntohl (mp->retval);
2406   if (vam->async_mode)
2407     {
2408       vam->async_errors += (retval < 0);
2409     }
2410   else
2411     {
2412       vam->retval = retval;
2413       vam->result_ready = 1;
2414     }
2415 }
2416
2417 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2418   (vl_api_vxlan_offload_rx_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   vat_json_node_t node;
2422
2423   vat_json_init_object (&node);
2424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425
2426   vat_json_print (vam->ofp, &node);
2427   vat_json_free (&node);
2428
2429   vam->retval = ntohl (mp->retval);
2430   vam->result_ready = 1;
2431 }
2432
2433 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2434   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437   i32 retval = ntohl (mp->retval);
2438   if (vam->async_mode)
2439     {
2440       vam->async_errors += (retval < 0);
2441     }
2442   else
2443     {
2444       vam->retval = retval;
2445       vam->sw_if_index = ntohl (mp->sw_if_index);
2446       vam->result_ready = 1;
2447     }
2448 }
2449
2450 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2451   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   vat_json_node_t node;
2455
2456   vat_json_init_object (&node);
2457   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2458   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2459
2460   vat_json_print (vam->ofp, &node);
2461   vat_json_free (&node);
2462
2463   vam->retval = ntohl (mp->retval);
2464   vam->result_ready = 1;
2465 }
2466
2467 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2468   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2469 {
2470   vat_main_t *vam = &vat_main;
2471   i32 retval = ntohl (mp->retval);
2472   if (vam->async_mode)
2473     {
2474       vam->async_errors += (retval < 0);
2475     }
2476   else
2477     {
2478       vam->retval = retval;
2479       vam->sw_if_index = ntohl (mp->sw_if_index);
2480       vam->result_ready = 1;
2481     }
2482   vam->regenerate_interface_table = 1;
2483 }
2484
2485 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2486   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2487 {
2488   vat_main_t *vam = &vat_main;
2489   vat_json_node_t node;
2490
2491   vat_json_init_object (&node);
2492   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2493   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2494
2495   vat_json_print (vam->ofp, &node);
2496   vat_json_free (&node);
2497
2498   vam->retval = ntohl (mp->retval);
2499   vam->result_ready = 1;
2500 }
2501
2502 static void vl_api_gre_add_del_tunnel_reply_t_handler
2503   (vl_api_gre_add_del_tunnel_reply_t * mp)
2504 {
2505   vat_main_t *vam = &vat_main;
2506   i32 retval = ntohl (mp->retval);
2507   if (vam->async_mode)
2508     {
2509       vam->async_errors += (retval < 0);
2510     }
2511   else
2512     {
2513       vam->retval = retval;
2514       vam->sw_if_index = ntohl (mp->sw_if_index);
2515       vam->result_ready = 1;
2516     }
2517 }
2518
2519 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2520   (vl_api_gre_add_del_tunnel_reply_t * mp)
2521 {
2522   vat_main_t *vam = &vat_main;
2523   vat_json_node_t node;
2524
2525   vat_json_init_object (&node);
2526   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2527   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2528
2529   vat_json_print (vam->ofp, &node);
2530   vat_json_free (&node);
2531
2532   vam->retval = ntohl (mp->retval);
2533   vam->result_ready = 1;
2534 }
2535
2536 static void vl_api_create_vhost_user_if_reply_t_handler
2537   (vl_api_create_vhost_user_if_reply_t * mp)
2538 {
2539   vat_main_t *vam = &vat_main;
2540   i32 retval = ntohl (mp->retval);
2541   if (vam->async_mode)
2542     {
2543       vam->async_errors += (retval < 0);
2544     }
2545   else
2546     {
2547       vam->retval = retval;
2548       vam->sw_if_index = ntohl (mp->sw_if_index);
2549       vam->result_ready = 1;
2550     }
2551   vam->regenerate_interface_table = 1;
2552 }
2553
2554 static void vl_api_create_vhost_user_if_reply_t_handler_json
2555   (vl_api_create_vhost_user_if_reply_t * mp)
2556 {
2557   vat_main_t *vam = &vat_main;
2558   vat_json_node_t node;
2559
2560   vat_json_init_object (&node);
2561   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2562   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2563
2564   vat_json_print (vam->ofp, &node);
2565   vat_json_free (&node);
2566
2567   vam->retval = ntohl (mp->retval);
2568   vam->result_ready = 1;
2569 }
2570
2571 static void vl_api_dns_resolve_name_reply_t_handler
2572   (vl_api_dns_resolve_name_reply_t * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   i32 retval = ntohl (mp->retval);
2576   if (vam->async_mode)
2577     {
2578       vam->async_errors += (retval < 0);
2579     }
2580   else
2581     {
2582       vam->retval = retval;
2583       vam->result_ready = 1;
2584
2585       if (retval == 0)
2586         {
2587           if (mp->ip4_set)
2588             clib_warning ("ip4 address %U", format_ip4_address,
2589                           (ip4_address_t *) mp->ip4_address);
2590           if (mp->ip6_set)
2591             clib_warning ("ip6 address %U", format_ip6_address,
2592                           (ip6_address_t *) mp->ip6_address);
2593         }
2594       else
2595         clib_warning ("retval %d", retval);
2596     }
2597 }
2598
2599 static void vl_api_dns_resolve_name_reply_t_handler_json
2600   (vl_api_dns_resolve_name_reply_t * mp)
2601 {
2602   clib_warning ("not implemented");
2603 }
2604
2605 static void vl_api_dns_resolve_ip_reply_t_handler
2606   (vl_api_dns_resolve_ip_reply_t * mp)
2607 {
2608   vat_main_t *vam = &vat_main;
2609   i32 retval = ntohl (mp->retval);
2610   if (vam->async_mode)
2611     {
2612       vam->async_errors += (retval < 0);
2613     }
2614   else
2615     {
2616       vam->retval = retval;
2617       vam->result_ready = 1;
2618
2619       if (retval == 0)
2620         {
2621           clib_warning ("canonical name %s", mp->name);
2622         }
2623       else
2624         clib_warning ("retval %d", retval);
2625     }
2626 }
2627
2628 static void vl_api_dns_resolve_ip_reply_t_handler_json
2629   (vl_api_dns_resolve_ip_reply_t * mp)
2630 {
2631   clib_warning ("not implemented");
2632 }
2633
2634
2635 static void vl_api_ip_address_details_t_handler
2636   (vl_api_ip_address_details_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   static ip_address_details_t empty_ip_address_details = { {0} };
2640   ip_address_details_t *address = NULL;
2641   ip_details_t *current_ip_details = NULL;
2642   ip_details_t *details = NULL;
2643
2644   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2645
2646   if (!details || vam->current_sw_if_index >= vec_len (details)
2647       || !details[vam->current_sw_if_index].present)
2648     {
2649       errmsg ("ip address details arrived but not stored");
2650       errmsg ("ip_dump should be called first");
2651       return;
2652     }
2653
2654   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2655
2656 #define addresses (current_ip_details->addr)
2657
2658   vec_validate_init_empty (addresses, vec_len (addresses),
2659                            empty_ip_address_details);
2660
2661   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2662
2663   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2664   address->prefix_length = mp->prefix_length;
2665 #undef addresses
2666 }
2667
2668 static void vl_api_ip_address_details_t_handler_json
2669   (vl_api_ip_address_details_t * mp)
2670 {
2671   vat_main_t *vam = &vat_main;
2672   vat_json_node_t *node = NULL;
2673   struct in6_addr ip6;
2674   struct in_addr ip4;
2675
2676   if (VAT_JSON_ARRAY != vam->json_tree.type)
2677     {
2678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2679       vat_json_init_array (&vam->json_tree);
2680     }
2681   node = vat_json_array_add (&vam->json_tree);
2682
2683   vat_json_init_object (node);
2684   if (vam->is_ipv6)
2685     {
2686       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2687       vat_json_object_add_ip6 (node, "ip", ip6);
2688     }
2689   else
2690     {
2691       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2692       vat_json_object_add_ip4 (node, "ip", ip4);
2693     }
2694   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2695 }
2696
2697 static void
2698 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2699 {
2700   vat_main_t *vam = &vat_main;
2701   static ip_details_t empty_ip_details = { 0 };
2702   ip_details_t *ip = NULL;
2703   u32 sw_if_index = ~0;
2704
2705   sw_if_index = ntohl (mp->sw_if_index);
2706
2707   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2708                            sw_if_index, empty_ip_details);
2709
2710   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2711                          sw_if_index);
2712
2713   ip->present = 1;
2714 }
2715
2716 static void
2717 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2718 {
2719   vat_main_t *vam = &vat_main;
2720
2721   if (VAT_JSON_ARRAY != vam->json_tree.type)
2722     {
2723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2724       vat_json_init_array (&vam->json_tree);
2725     }
2726   vat_json_array_add_uint (&vam->json_tree,
2727                            clib_net_to_host_u32 (mp->sw_if_index));
2728 }
2729
2730 static void
2731 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2732 {
2733   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2734           "router_addr %U host_mac %U",
2735           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2736           mp->lease.hostname,
2737           format_ip4_address, &mp->lease.host_address,
2738           format_ip4_address, &mp->lease.router_address,
2739           format_ethernet_address, mp->lease.host_mac);
2740 }
2741
2742 static void vl_api_dhcp_compl_event_t_handler_json
2743   (vl_api_dhcp_compl_event_t * mp)
2744 {
2745   /* JSON output not supported */
2746 }
2747
2748 static void vl_api_get_first_msg_id_reply_t_handler
2749   (vl_api_get_first_msg_id_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   i32 retval = ntohl (mp->retval);
2753
2754   if (vam->async_mode)
2755     {
2756       vam->async_errors += (retval < 0);
2757     }
2758   else
2759     {
2760       vam->retval = retval;
2761       vam->result_ready = 1;
2762     }
2763   if (retval >= 0)
2764     {
2765       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2766     }
2767 }
2768
2769 static void vl_api_get_first_msg_id_reply_t_handler_json
2770   (vl_api_get_first_msg_id_reply_t * mp)
2771 {
2772   vat_main_t *vam = &vat_main;
2773   vat_json_node_t node;
2774
2775   vat_json_init_object (&node);
2776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2777   vat_json_object_add_uint (&node, "first_msg_id",
2778                             (uint) ntohs (mp->first_msg_id));
2779
2780   vat_json_print (vam->ofp, &node);
2781   vat_json_free (&node);
2782
2783   vam->retval = ntohl (mp->retval);
2784   vam->result_ready = 1;
2785 }
2786
2787 static void vl_api_get_node_graph_reply_t_handler
2788   (vl_api_get_node_graph_reply_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   api_main_t *am = &api_main;
2792   i32 retval = ntohl (mp->retval);
2793   u8 *pvt_copy, *reply;
2794   void *oldheap;
2795   vlib_node_t *node;
2796   int i;
2797
2798   if (vam->async_mode)
2799     {
2800       vam->async_errors += (retval < 0);
2801     }
2802   else
2803     {
2804       vam->retval = retval;
2805       vam->result_ready = 1;
2806     }
2807
2808   /* "Should never happen..." */
2809   if (retval != 0)
2810     return;
2811
2812   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2813   pvt_copy = vec_dup (reply);
2814
2815   /* Toss the shared-memory original... */
2816   pthread_mutex_lock (&am->vlib_rp->mutex);
2817   oldheap = svm_push_data_heap (am->vlib_rp);
2818
2819   vec_free (reply);
2820
2821   svm_pop_heap (oldheap);
2822   pthread_mutex_unlock (&am->vlib_rp->mutex);
2823
2824   if (vam->graph_nodes)
2825     {
2826       hash_free (vam->graph_node_index_by_name);
2827
2828       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2829         {
2830           node = vam->graph_nodes[0][i];
2831           vec_free (node->name);
2832           vec_free (node->next_nodes);
2833           vec_free (node);
2834         }
2835       vec_free (vam->graph_nodes[0]);
2836       vec_free (vam->graph_nodes);
2837     }
2838
2839   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2840   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2841   vec_free (pvt_copy);
2842
2843   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2844     {
2845       node = vam->graph_nodes[0][i];
2846       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2847     }
2848 }
2849
2850 static void vl_api_get_node_graph_reply_t_handler_json
2851   (vl_api_get_node_graph_reply_t * mp)
2852 {
2853   vat_main_t *vam = &vat_main;
2854   api_main_t *am = &api_main;
2855   void *oldheap;
2856   vat_json_node_t node;
2857   u8 *reply;
2858
2859   /* $$$$ make this real? */
2860   vat_json_init_object (&node);
2861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2862   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2863
2864   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2865
2866   /* Toss the shared-memory original... */
2867   pthread_mutex_lock (&am->vlib_rp->mutex);
2868   oldheap = svm_push_data_heap (am->vlib_rp);
2869
2870   vec_free (reply);
2871
2872   svm_pop_heap (oldheap);
2873   pthread_mutex_unlock (&am->vlib_rp->mutex);
2874
2875   vat_json_print (vam->ofp, &node);
2876   vat_json_free (&node);
2877
2878   vam->retval = ntohl (mp->retval);
2879   vam->result_ready = 1;
2880 }
2881
2882 static void
2883 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886   u8 *s = 0;
2887
2888   if (mp->local)
2889     {
2890       s = format (s, "%=16d%=16d%=16d",
2891                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2892     }
2893   else
2894     {
2895       s = format (s, "%=16U%=16d%=16d",
2896                   mp->is_ipv6 ? format_ip6_address :
2897                   format_ip4_address,
2898                   mp->ip_address, mp->priority, mp->weight);
2899     }
2900
2901   print (vam->ofp, "%v", s);
2902   vec_free (s);
2903 }
2904
2905 static void
2906 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2907 {
2908   vat_main_t *vam = &vat_main;
2909   vat_json_node_t *node = NULL;
2910   struct in6_addr ip6;
2911   struct in_addr ip4;
2912
2913   if (VAT_JSON_ARRAY != vam->json_tree.type)
2914     {
2915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2916       vat_json_init_array (&vam->json_tree);
2917     }
2918   node = vat_json_array_add (&vam->json_tree);
2919   vat_json_init_object (node);
2920
2921   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2922   vat_json_object_add_uint (node, "priority", mp->priority);
2923   vat_json_object_add_uint (node, "weight", mp->weight);
2924
2925   if (mp->local)
2926     vat_json_object_add_uint (node, "sw_if_index",
2927                               clib_net_to_host_u32 (mp->sw_if_index));
2928   else
2929     {
2930       if (mp->is_ipv6)
2931         {
2932           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2933           vat_json_object_add_ip6 (node, "address", ip6);
2934         }
2935       else
2936         {
2937           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2938           vat_json_object_add_ip4 (node, "address", ip4);
2939         }
2940     }
2941 }
2942
2943 static void
2944 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2945                                           mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   u8 *ls_name = 0;
2949
2950   ls_name = format (0, "%s", mp->ls_name);
2951
2952   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2953          ls_name);
2954   vec_free (ls_name);
2955 }
2956
2957 static void
2958   vl_api_one_locator_set_details_t_handler_json
2959   (vl_api_one_locator_set_details_t * mp)
2960 {
2961   vat_main_t *vam = &vat_main;
2962   vat_json_node_t *node = 0;
2963   u8 *ls_name = 0;
2964
2965   ls_name = format (0, "%s", mp->ls_name);
2966   vec_add1 (ls_name, 0);
2967
2968   if (VAT_JSON_ARRAY != vam->json_tree.type)
2969     {
2970       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2971       vat_json_init_array (&vam->json_tree);
2972     }
2973   node = vat_json_array_add (&vam->json_tree);
2974
2975   vat_json_init_object (node);
2976   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2977   vat_json_object_add_uint (node, "ls_index",
2978                             clib_net_to_host_u32 (mp->ls_index));
2979   vec_free (ls_name);
2980 }
2981
2982 typedef struct
2983 {
2984   u32 spi;
2985   u8 si;
2986 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2987
2988 uword
2989 unformat_nsh_address (unformat_input_t * input, va_list * args)
2990 {
2991   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2992   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2993 }
2994
2995 u8 *
2996 format_nsh_address_vat (u8 * s, va_list * args)
2997 {
2998   nsh_t *a = va_arg (*args, nsh_t *);
2999   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3000 }
3001
3002 static u8 *
3003 format_lisp_flat_eid (u8 * s, va_list * args)
3004 {
3005   u32 type = va_arg (*args, u32);
3006   u8 *eid = va_arg (*args, u8 *);
3007   u32 eid_len = va_arg (*args, u32);
3008
3009   switch (type)
3010     {
3011     case 0:
3012       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3013     case 1:
3014       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3015     case 2:
3016       return format (s, "%U", format_ethernet_address, eid);
3017     case 3:
3018       return format (s, "%U", format_nsh_address_vat, eid);
3019     }
3020   return 0;
3021 }
3022
3023 static u8 *
3024 format_lisp_eid_vat (u8 * s, va_list * args)
3025 {
3026   u32 type = va_arg (*args, u32);
3027   u8 *eid = va_arg (*args, u8 *);
3028   u32 eid_len = va_arg (*args, u32);
3029   u8 *seid = va_arg (*args, u8 *);
3030   u32 seid_len = va_arg (*args, u32);
3031   u32 is_src_dst = va_arg (*args, u32);
3032
3033   if (is_src_dst)
3034     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3035
3036   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3037
3038   return s;
3039 }
3040
3041 static void
3042 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3043 {
3044   vat_main_t *vam = &vat_main;
3045   u8 *s = 0, *eid = 0;
3046
3047   if (~0 == mp->locator_set_index)
3048     s = format (0, "action: %d", mp->action);
3049   else
3050     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3051
3052   eid = format (0, "%U", format_lisp_eid_vat,
3053                 mp->eid_type,
3054                 mp->eid,
3055                 mp->eid_prefix_len,
3056                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3057   vec_add1 (eid, 0);
3058
3059   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3060          clib_net_to_host_u32 (mp->vni),
3061          eid,
3062          mp->is_local ? "local" : "remote",
3063          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3064          clib_net_to_host_u16 (mp->key_id), mp->key);
3065
3066   vec_free (s);
3067   vec_free (eid);
3068 }
3069
3070 static void
3071 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3072                                              * mp)
3073 {
3074   vat_main_t *vam = &vat_main;
3075   vat_json_node_t *node = 0;
3076   u8 *eid = 0;
3077
3078   if (VAT_JSON_ARRAY != vam->json_tree.type)
3079     {
3080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3081       vat_json_init_array (&vam->json_tree);
3082     }
3083   node = vat_json_array_add (&vam->json_tree);
3084
3085   vat_json_init_object (node);
3086   if (~0 == mp->locator_set_index)
3087     vat_json_object_add_uint (node, "action", mp->action);
3088   else
3089     vat_json_object_add_uint (node, "locator_set_index",
3090                               clib_net_to_host_u32 (mp->locator_set_index));
3091
3092   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3093   if (mp->eid_type == 3)
3094     {
3095       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3096       vat_json_init_object (nsh_json);
3097       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3098       vat_json_object_add_uint (nsh_json, "spi",
3099                                 clib_net_to_host_u32 (nsh->spi));
3100       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3101     }
3102   else
3103     {
3104       eid = format (0, "%U", format_lisp_eid_vat,
3105                     mp->eid_type,
3106                     mp->eid,
3107                     mp->eid_prefix_len,
3108                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3109       vec_add1 (eid, 0);
3110       vat_json_object_add_string_copy (node, "eid", eid);
3111       vec_free (eid);
3112     }
3113   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3114   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3115   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3116
3117   if (mp->key_id)
3118     {
3119       vat_json_object_add_uint (node, "key_id",
3120                                 clib_net_to_host_u16 (mp->key_id));
3121       vat_json_object_add_string_copy (node, "key", mp->key);
3122     }
3123 }
3124
3125 static void
3126 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   u8 *seid = 0, *deid = 0;
3130   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3131
3132   deid = format (0, "%U", format_lisp_eid_vat,
3133                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3134
3135   seid = format (0, "%U", format_lisp_eid_vat,
3136                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3137
3138   vec_add1 (deid, 0);
3139   vec_add1 (seid, 0);
3140
3141   if (mp->is_ip4)
3142     format_ip_address_fcn = format_ip4_address;
3143   else
3144     format_ip_address_fcn = format_ip6_address;
3145
3146
3147   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3148          clib_net_to_host_u32 (mp->vni),
3149          seid, deid,
3150          format_ip_address_fcn, mp->lloc,
3151          format_ip_address_fcn, mp->rloc,
3152          clib_net_to_host_u32 (mp->pkt_count),
3153          clib_net_to_host_u32 (mp->bytes));
3154
3155   vec_free (deid);
3156   vec_free (seid);
3157 }
3158
3159 static void
3160 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3161 {
3162   struct in6_addr ip6;
3163   struct in_addr ip4;
3164   vat_main_t *vam = &vat_main;
3165   vat_json_node_t *node = 0;
3166   u8 *deid = 0, *seid = 0;
3167
3168   if (VAT_JSON_ARRAY != vam->json_tree.type)
3169     {
3170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3171       vat_json_init_array (&vam->json_tree);
3172     }
3173   node = vat_json_array_add (&vam->json_tree);
3174
3175   vat_json_init_object (node);
3176   deid = format (0, "%U", format_lisp_eid_vat,
3177                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3178
3179   seid = format (0, "%U", format_lisp_eid_vat,
3180                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3181
3182   vec_add1 (deid, 0);
3183   vec_add1 (seid, 0);
3184
3185   vat_json_object_add_string_copy (node, "seid", seid);
3186   vat_json_object_add_string_copy (node, "deid", deid);
3187   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3188
3189   if (mp->is_ip4)
3190     {
3191       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3192       vat_json_object_add_ip4 (node, "lloc", ip4);
3193       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3194       vat_json_object_add_ip4 (node, "rloc", ip4);
3195     }
3196   else
3197     {
3198       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3199       vat_json_object_add_ip6 (node, "lloc", ip6);
3200       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3201       vat_json_object_add_ip6 (node, "rloc", ip6);
3202     }
3203   vat_json_object_add_uint (node, "pkt_count",
3204                             clib_net_to_host_u32 (mp->pkt_count));
3205   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3206
3207   vec_free (deid);
3208   vec_free (seid);
3209 }
3210
3211 static void
3212   vl_api_one_eid_table_map_details_t_handler
3213   (vl_api_one_eid_table_map_details_t * mp)
3214 {
3215   vat_main_t *vam = &vat_main;
3216
3217   u8 *line = format (0, "%=10d%=10d",
3218                      clib_net_to_host_u32 (mp->vni),
3219                      clib_net_to_host_u32 (mp->dp_table));
3220   print (vam->ofp, "%v", line);
3221   vec_free (line);
3222 }
3223
3224 static void
3225   vl_api_one_eid_table_map_details_t_handler_json
3226   (vl_api_one_eid_table_map_details_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   vat_json_node_t *node = NULL;
3230
3231   if (VAT_JSON_ARRAY != vam->json_tree.type)
3232     {
3233       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3234       vat_json_init_array (&vam->json_tree);
3235     }
3236   node = vat_json_array_add (&vam->json_tree);
3237   vat_json_init_object (node);
3238   vat_json_object_add_uint (node, "dp_table",
3239                             clib_net_to_host_u32 (mp->dp_table));
3240   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3241 }
3242
3243 static void
3244   vl_api_one_eid_table_vni_details_t_handler
3245   (vl_api_one_eid_table_vni_details_t * mp)
3246 {
3247   vat_main_t *vam = &vat_main;
3248
3249   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3250   print (vam->ofp, "%v", line);
3251   vec_free (line);
3252 }
3253
3254 static void
3255   vl_api_one_eid_table_vni_details_t_handler_json
3256   (vl_api_one_eid_table_vni_details_t * mp)
3257 {
3258   vat_main_t *vam = &vat_main;
3259   vat_json_node_t *node = NULL;
3260
3261   if (VAT_JSON_ARRAY != vam->json_tree.type)
3262     {
3263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3264       vat_json_init_array (&vam->json_tree);
3265     }
3266   node = vat_json_array_add (&vam->json_tree);
3267   vat_json_init_object (node);
3268   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3269 }
3270
3271 static void
3272   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3273   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   int retval = clib_net_to_host_u32 (mp->retval);
3277
3278   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3279   print (vam->ofp, "fallback threshold value: %d", mp->value);
3280
3281   vam->retval = retval;
3282   vam->result_ready = 1;
3283 }
3284
3285 static void
3286   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3287   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3288 {
3289   vat_main_t *vam = &vat_main;
3290   vat_json_node_t _node, *node = &_node;
3291   int retval = clib_net_to_host_u32 (mp->retval);
3292
3293   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3294   vat_json_init_object (node);
3295   vat_json_object_add_uint (node, "value", mp->value);
3296
3297   vat_json_print (vam->ofp, node);
3298   vat_json_free (node);
3299
3300   vam->retval = retval;
3301   vam->result_ready = 1;
3302 }
3303
3304 static void
3305   vl_api_show_one_map_register_state_reply_t_handler
3306   (vl_api_show_one_map_register_state_reply_t * mp)
3307 {
3308   vat_main_t *vam = &vat_main;
3309   int retval = clib_net_to_host_u32 (mp->retval);
3310
3311   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3312
3313   vam->retval = retval;
3314   vam->result_ready = 1;
3315 }
3316
3317 static void
3318   vl_api_show_one_map_register_state_reply_t_handler_json
3319   (vl_api_show_one_map_register_state_reply_t * mp)
3320 {
3321   vat_main_t *vam = &vat_main;
3322   vat_json_node_t _node, *node = &_node;
3323   int retval = clib_net_to_host_u32 (mp->retval);
3324
3325   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3326
3327   vat_json_init_object (node);
3328   vat_json_object_add_string_copy (node, "state", s);
3329
3330   vat_json_print (vam->ofp, node);
3331   vat_json_free (node);
3332
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335   vec_free (s);
3336 }
3337
3338 static void
3339   vl_api_show_one_rloc_probe_state_reply_t_handler
3340   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   if (retval)
3346     goto end;
3347
3348   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3349 end:
3350   vam->retval = retval;
3351   vam->result_ready = 1;
3352 }
3353
3354 static void
3355   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3356   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3357 {
3358   vat_main_t *vam = &vat_main;
3359   vat_json_node_t _node, *node = &_node;
3360   int retval = clib_net_to_host_u32 (mp->retval);
3361
3362   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3363   vat_json_init_object (node);
3364   vat_json_object_add_string_copy (node, "state", s);
3365
3366   vat_json_print (vam->ofp, node);
3367   vat_json_free (node);
3368
3369   vam->retval = retval;
3370   vam->result_ready = 1;
3371   vec_free (s);
3372 }
3373
3374 static void
3375   vl_api_show_one_stats_enable_disable_reply_t_handler
3376   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3377 {
3378   vat_main_t *vam = &vat_main;
3379   int retval = clib_net_to_host_u32 (mp->retval);
3380
3381   if (retval)
3382     goto end;
3383
3384   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3385 end:
3386   vam->retval = retval;
3387   vam->result_ready = 1;
3388 }
3389
3390 static void
3391   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3392   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395   vat_json_node_t _node, *node = &_node;
3396   int retval = clib_net_to_host_u32 (mp->retval);
3397
3398   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3399   vat_json_init_object (node);
3400   vat_json_object_add_string_copy (node, "state", s);
3401
3402   vat_json_print (vam->ofp, node);
3403   vat_json_free (node);
3404
3405   vam->retval = retval;
3406   vam->result_ready = 1;
3407   vec_free (s);
3408 }
3409
3410 static void
3411 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3412 {
3413   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3414   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3415   e->vni = clib_net_to_host_u32 (e->vni);
3416 }
3417
3418 static void
3419   gpe_fwd_entries_get_reply_t_net_to_host
3420   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3421 {
3422   u32 i;
3423
3424   mp->count = clib_net_to_host_u32 (mp->count);
3425   for (i = 0; i < mp->count; i++)
3426     {
3427       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3428     }
3429 }
3430
3431 static u8 *
3432 format_gpe_encap_mode (u8 * s, va_list * args)
3433 {
3434   u32 mode = va_arg (*args, u32);
3435
3436   switch (mode)
3437     {
3438     case 0:
3439       return format (s, "lisp");
3440     case 1:
3441       return format (s, "vxlan");
3442     }
3443   return 0;
3444 }
3445
3446 static void
3447   vl_api_gpe_get_encap_mode_reply_t_handler
3448   (vl_api_gpe_get_encap_mode_reply_t * mp)
3449 {
3450   vat_main_t *vam = &vat_main;
3451
3452   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3453   vam->retval = ntohl (mp->retval);
3454   vam->result_ready = 1;
3455 }
3456
3457 static void
3458   vl_api_gpe_get_encap_mode_reply_t_handler_json
3459   (vl_api_gpe_get_encap_mode_reply_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462   vat_json_node_t node;
3463
3464   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3465   vec_add1 (encap_mode, 0);
3466
3467   vat_json_init_object (&node);
3468   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3469
3470   vec_free (encap_mode);
3471   vat_json_print (vam->ofp, &node);
3472   vat_json_free (&node);
3473
3474   vam->retval = ntohl (mp->retval);
3475   vam->result_ready = 1;
3476 }
3477
3478 static void
3479   vl_api_gpe_fwd_entry_path_details_t_handler
3480   (vl_api_gpe_fwd_entry_path_details_t * mp)
3481 {
3482   vat_main_t *vam = &vat_main;
3483   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3484
3485   if (mp->lcl_loc.is_ip4)
3486     format_ip_address_fcn = format_ip4_address;
3487   else
3488     format_ip_address_fcn = format_ip6_address;
3489
3490   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3491          format_ip_address_fcn, &mp->lcl_loc,
3492          format_ip_address_fcn, &mp->rmt_loc);
3493 }
3494
3495 static void
3496 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3497 {
3498   struct in6_addr ip6;
3499   struct in_addr ip4;
3500
3501   if (loc->is_ip4)
3502     {
3503       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3504       vat_json_object_add_ip4 (n, "address", ip4);
3505     }
3506   else
3507     {
3508       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3509       vat_json_object_add_ip6 (n, "address", ip6);
3510     }
3511   vat_json_object_add_uint (n, "weight", loc->weight);
3512 }
3513
3514 static void
3515   vl_api_gpe_fwd_entry_path_details_t_handler_json
3516   (vl_api_gpe_fwd_entry_path_details_t * mp)
3517 {
3518   vat_main_t *vam = &vat_main;
3519   vat_json_node_t *node = NULL;
3520   vat_json_node_t *loc_node;
3521
3522   if (VAT_JSON_ARRAY != vam->json_tree.type)
3523     {
3524       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3525       vat_json_init_array (&vam->json_tree);
3526     }
3527   node = vat_json_array_add (&vam->json_tree);
3528   vat_json_init_object (node);
3529
3530   loc_node = vat_json_object_add (node, "local_locator");
3531   vat_json_init_object (loc_node);
3532   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3533
3534   loc_node = vat_json_object_add (node, "remote_locator");
3535   vat_json_init_object (loc_node);
3536   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3537 }
3538
3539 static void
3540   vl_api_gpe_fwd_entries_get_reply_t_handler
3541   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3542 {
3543   vat_main_t *vam = &vat_main;
3544   u32 i;
3545   int retval = clib_net_to_host_u32 (mp->retval);
3546   vl_api_gpe_fwd_entry_t *e;
3547
3548   if (retval)
3549     goto end;
3550
3551   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3552
3553   for (i = 0; i < mp->count; i++)
3554     {
3555       e = &mp->entries[i];
3556       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3557              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3558              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3559     }
3560
3561 end:
3562   vam->retval = retval;
3563   vam->result_ready = 1;
3564 }
3565
3566 static void
3567   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3568   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3569 {
3570   u8 *s = 0;
3571   vat_main_t *vam = &vat_main;
3572   vat_json_node_t *e = 0, root;
3573   u32 i;
3574   int retval = clib_net_to_host_u32 (mp->retval);
3575   vl_api_gpe_fwd_entry_t *fwd;
3576
3577   if (retval)
3578     goto end;
3579
3580   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3581   vat_json_init_array (&root);
3582
3583   for (i = 0; i < mp->count; i++)
3584     {
3585       e = vat_json_array_add (&root);
3586       fwd = &mp->entries[i];
3587
3588       vat_json_init_object (e);
3589       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3590       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3591       vat_json_object_add_int (e, "vni", fwd->vni);
3592       vat_json_object_add_int (e, "action", fwd->action);
3593
3594       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3595                   fwd->leid_prefix_len);
3596       vec_add1 (s, 0);
3597       vat_json_object_add_string_copy (e, "leid", s);
3598       vec_free (s);
3599
3600       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3601                   fwd->reid_prefix_len);
3602       vec_add1 (s, 0);
3603       vat_json_object_add_string_copy (e, "reid", s);
3604       vec_free (s);
3605     }
3606
3607   vat_json_print (vam->ofp, &root);
3608   vat_json_free (&root);
3609
3610 end:
3611   vam->retval = retval;
3612   vam->result_ready = 1;
3613 }
3614
3615 static void
3616   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3617   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620   u32 i, n;
3621   int retval = clib_net_to_host_u32 (mp->retval);
3622   vl_api_gpe_native_fwd_rpath_t *r;
3623
3624   if (retval)
3625     goto end;
3626
3627   n = clib_net_to_host_u32 (mp->count);
3628
3629   for (i = 0; i < n; i++)
3630     {
3631       r = &mp->entries[i];
3632       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3633              clib_net_to_host_u32 (r->fib_index),
3634              clib_net_to_host_u32 (r->nh_sw_if_index),
3635              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3636     }
3637
3638 end:
3639   vam->retval = retval;
3640   vam->result_ready = 1;
3641 }
3642
3643 static void
3644   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3645   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3646 {
3647   vat_main_t *vam = &vat_main;
3648   vat_json_node_t root, *e;
3649   u32 i, n;
3650   int retval = clib_net_to_host_u32 (mp->retval);
3651   vl_api_gpe_native_fwd_rpath_t *r;
3652   u8 *s;
3653
3654   if (retval)
3655     goto end;
3656
3657   n = clib_net_to_host_u32 (mp->count);
3658   vat_json_init_array (&root);
3659
3660   for (i = 0; i < n; i++)
3661     {
3662       e = vat_json_array_add (&root);
3663       vat_json_init_object (e);
3664       r = &mp->entries[i];
3665       s =
3666         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3667                 r->nh_addr);
3668       vec_add1 (s, 0);
3669       vat_json_object_add_string_copy (e, "ip4", s);
3670       vec_free (s);
3671
3672       vat_json_object_add_uint (e, "fib_index",
3673                                 clib_net_to_host_u32 (r->fib_index));
3674       vat_json_object_add_uint (e, "nh_sw_if_index",
3675                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3676     }
3677
3678   vat_json_print (vam->ofp, &root);
3679   vat_json_free (&root);
3680
3681 end:
3682   vam->retval = retval;
3683   vam->result_ready = 1;
3684 }
3685
3686 static void
3687   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3688   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691   u32 i, n;
3692   int retval = clib_net_to_host_u32 (mp->retval);
3693
3694   if (retval)
3695     goto end;
3696
3697   n = clib_net_to_host_u32 (mp->count);
3698
3699   for (i = 0; i < n; i++)
3700     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3701
3702 end:
3703   vam->retval = retval;
3704   vam->result_ready = 1;
3705 }
3706
3707 static void
3708   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3709   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3710 {
3711   vat_main_t *vam = &vat_main;
3712   vat_json_node_t root;
3713   u32 i, n;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715
3716   if (retval)
3717     goto end;
3718
3719   n = clib_net_to_host_u32 (mp->count);
3720   vat_json_init_array (&root);
3721
3722   for (i = 0; i < n; i++)
3723     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3724
3725   vat_json_print (vam->ofp, &root);
3726   vat_json_free (&root);
3727
3728 end:
3729   vam->retval = retval;
3730   vam->result_ready = 1;
3731 }
3732
3733 static void
3734   vl_api_one_ndp_entries_get_reply_t_handler
3735   (vl_api_one_ndp_entries_get_reply_t * mp)
3736 {
3737   vat_main_t *vam = &vat_main;
3738   u32 i, n;
3739   int retval = clib_net_to_host_u32 (mp->retval);
3740
3741   if (retval)
3742     goto end;
3743
3744   n = clib_net_to_host_u32 (mp->count);
3745
3746   for (i = 0; i < n; i++)
3747     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3748            format_ethernet_address, mp->entries[i].mac);
3749
3750 end:
3751   vam->retval = retval;
3752   vam->result_ready = 1;
3753 }
3754
3755 static void
3756   vl_api_one_ndp_entries_get_reply_t_handler_json
3757   (vl_api_one_ndp_entries_get_reply_t * mp)
3758 {
3759   u8 *s = 0;
3760   vat_main_t *vam = &vat_main;
3761   vat_json_node_t *e = 0, root;
3762   u32 i, n;
3763   int retval = clib_net_to_host_u32 (mp->retval);
3764   vl_api_one_ndp_entry_t *arp_entry;
3765
3766   if (retval)
3767     goto end;
3768
3769   n = clib_net_to_host_u32 (mp->count);
3770   vat_json_init_array (&root);
3771
3772   for (i = 0; i < n; i++)
3773     {
3774       e = vat_json_array_add (&root);
3775       arp_entry = &mp->entries[i];
3776
3777       vat_json_init_object (e);
3778       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3779       vec_add1 (s, 0);
3780
3781       vat_json_object_add_string_copy (e, "mac", s);
3782       vec_free (s);
3783
3784       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3785       vec_add1 (s, 0);
3786       vat_json_object_add_string_copy (e, "ip6", s);
3787       vec_free (s);
3788     }
3789
3790   vat_json_print (vam->ofp, &root);
3791   vat_json_free (&root);
3792
3793 end:
3794   vam->retval = retval;
3795   vam->result_ready = 1;
3796 }
3797
3798 static void
3799   vl_api_one_l2_arp_entries_get_reply_t_handler
3800   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3801 {
3802   vat_main_t *vam = &vat_main;
3803   u32 i, n;
3804   int retval = clib_net_to_host_u32 (mp->retval);
3805
3806   if (retval)
3807     goto end;
3808
3809   n = clib_net_to_host_u32 (mp->count);
3810
3811   for (i = 0; i < n; i++)
3812     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3813            format_ethernet_address, mp->entries[i].mac);
3814
3815 end:
3816   vam->retval = retval;
3817   vam->result_ready = 1;
3818 }
3819
3820 static void
3821   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3822   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3823 {
3824   u8 *s = 0;
3825   vat_main_t *vam = &vat_main;
3826   vat_json_node_t *e = 0, root;
3827   u32 i, n;
3828   int retval = clib_net_to_host_u32 (mp->retval);
3829   vl_api_one_l2_arp_entry_t *arp_entry;
3830
3831   if (retval)
3832     goto end;
3833
3834   n = clib_net_to_host_u32 (mp->count);
3835   vat_json_init_array (&root);
3836
3837   for (i = 0; i < n; i++)
3838     {
3839       e = vat_json_array_add (&root);
3840       arp_entry = &mp->entries[i];
3841
3842       vat_json_init_object (e);
3843       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3844       vec_add1 (s, 0);
3845
3846       vat_json_object_add_string_copy (e, "mac", s);
3847       vec_free (s);
3848
3849       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3850       vec_add1 (s, 0);
3851       vat_json_object_add_string_copy (e, "ip4", s);
3852       vec_free (s);
3853     }
3854
3855   vat_json_print (vam->ofp, &root);
3856   vat_json_free (&root);
3857
3858 end:
3859   vam->retval = retval;
3860   vam->result_ready = 1;
3861 }
3862
3863 static void
3864 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   u32 i, n;
3868   int retval = clib_net_to_host_u32 (mp->retval);
3869
3870   if (retval)
3871     goto end;
3872
3873   n = clib_net_to_host_u32 (mp->count);
3874
3875   for (i = 0; i < n; i++)
3876     {
3877       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880 end:
3881   vam->retval = retval;
3882   vam->result_ready = 1;
3883 }
3884
3885 static void
3886   vl_api_one_ndp_bd_get_reply_t_handler_json
3887   (vl_api_one_ndp_bd_get_reply_t * mp)
3888 {
3889   vat_main_t *vam = &vat_main;
3890   vat_json_node_t root;
3891   u32 i, n;
3892   int retval = clib_net_to_host_u32 (mp->retval);
3893
3894   if (retval)
3895     goto end;
3896
3897   n = clib_net_to_host_u32 (mp->count);
3898   vat_json_init_array (&root);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       vat_json_array_add_uint (&root,
3903                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3904     }
3905
3906   vat_json_print (vam->ofp, &root);
3907   vat_json_free (&root);
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_l2_arp_bd_get_reply_t_handler
3916   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3917 {
3918   vat_main_t *vam = &vat_main;
3919   u32 i, n;
3920   int retval = clib_net_to_host_u32 (mp->retval);
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       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3930     }
3931
3932 end:
3933   vam->retval = retval;
3934   vam->result_ready = 1;
3935 }
3936
3937 static void
3938   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3939   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3940 {
3941   vat_main_t *vam = &vat_main;
3942   vat_json_node_t root;
3943   u32 i, n;
3944   int retval = clib_net_to_host_u32 (mp->retval);
3945
3946   if (retval)
3947     goto end;
3948
3949   n = clib_net_to_host_u32 (mp->count);
3950   vat_json_init_array (&root);
3951
3952   for (i = 0; i < n; i++)
3953     {
3954       vat_json_array_add_uint (&root,
3955                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3956     }
3957
3958   vat_json_print (vam->ofp, &root);
3959   vat_json_free (&root);
3960
3961 end:
3962   vam->retval = retval;
3963   vam->result_ready = 1;
3964 }
3965
3966 static void
3967   vl_api_one_adjacencies_get_reply_t_handler
3968   (vl_api_one_adjacencies_get_reply_t * mp)
3969 {
3970   vat_main_t *vam = &vat_main;
3971   u32 i, n;
3972   int retval = clib_net_to_host_u32 (mp->retval);
3973   vl_api_one_adjacency_t *a;
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     {
3982       a = &mp->adjacencies[i];
3983       print (vam->ofp, "%U %40U",
3984              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3985              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3986     }
3987
3988 end:
3989   vam->retval = retval;
3990   vam->result_ready = 1;
3991 }
3992
3993 static void
3994   vl_api_one_adjacencies_get_reply_t_handler_json
3995   (vl_api_one_adjacencies_get_reply_t * mp)
3996 {
3997   u8 *s = 0;
3998   vat_main_t *vam = &vat_main;
3999   vat_json_node_t *e = 0, root;
4000   u32 i, n;
4001   int retval = clib_net_to_host_u32 (mp->retval);
4002   vl_api_one_adjacency_t *a;
4003
4004   if (retval)
4005     goto end;
4006
4007   n = clib_net_to_host_u32 (mp->count);
4008   vat_json_init_array (&root);
4009
4010   for (i = 0; i < n; i++)
4011     {
4012       e = vat_json_array_add (&root);
4013       a = &mp->adjacencies[i];
4014
4015       vat_json_init_object (e);
4016       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4017                   a->leid_prefix_len);
4018       vec_add1 (s, 0);
4019       vat_json_object_add_string_copy (e, "leid", s);
4020       vec_free (s);
4021
4022       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4023                   a->reid_prefix_len);
4024       vec_add1 (s, 0);
4025       vat_json_object_add_string_copy (e, "reid", s);
4026       vec_free (s);
4027     }
4028
4029   vat_json_print (vam->ofp, &root);
4030   vat_json_free (&root);
4031
4032 end:
4033   vam->retval = retval;
4034   vam->result_ready = 1;
4035 }
4036
4037 static void
4038 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041
4042   print (vam->ofp, "%=20U",
4043          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4044          mp->ip_address);
4045 }
4046
4047 static void
4048   vl_api_one_map_server_details_t_handler_json
4049   (vl_api_one_map_server_details_t * mp)
4050 {
4051   vat_main_t *vam = &vat_main;
4052   vat_json_node_t *node = NULL;
4053   struct in6_addr ip6;
4054   struct in_addr ip4;
4055
4056   if (VAT_JSON_ARRAY != vam->json_tree.type)
4057     {
4058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4059       vat_json_init_array (&vam->json_tree);
4060     }
4061   node = vat_json_array_add (&vam->json_tree);
4062
4063   vat_json_init_object (node);
4064   if (mp->is_ipv6)
4065     {
4066       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4067       vat_json_object_add_ip6 (node, "map-server", ip6);
4068     }
4069   else
4070     {
4071       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4072       vat_json_object_add_ip4 (node, "map-server", ip4);
4073     }
4074 }
4075
4076 static void
4077 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4078                                            * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081
4082   print (vam->ofp, "%=20U",
4083          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4084          mp->ip_address);
4085 }
4086
4087 static void
4088   vl_api_one_map_resolver_details_t_handler_json
4089   (vl_api_one_map_resolver_details_t * mp)
4090 {
4091   vat_main_t *vam = &vat_main;
4092   vat_json_node_t *node = NULL;
4093   struct in6_addr ip6;
4094   struct in_addr ip4;
4095
4096   if (VAT_JSON_ARRAY != vam->json_tree.type)
4097     {
4098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4099       vat_json_init_array (&vam->json_tree);
4100     }
4101   node = vat_json_array_add (&vam->json_tree);
4102
4103   vat_json_init_object (node);
4104   if (mp->is_ipv6)
4105     {
4106       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4107       vat_json_object_add_ip6 (node, "map resolver", ip6);
4108     }
4109   else
4110     {
4111       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4112       vat_json_object_add_ip4 (node, "map resolver", ip4);
4113     }
4114 }
4115
4116 static void
4117 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4118 {
4119   vat_main_t *vam = &vat_main;
4120   i32 retval = ntohl (mp->retval);
4121
4122   if (0 <= retval)
4123     {
4124       print (vam->ofp, "feature: %s\ngpe: %s",
4125              mp->feature_status ? "enabled" : "disabled",
4126              mp->gpe_status ? "enabled" : "disabled");
4127     }
4128
4129   vam->retval = retval;
4130   vam->result_ready = 1;
4131 }
4132
4133 static void
4134   vl_api_show_one_status_reply_t_handler_json
4135   (vl_api_show_one_status_reply_t * mp)
4136 {
4137   vat_main_t *vam = &vat_main;
4138   vat_json_node_t node;
4139   u8 *gpe_status = NULL;
4140   u8 *feature_status = NULL;
4141
4142   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4143   feature_status = format (0, "%s",
4144                            mp->feature_status ? "enabled" : "disabled");
4145   vec_add1 (gpe_status, 0);
4146   vec_add1 (feature_status, 0);
4147
4148   vat_json_init_object (&node);
4149   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4150   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4151
4152   vec_free (gpe_status);
4153   vec_free (feature_status);
4154
4155   vat_json_print (vam->ofp, &node);
4156   vat_json_free (&node);
4157
4158   vam->retval = ntohl (mp->retval);
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4164   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4165 {
4166   vat_main_t *vam = &vat_main;
4167   i32 retval = ntohl (mp->retval);
4168
4169   if (retval >= 0)
4170     {
4171       print (vam->ofp, "%=20s", mp->locator_set_name);
4172     }
4173
4174   vam->retval = retval;
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4180   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   vat_json_node_t *node = NULL;
4184
4185   if (VAT_JSON_ARRAY != vam->json_tree.type)
4186     {
4187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4188       vat_json_init_array (&vam->json_tree);
4189     }
4190   node = vat_json_array_add (&vam->json_tree);
4191
4192   vat_json_init_object (node);
4193   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4194
4195   vat_json_print (vam->ofp, node);
4196   vat_json_free (node);
4197
4198   vam->retval = ntohl (mp->retval);
4199   vam->result_ready = 1;
4200 }
4201
4202 static u8 *
4203 format_lisp_map_request_mode (u8 * s, va_list * args)
4204 {
4205   u32 mode = va_arg (*args, u32);
4206
4207   switch (mode)
4208     {
4209     case 0:
4210       return format (0, "dst-only");
4211     case 1:
4212       return format (0, "src-dst");
4213     }
4214   return 0;
4215 }
4216
4217 static void
4218   vl_api_show_one_map_request_mode_reply_t_handler
4219   (vl_api_show_one_map_request_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       u32 mode = mp->mode;
4227       print (vam->ofp, "map_request_mode: %U",
4228              format_lisp_map_request_mode, mode);
4229     }
4230
4231   vam->retval = retval;
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_show_one_map_request_mode_reply_t_handler_json
4237   (vl_api_show_one_map_request_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   vat_json_node_t node;
4241   u8 *s = 0;
4242   u32 mode;
4243
4244   mode = mp->mode;
4245   s = format (0, "%U", format_lisp_map_request_mode, mode);
4246   vec_add1 (s, 0);
4247
4248   vat_json_init_object (&node);
4249   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4250   vat_json_print (vam->ofp, &node);
4251   vat_json_free (&node);
4252
4253   vec_free (s);
4254   vam->retval = ntohl (mp->retval);
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_xtr_mode_reply_t_handler
4260   (vl_api_one_show_xtr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   i32 retval = ntohl (mp->retval);
4264
4265   if (0 <= retval)
4266     {
4267       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4268     }
4269
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_xtr_mode_reply_t_handler_json
4276   (vl_api_one_show_xtr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t node;
4280   u8 *status = 0;
4281
4282   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4283   vec_add1 (status, 0);
4284
4285   vat_json_init_object (&node);
4286   vat_json_object_add_string_copy (&node, "status", status);
4287
4288   vec_free (status);
4289
4290   vat_json_print (vam->ofp, &node);
4291   vat_json_free (&node);
4292
4293   vam->retval = ntohl (mp->retval);
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_one_show_pitr_mode_reply_t_handler
4299   (vl_api_one_show_pitr_mode_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   i32 retval = ntohl (mp->retval);
4303
4304   if (0 <= retval)
4305     {
4306       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4307     }
4308
4309   vam->retval = retval;
4310   vam->result_ready = 1;
4311 }
4312
4313 static void
4314   vl_api_one_show_pitr_mode_reply_t_handler_json
4315   (vl_api_one_show_pitr_mode_reply_t * mp)
4316 {
4317   vat_main_t *vam = &vat_main;
4318   vat_json_node_t node;
4319   u8 *status = 0;
4320
4321   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4322   vec_add1 (status, 0);
4323
4324   vat_json_init_object (&node);
4325   vat_json_object_add_string_copy (&node, "status", status);
4326
4327   vec_free (status);
4328
4329   vat_json_print (vam->ofp, &node);
4330   vat_json_free (&node);
4331
4332   vam->retval = ntohl (mp->retval);
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_one_show_petr_mode_reply_t_handler
4338   (vl_api_one_show_petr_mode_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   i32 retval = ntohl (mp->retval);
4342
4343   if (0 <= retval)
4344     {
4345       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4346     }
4347
4348   vam->retval = retval;
4349   vam->result_ready = 1;
4350 }
4351
4352 static void
4353   vl_api_one_show_petr_mode_reply_t_handler_json
4354   (vl_api_one_show_petr_mode_reply_t * mp)
4355 {
4356   vat_main_t *vam = &vat_main;
4357   vat_json_node_t node;
4358   u8 *status = 0;
4359
4360   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4361   vec_add1 (status, 0);
4362
4363   vat_json_init_object (&node);
4364   vat_json_object_add_string_copy (&node, "status", status);
4365
4366   vec_free (status);
4367
4368   vat_json_print (vam->ofp, &node);
4369   vat_json_free (&node);
4370
4371   vam->retval = ntohl (mp->retval);
4372   vam->result_ready = 1;
4373 }
4374
4375 static void
4376   vl_api_show_one_use_petr_reply_t_handler
4377   (vl_api_show_one_use_petr_reply_t * mp)
4378 {
4379   vat_main_t *vam = &vat_main;
4380   i32 retval = ntohl (mp->retval);
4381
4382   if (0 <= retval)
4383     {
4384       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4385       if (mp->status)
4386         {
4387           print (vam->ofp, "Proxy-ETR address; %U",
4388                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4389                  mp->address);
4390         }
4391     }
4392
4393   vam->retval = retval;
4394   vam->result_ready = 1;
4395 }
4396
4397 static void
4398   vl_api_show_one_use_petr_reply_t_handler_json
4399   (vl_api_show_one_use_petr_reply_t * mp)
4400 {
4401   vat_main_t *vam = &vat_main;
4402   vat_json_node_t node;
4403   u8 *status = 0;
4404   struct in_addr ip4;
4405   struct in6_addr ip6;
4406
4407   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4408   vec_add1 (status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "status", status);
4412   if (mp->status)
4413     {
4414       if (mp->is_ip4)
4415         {
4416           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4417           vat_json_object_add_ip6 (&node, "address", ip6);
4418         }
4419       else
4420         {
4421           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4422           vat_json_object_add_ip4 (&node, "address", ip4);
4423         }
4424     }
4425
4426   vec_free (status);
4427
4428   vat_json_print (vam->ofp, &node);
4429   vat_json_free (&node);
4430
4431   vam->retval = ntohl (mp->retval);
4432   vam->result_ready = 1;
4433 }
4434
4435 static void
4436   vl_api_show_one_nsh_mapping_reply_t_handler
4437   (vl_api_show_one_nsh_mapping_reply_t * mp)
4438 {
4439   vat_main_t *vam = &vat_main;
4440   i32 retval = ntohl (mp->retval);
4441
4442   if (0 <= retval)
4443     {
4444       print (vam->ofp, "%-20s%-16s",
4445              mp->is_set ? "set" : "not-set",
4446              mp->is_set ? (char *) mp->locator_set_name : "");
4447     }
4448
4449   vam->retval = retval;
4450   vam->result_ready = 1;
4451 }
4452
4453 static void
4454   vl_api_show_one_nsh_mapping_reply_t_handler_json
4455   (vl_api_show_one_nsh_mapping_reply_t * mp)
4456 {
4457   vat_main_t *vam = &vat_main;
4458   vat_json_node_t node;
4459   u8 *status = 0;
4460
4461   status = format (0, "%s", mp->is_set ? "yes" : "no");
4462   vec_add1 (status, 0);
4463
4464   vat_json_init_object (&node);
4465   vat_json_object_add_string_copy (&node, "is_set", status);
4466   if (mp->is_set)
4467     {
4468       vat_json_object_add_string_copy (&node, "locator_set",
4469                                        mp->locator_set_name);
4470     }
4471
4472   vec_free (status);
4473
4474   vat_json_print (vam->ofp, &node);
4475   vat_json_free (&node);
4476
4477   vam->retval = ntohl (mp->retval);
4478   vam->result_ready = 1;
4479 }
4480
4481 static void
4482   vl_api_show_one_map_register_ttl_reply_t_handler
4483   (vl_api_show_one_map_register_ttl_reply_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   i32 retval = ntohl (mp->retval);
4487
4488   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4489
4490   if (0 <= retval)
4491     {
4492       print (vam->ofp, "ttl: %u", mp->ttl);
4493     }
4494
4495   vam->retval = retval;
4496   vam->result_ready = 1;
4497 }
4498
4499 static void
4500   vl_api_show_one_map_register_ttl_reply_t_handler_json
4501   (vl_api_show_one_map_register_ttl_reply_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   vat_json_node_t node;
4505
4506   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4507   vat_json_init_object (&node);
4508   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4509
4510   vat_json_print (vam->ofp, &node);
4511   vat_json_free (&node);
4512
4513   vam->retval = ntohl (mp->retval);
4514   vam->result_ready = 1;
4515 }
4516
4517 static void
4518 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4519 {
4520   vat_main_t *vam = &vat_main;
4521   i32 retval = ntohl (mp->retval);
4522
4523   if (0 <= retval)
4524     {
4525       print (vam->ofp, "%-20s%-16s",
4526              mp->status ? "enabled" : "disabled",
4527              mp->status ? (char *) mp->locator_set_name : "");
4528     }
4529
4530   vam->retval = retval;
4531   vam->result_ready = 1;
4532 }
4533
4534 static void
4535 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4536 {
4537   vat_main_t *vam = &vat_main;
4538   vat_json_node_t node;
4539   u8 *status = 0;
4540
4541   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4542   vec_add1 (status, 0);
4543
4544   vat_json_init_object (&node);
4545   vat_json_object_add_string_copy (&node, "status", status);
4546   if (mp->status)
4547     {
4548       vat_json_object_add_string_copy (&node, "locator_set",
4549                                        mp->locator_set_name);
4550     }
4551
4552   vec_free (status);
4553
4554   vat_json_print (vam->ofp, &node);
4555   vat_json_free (&node);
4556
4557   vam->retval = ntohl (mp->retval);
4558   vam->result_ready = 1;
4559 }
4560
4561 static u8 *
4562 format_policer_type (u8 * s, va_list * va)
4563 {
4564   u32 i = va_arg (*va, u32);
4565
4566   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4567     s = format (s, "1r2c");
4568   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4569     s = format (s, "1r3c");
4570   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4571     s = format (s, "2r3c-2698");
4572   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4573     s = format (s, "2r3c-4115");
4574   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4575     s = format (s, "2r3c-mef5cf1");
4576   else
4577     s = format (s, "ILLEGAL");
4578   return s;
4579 }
4580
4581 static u8 *
4582 format_policer_rate_type (u8 * s, va_list * va)
4583 {
4584   u32 i = va_arg (*va, u32);
4585
4586   if (i == SSE2_QOS_RATE_KBPS)
4587     s = format (s, "kbps");
4588   else if (i == SSE2_QOS_RATE_PPS)
4589     s = format (s, "pps");
4590   else
4591     s = format (s, "ILLEGAL");
4592   return s;
4593 }
4594
4595 static u8 *
4596 format_policer_round_type (u8 * s, va_list * va)
4597 {
4598   u32 i = va_arg (*va, u32);
4599
4600   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4601     s = format (s, "closest");
4602   else if (i == SSE2_QOS_ROUND_TO_UP)
4603     s = format (s, "up");
4604   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4605     s = format (s, "down");
4606   else
4607     s = format (s, "ILLEGAL");
4608   return s;
4609 }
4610
4611 static u8 *
4612 format_policer_action_type (u8 * s, va_list * va)
4613 {
4614   u32 i = va_arg (*va, u32);
4615
4616   if (i == SSE2_QOS_ACTION_DROP)
4617     s = format (s, "drop");
4618   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4619     s = format (s, "transmit");
4620   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4621     s = format (s, "mark-and-transmit");
4622   else
4623     s = format (s, "ILLEGAL");
4624   return s;
4625 }
4626
4627 static u8 *
4628 format_dscp (u8 * s, va_list * va)
4629 {
4630   u32 i = va_arg (*va, u32);
4631   char *t = 0;
4632
4633   switch (i)
4634     {
4635 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4636       foreach_vnet_dscp
4637 #undef _
4638     default:
4639       return format (s, "ILLEGAL");
4640     }
4641   s = format (s, "%s", t);
4642   return s;
4643 }
4644
4645 static void
4646 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4647 {
4648   vat_main_t *vam = &vat_main;
4649   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4650
4651   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4652     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4653   else
4654     conform_dscp_str = format (0, "");
4655
4656   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4657     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4658   else
4659     exceed_dscp_str = format (0, "");
4660
4661   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4662     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4663   else
4664     violate_dscp_str = format (0, "");
4665
4666   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4667          "rate type %U, round type %U, %s rate, %s color-aware, "
4668          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4669          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4670          "conform action %U%s, exceed action %U%s, violate action %U%s",
4671          mp->name,
4672          format_policer_type, mp->type,
4673          ntohl (mp->cir),
4674          ntohl (mp->eir),
4675          clib_net_to_host_u64 (mp->cb),
4676          clib_net_to_host_u64 (mp->eb),
4677          format_policer_rate_type, mp->rate_type,
4678          format_policer_round_type, mp->round_type,
4679          mp->single_rate ? "single" : "dual",
4680          mp->color_aware ? "is" : "not",
4681          ntohl (mp->cir_tokens_per_period),
4682          ntohl (mp->pir_tokens_per_period),
4683          ntohl (mp->scale),
4684          ntohl (mp->current_limit),
4685          ntohl (mp->current_bucket),
4686          ntohl (mp->extended_limit),
4687          ntohl (mp->extended_bucket),
4688          clib_net_to_host_u64 (mp->last_update_time),
4689          format_policer_action_type, mp->conform_action_type,
4690          conform_dscp_str,
4691          format_policer_action_type, mp->exceed_action_type,
4692          exceed_dscp_str,
4693          format_policer_action_type, mp->violate_action_type,
4694          violate_dscp_str);
4695
4696   vec_free (conform_dscp_str);
4697   vec_free (exceed_dscp_str);
4698   vec_free (violate_dscp_str);
4699 }
4700
4701 static void vl_api_policer_details_t_handler_json
4702   (vl_api_policer_details_t * mp)
4703 {
4704   vat_main_t *vam = &vat_main;
4705   vat_json_node_t *node;
4706   u8 *rate_type_str, *round_type_str, *type_str;
4707   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4708
4709   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4710   round_type_str =
4711     format (0, "%U", format_policer_round_type, mp->round_type);
4712   type_str = format (0, "%U", format_policer_type, mp->type);
4713   conform_action_str = format (0, "%U", format_policer_action_type,
4714                                mp->conform_action_type);
4715   exceed_action_str = format (0, "%U", format_policer_action_type,
4716                               mp->exceed_action_type);
4717   violate_action_str = format (0, "%U", format_policer_action_type,
4718                                mp->violate_action_type);
4719
4720   if (VAT_JSON_ARRAY != vam->json_tree.type)
4721     {
4722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4723       vat_json_init_array (&vam->json_tree);
4724     }
4725   node = vat_json_array_add (&vam->json_tree);
4726
4727   vat_json_init_object (node);
4728   vat_json_object_add_string_copy (node, "name", mp->name);
4729   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4730   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4731   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4732   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4733   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4734   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4735   vat_json_object_add_string_copy (node, "type", type_str);
4736   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4737   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4738   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4739   vat_json_object_add_uint (node, "cir_tokens_per_period",
4740                             ntohl (mp->cir_tokens_per_period));
4741   vat_json_object_add_uint (node, "eir_tokens_per_period",
4742                             ntohl (mp->pir_tokens_per_period));
4743   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4744   vat_json_object_add_uint (node, "current_bucket",
4745                             ntohl (mp->current_bucket));
4746   vat_json_object_add_uint (node, "extended_limit",
4747                             ntohl (mp->extended_limit));
4748   vat_json_object_add_uint (node, "extended_bucket",
4749                             ntohl (mp->extended_bucket));
4750   vat_json_object_add_uint (node, "last_update_time",
4751                             ntohl (mp->last_update_time));
4752   vat_json_object_add_string_copy (node, "conform_action",
4753                                    conform_action_str);
4754   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4755     {
4756       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4757       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4758       vec_free (dscp_str);
4759     }
4760   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4761   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4762     {
4763       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4764       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4765       vec_free (dscp_str);
4766     }
4767   vat_json_object_add_string_copy (node, "violate_action",
4768                                    violate_action_str);
4769   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4770     {
4771       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4772       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4773       vec_free (dscp_str);
4774     }
4775
4776   vec_free (rate_type_str);
4777   vec_free (round_type_str);
4778   vec_free (type_str);
4779   vec_free (conform_action_str);
4780   vec_free (exceed_action_str);
4781   vec_free (violate_action_str);
4782 }
4783
4784 static void
4785 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4786                                            mp)
4787 {
4788   vat_main_t *vam = &vat_main;
4789   int i, count = ntohl (mp->count);
4790
4791   if (count > 0)
4792     print (vam->ofp, "classify table ids (%d) : ", count);
4793   for (i = 0; i < count; i++)
4794     {
4795       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4796       print (vam->ofp, (i < count - 1) ? "," : "");
4797     }
4798   vam->retval = ntohl (mp->retval);
4799   vam->result_ready = 1;
4800 }
4801
4802 static void
4803   vl_api_classify_table_ids_reply_t_handler_json
4804   (vl_api_classify_table_ids_reply_t * mp)
4805 {
4806   vat_main_t *vam = &vat_main;
4807   int i, count = ntohl (mp->count);
4808
4809   if (count > 0)
4810     {
4811       vat_json_node_t node;
4812
4813       vat_json_init_object (&node);
4814       for (i = 0; i < count; i++)
4815         {
4816           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4817         }
4818       vat_json_print (vam->ofp, &node);
4819       vat_json_free (&node);
4820     }
4821   vam->retval = ntohl (mp->retval);
4822   vam->result_ready = 1;
4823 }
4824
4825 static void
4826   vl_api_classify_table_by_interface_reply_t_handler
4827   (vl_api_classify_table_by_interface_reply_t * mp)
4828 {
4829   vat_main_t *vam = &vat_main;
4830   u32 table_id;
4831
4832   table_id = ntohl (mp->l2_table_id);
4833   if (table_id != ~0)
4834     print (vam->ofp, "l2 table id : %d", table_id);
4835   else
4836     print (vam->ofp, "l2 table id : No input ACL tables configured");
4837   table_id = ntohl (mp->ip4_table_id);
4838   if (table_id != ~0)
4839     print (vam->ofp, "ip4 table id : %d", table_id);
4840   else
4841     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4842   table_id = ntohl (mp->ip6_table_id);
4843   if (table_id != ~0)
4844     print (vam->ofp, "ip6 table id : %d", table_id);
4845   else
4846     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4847   vam->retval = ntohl (mp->retval);
4848   vam->result_ready = 1;
4849 }
4850
4851 static void
4852   vl_api_classify_table_by_interface_reply_t_handler_json
4853   (vl_api_classify_table_by_interface_reply_t * mp)
4854 {
4855   vat_main_t *vam = &vat_main;
4856   vat_json_node_t node;
4857
4858   vat_json_init_object (&node);
4859
4860   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4861   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4862   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4863
4864   vat_json_print (vam->ofp, &node);
4865   vat_json_free (&node);
4866
4867   vam->retval = ntohl (mp->retval);
4868   vam->result_ready = 1;
4869 }
4870
4871 static void vl_api_policer_add_del_reply_t_handler
4872   (vl_api_policer_add_del_reply_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   i32 retval = ntohl (mp->retval);
4876   if (vam->async_mode)
4877     {
4878       vam->async_errors += (retval < 0);
4879     }
4880   else
4881     {
4882       vam->retval = retval;
4883       vam->result_ready = 1;
4884       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4885         /*
4886          * Note: this is just barely thread-safe, depends on
4887          * the main thread spinning waiting for an answer...
4888          */
4889         errmsg ("policer index %d", ntohl (mp->policer_index));
4890     }
4891 }
4892
4893 static void vl_api_policer_add_del_reply_t_handler_json
4894   (vl_api_policer_add_del_reply_t * mp)
4895 {
4896   vat_main_t *vam = &vat_main;
4897   vat_json_node_t node;
4898
4899   vat_json_init_object (&node);
4900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4901   vat_json_object_add_uint (&node, "policer_index",
4902                             ntohl (mp->policer_index));
4903
4904   vat_json_print (vam->ofp, &node);
4905   vat_json_free (&node);
4906
4907   vam->retval = ntohl (mp->retval);
4908   vam->result_ready = 1;
4909 }
4910
4911 /* Format hex dump. */
4912 u8 *
4913 format_hex_bytes (u8 * s, va_list * va)
4914 {
4915   u8 *bytes = va_arg (*va, u8 *);
4916   int n_bytes = va_arg (*va, int);
4917   uword i;
4918
4919   /* Print short or long form depending on byte count. */
4920   uword short_form = n_bytes <= 32;
4921   u32 indent = format_get_indent (s);
4922
4923   if (n_bytes == 0)
4924     return s;
4925
4926   for (i = 0; i < n_bytes; i++)
4927     {
4928       if (!short_form && (i % 32) == 0)
4929         s = format (s, "%08x: ", i);
4930       s = format (s, "%02x", bytes[i]);
4931       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4932         s = format (s, "\n%U", format_white_space, indent);
4933     }
4934
4935   return s;
4936 }
4937
4938 static void
4939 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4940                                             * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   i32 retval = ntohl (mp->retval);
4944   if (retval == 0)
4945     {
4946       print (vam->ofp, "classify table info :");
4947       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4948              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4949              ntohl (mp->miss_next_index));
4950       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4951              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4952              ntohl (mp->match_n_vectors));
4953       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4954              ntohl (mp->mask_length));
4955     }
4956   vam->retval = retval;
4957   vam->result_ready = 1;
4958 }
4959
4960 static void
4961   vl_api_classify_table_info_reply_t_handler_json
4962   (vl_api_classify_table_info_reply_t * mp)
4963 {
4964   vat_main_t *vam = &vat_main;
4965   vat_json_node_t node;
4966
4967   i32 retval = ntohl (mp->retval);
4968   if (retval == 0)
4969     {
4970       vat_json_init_object (&node);
4971
4972       vat_json_object_add_int (&node, "sessions",
4973                                ntohl (mp->active_sessions));
4974       vat_json_object_add_int (&node, "nexttbl",
4975                                ntohl (mp->next_table_index));
4976       vat_json_object_add_int (&node, "nextnode",
4977                                ntohl (mp->miss_next_index));
4978       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4979       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4980       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4981       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4982                       ntohl (mp->mask_length), 0);
4983       vat_json_object_add_string_copy (&node, "mask", s);
4984
4985       vat_json_print (vam->ofp, &node);
4986       vat_json_free (&node);
4987     }
4988   vam->retval = ntohl (mp->retval);
4989   vam->result_ready = 1;
4990 }
4991
4992 static void
4993 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4994                                            mp)
4995 {
4996   vat_main_t *vam = &vat_main;
4997
4998   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4999          ntohl (mp->hit_next_index), ntohl (mp->advance),
5000          ntohl (mp->opaque_index));
5001   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5002          ntohl (mp->match_length));
5003 }
5004
5005 static void
5006   vl_api_classify_session_details_t_handler_json
5007   (vl_api_classify_session_details_t * mp)
5008 {
5009   vat_main_t *vam = &vat_main;
5010   vat_json_node_t *node = NULL;
5011
5012   if (VAT_JSON_ARRAY != vam->json_tree.type)
5013     {
5014       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5015       vat_json_init_array (&vam->json_tree);
5016     }
5017   node = vat_json_array_add (&vam->json_tree);
5018
5019   vat_json_init_object (node);
5020   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5021   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5022   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5023   u8 *s =
5024     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5025             0);
5026   vat_json_object_add_string_copy (node, "match", s);
5027 }
5028
5029 static void vl_api_pg_create_interface_reply_t_handler
5030   (vl_api_pg_create_interface_reply_t * mp)
5031 {
5032   vat_main_t *vam = &vat_main;
5033
5034   vam->retval = ntohl (mp->retval);
5035   vam->result_ready = 1;
5036 }
5037
5038 static void vl_api_pg_create_interface_reply_t_handler_json
5039   (vl_api_pg_create_interface_reply_t * mp)
5040 {
5041   vat_main_t *vam = &vat_main;
5042   vat_json_node_t node;
5043
5044   i32 retval = ntohl (mp->retval);
5045   if (retval == 0)
5046     {
5047       vat_json_init_object (&node);
5048
5049       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5050
5051       vat_json_print (vam->ofp, &node);
5052       vat_json_free (&node);
5053     }
5054   vam->retval = ntohl (mp->retval);
5055   vam->result_ready = 1;
5056 }
5057
5058 static void vl_api_policer_classify_details_t_handler
5059   (vl_api_policer_classify_details_t * mp)
5060 {
5061   vat_main_t *vam = &vat_main;
5062
5063   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5064          ntohl (mp->table_index));
5065 }
5066
5067 static void vl_api_policer_classify_details_t_handler_json
5068   (vl_api_policer_classify_details_t * mp)
5069 {
5070   vat_main_t *vam = &vat_main;
5071   vat_json_node_t *node;
5072
5073   if (VAT_JSON_ARRAY != vam->json_tree.type)
5074     {
5075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5076       vat_json_init_array (&vam->json_tree);
5077     }
5078   node = vat_json_array_add (&vam->json_tree);
5079
5080   vat_json_init_object (node);
5081   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5082   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5083 }
5084
5085 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5086   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5087 {
5088   vat_main_t *vam = &vat_main;
5089   i32 retval = ntohl (mp->retval);
5090   if (vam->async_mode)
5091     {
5092       vam->async_errors += (retval < 0);
5093     }
5094   else
5095     {
5096       vam->retval = retval;
5097       vam->sw_if_index = ntohl (mp->sw_if_index);
5098       vam->result_ready = 1;
5099     }
5100   vam->regenerate_interface_table = 1;
5101 }
5102
5103 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5104   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5105 {
5106   vat_main_t *vam = &vat_main;
5107   vat_json_node_t node;
5108
5109   vat_json_init_object (&node);
5110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5111   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5112
5113   vat_json_print (vam->ofp, &node);
5114   vat_json_free (&node);
5115
5116   vam->retval = ntohl (mp->retval);
5117   vam->result_ready = 1;
5118 }
5119
5120 static void vl_api_flow_classify_details_t_handler
5121   (vl_api_flow_classify_details_t * mp)
5122 {
5123   vat_main_t *vam = &vat_main;
5124
5125   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5126          ntohl (mp->table_index));
5127 }
5128
5129 static void vl_api_flow_classify_details_t_handler_json
5130   (vl_api_flow_classify_details_t * mp)
5131 {
5132   vat_main_t *vam = &vat_main;
5133   vat_json_node_t *node;
5134
5135   if (VAT_JSON_ARRAY != vam->json_tree.type)
5136     {
5137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5138       vat_json_init_array (&vam->json_tree);
5139     }
5140   node = vat_json_array_add (&vam->json_tree);
5141
5142   vat_json_init_object (node);
5143   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5144   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5145 }
5146
5147 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5148 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5149 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5150 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5151 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5152 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5153 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5154 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5155 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5156 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5157
5158 /*
5159  * Generate boilerplate reply handlers, which
5160  * dig the return value out of the xxx_reply_t API message,
5161  * stick it into vam->retval, and set vam->result_ready
5162  *
5163  * Could also do this by pointing N message decode slots at
5164  * a single function, but that could break in subtle ways.
5165  */
5166
5167 #define foreach_standard_reply_retval_handler           \
5168 _(sw_interface_set_flags_reply)                         \
5169 _(sw_interface_add_del_address_reply)                   \
5170 _(sw_interface_set_rx_mode_reply)                       \
5171 _(sw_interface_set_rx_placement_reply)                  \
5172 _(sw_interface_set_table_reply)                         \
5173 _(sw_interface_set_mpls_enable_reply)                   \
5174 _(sw_interface_set_vpath_reply)                         \
5175 _(sw_interface_set_vxlan_bypass_reply)                  \
5176 _(sw_interface_set_geneve_bypass_reply)                 \
5177 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5178 _(sw_interface_set_l2_bridge_reply)                     \
5179 _(bridge_domain_add_del_reply)                          \
5180 _(sw_interface_set_l2_xconnect_reply)                   \
5181 _(l2fib_add_del_reply)                                  \
5182 _(l2fib_flush_int_reply)                                \
5183 _(l2fib_flush_bd_reply)                                 \
5184 _(ip_add_del_route_reply)                               \
5185 _(ip_table_add_del_reply)                               \
5186 _(ip_mroute_add_del_reply)                              \
5187 _(mpls_route_add_del_reply)                             \
5188 _(mpls_table_add_del_reply)                             \
5189 _(mpls_ip_bind_unbind_reply)                            \
5190 _(bier_route_add_del_reply)                             \
5191 _(bier_table_add_del_reply)                             \
5192 _(proxy_arp_add_del_reply)                              \
5193 _(proxy_arp_intfc_enable_disable_reply)                 \
5194 _(sw_interface_set_unnumbered_reply)                    \
5195 _(ip_neighbor_add_del_reply)                            \
5196 _(oam_add_del_reply)                                    \
5197 _(reset_fib_reply)                                      \
5198 _(dhcp_proxy_config_reply)                              \
5199 _(dhcp_proxy_set_vss_reply)                             \
5200 _(dhcp_client_config_reply)                             \
5201 _(set_ip_flow_hash_reply)                               \
5202 _(sw_interface_ip6_enable_disable_reply)                \
5203 _(ip6nd_proxy_add_del_reply)                            \
5204 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5205 _(sw_interface_ip6nd_ra_config_reply)                   \
5206 _(set_arp_neighbor_limit_reply)                         \
5207 _(l2_patch_add_del_reply)                               \
5208 _(sr_mpls_policy_add_reply)                             \
5209 _(sr_mpls_policy_mod_reply)                             \
5210 _(sr_mpls_policy_del_reply)                             \
5211 _(sr_policy_add_reply)                                  \
5212 _(sr_policy_mod_reply)                                  \
5213 _(sr_policy_del_reply)                                  \
5214 _(sr_localsid_add_del_reply)                            \
5215 _(sr_steering_add_del_reply)                            \
5216 _(classify_add_del_session_reply)                       \
5217 _(classify_set_interface_ip_table_reply)                \
5218 _(classify_set_interface_l2_tables_reply)               \
5219 _(l2tpv3_set_tunnel_cookies_reply)                      \
5220 _(l2tpv3_interface_enable_disable_reply)                \
5221 _(l2tpv3_set_lookup_key_reply)                          \
5222 _(l2_fib_clear_table_reply)                             \
5223 _(l2_interface_efp_filter_reply)                        \
5224 _(l2_interface_vlan_tag_rewrite_reply)                  \
5225 _(modify_vhost_user_if_reply)                           \
5226 _(delete_vhost_user_if_reply)                           \
5227 _(ip_probe_neighbor_reply)                              \
5228 _(ip_scan_neighbor_enable_disable_reply)                \
5229 _(want_ip4_arp_events_reply)                            \
5230 _(want_ip6_nd_events_reply)                             \
5231 _(want_l2_macs_events_reply)                            \
5232 _(input_acl_set_interface_reply)                        \
5233 _(ipsec_spd_add_del_reply)                              \
5234 _(ipsec_interface_add_del_spd_reply)                    \
5235 _(ipsec_spd_add_del_entry_reply)                        \
5236 _(ipsec_sad_add_del_entry_reply)                        \
5237 _(ipsec_sa_set_key_reply)                               \
5238 _(ipsec_tunnel_if_add_del_reply)                        \
5239 _(ipsec_tunnel_if_set_key_reply)                        \
5240 _(ipsec_tunnel_if_set_sa_reply)                         \
5241 _(ikev2_profile_add_del_reply)                          \
5242 _(ikev2_profile_set_auth_reply)                         \
5243 _(ikev2_profile_set_id_reply)                           \
5244 _(ikev2_profile_set_ts_reply)                           \
5245 _(ikev2_set_local_key_reply)                            \
5246 _(ikev2_set_responder_reply)                            \
5247 _(ikev2_set_ike_transforms_reply)                       \
5248 _(ikev2_set_esp_transforms_reply)                       \
5249 _(ikev2_set_sa_lifetime_reply)                          \
5250 _(ikev2_initiate_sa_init_reply)                         \
5251 _(ikev2_initiate_del_ike_sa_reply)                      \
5252 _(ikev2_initiate_del_child_sa_reply)                    \
5253 _(ikev2_initiate_rekey_child_sa_reply)                  \
5254 _(delete_loopback_reply)                                \
5255 _(bd_ip_mac_add_del_reply)                              \
5256 _(want_interface_events_reply)                          \
5257 _(cop_interface_enable_disable_reply)                   \
5258 _(cop_whitelist_enable_disable_reply)                   \
5259 _(sw_interface_clear_stats_reply)                       \
5260 _(ioam_enable_reply)                                    \
5261 _(ioam_disable_reply)                                   \
5262 _(one_add_del_locator_reply)                            \
5263 _(one_add_del_local_eid_reply)                          \
5264 _(one_add_del_remote_mapping_reply)                     \
5265 _(one_add_del_adjacency_reply)                          \
5266 _(one_add_del_map_resolver_reply)                       \
5267 _(one_add_del_map_server_reply)                         \
5268 _(one_enable_disable_reply)                             \
5269 _(one_rloc_probe_enable_disable_reply)                  \
5270 _(one_map_register_enable_disable_reply)                \
5271 _(one_map_register_set_ttl_reply)                       \
5272 _(one_set_transport_protocol_reply)                     \
5273 _(one_map_register_fallback_threshold_reply)            \
5274 _(one_pitr_set_locator_set_reply)                       \
5275 _(one_map_request_mode_reply)                           \
5276 _(one_add_del_map_request_itr_rlocs_reply)              \
5277 _(one_eid_table_add_del_map_reply)                      \
5278 _(one_use_petr_reply)                                   \
5279 _(one_stats_enable_disable_reply)                       \
5280 _(one_add_del_l2_arp_entry_reply)                       \
5281 _(one_add_del_ndp_entry_reply)                          \
5282 _(one_stats_flush_reply)                                \
5283 _(one_enable_disable_xtr_mode_reply)                    \
5284 _(one_enable_disable_pitr_mode_reply)                   \
5285 _(one_enable_disable_petr_mode_reply)                   \
5286 _(gpe_enable_disable_reply)                             \
5287 _(gpe_set_encap_mode_reply)                             \
5288 _(gpe_add_del_iface_reply)                              \
5289 _(gpe_add_del_native_fwd_rpath_reply)                   \
5290 _(af_packet_delete_reply)                               \
5291 _(policer_classify_set_interface_reply)                 \
5292 _(netmap_create_reply)                                  \
5293 _(netmap_delete_reply)                                  \
5294 _(set_ipfix_exporter_reply)                             \
5295 _(set_ipfix_classify_stream_reply)                      \
5296 _(ipfix_classify_table_add_del_reply)                   \
5297 _(flow_classify_set_interface_reply)                    \
5298 _(sw_interface_span_enable_disable_reply)               \
5299 _(pg_capture_reply)                                     \
5300 _(pg_enable_disable_reply)                              \
5301 _(ip_source_and_port_range_check_add_del_reply)         \
5302 _(ip_source_and_port_range_check_interface_add_del_reply)\
5303 _(delete_subif_reply)                                   \
5304 _(l2_interface_pbb_tag_rewrite_reply)                   \
5305 _(set_punt_reply)                                       \
5306 _(feature_enable_disable_reply)                         \
5307 _(sw_interface_tag_add_del_reply)                       \
5308 _(hw_interface_set_mtu_reply)                           \
5309 _(p2p_ethernet_add_reply)                               \
5310 _(p2p_ethernet_del_reply)                               \
5311 _(lldp_config_reply)                                    \
5312 _(sw_interface_set_lldp_reply)                          \
5313 _(tcp_configure_src_addresses_reply)                    \
5314 _(dns_enable_disable_reply)                             \
5315 _(dns_name_server_add_del_reply)                        \
5316 _(session_rule_add_del_reply)                           \
5317 _(ip_container_proxy_add_del_reply)                     \
5318 _(output_acl_set_interface_reply)                       \
5319 _(qos_record_enable_disable_reply)
5320
5321 #define _(n)                                    \
5322     static void vl_api_##n##_t_handler          \
5323     (vl_api_##n##_t * mp)                       \
5324     {                                           \
5325         vat_main_t * vam = &vat_main;           \
5326         i32 retval = ntohl(mp->retval);         \
5327         if (vam->async_mode) {                  \
5328             vam->async_errors += (retval < 0);  \
5329         } else {                                \
5330             vam->retval = retval;               \
5331             vam->result_ready = 1;              \
5332         }                                       \
5333     }
5334 foreach_standard_reply_retval_handler;
5335 #undef _
5336
5337 #define _(n)                                    \
5338     static void vl_api_##n##_t_handler_json     \
5339     (vl_api_##n##_t * mp)                       \
5340     {                                           \
5341         vat_main_t * vam = &vat_main;           \
5342         vat_json_node_t node;                   \
5343         vat_json_init_object(&node);            \
5344         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5345         vat_json_print(vam->ofp, &node);        \
5346         vam->retval = ntohl(mp->retval);        \
5347         vam->result_ready = 1;                  \
5348     }
5349 foreach_standard_reply_retval_handler;
5350 #undef _
5351
5352 /*
5353  * Table of message reply handlers, must include boilerplate handlers
5354  * we just generated
5355  */
5356
5357 #define foreach_vpe_api_reply_msg                                       \
5358 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5359 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5360 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5361 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5362 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5363 _(CLI_REPLY, cli_reply)                                                 \
5364 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5365 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5366   sw_interface_add_del_address_reply)                                   \
5367 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5368 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5369 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5370 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5371 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5372 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5373 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5374 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5375 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5376 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5377   sw_interface_set_l2_xconnect_reply)                                   \
5378 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5379   sw_interface_set_l2_bridge_reply)                                     \
5380 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5381 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5382 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5383 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5384 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5385 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5386 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5387 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5388 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5389 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5390 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5391 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5392 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5393 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5394 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5395 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5396 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5397 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5398 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5399 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5400 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5401 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5402 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5403 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5404 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5405 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5406 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5407 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5408 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5409 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5410 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5411   proxy_arp_intfc_enable_disable_reply)                                 \
5412 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5413 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5414   sw_interface_set_unnumbered_reply)                                    \
5415 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5416 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5417 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5418 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5419 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5420 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5421 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5422 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5423 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5424 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5425 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5426   sw_interface_ip6_enable_disable_reply)                                \
5427 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5428 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5429 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5430   sw_interface_ip6nd_ra_prefix_reply)                                   \
5431 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5432   sw_interface_ip6nd_ra_config_reply)                                   \
5433 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5434 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5435 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5436 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5437 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5438 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5439 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5440 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5441 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5442 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5443 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5444 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5445 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5446 classify_set_interface_ip_table_reply)                                  \
5447 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5448   classify_set_interface_l2_tables_reply)                               \
5449 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5450 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5451 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5452 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5453 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5454   l2tpv3_interface_enable_disable_reply)                                \
5455 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5456 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5457 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5458 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5459 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5460 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5461 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5462 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5463 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5464 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5465 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5466 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5467 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5468 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5469 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5470 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5471 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5472 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5473 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5474 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5475 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5476 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5477 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5478 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5479 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5480 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5481 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5482 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5483 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5484 _(L2_MACS_EVENT, l2_macs_event)                                         \
5485 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5486 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5487 _(IP_DETAILS, ip_details)                                               \
5488 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5489 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5490 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5491 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5492 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5493 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5494 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5495 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5496 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5497 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5498 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5499 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5500 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5501 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5502 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5503 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5504 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5505 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5506 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5507 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5508 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5509 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5510 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5511 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5512 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5513 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5514 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5515 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5516 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5517 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5518 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5519 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5520 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5521 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5522 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5523 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5524 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5525 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5526 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5527 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5528 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5529 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5530 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5531   one_map_register_enable_disable_reply)                                \
5532 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5533 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5534 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5535 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5536   one_map_register_fallback_threshold_reply)                            \
5537 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5538   one_rloc_probe_enable_disable_reply)                                  \
5539 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5540 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5541 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5542 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5543 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5544 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5545 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5546 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5547 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5548 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5549 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5550 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5551 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5552 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5553 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5554 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5555   show_one_stats_enable_disable_reply)                                  \
5556 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5557 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5558 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5559 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5560 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5561 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5562 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5563 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5564   one_enable_disable_pitr_mode_reply)                                   \
5565 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5566   one_enable_disable_petr_mode_reply)                                   \
5567 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5568 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5569 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5570 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5571 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5572 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5573 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5574 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5575 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5576 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5577 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5578 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5579   gpe_add_del_native_fwd_rpath_reply)                                   \
5580 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5581   gpe_fwd_entry_path_details)                                           \
5582 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5583 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5584   one_add_del_map_request_itr_rlocs_reply)                              \
5585 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5586   one_get_map_request_itr_rlocs_reply)                                  \
5587 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5588 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5589 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5590 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5591 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5592 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5593   show_one_map_register_state_reply)                                    \
5594 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5595 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5596   show_one_map_register_fallback_threshold_reply)                       \
5597 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5598 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5599 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5600 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5601 _(POLICER_DETAILS, policer_details)                                     \
5602 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5603 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5604 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5605 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5606 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5607 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5608 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5609 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5610 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5611 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5612 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5613 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5614 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5615 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5616 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5617 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5618 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5619 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5620 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5621 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5622 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5623 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5624 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5625 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5626 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5627  ip_source_and_port_range_check_add_del_reply)                          \
5628 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5629  ip_source_and_port_range_check_interface_add_del_reply)                \
5630 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5631 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5632 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5633 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5634 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5635 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5636 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5637 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5638 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5639 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5640 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5641 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5642 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5643 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5644 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5645 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5646 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5647 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5648 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5649 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5650 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5651 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5652 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5653 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5654 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5655 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5656 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5657 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5658
5659 #define foreach_standalone_reply_msg                                    \
5660 _(SW_INTERFACE_EVENT, sw_interface_event)
5661
5662 typedef struct
5663 {
5664   u8 *name;
5665   u32 value;
5666 } name_sort_t;
5667
5668 #define STR_VTR_OP_CASE(op)     \
5669     case L2_VTR_ ## op:         \
5670         return "" # op;
5671
5672 static const char *
5673 str_vtr_op (u32 vtr_op)
5674 {
5675   switch (vtr_op)
5676     {
5677       STR_VTR_OP_CASE (DISABLED);
5678       STR_VTR_OP_CASE (PUSH_1);
5679       STR_VTR_OP_CASE (PUSH_2);
5680       STR_VTR_OP_CASE (POP_1);
5681       STR_VTR_OP_CASE (POP_2);
5682       STR_VTR_OP_CASE (TRANSLATE_1_1);
5683       STR_VTR_OP_CASE (TRANSLATE_1_2);
5684       STR_VTR_OP_CASE (TRANSLATE_2_1);
5685       STR_VTR_OP_CASE (TRANSLATE_2_2);
5686     }
5687
5688   return "UNKNOWN";
5689 }
5690
5691 static int
5692 dump_sub_interface_table (vat_main_t * vam)
5693 {
5694   const sw_interface_subif_t *sub = NULL;
5695
5696   if (vam->json_output)
5697     {
5698       clib_warning
5699         ("JSON output supported only for VPE API calls and dump_stats_table");
5700       return -99;
5701     }
5702
5703   print (vam->ofp,
5704          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5705          "Interface", "sw_if_index",
5706          "sub id", "dot1ad", "tags", "outer id",
5707          "inner id", "exact", "default", "outer any", "inner any");
5708
5709   vec_foreach (sub, vam->sw_if_subif_table)
5710   {
5711     print (vam->ofp,
5712            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5713            sub->interface_name,
5714            sub->sw_if_index,
5715            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5716            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5717            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5718            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5719     if (sub->vtr_op != L2_VTR_DISABLED)
5720       {
5721         print (vam->ofp,
5722                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5723                "tag1: %d tag2: %d ]",
5724                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5725                sub->vtr_tag1, sub->vtr_tag2);
5726       }
5727   }
5728
5729   return 0;
5730 }
5731
5732 static int
5733 name_sort_cmp (void *a1, void *a2)
5734 {
5735   name_sort_t *n1 = a1;
5736   name_sort_t *n2 = a2;
5737
5738   return strcmp ((char *) n1->name, (char *) n2->name);
5739 }
5740
5741 static int
5742 dump_interface_table (vat_main_t * vam)
5743 {
5744   hash_pair_t *p;
5745   name_sort_t *nses = 0, *ns;
5746
5747   if (vam->json_output)
5748     {
5749       clib_warning
5750         ("JSON output supported only for VPE API calls and dump_stats_table");
5751       return -99;
5752     }
5753
5754   /* *INDENT-OFF* */
5755   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5756   ({
5757     vec_add2 (nses, ns, 1);
5758     ns->name = (u8 *)(p->key);
5759     ns->value = (u32) p->value[0];
5760   }));
5761   /* *INDENT-ON* */
5762
5763   vec_sort_with_function (nses, name_sort_cmp);
5764
5765   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5766   vec_foreach (ns, nses)
5767   {
5768     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5769   }
5770   vec_free (nses);
5771   return 0;
5772 }
5773
5774 static int
5775 dump_ip_table (vat_main_t * vam, int is_ipv6)
5776 {
5777   const ip_details_t *det = NULL;
5778   const ip_address_details_t *address = NULL;
5779   u32 i = ~0;
5780
5781   print (vam->ofp, "%-12s", "sw_if_index");
5782
5783   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5784   {
5785     i++;
5786     if (!det->present)
5787       {
5788         continue;
5789       }
5790     print (vam->ofp, "%-12d", i);
5791     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5792     if (!det->addr)
5793       {
5794         continue;
5795       }
5796     vec_foreach (address, det->addr)
5797     {
5798       print (vam->ofp,
5799              "            %-30U%-13d",
5800              is_ipv6 ? format_ip6_address : format_ip4_address,
5801              address->ip, address->prefix_length);
5802     }
5803   }
5804
5805   return 0;
5806 }
5807
5808 static int
5809 dump_ipv4_table (vat_main_t * vam)
5810 {
5811   if (vam->json_output)
5812     {
5813       clib_warning
5814         ("JSON output supported only for VPE API calls and dump_stats_table");
5815       return -99;
5816     }
5817
5818   return dump_ip_table (vam, 0);
5819 }
5820
5821 static int
5822 dump_ipv6_table (vat_main_t * vam)
5823 {
5824   if (vam->json_output)
5825     {
5826       clib_warning
5827         ("JSON output supported only for VPE API calls and dump_stats_table");
5828       return -99;
5829     }
5830
5831   return dump_ip_table (vam, 1);
5832 }
5833
5834 /*
5835  * Pass CLI buffers directly in the CLI_INBAND API message,
5836  * instead of an additional shared memory area.
5837  */
5838 static int
5839 exec_inband (vat_main_t * vam)
5840 {
5841   vl_api_cli_inband_t *mp;
5842   unformat_input_t *i = vam->input;
5843   int ret;
5844
5845   if (vec_len (i->buffer) == 0)
5846     return -1;
5847
5848   if (vam->exec_mode == 0 && unformat (i, "mode"))
5849     {
5850       vam->exec_mode = 1;
5851       return 0;
5852     }
5853   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5854     {
5855       vam->exec_mode = 0;
5856       return 0;
5857     }
5858
5859   /*
5860    * In order for the CLI command to work, it
5861    * must be a vector ending in \n, not a C-string ending
5862    * in \n\0.
5863    */
5864   u32 len = vec_len (vam->input->buffer);
5865   M2 (CLI_INBAND, mp, len);
5866   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5867
5868   S (mp);
5869   W (ret);
5870   /* json responses may or may not include a useful reply... */
5871   if (vec_len (vam->cmd_reply))
5872     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5873   return ret;
5874 }
5875
5876 int
5877 exec (vat_main_t * vam)
5878 {
5879   return exec_inband (vam);
5880 }
5881
5882 static int
5883 api_create_loopback (vat_main_t * vam)
5884 {
5885   unformat_input_t *i = vam->input;
5886   vl_api_create_loopback_t *mp;
5887   vl_api_create_loopback_instance_t *mp_lbi;
5888   u8 mac_address[6];
5889   u8 mac_set = 0;
5890   u8 is_specified = 0;
5891   u32 user_instance = 0;
5892   int ret;
5893
5894   clib_memset (mac_address, 0, sizeof (mac_address));
5895
5896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5897     {
5898       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5899         mac_set = 1;
5900       if (unformat (i, "instance %d", &user_instance))
5901         is_specified = 1;
5902       else
5903         break;
5904     }
5905
5906   if (is_specified)
5907     {
5908       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5909       mp_lbi->is_specified = is_specified;
5910       if (is_specified)
5911         mp_lbi->user_instance = htonl (user_instance);
5912       if (mac_set)
5913         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5914       S (mp_lbi);
5915     }
5916   else
5917     {
5918       /* Construct the API message */
5919       M (CREATE_LOOPBACK, mp);
5920       if (mac_set)
5921         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5922       S (mp);
5923     }
5924
5925   W (ret);
5926   return ret;
5927 }
5928
5929 static int
5930 api_delete_loopback (vat_main_t * vam)
5931 {
5932   unformat_input_t *i = vam->input;
5933   vl_api_delete_loopback_t *mp;
5934   u32 sw_if_index = ~0;
5935   int ret;
5936
5937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5938     {
5939       if (unformat (i, "sw_if_index %d", &sw_if_index))
5940         ;
5941       else
5942         break;
5943     }
5944
5945   if (sw_if_index == ~0)
5946     {
5947       errmsg ("missing sw_if_index");
5948       return -99;
5949     }
5950
5951   /* Construct the API message */
5952   M (DELETE_LOOPBACK, mp);
5953   mp->sw_if_index = ntohl (sw_if_index);
5954
5955   S (mp);
5956   W (ret);
5957   return ret;
5958 }
5959
5960 static int
5961 api_want_interface_events (vat_main_t * vam)
5962 {
5963   unformat_input_t *i = vam->input;
5964   vl_api_want_interface_events_t *mp;
5965   int enable = -1;
5966   int ret;
5967
5968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5969     {
5970       if (unformat (i, "enable"))
5971         enable = 1;
5972       else if (unformat (i, "disable"))
5973         enable = 0;
5974       else
5975         break;
5976     }
5977
5978   if (enable == -1)
5979     {
5980       errmsg ("missing enable|disable");
5981       return -99;
5982     }
5983
5984   M (WANT_INTERFACE_EVENTS, mp);
5985   mp->enable_disable = enable;
5986
5987   vam->interface_event_display = enable;
5988
5989   S (mp);
5990   W (ret);
5991   return ret;
5992 }
5993
5994
5995 /* Note: non-static, called once to set up the initial intfc table */
5996 int
5997 api_sw_interface_dump (vat_main_t * vam)
5998 {
5999   vl_api_sw_interface_dump_t *mp;
6000   vl_api_control_ping_t *mp_ping;
6001   hash_pair_t *p;
6002   name_sort_t *nses = 0, *ns;
6003   sw_interface_subif_t *sub = NULL;
6004   int ret;
6005
6006   /* Toss the old name table */
6007   /* *INDENT-OFF* */
6008   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6009   ({
6010     vec_add2 (nses, ns, 1);
6011     ns->name = (u8 *)(p->key);
6012     ns->value = (u32) p->value[0];
6013   }));
6014   /* *INDENT-ON* */
6015
6016   hash_free (vam->sw_if_index_by_interface_name);
6017
6018   vec_foreach (ns, nses) vec_free (ns->name);
6019
6020   vec_free (nses);
6021
6022   vec_foreach (sub, vam->sw_if_subif_table)
6023   {
6024     vec_free (sub->interface_name);
6025   }
6026   vec_free (vam->sw_if_subif_table);
6027
6028   /* recreate the interface name hash table */
6029   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6030
6031   /*
6032    * Ask for all interface names. Otherwise, the epic catalog of
6033    * name filters becomes ridiculously long, and vat ends up needing
6034    * to be taught about new interface types.
6035    */
6036   M (SW_INTERFACE_DUMP, mp);
6037   S (mp);
6038
6039   /* Use a control ping for synchronization */
6040   MPING (CONTROL_PING, mp_ping);
6041   S (mp_ping);
6042
6043   W (ret);
6044   return ret;
6045 }
6046
6047 static int
6048 api_sw_interface_set_flags (vat_main_t * vam)
6049 {
6050   unformat_input_t *i = vam->input;
6051   vl_api_sw_interface_set_flags_t *mp;
6052   u32 sw_if_index;
6053   u8 sw_if_index_set = 0;
6054   u8 admin_up = 0;
6055   int ret;
6056
6057   /* Parse args required to build the message */
6058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6059     {
6060       if (unformat (i, "admin-up"))
6061         admin_up = 1;
6062       else if (unformat (i, "admin-down"))
6063         admin_up = 0;
6064       else
6065         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6066         sw_if_index_set = 1;
6067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6068         sw_if_index_set = 1;
6069       else
6070         break;
6071     }
6072
6073   if (sw_if_index_set == 0)
6074     {
6075       errmsg ("missing interface name or sw_if_index");
6076       return -99;
6077     }
6078
6079   /* Construct the API message */
6080   M (SW_INTERFACE_SET_FLAGS, mp);
6081   mp->sw_if_index = ntohl (sw_if_index);
6082   mp->admin_up_down = admin_up;
6083
6084   /* send it... */
6085   S (mp);
6086
6087   /* Wait for a reply, return the good/bad news... */
6088   W (ret);
6089   return ret;
6090 }
6091
6092 static int
6093 api_sw_interface_set_rx_mode (vat_main_t * vam)
6094 {
6095   unformat_input_t *i = vam->input;
6096   vl_api_sw_interface_set_rx_mode_t *mp;
6097   u32 sw_if_index;
6098   u8 sw_if_index_set = 0;
6099   int ret;
6100   u8 queue_id_valid = 0;
6101   u32 queue_id;
6102   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6103
6104   /* Parse args required to build the message */
6105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6106     {
6107       if (unformat (i, "queue %d", &queue_id))
6108         queue_id_valid = 1;
6109       else if (unformat (i, "polling"))
6110         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6111       else if (unformat (i, "interrupt"))
6112         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6113       else if (unformat (i, "adaptive"))
6114         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6115       else
6116         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6117         sw_if_index_set = 1;
6118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6119         sw_if_index_set = 1;
6120       else
6121         break;
6122     }
6123
6124   if (sw_if_index_set == 0)
6125     {
6126       errmsg ("missing interface name or sw_if_index");
6127       return -99;
6128     }
6129   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6130     {
6131       errmsg ("missing rx-mode");
6132       return -99;
6133     }
6134
6135   /* Construct the API message */
6136   M (SW_INTERFACE_SET_RX_MODE, mp);
6137   mp->sw_if_index = ntohl (sw_if_index);
6138   mp->mode = mode;
6139   mp->queue_id_valid = queue_id_valid;
6140   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6141
6142   /* send it... */
6143   S (mp);
6144
6145   /* Wait for a reply, return the good/bad news... */
6146   W (ret);
6147   return ret;
6148 }
6149
6150 static int
6151 api_sw_interface_set_rx_placement (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_sw_interface_set_rx_placement_t *mp;
6155   u32 sw_if_index;
6156   u8 sw_if_index_set = 0;
6157   int ret;
6158   u8 is_main = 0;
6159   u32 queue_id, thread_index;
6160
6161   /* Parse args required to build the message */
6162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6163     {
6164       if (unformat (i, "queue %d", &queue_id))
6165         ;
6166       else if (unformat (i, "main"))
6167         is_main = 1;
6168       else if (unformat (i, "worker %d", &thread_index))
6169         ;
6170       else
6171         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6172         sw_if_index_set = 1;
6173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6174         sw_if_index_set = 1;
6175       else
6176         break;
6177     }
6178
6179   if (sw_if_index_set == 0)
6180     {
6181       errmsg ("missing interface name or sw_if_index");
6182       return -99;
6183     }
6184
6185   if (is_main)
6186     thread_index = 0;
6187   /* Construct the API message */
6188   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6189   mp->sw_if_index = ntohl (sw_if_index);
6190   mp->worker_id = ntohl (thread_index);
6191   mp->queue_id = ntohl (queue_id);
6192   mp->is_main = is_main;
6193
6194   /* send it... */
6195   S (mp);
6196   /* Wait for a reply, return the good/bad news... */
6197   W (ret);
6198   return ret;
6199 }
6200
6201 static void vl_api_sw_interface_rx_placement_details_t_handler
6202   (vl_api_sw_interface_rx_placement_details_t * mp)
6203 {
6204   vat_main_t *vam = &vat_main;
6205   u32 worker_id = ntohl (mp->worker_id);
6206
6207   print (vam->ofp,
6208          "\n%-11d %-11s %-6d %-5d %-9s",
6209          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6210          worker_id, ntohl (mp->queue_id),
6211          (mp->mode ==
6212           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6213 }
6214
6215 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6216   (vl_api_sw_interface_rx_placement_details_t * mp)
6217 {
6218   vat_main_t *vam = &vat_main;
6219   vat_json_node_t *node = NULL;
6220
6221   if (VAT_JSON_ARRAY != vam->json_tree.type)
6222     {
6223       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6224       vat_json_init_array (&vam->json_tree);
6225     }
6226   node = vat_json_array_add (&vam->json_tree);
6227
6228   vat_json_init_object (node);
6229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6230   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6231   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6232   vat_json_object_add_uint (node, "mode", mp->mode);
6233 }
6234
6235 static int
6236 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6237 {
6238   unformat_input_t *i = vam->input;
6239   vl_api_sw_interface_rx_placement_dump_t *mp;
6240   vl_api_control_ping_t *mp_ping;
6241   int ret;
6242   u32 sw_if_index;
6243   u8 sw_if_index_set = 0;
6244
6245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6246     {
6247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6248         sw_if_index_set++;
6249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6250         sw_if_index_set++;
6251       else
6252         break;
6253     }
6254
6255   print (vam->ofp,
6256          "\n%-11s %-11s %-6s %-5s %-4s",
6257          "sw_if_index", "main/worker", "thread", "queue", "mode");
6258
6259   /* Dump Interface rx placement */
6260   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6261
6262   if (sw_if_index_set)
6263     mp->sw_if_index = htonl (sw_if_index);
6264   else
6265     mp->sw_if_index = ~0;
6266
6267   S (mp);
6268
6269   /* Use a control ping for synchronization */
6270   MPING (CONTROL_PING, mp_ping);
6271   S (mp_ping);
6272
6273   W (ret);
6274   return ret;
6275 }
6276
6277 static int
6278 api_sw_interface_clear_stats (vat_main_t * vam)
6279 {
6280   unformat_input_t *i = vam->input;
6281   vl_api_sw_interface_clear_stats_t *mp;
6282   u32 sw_if_index;
6283   u8 sw_if_index_set = 0;
6284   int ret;
6285
6286   /* Parse args required to build the message */
6287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6288     {
6289       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6290         sw_if_index_set = 1;
6291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6292         sw_if_index_set = 1;
6293       else
6294         break;
6295     }
6296
6297   /* Construct the API message */
6298   M (SW_INTERFACE_CLEAR_STATS, mp);
6299
6300   if (sw_if_index_set == 1)
6301     mp->sw_if_index = ntohl (sw_if_index);
6302   else
6303     mp->sw_if_index = ~0;
6304
6305   /* send it... */
6306   S (mp);
6307
6308   /* Wait for a reply, return the good/bad news... */
6309   W (ret);
6310   return ret;
6311 }
6312
6313 static int
6314 api_sw_interface_add_del_address (vat_main_t * vam)
6315 {
6316   unformat_input_t *i = vam->input;
6317   vl_api_sw_interface_add_del_address_t *mp;
6318   u32 sw_if_index;
6319   u8 sw_if_index_set = 0;
6320   u8 is_add = 1, del_all = 0;
6321   u32 address_length = 0;
6322   u8 v4_address_set = 0;
6323   u8 v6_address_set = 0;
6324   ip4_address_t v4address;
6325   ip6_address_t v6address;
6326   int ret;
6327
6328   /* Parse args required to build the message */
6329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6330     {
6331       if (unformat (i, "del-all"))
6332         del_all = 1;
6333       else if (unformat (i, "del"))
6334         is_add = 0;
6335       else
6336         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6337         sw_if_index_set = 1;
6338       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6339         sw_if_index_set = 1;
6340       else if (unformat (i, "%U/%d",
6341                          unformat_ip4_address, &v4address, &address_length))
6342         v4_address_set = 1;
6343       else if (unformat (i, "%U/%d",
6344                          unformat_ip6_address, &v6address, &address_length))
6345         v6_address_set = 1;
6346       else
6347         break;
6348     }
6349
6350   if (sw_if_index_set == 0)
6351     {
6352       errmsg ("missing interface name or sw_if_index");
6353       return -99;
6354     }
6355   if (v4_address_set && v6_address_set)
6356     {
6357       errmsg ("both v4 and v6 addresses set");
6358       return -99;
6359     }
6360   if (!v4_address_set && !v6_address_set && !del_all)
6361     {
6362       errmsg ("no addresses set");
6363       return -99;
6364     }
6365
6366   /* Construct the API message */
6367   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6368
6369   mp->sw_if_index = ntohl (sw_if_index);
6370   mp->is_add = is_add;
6371   mp->del_all = del_all;
6372   if (v6_address_set)
6373     {
6374       mp->is_ipv6 = 1;
6375       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6376     }
6377   else
6378     {
6379       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6380     }
6381   mp->address_length = address_length;
6382
6383   /* send it... */
6384   S (mp);
6385
6386   /* Wait for a reply, return good/bad news  */
6387   W (ret);
6388   return ret;
6389 }
6390
6391 static int
6392 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6393 {
6394   unformat_input_t *i = vam->input;
6395   vl_api_sw_interface_set_mpls_enable_t *mp;
6396   u32 sw_if_index;
6397   u8 sw_if_index_set = 0;
6398   u8 enable = 1;
6399   int ret;
6400
6401   /* Parse args required to build the message */
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "disable"))
6409         enable = 0;
6410       else if (unformat (i, "dis"))
6411         enable = 0;
6412       else
6413         break;
6414     }
6415
6416   if (sw_if_index_set == 0)
6417     {
6418       errmsg ("missing interface name or sw_if_index");
6419       return -99;
6420     }
6421
6422   /* Construct the API message */
6423   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6424
6425   mp->sw_if_index = ntohl (sw_if_index);
6426   mp->enable = enable;
6427
6428   /* send it... */
6429   S (mp);
6430
6431   /* Wait for a reply... */
6432   W (ret);
6433   return ret;
6434 }
6435
6436 static int
6437 api_sw_interface_set_table (vat_main_t * vam)
6438 {
6439   unformat_input_t *i = vam->input;
6440   vl_api_sw_interface_set_table_t *mp;
6441   u32 sw_if_index, vrf_id = 0;
6442   u8 sw_if_index_set = 0;
6443   u8 is_ipv6 = 0;
6444   int ret;
6445
6446   /* Parse args required to build the message */
6447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6448     {
6449       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6450         sw_if_index_set = 1;
6451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6452         sw_if_index_set = 1;
6453       else if (unformat (i, "vrf %d", &vrf_id))
6454         ;
6455       else if (unformat (i, "ipv6"))
6456         is_ipv6 = 1;
6457       else
6458         break;
6459     }
6460
6461   if (sw_if_index_set == 0)
6462     {
6463       errmsg ("missing interface name or sw_if_index");
6464       return -99;
6465     }
6466
6467   /* Construct the API message */
6468   M (SW_INTERFACE_SET_TABLE, mp);
6469
6470   mp->sw_if_index = ntohl (sw_if_index);
6471   mp->is_ipv6 = is_ipv6;
6472   mp->vrf_id = ntohl (vrf_id);
6473
6474   /* send it... */
6475   S (mp);
6476
6477   /* Wait for a reply... */
6478   W (ret);
6479   return ret;
6480 }
6481
6482 static void vl_api_sw_interface_get_table_reply_t_handler
6483   (vl_api_sw_interface_get_table_reply_t * mp)
6484 {
6485   vat_main_t *vam = &vat_main;
6486
6487   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6488
6489   vam->retval = ntohl (mp->retval);
6490   vam->result_ready = 1;
6491
6492 }
6493
6494 static void vl_api_sw_interface_get_table_reply_t_handler_json
6495   (vl_api_sw_interface_get_table_reply_t * mp)
6496 {
6497   vat_main_t *vam = &vat_main;
6498   vat_json_node_t node;
6499
6500   vat_json_init_object (&node);
6501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6502   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6503
6504   vat_json_print (vam->ofp, &node);
6505   vat_json_free (&node);
6506
6507   vam->retval = ntohl (mp->retval);
6508   vam->result_ready = 1;
6509 }
6510
6511 static int
6512 api_sw_interface_get_table (vat_main_t * vam)
6513 {
6514   unformat_input_t *i = vam->input;
6515   vl_api_sw_interface_get_table_t *mp;
6516   u32 sw_if_index;
6517   u8 sw_if_index_set = 0;
6518   u8 is_ipv6 = 0;
6519   int ret;
6520
6521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6522     {
6523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6524         sw_if_index_set = 1;
6525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6526         sw_if_index_set = 1;
6527       else if (unformat (i, "ipv6"))
6528         is_ipv6 = 1;
6529       else
6530         break;
6531     }
6532
6533   if (sw_if_index_set == 0)
6534     {
6535       errmsg ("missing interface name or sw_if_index");
6536       return -99;
6537     }
6538
6539   M (SW_INTERFACE_GET_TABLE, mp);
6540   mp->sw_if_index = htonl (sw_if_index);
6541   mp->is_ipv6 = is_ipv6;
6542
6543   S (mp);
6544   W (ret);
6545   return ret;
6546 }
6547
6548 static int
6549 api_sw_interface_set_vpath (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_sw_interface_set_vpath_t *mp;
6553   u32 sw_if_index = 0;
6554   u8 sw_if_index_set = 0;
6555   u8 is_enable = 0;
6556   int ret;
6557
6558   /* Parse args required to build the message */
6559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6560     {
6561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6562         sw_if_index_set = 1;
6563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6564         sw_if_index_set = 1;
6565       else if (unformat (i, "enable"))
6566         is_enable = 1;
6567       else if (unformat (i, "disable"))
6568         is_enable = 0;
6569       else
6570         break;
6571     }
6572
6573   if (sw_if_index_set == 0)
6574     {
6575       errmsg ("missing interface name or sw_if_index");
6576       return -99;
6577     }
6578
6579   /* Construct the API message */
6580   M (SW_INTERFACE_SET_VPATH, mp);
6581
6582   mp->sw_if_index = ntohl (sw_if_index);
6583   mp->enable = is_enable;
6584
6585   /* send it... */
6586   S (mp);
6587
6588   /* Wait for a reply... */
6589   W (ret);
6590   return ret;
6591 }
6592
6593 static int
6594 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6595 {
6596   unformat_input_t *i = vam->input;
6597   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6598   u32 sw_if_index = 0;
6599   u8 sw_if_index_set = 0;
6600   u8 is_enable = 1;
6601   u8 is_ipv6 = 0;
6602   int ret;
6603
6604   /* Parse args required to build the message */
6605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6606     {
6607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6608         sw_if_index_set = 1;
6609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6610         sw_if_index_set = 1;
6611       else if (unformat (i, "enable"))
6612         is_enable = 1;
6613       else if (unformat (i, "disable"))
6614         is_enable = 0;
6615       else if (unformat (i, "ip4"))
6616         is_ipv6 = 0;
6617       else if (unformat (i, "ip6"))
6618         is_ipv6 = 1;
6619       else
6620         break;
6621     }
6622
6623   if (sw_if_index_set == 0)
6624     {
6625       errmsg ("missing interface name or sw_if_index");
6626       return -99;
6627     }
6628
6629   /* Construct the API message */
6630   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6631
6632   mp->sw_if_index = ntohl (sw_if_index);
6633   mp->enable = is_enable;
6634   mp->is_ipv6 = is_ipv6;
6635
6636   /* send it... */
6637   S (mp);
6638
6639   /* Wait for a reply... */
6640   W (ret);
6641   return ret;
6642 }
6643
6644 static int
6645 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6646 {
6647   unformat_input_t *i = vam->input;
6648   vl_api_sw_interface_set_geneve_bypass_t *mp;
6649   u32 sw_if_index = 0;
6650   u8 sw_if_index_set = 0;
6651   u8 is_enable = 1;
6652   u8 is_ipv6 = 0;
6653   int ret;
6654
6655   /* Parse args required to build the message */
6656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6657     {
6658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6659         sw_if_index_set = 1;
6660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6661         sw_if_index_set = 1;
6662       else if (unformat (i, "enable"))
6663         is_enable = 1;
6664       else if (unformat (i, "disable"))
6665         is_enable = 0;
6666       else if (unformat (i, "ip4"))
6667         is_ipv6 = 0;
6668       else if (unformat (i, "ip6"))
6669         is_ipv6 = 1;
6670       else
6671         break;
6672     }
6673
6674   if (sw_if_index_set == 0)
6675     {
6676       errmsg ("missing interface name or sw_if_index");
6677       return -99;
6678     }
6679
6680   /* Construct the API message */
6681   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6682
6683   mp->sw_if_index = ntohl (sw_if_index);
6684   mp->enable = is_enable;
6685   mp->is_ipv6 = is_ipv6;
6686
6687   /* send it... */
6688   S (mp);
6689
6690   /* Wait for a reply... */
6691   W (ret);
6692   return ret;
6693 }
6694
6695 static int
6696 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6697 {
6698   unformat_input_t *i = vam->input;
6699   vl_api_sw_interface_set_l2_xconnect_t *mp;
6700   u32 rx_sw_if_index;
6701   u8 rx_sw_if_index_set = 0;
6702   u32 tx_sw_if_index;
6703   u8 tx_sw_if_index_set = 0;
6704   u8 enable = 1;
6705   int ret;
6706
6707   /* Parse args required to build the message */
6708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6709     {
6710       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6711         rx_sw_if_index_set = 1;
6712       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6713         tx_sw_if_index_set = 1;
6714       else if (unformat (i, "rx"))
6715         {
6716           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6717             {
6718               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6719                             &rx_sw_if_index))
6720                 rx_sw_if_index_set = 1;
6721             }
6722           else
6723             break;
6724         }
6725       else if (unformat (i, "tx"))
6726         {
6727           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6728             {
6729               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6730                             &tx_sw_if_index))
6731                 tx_sw_if_index_set = 1;
6732             }
6733           else
6734             break;
6735         }
6736       else if (unformat (i, "enable"))
6737         enable = 1;
6738       else if (unformat (i, "disable"))
6739         enable = 0;
6740       else
6741         break;
6742     }
6743
6744   if (rx_sw_if_index_set == 0)
6745     {
6746       errmsg ("missing rx interface name or rx_sw_if_index");
6747       return -99;
6748     }
6749
6750   if (enable && (tx_sw_if_index_set == 0))
6751     {
6752       errmsg ("missing tx interface name or tx_sw_if_index");
6753       return -99;
6754     }
6755
6756   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6757
6758   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6759   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6760   mp->enable = enable;
6761
6762   S (mp);
6763   W (ret);
6764   return ret;
6765 }
6766
6767 static int
6768 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6769 {
6770   unformat_input_t *i = vam->input;
6771   vl_api_sw_interface_set_l2_bridge_t *mp;
6772   vl_api_l2_port_type_t port_type;
6773   u32 rx_sw_if_index;
6774   u8 rx_sw_if_index_set = 0;
6775   u32 bd_id;
6776   u8 bd_id_set = 0;
6777   u32 shg = 0;
6778   u8 enable = 1;
6779   int ret;
6780
6781   port_type = L2_API_PORT_TYPE_NORMAL;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6787         rx_sw_if_index_set = 1;
6788       else if (unformat (i, "bd_id %d", &bd_id))
6789         bd_id_set = 1;
6790       else
6791         if (unformat
6792             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6793         rx_sw_if_index_set = 1;
6794       else if (unformat (i, "shg %d", &shg))
6795         ;
6796       else if (unformat (i, "bvi"))
6797         port_type = L2_API_PORT_TYPE_BVI;
6798       else if (unformat (i, "uu-fwd"))
6799         port_type = L2_API_PORT_TYPE_UU_FWD;
6800       else if (unformat (i, "enable"))
6801         enable = 1;
6802       else if (unformat (i, "disable"))
6803         enable = 0;
6804       else
6805         break;
6806     }
6807
6808   if (rx_sw_if_index_set == 0)
6809     {
6810       errmsg ("missing rx interface name or sw_if_index");
6811       return -99;
6812     }
6813
6814   if (enable && (bd_id_set == 0))
6815     {
6816       errmsg ("missing bridge domain");
6817       return -99;
6818     }
6819
6820   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6821
6822   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6823   mp->bd_id = ntohl (bd_id);
6824   mp->shg = (u8) shg;
6825   mp->port_type = ntohl (port_type);
6826   mp->enable = enable;
6827
6828   S (mp);
6829   W (ret);
6830   return ret;
6831 }
6832
6833 static int
6834 api_bridge_domain_dump (vat_main_t * vam)
6835 {
6836   unformat_input_t *i = vam->input;
6837   vl_api_bridge_domain_dump_t *mp;
6838   vl_api_control_ping_t *mp_ping;
6839   u32 bd_id = ~0;
6840   int ret;
6841
6842   /* Parse args required to build the message */
6843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6844     {
6845       if (unformat (i, "bd_id %d", &bd_id))
6846         ;
6847       else
6848         break;
6849     }
6850
6851   M (BRIDGE_DOMAIN_DUMP, mp);
6852   mp->bd_id = ntohl (bd_id);
6853   S (mp);
6854
6855   /* Use a control ping for synchronization */
6856   MPING (CONTROL_PING, mp_ping);
6857   S (mp_ping);
6858
6859   W (ret);
6860   return ret;
6861 }
6862
6863 static int
6864 api_bridge_domain_add_del (vat_main_t * vam)
6865 {
6866   unformat_input_t *i = vam->input;
6867   vl_api_bridge_domain_add_del_t *mp;
6868   u32 bd_id = ~0;
6869   u8 is_add = 1;
6870   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6871   u8 *bd_tag = NULL;
6872   u32 mac_age = 0;
6873   int ret;
6874
6875   /* Parse args required to build the message */
6876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6877     {
6878       if (unformat (i, "bd_id %d", &bd_id))
6879         ;
6880       else if (unformat (i, "flood %d", &flood))
6881         ;
6882       else if (unformat (i, "uu-flood %d", &uu_flood))
6883         ;
6884       else if (unformat (i, "forward %d", &forward))
6885         ;
6886       else if (unformat (i, "learn %d", &learn))
6887         ;
6888       else if (unformat (i, "arp-term %d", &arp_term))
6889         ;
6890       else if (unformat (i, "mac-age %d", &mac_age))
6891         ;
6892       else if (unformat (i, "bd-tag %s", &bd_tag))
6893         ;
6894       else if (unformat (i, "del"))
6895         {
6896           is_add = 0;
6897           flood = uu_flood = forward = learn = 0;
6898         }
6899       else
6900         break;
6901     }
6902
6903   if (bd_id == ~0)
6904     {
6905       errmsg ("missing bridge domain");
6906       ret = -99;
6907       goto done;
6908     }
6909
6910   if (mac_age > 255)
6911     {
6912       errmsg ("mac age must be less than 256 ");
6913       ret = -99;
6914       goto done;
6915     }
6916
6917   if ((bd_tag) && (vec_len (bd_tag) > 63))
6918     {
6919       errmsg ("bd-tag cannot be longer than 63");
6920       ret = -99;
6921       goto done;
6922     }
6923
6924   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6925
6926   mp->bd_id = ntohl (bd_id);
6927   mp->flood = flood;
6928   mp->uu_flood = uu_flood;
6929   mp->forward = forward;
6930   mp->learn = learn;
6931   mp->arp_term = arp_term;
6932   mp->is_add = is_add;
6933   mp->mac_age = (u8) mac_age;
6934   if (bd_tag)
6935     {
6936       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6937       mp->bd_tag[vec_len (bd_tag)] = 0;
6938     }
6939   S (mp);
6940   W (ret);
6941
6942 done:
6943   vec_free (bd_tag);
6944   return ret;
6945 }
6946
6947 static int
6948 api_l2fib_flush_bd (vat_main_t * vam)
6949 {
6950   unformat_input_t *i = vam->input;
6951   vl_api_l2fib_flush_bd_t *mp;
6952   u32 bd_id = ~0;
6953   int ret;
6954
6955   /* Parse args required to build the message */
6956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6957     {
6958       if (unformat (i, "bd_id %d", &bd_id));
6959       else
6960         break;
6961     }
6962
6963   if (bd_id == ~0)
6964     {
6965       errmsg ("missing bridge domain");
6966       return -99;
6967     }
6968
6969   M (L2FIB_FLUSH_BD, mp);
6970
6971   mp->bd_id = htonl (bd_id);
6972
6973   S (mp);
6974   W (ret);
6975   return ret;
6976 }
6977
6978 static int
6979 api_l2fib_flush_int (vat_main_t * vam)
6980 {
6981   unformat_input_t *i = vam->input;
6982   vl_api_l2fib_flush_int_t *mp;
6983   u32 sw_if_index = ~0;
6984   int ret;
6985
6986   /* Parse args required to build the message */
6987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6988     {
6989       if (unformat (i, "sw_if_index %d", &sw_if_index));
6990       else
6991         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6992       else
6993         break;
6994     }
6995
6996   if (sw_if_index == ~0)
6997     {
6998       errmsg ("missing interface name or sw_if_index");
6999       return -99;
7000     }
7001
7002   M (L2FIB_FLUSH_INT, mp);
7003
7004   mp->sw_if_index = ntohl (sw_if_index);
7005
7006   S (mp);
7007   W (ret);
7008   return ret;
7009 }
7010
7011 static int
7012 api_l2fib_add_del (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_l2fib_add_del_t *mp;
7016   f64 timeout;
7017   u8 mac[6] = { 0 };
7018   u8 mac_set = 0;
7019   u32 bd_id;
7020   u8 bd_id_set = 0;
7021   u32 sw_if_index = 0;
7022   u8 sw_if_index_set = 0;
7023   u8 is_add = 1;
7024   u8 static_mac = 0;
7025   u8 filter_mac = 0;
7026   u8 bvi_mac = 0;
7027   int count = 1;
7028   f64 before = 0;
7029   int j;
7030
7031   /* Parse args required to build the message */
7032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7033     {
7034       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7035         mac_set = 1;
7036       else if (unformat (i, "bd_id %d", &bd_id))
7037         bd_id_set = 1;
7038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7039         sw_if_index_set = 1;
7040       else if (unformat (i, "sw_if"))
7041         {
7042           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7043             {
7044               if (unformat
7045                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7046                 sw_if_index_set = 1;
7047             }
7048           else
7049             break;
7050         }
7051       else if (unformat (i, "static"))
7052         static_mac = 1;
7053       else if (unformat (i, "filter"))
7054         {
7055           filter_mac = 1;
7056           static_mac = 1;
7057         }
7058       else if (unformat (i, "bvi"))
7059         {
7060           bvi_mac = 1;
7061           static_mac = 1;
7062         }
7063       else if (unformat (i, "del"))
7064         is_add = 0;
7065       else if (unformat (i, "count %d", &count))
7066         ;
7067       else
7068         break;
7069     }
7070
7071   if (mac_set == 0)
7072     {
7073       errmsg ("missing mac address");
7074       return -99;
7075     }
7076
7077   if (bd_id_set == 0)
7078     {
7079       errmsg ("missing bridge domain");
7080       return -99;
7081     }
7082
7083   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7084     {
7085       errmsg ("missing interface name or sw_if_index");
7086       return -99;
7087     }
7088
7089   if (count > 1)
7090     {
7091       /* Turn on async mode */
7092       vam->async_mode = 1;
7093       vam->async_errors = 0;
7094       before = vat_time_now (vam);
7095     }
7096
7097   for (j = 0; j < count; j++)
7098     {
7099       M (L2FIB_ADD_DEL, mp);
7100
7101       clib_memcpy (mp->mac, mac, 6);
7102       mp->bd_id = ntohl (bd_id);
7103       mp->is_add = is_add;
7104       mp->sw_if_index = ntohl (sw_if_index);
7105
7106       if (is_add)
7107         {
7108           mp->static_mac = static_mac;
7109           mp->filter_mac = filter_mac;
7110           mp->bvi_mac = bvi_mac;
7111         }
7112       increment_mac_address (mac);
7113       /* send it... */
7114       S (mp);
7115     }
7116
7117   if (count > 1)
7118     {
7119       vl_api_control_ping_t *mp_ping;
7120       f64 after;
7121
7122       /* Shut off async mode */
7123       vam->async_mode = 0;
7124
7125       MPING (CONTROL_PING, mp_ping);
7126       S (mp_ping);
7127
7128       timeout = vat_time_now (vam) + 1.0;
7129       while (vat_time_now (vam) < timeout)
7130         if (vam->result_ready == 1)
7131           goto out;
7132       vam->retval = -99;
7133
7134     out:
7135       if (vam->retval == -99)
7136         errmsg ("timeout");
7137
7138       if (vam->async_errors > 0)
7139         {
7140           errmsg ("%d asynchronous errors", vam->async_errors);
7141           vam->retval = -98;
7142         }
7143       vam->async_errors = 0;
7144       after = vat_time_now (vam);
7145
7146       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7147              count, after - before, count / (after - before));
7148     }
7149   else
7150     {
7151       int ret;
7152
7153       /* Wait for a reply... */
7154       W (ret);
7155       return ret;
7156     }
7157   /* Return the good/bad news */
7158   return (vam->retval);
7159 }
7160
7161 static int
7162 api_bridge_domain_set_mac_age (vat_main_t * vam)
7163 {
7164   unformat_input_t *i = vam->input;
7165   vl_api_bridge_domain_set_mac_age_t *mp;
7166   u32 bd_id = ~0;
7167   u32 mac_age = 0;
7168   int ret;
7169
7170   /* Parse args required to build the message */
7171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7172     {
7173       if (unformat (i, "bd_id %d", &bd_id));
7174       else if (unformat (i, "mac-age %d", &mac_age));
7175       else
7176         break;
7177     }
7178
7179   if (bd_id == ~0)
7180     {
7181       errmsg ("missing bridge domain");
7182       return -99;
7183     }
7184
7185   if (mac_age > 255)
7186     {
7187       errmsg ("mac age must be less than 256 ");
7188       return -99;
7189     }
7190
7191   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7192
7193   mp->bd_id = htonl (bd_id);
7194   mp->mac_age = (u8) mac_age;
7195
7196   S (mp);
7197   W (ret);
7198   return ret;
7199 }
7200
7201 static int
7202 api_l2_flags (vat_main_t * vam)
7203 {
7204   unformat_input_t *i = vam->input;
7205   vl_api_l2_flags_t *mp;
7206   u32 sw_if_index;
7207   u32 flags = 0;
7208   u8 sw_if_index_set = 0;
7209   u8 is_set = 0;
7210   int ret;
7211
7212   /* Parse args required to build the message */
7213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7214     {
7215       if (unformat (i, "sw_if_index %d", &sw_if_index))
7216         sw_if_index_set = 1;
7217       else if (unformat (i, "sw_if"))
7218         {
7219           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7220             {
7221               if (unformat
7222                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7223                 sw_if_index_set = 1;
7224             }
7225           else
7226             break;
7227         }
7228       else if (unformat (i, "learn"))
7229         flags |= L2_LEARN;
7230       else if (unformat (i, "forward"))
7231         flags |= L2_FWD;
7232       else if (unformat (i, "flood"))
7233         flags |= L2_FLOOD;
7234       else if (unformat (i, "uu-flood"))
7235         flags |= L2_UU_FLOOD;
7236       else if (unformat (i, "arp-term"))
7237         flags |= L2_ARP_TERM;
7238       else if (unformat (i, "off"))
7239         is_set = 0;
7240       else if (unformat (i, "disable"))
7241         is_set = 0;
7242       else
7243         break;
7244     }
7245
7246   if (sw_if_index_set == 0)
7247     {
7248       errmsg ("missing interface name or sw_if_index");
7249       return -99;
7250     }
7251
7252   M (L2_FLAGS, mp);
7253
7254   mp->sw_if_index = ntohl (sw_if_index);
7255   mp->feature_bitmap = ntohl (flags);
7256   mp->is_set = is_set;
7257
7258   S (mp);
7259   W (ret);
7260   return ret;
7261 }
7262
7263 static int
7264 api_bridge_flags (vat_main_t * vam)
7265 {
7266   unformat_input_t *i = vam->input;
7267   vl_api_bridge_flags_t *mp;
7268   u32 bd_id;
7269   u8 bd_id_set = 0;
7270   u8 is_set = 1;
7271   bd_flags_t flags = 0;
7272   int ret;
7273
7274   /* Parse args required to build the message */
7275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7276     {
7277       if (unformat (i, "bd_id %d", &bd_id))
7278         bd_id_set = 1;
7279       else if (unformat (i, "learn"))
7280         flags |= BRIDGE_API_FLAG_LEARN;
7281       else if (unformat (i, "forward"))
7282         flags |= BRIDGE_API_FLAG_FWD;
7283       else if (unformat (i, "flood"))
7284         flags |= BRIDGE_API_FLAG_FLOOD;
7285       else if (unformat (i, "uu-flood"))
7286         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7287       else if (unformat (i, "arp-term"))
7288         flags |= BRIDGE_API_FLAG_ARP_TERM;
7289       else if (unformat (i, "off"))
7290         is_set = 0;
7291       else if (unformat (i, "disable"))
7292         is_set = 0;
7293       else
7294         break;
7295     }
7296
7297   if (bd_id_set == 0)
7298     {
7299       errmsg ("missing bridge domain");
7300       return -99;
7301     }
7302
7303   M (BRIDGE_FLAGS, mp);
7304
7305   mp->bd_id = ntohl (bd_id);
7306   mp->flags = ntohl (flags);
7307   mp->is_set = is_set;
7308
7309   S (mp);
7310   W (ret);
7311   return ret;
7312 }
7313
7314 static int
7315 api_bd_ip_mac_add_del (vat_main_t * vam)
7316 {
7317   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7318   vl_api_mac_address_t mac = { 0 };
7319   unformat_input_t *i = vam->input;
7320   vl_api_bd_ip_mac_add_del_t *mp;
7321   ip46_type_t type;
7322   u32 bd_id;
7323   u8 is_ipv6 = 0;
7324   u8 is_add = 1;
7325   u8 bd_id_set = 0;
7326   u8 ip_set = 0;
7327   u8 mac_set = 0;
7328   u8 macaddr[6];
7329   int ret;
7330
7331
7332   /* Parse args required to build the message */
7333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7334     {
7335       if (unformat (i, "bd_id %d", &bd_id))
7336         {
7337           bd_id_set++;
7338         }
7339       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7340         {
7341           ip_set++;
7342         }
7343       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7344         {
7345           mac_set++;
7346         }
7347       else if (unformat (i, "del"))
7348         is_add = 0;
7349       else
7350         break;
7351     }
7352
7353   if (bd_id_set == 0)
7354     {
7355       errmsg ("missing bridge domain");
7356       return -99;
7357     }
7358   else if (ip_set == 0)
7359     {
7360       errmsg ("missing IP address");
7361       return -99;
7362     }
7363   else if (mac_set == 0)
7364     {
7365       errmsg ("missing MAC address");
7366       return -99;
7367     }
7368
7369   M (BD_IP_MAC_ADD_DEL, mp);
7370
7371   mp->bd_id = ntohl (bd_id);
7372   mp->is_add = is_add;
7373
7374   clib_memcpy (&mp->ip, &ip, sizeof (ip));
7375   clib_memcpy (&mp->mac, &mac, sizeof (mac));
7376
7377   S (mp);
7378   W (ret);
7379   return ret;
7380 }
7381
7382 static void vl_api_bd_ip_mac_details_t_handler
7383   (vl_api_bd_ip_mac_details_t * mp)
7384 {
7385   vat_main_t *vam = &vat_main;
7386   u8 *ip = 0;
7387
7388   if (!mp->is_ipv6)
7389     ip =
7390       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7391   else
7392     ip =
7393       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7394
7395   print (vam->ofp,
7396          "\n%-5d %-7s %-20U %-30s",
7397          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7398          format_ethernet_address, mp->mac_address, ip);
7399
7400   vec_free (ip);
7401 }
7402
7403 static void vl_api_bd_ip_mac_details_t_handler_json
7404   (vl_api_bd_ip_mac_details_t * mp)
7405 {
7406   vat_main_t *vam = &vat_main;
7407   vat_json_node_t *node = NULL;
7408
7409   if (VAT_JSON_ARRAY != vam->json_tree.type)
7410     {
7411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7412       vat_json_init_array (&vam->json_tree);
7413     }
7414   node = vat_json_array_add (&vam->json_tree);
7415
7416   vat_json_init_object (node);
7417   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7418   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7419   vat_json_object_add_string_copy (node, "mac_address",
7420                                    format (0, "%U", format_ethernet_address,
7421                                            &mp->mac_address));
7422   u8 *ip = 0;
7423
7424   if (!mp->is_ipv6)
7425     ip =
7426       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7427   else
7428     ip =
7429       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7430   vat_json_object_add_string_copy (node, "ip_address", ip);
7431   vec_free (ip);
7432 }
7433
7434 static int
7435 api_bd_ip_mac_dump (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_bd_ip_mac_dump_t *mp;
7439   vl_api_control_ping_t *mp_ping;
7440   int ret;
7441   u32 bd_id;
7442   u8 bd_id_set = 0;
7443
7444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7445     {
7446       if (unformat (i, "bd_id %d", &bd_id))
7447         {
7448           bd_id_set++;
7449         }
7450       else
7451         break;
7452     }
7453
7454   print (vam->ofp,
7455          "\n%-5s %-7s %-20s %-30s",
7456          "bd_id", "is_ipv6", "mac_address", "ip_address");
7457
7458   /* Dump Bridge Domain Ip to Mac entries */
7459   M (BD_IP_MAC_DUMP, mp);
7460
7461   if (bd_id_set)
7462     mp->bd_id = htonl (bd_id);
7463   else
7464     mp->bd_id = ~0;
7465
7466   S (mp);
7467
7468   /* Use a control ping for synchronization */
7469   MPING (CONTROL_PING, mp_ping);
7470   S (mp_ping);
7471
7472   W (ret);
7473   return ret;
7474 }
7475
7476 static int
7477 api_tap_connect (vat_main_t * vam)
7478 {
7479   unformat_input_t *i = vam->input;
7480   vl_api_tap_connect_t *mp;
7481   u8 mac_address[6];
7482   u8 random_mac = 1;
7483   u8 name_set = 0;
7484   u8 *tap_name;
7485   u8 *tag = 0;
7486   ip4_address_t ip4_address;
7487   u32 ip4_mask_width;
7488   int ip4_address_set = 0;
7489   ip6_address_t ip6_address;
7490   u32 ip6_mask_width;
7491   int ip6_address_set = 0;
7492   int ret;
7493
7494   clib_memset (mac_address, 0, sizeof (mac_address));
7495
7496   /* Parse args required to build the message */
7497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7500         {
7501           random_mac = 0;
7502         }
7503       else if (unformat (i, "random-mac"))
7504         random_mac = 1;
7505       else if (unformat (i, "tapname %s", &tap_name))
7506         name_set = 1;
7507       else if (unformat (i, "tag %s", &tag))
7508         ;
7509       else if (unformat (i, "address %U/%d",
7510                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7511         ip4_address_set = 1;
7512       else if (unformat (i, "address %U/%d",
7513                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7514         ip6_address_set = 1;
7515       else
7516         break;
7517     }
7518
7519   if (name_set == 0)
7520     {
7521       errmsg ("missing tap name");
7522       return -99;
7523     }
7524   if (vec_len (tap_name) > 63)
7525     {
7526       errmsg ("tap name too long");
7527       return -99;
7528     }
7529   vec_add1 (tap_name, 0);
7530
7531   if (vec_len (tag) > 63)
7532     {
7533       errmsg ("tag too long");
7534       return -99;
7535     }
7536
7537   /* Construct the API message */
7538   M (TAP_CONNECT, mp);
7539
7540   mp->use_random_mac = random_mac;
7541   clib_memcpy (mp->mac_address, mac_address, 6);
7542   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7543   if (tag)
7544     clib_memcpy (mp->tag, tag, vec_len (tag));
7545
7546   if (ip4_address_set)
7547     {
7548       mp->ip4_address_set = 1;
7549       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7550       mp->ip4_mask_width = ip4_mask_width;
7551     }
7552   if (ip6_address_set)
7553     {
7554       mp->ip6_address_set = 1;
7555       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7556       mp->ip6_mask_width = ip6_mask_width;
7557     }
7558
7559   vec_free (tap_name);
7560   vec_free (tag);
7561
7562   /* send it... */
7563   S (mp);
7564
7565   /* Wait for a reply... */
7566   W (ret);
7567   return ret;
7568 }
7569
7570 static int
7571 api_tap_modify (vat_main_t * vam)
7572 {
7573   unformat_input_t *i = vam->input;
7574   vl_api_tap_modify_t *mp;
7575   u8 mac_address[6];
7576   u8 random_mac = 1;
7577   u8 name_set = 0;
7578   u8 *tap_name;
7579   u32 sw_if_index = ~0;
7580   u8 sw_if_index_set = 0;
7581   int ret;
7582
7583   clib_memset (mac_address, 0, sizeof (mac_address));
7584
7585   /* Parse args required to build the message */
7586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7587     {
7588       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7589         sw_if_index_set = 1;
7590       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7591         sw_if_index_set = 1;
7592       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7593         {
7594           random_mac = 0;
7595         }
7596       else if (unformat (i, "random-mac"))
7597         random_mac = 1;
7598       else if (unformat (i, "tapname %s", &tap_name))
7599         name_set = 1;
7600       else
7601         break;
7602     }
7603
7604   if (sw_if_index_set == 0)
7605     {
7606       errmsg ("missing vpp interface name");
7607       return -99;
7608     }
7609   if (name_set == 0)
7610     {
7611       errmsg ("missing tap name");
7612       return -99;
7613     }
7614   if (vec_len (tap_name) > 63)
7615     {
7616       errmsg ("tap name too long");
7617     }
7618   vec_add1 (tap_name, 0);
7619
7620   /* Construct the API message */
7621   M (TAP_MODIFY, mp);
7622
7623   mp->use_random_mac = random_mac;
7624   mp->sw_if_index = ntohl (sw_if_index);
7625   clib_memcpy (mp->mac_address, mac_address, 6);
7626   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7627   vec_free (tap_name);
7628
7629   /* send it... */
7630   S (mp);
7631
7632   /* Wait for a reply... */
7633   W (ret);
7634   return ret;
7635 }
7636
7637 static int
7638 api_tap_delete (vat_main_t * vam)
7639 {
7640   unformat_input_t *i = vam->input;
7641   vl_api_tap_delete_t *mp;
7642   u32 sw_if_index = ~0;
7643   u8 sw_if_index_set = 0;
7644   int ret;
7645
7646   /* Parse args required to build the message */
7647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7648     {
7649       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7650         sw_if_index_set = 1;
7651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7652         sw_if_index_set = 1;
7653       else
7654         break;
7655     }
7656
7657   if (sw_if_index_set == 0)
7658     {
7659       errmsg ("missing vpp interface name");
7660       return -99;
7661     }
7662
7663   /* Construct the API message */
7664   M (TAP_DELETE, mp);
7665
7666   mp->sw_if_index = ntohl (sw_if_index);
7667
7668   /* send it... */
7669   S (mp);
7670
7671   /* Wait for a reply... */
7672   W (ret);
7673   return ret;
7674 }
7675
7676 static int
7677 api_tap_create_v2 (vat_main_t * vam)
7678 {
7679   unformat_input_t *i = vam->input;
7680   vl_api_tap_create_v2_t *mp;
7681   u8 mac_address[6];
7682   u8 random_mac = 1;
7683   u32 id = ~0;
7684   u8 *host_if_name = 0;
7685   u8 *host_ns = 0;
7686   u8 host_mac_addr[6];
7687   u8 host_mac_addr_set = 0;
7688   u8 *host_bridge = 0;
7689   ip4_address_t host_ip4_addr;
7690   ip4_address_t host_ip4_gw;
7691   u8 host_ip4_gw_set = 0;
7692   u32 host_ip4_prefix_len = 0;
7693   ip6_address_t host_ip6_addr;
7694   ip6_address_t host_ip6_gw;
7695   u8 host_ip6_gw_set = 0;
7696   u32 host_ip6_prefix_len = 0;
7697   int ret;
7698   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7699
7700   clib_memset (mac_address, 0, sizeof (mac_address));
7701
7702   /* Parse args required to build the message */
7703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7704     {
7705       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7706         {
7707           random_mac = 0;
7708         }
7709       else if (unformat (i, "id %u", &id))
7710         ;
7711       else if (unformat (i, "host-if-name %s", &host_if_name))
7712         ;
7713       else if (unformat (i, "host-ns %s", &host_ns))
7714         ;
7715       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7716                          host_mac_addr))
7717         host_mac_addr_set = 1;
7718       else if (unformat (i, "host-bridge %s", &host_bridge))
7719         ;
7720       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7721                          &host_ip4_addr, &host_ip4_prefix_len))
7722         ;
7723       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7724                          &host_ip6_addr, &host_ip6_prefix_len))
7725         ;
7726       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7727                          &host_ip4_gw))
7728         host_ip4_gw_set = 1;
7729       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7730                          &host_ip6_gw))
7731         host_ip6_gw_set = 1;
7732       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7733         ;
7734       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7735         ;
7736       else
7737         break;
7738     }
7739
7740   if (vec_len (host_if_name) > 63)
7741     {
7742       errmsg ("tap name too long. ");
7743       return -99;
7744     }
7745   if (vec_len (host_ns) > 63)
7746     {
7747       errmsg ("host name space too long. ");
7748       return -99;
7749     }
7750   if (vec_len (host_bridge) > 63)
7751     {
7752       errmsg ("host bridge name too long. ");
7753       return -99;
7754     }
7755   if (host_ip4_prefix_len > 32)
7756     {
7757       errmsg ("host ip4 prefix length not valid. ");
7758       return -99;
7759     }
7760   if (host_ip6_prefix_len > 128)
7761     {
7762       errmsg ("host ip6 prefix length not valid. ");
7763       return -99;
7764     }
7765   if (!is_pow2 (rx_ring_sz))
7766     {
7767       errmsg ("rx ring size must be power of 2. ");
7768       return -99;
7769     }
7770   if (rx_ring_sz > 32768)
7771     {
7772       errmsg ("rx ring size must be 32768 or lower. ");
7773       return -99;
7774     }
7775   if (!is_pow2 (tx_ring_sz))
7776     {
7777       errmsg ("tx ring size must be power of 2. ");
7778       return -99;
7779     }
7780   if (tx_ring_sz > 32768)
7781     {
7782       errmsg ("tx ring size must be 32768 or lower. ");
7783       return -99;
7784     }
7785
7786   /* Construct the API message */
7787   M (TAP_CREATE_V2, mp);
7788
7789   mp->use_random_mac = random_mac;
7790
7791   mp->id = ntohl (id);
7792   mp->host_namespace_set = host_ns != 0;
7793   mp->host_bridge_set = host_bridge != 0;
7794   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7795   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7796   mp->rx_ring_sz = ntohs (rx_ring_sz);
7797   mp->tx_ring_sz = ntohs (tx_ring_sz);
7798
7799   if (random_mac == 0)
7800     clib_memcpy (mp->mac_address, mac_address, 6);
7801   if (host_mac_addr_set)
7802     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7803   if (host_if_name)
7804     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7805   if (host_ns)
7806     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7807   if (host_bridge)
7808     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7809   if (host_ip4_prefix_len)
7810     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7811   if (host_ip6_prefix_len)
7812     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7813   if (host_ip4_gw_set)
7814     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7815   if (host_ip6_gw_set)
7816     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7817
7818   vec_free (host_ns);
7819   vec_free (host_if_name);
7820   vec_free (host_bridge);
7821
7822   /* send it... */
7823   S (mp);
7824
7825   /* Wait for a reply... */
7826   W (ret);
7827   return ret;
7828 }
7829
7830 static int
7831 api_tap_delete_v2 (vat_main_t * vam)
7832 {
7833   unformat_input_t *i = vam->input;
7834   vl_api_tap_delete_v2_t *mp;
7835   u32 sw_if_index = ~0;
7836   u8 sw_if_index_set = 0;
7837   int ret;
7838
7839   /* Parse args required to build the message */
7840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7841     {
7842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7843         sw_if_index_set = 1;
7844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7845         sw_if_index_set = 1;
7846       else
7847         break;
7848     }
7849
7850   if (sw_if_index_set == 0)
7851     {
7852       errmsg ("missing vpp interface name. ");
7853       return -99;
7854     }
7855
7856   /* Construct the API message */
7857   M (TAP_DELETE_V2, mp);
7858
7859   mp->sw_if_index = ntohl (sw_if_index);
7860
7861   /* send it... */
7862   S (mp);
7863
7864   /* Wait for a reply... */
7865   W (ret);
7866   return ret;
7867 }
7868
7869 static int
7870 api_bond_create (vat_main_t * vam)
7871 {
7872   unformat_input_t *i = vam->input;
7873   vl_api_bond_create_t *mp;
7874   u8 mac_address[6];
7875   u8 custom_mac = 0;
7876   int ret;
7877   u8 mode;
7878   u8 lb;
7879   u8 mode_is_set = 0;
7880
7881   clib_memset (mac_address, 0, sizeof (mac_address));
7882   lb = BOND_LB_L2;
7883
7884   /* Parse args required to build the message */
7885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7886     {
7887       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7888         mode_is_set = 1;
7889       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7890                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7891         ;
7892       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7893                          mac_address))
7894         custom_mac = 1;
7895       else
7896         break;
7897     }
7898
7899   if (mode_is_set == 0)
7900     {
7901       errmsg ("Missing bond mode. ");
7902       return -99;
7903     }
7904
7905   /* Construct the API message */
7906   M (BOND_CREATE, mp);
7907
7908   mp->use_custom_mac = custom_mac;
7909
7910   mp->mode = mode;
7911   mp->lb = lb;
7912
7913   if (custom_mac)
7914     clib_memcpy (mp->mac_address, mac_address, 6);
7915
7916   /* send it... */
7917   S (mp);
7918
7919   /* Wait for a reply... */
7920   W (ret);
7921   return ret;
7922 }
7923
7924 static int
7925 api_bond_delete (vat_main_t * vam)
7926 {
7927   unformat_input_t *i = vam->input;
7928   vl_api_bond_delete_t *mp;
7929   u32 sw_if_index = ~0;
7930   u8 sw_if_index_set = 0;
7931   int ret;
7932
7933   /* Parse args required to build the message */
7934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7937         sw_if_index_set = 1;
7938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7939         sw_if_index_set = 1;
7940       else
7941         break;
7942     }
7943
7944   if (sw_if_index_set == 0)
7945     {
7946       errmsg ("missing vpp interface name. ");
7947       return -99;
7948     }
7949
7950   /* Construct the API message */
7951   M (BOND_DELETE, mp);
7952
7953   mp->sw_if_index = ntohl (sw_if_index);
7954
7955   /* send it... */
7956   S (mp);
7957
7958   /* Wait for a reply... */
7959   W (ret);
7960   return ret;
7961 }
7962
7963 static int
7964 api_bond_enslave (vat_main_t * vam)
7965 {
7966   unformat_input_t *i = vam->input;
7967   vl_api_bond_enslave_t *mp;
7968   u32 bond_sw_if_index;
7969   int ret;
7970   u8 is_passive;
7971   u8 is_long_timeout;
7972   u32 bond_sw_if_index_is_set = 0;
7973   u32 sw_if_index;
7974   u8 sw_if_index_is_set = 0;
7975
7976   /* Parse args required to build the message */
7977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7978     {
7979       if (unformat (i, "sw_if_index %d", &sw_if_index))
7980         sw_if_index_is_set = 1;
7981       else if (unformat (i, "bond %u", &bond_sw_if_index))
7982         bond_sw_if_index_is_set = 1;
7983       else if (unformat (i, "passive %d", &is_passive))
7984         ;
7985       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7986         ;
7987       else
7988         break;
7989     }
7990
7991   if (bond_sw_if_index_is_set == 0)
7992     {
7993       errmsg ("Missing bond sw_if_index. ");
7994       return -99;
7995     }
7996   if (sw_if_index_is_set == 0)
7997     {
7998       errmsg ("Missing slave sw_if_index. ");
7999       return -99;
8000     }
8001
8002   /* Construct the API message */
8003   M (BOND_ENSLAVE, mp);
8004
8005   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8006   mp->sw_if_index = ntohl (sw_if_index);
8007   mp->is_long_timeout = is_long_timeout;
8008   mp->is_passive = is_passive;
8009
8010   /* send it... */
8011   S (mp);
8012
8013   /* Wait for a reply... */
8014   W (ret);
8015   return ret;
8016 }
8017
8018 static int
8019 api_bond_detach_slave (vat_main_t * vam)
8020 {
8021   unformat_input_t *i = vam->input;
8022   vl_api_bond_detach_slave_t *mp;
8023   u32 sw_if_index = ~0;
8024   u8 sw_if_index_set = 0;
8025   int ret;
8026
8027   /* Parse args required to build the message */
8028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8029     {
8030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8031         sw_if_index_set = 1;
8032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8033         sw_if_index_set = 1;
8034       else
8035         break;
8036     }
8037
8038   if (sw_if_index_set == 0)
8039     {
8040       errmsg ("missing vpp interface name. ");
8041       return -99;
8042     }
8043
8044   /* Construct the API message */
8045   M (BOND_DETACH_SLAVE, mp);
8046
8047   mp->sw_if_index = ntohl (sw_if_index);
8048
8049   /* send it... */
8050   S (mp);
8051
8052   /* Wait for a reply... */
8053   W (ret);
8054   return ret;
8055 }
8056
8057 static int
8058 api_ip_table_add_del (vat_main_t * vam)
8059 {
8060   unformat_input_t *i = vam->input;
8061   vl_api_ip_table_add_del_t *mp;
8062   u32 table_id = ~0;
8063   u8 is_ipv6 = 0;
8064   u8 is_add = 1;
8065   int ret = 0;
8066
8067   /* Parse args required to build the message */
8068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8069     {
8070       if (unformat (i, "ipv6"))
8071         is_ipv6 = 1;
8072       else if (unformat (i, "del"))
8073         is_add = 0;
8074       else if (unformat (i, "add"))
8075         is_add = 1;
8076       else if (unformat (i, "table %d", &table_id))
8077         ;
8078       else
8079         {
8080           clib_warning ("parse error '%U'", format_unformat_error, i);
8081           return -99;
8082         }
8083     }
8084
8085   if (~0 == table_id)
8086     {
8087       errmsg ("missing table-ID");
8088       return -99;
8089     }
8090
8091   /* Construct the API message */
8092   M (IP_TABLE_ADD_DEL, mp);
8093
8094   mp->table_id = ntohl (table_id);
8095   mp->is_ipv6 = is_ipv6;
8096   mp->is_add = is_add;
8097
8098   /* send it... */
8099   S (mp);
8100
8101   /* Wait for a reply... */
8102   W (ret);
8103
8104   return ret;
8105 }
8106
8107 static int
8108 api_ip_add_del_route (vat_main_t * vam)
8109 {
8110   unformat_input_t *i = vam->input;
8111   vl_api_ip_add_del_route_t *mp;
8112   u32 sw_if_index = ~0, vrf_id = 0;
8113   u8 is_ipv6 = 0;
8114   u8 is_local = 0, is_drop = 0;
8115   u8 is_unreach = 0, is_prohibit = 0;
8116   u8 is_add = 1;
8117   u32 next_hop_weight = 1;
8118   u8 is_multipath = 0;
8119   u8 address_set = 0;
8120   u8 address_length_set = 0;
8121   u32 next_hop_table_id = 0;
8122   u32 resolve_attempts = 0;
8123   u32 dst_address_length = 0;
8124   u8 next_hop_set = 0;
8125   ip4_address_t v4_dst_address, v4_next_hop_address;
8126   ip6_address_t v6_dst_address, v6_next_hop_address;
8127   int count = 1;
8128   int j;
8129   f64 before = 0;
8130   u32 random_add_del = 0;
8131   u32 *random_vector = 0;
8132   uword *random_hash;
8133   u32 random_seed = 0xdeaddabe;
8134   u32 classify_table_index = ~0;
8135   u8 is_classify = 0;
8136   u8 resolve_host = 0, resolve_attached = 0;
8137   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8138   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8139   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8140
8141   clib_memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8142   clib_memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8143   /* Parse args required to build the message */
8144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8145     {
8146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8147         ;
8148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8149         ;
8150       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8151         {
8152           address_set = 1;
8153           is_ipv6 = 0;
8154         }
8155       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8156         {
8157           address_set = 1;
8158           is_ipv6 = 1;
8159         }
8160       else if (unformat (i, "/%d", &dst_address_length))
8161         {
8162           address_length_set = 1;
8163         }
8164
8165       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8166                                          &v4_next_hop_address))
8167         {
8168           next_hop_set = 1;
8169         }
8170       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8171                                          &v6_next_hop_address))
8172         {
8173           next_hop_set = 1;
8174         }
8175       else
8176         if (unformat
8177             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8178         {
8179           next_hop_set = 1;
8180         }
8181       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8182         {
8183           next_hop_set = 1;
8184         }
8185       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8186         ;
8187       else if (unformat (i, "weight %d", &next_hop_weight))
8188         ;
8189       else if (unformat (i, "drop"))
8190         {
8191           is_drop = 1;
8192         }
8193       else if (unformat (i, "null-send-unreach"))
8194         {
8195           is_unreach = 1;
8196         }
8197       else if (unformat (i, "null-send-prohibit"))
8198         {
8199           is_prohibit = 1;
8200         }
8201       else if (unformat (i, "local"))
8202         {
8203           is_local = 1;
8204         }
8205       else if (unformat (i, "classify %d", &classify_table_index))
8206         {
8207           is_classify = 1;
8208         }
8209       else if (unformat (i, "del"))
8210         is_add = 0;
8211       else if (unformat (i, "add"))
8212         is_add = 1;
8213       else if (unformat (i, "resolve-via-host"))
8214         resolve_host = 1;
8215       else if (unformat (i, "resolve-via-attached"))
8216         resolve_attached = 1;
8217       else if (unformat (i, "multipath"))
8218         is_multipath = 1;
8219       else if (unformat (i, "vrf %d", &vrf_id))
8220         ;
8221       else if (unformat (i, "count %d", &count))
8222         ;
8223       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8224         ;
8225       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8226         ;
8227       else if (unformat (i, "out-label %d", &next_hop_out_label))
8228         {
8229           vl_api_fib_mpls_label_t fib_label = {
8230             .label = ntohl (next_hop_out_label),
8231             .ttl = 64,
8232             .exp = 0,
8233           };
8234           vec_add1 (next_hop_out_label_stack, fib_label);
8235         }
8236       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8237         ;
8238       else if (unformat (i, "random"))
8239         random_add_del = 1;
8240       else if (unformat (i, "seed %d", &random_seed))
8241         ;
8242       else
8243         {
8244           clib_warning ("parse error '%U'", format_unformat_error, i);
8245           return -99;
8246         }
8247     }
8248
8249   if (!next_hop_set && !is_drop && !is_local &&
8250       !is_classify && !is_unreach && !is_prohibit &&
8251       MPLS_LABEL_INVALID == next_hop_via_label)
8252     {
8253       errmsg
8254         ("next hop / local / drop / unreach / prohibit / classify not set");
8255       return -99;
8256     }
8257
8258   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8259     {
8260       errmsg ("next hop and next-hop via label set");
8261       return -99;
8262     }
8263   if (address_set == 0)
8264     {
8265       errmsg ("missing addresses");
8266       return -99;
8267     }
8268
8269   if (address_length_set == 0)
8270     {
8271       errmsg ("missing address length");
8272       return -99;
8273     }
8274
8275   /* Generate a pile of unique, random routes */
8276   if (random_add_del)
8277     {
8278       u32 this_random_address;
8279       random_hash = hash_create (count, sizeof (uword));
8280
8281       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8282       for (j = 0; j <= count; j++)
8283         {
8284           do
8285             {
8286               this_random_address = random_u32 (&random_seed);
8287               this_random_address =
8288                 clib_host_to_net_u32 (this_random_address);
8289             }
8290           while (hash_get (random_hash, this_random_address));
8291           vec_add1 (random_vector, this_random_address);
8292           hash_set (random_hash, this_random_address, 1);
8293         }
8294       hash_free (random_hash);
8295       v4_dst_address.as_u32 = random_vector[0];
8296     }
8297
8298   if (count > 1)
8299     {
8300       /* Turn on async mode */
8301       vam->async_mode = 1;
8302       vam->async_errors = 0;
8303       before = vat_time_now (vam);
8304     }
8305
8306   for (j = 0; j < count; j++)
8307     {
8308       /* Construct the API message */
8309       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8310           vec_len (next_hop_out_label_stack));
8311
8312       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8313       mp->table_id = ntohl (vrf_id);
8314
8315       mp->is_add = is_add;
8316       mp->is_drop = is_drop;
8317       mp->is_unreach = is_unreach;
8318       mp->is_prohibit = is_prohibit;
8319       mp->is_ipv6 = is_ipv6;
8320       mp->is_local = is_local;
8321       mp->is_classify = is_classify;
8322       mp->is_multipath = is_multipath;
8323       mp->is_resolve_host = resolve_host;
8324       mp->is_resolve_attached = resolve_attached;
8325       mp->next_hop_weight = next_hop_weight;
8326       mp->next_hop_preference = 0;
8327       mp->dst_address_length = dst_address_length;
8328       mp->next_hop_table_id = ntohl (next_hop_table_id);
8329       mp->classify_table_index = ntohl (classify_table_index);
8330       mp->next_hop_via_label = ntohl (next_hop_via_label);
8331       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8332       if (0 != mp->next_hop_n_out_labels)
8333         {
8334           memcpy (mp->next_hop_out_label_stack,
8335                   next_hop_out_label_stack,
8336                   (vec_len (next_hop_out_label_stack) *
8337                    sizeof (vl_api_fib_mpls_label_t)));
8338           vec_free (next_hop_out_label_stack);
8339         }
8340
8341       if (is_ipv6)
8342         {
8343           clib_memcpy (mp->dst_address, &v6_dst_address,
8344                        sizeof (v6_dst_address));
8345           if (next_hop_set)
8346             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8347                          sizeof (v6_next_hop_address));
8348           increment_v6_address (&v6_dst_address);
8349         }
8350       else
8351         {
8352           clib_memcpy (mp->dst_address, &v4_dst_address,
8353                        sizeof (v4_dst_address));
8354           if (next_hop_set)
8355             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8356                          sizeof (v4_next_hop_address));
8357           if (random_add_del)
8358             v4_dst_address.as_u32 = random_vector[j + 1];
8359           else
8360             increment_v4_address (&v4_dst_address);
8361         }
8362       /* send it... */
8363       S (mp);
8364       /* If we receive SIGTERM, stop now... */
8365       if (vam->do_exit)
8366         break;
8367     }
8368
8369   /* When testing multiple add/del ops, use a control-ping to sync */
8370   if (count > 1)
8371     {
8372       vl_api_control_ping_t *mp_ping;
8373       f64 after;
8374       f64 timeout;
8375
8376       /* Shut off async mode */
8377       vam->async_mode = 0;
8378
8379       MPING (CONTROL_PING, mp_ping);
8380       S (mp_ping);
8381
8382       timeout = vat_time_now (vam) + 1.0;
8383       while (vat_time_now (vam) < timeout)
8384         if (vam->result_ready == 1)
8385           goto out;
8386       vam->retval = -99;
8387
8388     out:
8389       if (vam->retval == -99)
8390         errmsg ("timeout");
8391
8392       if (vam->async_errors > 0)
8393         {
8394           errmsg ("%d asynchronous errors", vam->async_errors);
8395           vam->retval = -98;
8396         }
8397       vam->async_errors = 0;
8398       after = vat_time_now (vam);
8399
8400       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8401       if (j > 0)
8402         count = j;
8403
8404       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8405              count, after - before, count / (after - before));
8406     }
8407   else
8408     {
8409       int ret;
8410
8411       /* Wait for a reply... */
8412       W (ret);
8413       return ret;
8414     }
8415
8416   /* Return the good/bad news */
8417   return (vam->retval);
8418 }
8419
8420 static int
8421 api_ip_mroute_add_del (vat_main_t * vam)
8422 {
8423   unformat_input_t *i = vam->input;
8424   vl_api_ip_mroute_add_del_t *mp;
8425   u32 sw_if_index = ~0, vrf_id = 0;
8426   u8 is_ipv6 = 0;
8427   u8 is_local = 0;
8428   u8 is_add = 1;
8429   u8 address_set = 0;
8430   u32 grp_address_length = 0;
8431   ip4_address_t v4_grp_address, v4_src_address;
8432   ip6_address_t v6_grp_address, v6_src_address;
8433   mfib_itf_flags_t iflags = 0;
8434   mfib_entry_flags_t eflags = 0;
8435   int ret;
8436
8437   /* Parse args required to build the message */
8438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8439     {
8440       if (unformat (i, "sw_if_index %d", &sw_if_index))
8441         ;
8442       else if (unformat (i, "%U %U",
8443                          unformat_ip4_address, &v4_src_address,
8444                          unformat_ip4_address, &v4_grp_address))
8445         {
8446           grp_address_length = 64;
8447           address_set = 1;
8448           is_ipv6 = 0;
8449         }
8450       else if (unformat (i, "%U %U",
8451                          unformat_ip6_address, &v6_src_address,
8452                          unformat_ip6_address, &v6_grp_address))
8453         {
8454           grp_address_length = 256;
8455           address_set = 1;
8456           is_ipv6 = 1;
8457         }
8458       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8459         {
8460           clib_memset (&v4_src_address, 0, sizeof (v4_src_address));
8461           grp_address_length = 32;
8462           address_set = 1;
8463           is_ipv6 = 0;
8464         }
8465       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8466         {
8467           clib_memset (&v6_src_address, 0, sizeof (v6_src_address));
8468           grp_address_length = 128;
8469           address_set = 1;
8470           is_ipv6 = 1;
8471         }
8472       else if (unformat (i, "/%d", &grp_address_length))
8473         ;
8474       else if (unformat (i, "local"))
8475         {
8476           is_local = 1;
8477         }
8478       else if (unformat (i, "del"))
8479         is_add = 0;
8480       else if (unformat (i, "add"))
8481         is_add = 1;
8482       else if (unformat (i, "vrf %d", &vrf_id))
8483         ;
8484       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8485         ;
8486       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8487         ;
8488       else
8489         {
8490           clib_warning ("parse error '%U'", format_unformat_error, i);
8491           return -99;
8492         }
8493     }
8494
8495   if (address_set == 0)
8496     {
8497       errmsg ("missing addresses\n");
8498       return -99;
8499     }
8500
8501   /* Construct the API message */
8502   M (IP_MROUTE_ADD_DEL, mp);
8503
8504   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8505   mp->table_id = ntohl (vrf_id);
8506
8507   mp->is_add = is_add;
8508   mp->is_ipv6 = is_ipv6;
8509   mp->is_local = is_local;
8510   mp->itf_flags = ntohl (iflags);
8511   mp->entry_flags = ntohl (eflags);
8512   mp->grp_address_length = grp_address_length;
8513   mp->grp_address_length = ntohs (mp->grp_address_length);
8514
8515   if (is_ipv6)
8516     {
8517       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8518       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8519     }
8520   else
8521     {
8522       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8523       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8524
8525     }
8526
8527   /* send it... */
8528   S (mp);
8529   /* Wait for a reply... */
8530   W (ret);
8531   return ret;
8532 }
8533
8534 static int
8535 api_mpls_table_add_del (vat_main_t * vam)
8536 {
8537   unformat_input_t *i = vam->input;
8538   vl_api_mpls_table_add_del_t *mp;
8539   u32 table_id = ~0;
8540   u8 is_add = 1;
8541   int ret = 0;
8542
8543   /* Parse args required to build the message */
8544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8545     {
8546       if (unformat (i, "table %d", &table_id))
8547         ;
8548       else if (unformat (i, "del"))
8549         is_add = 0;
8550       else if (unformat (i, "add"))
8551         is_add = 1;
8552       else
8553         {
8554           clib_warning ("parse error '%U'", format_unformat_error, i);
8555           return -99;
8556         }
8557     }
8558
8559   if (~0 == table_id)
8560     {
8561       errmsg ("missing table-ID");
8562       return -99;
8563     }
8564
8565   /* Construct the API message */
8566   M (MPLS_TABLE_ADD_DEL, mp);
8567
8568   mp->mt_table_id = ntohl (table_id);
8569   mp->mt_is_add = is_add;
8570
8571   /* send it... */
8572   S (mp);
8573
8574   /* Wait for a reply... */
8575   W (ret);
8576
8577   return ret;
8578 }
8579
8580 static int
8581 api_mpls_route_add_del (vat_main_t * vam)
8582 {
8583   unformat_input_t *i = vam->input;
8584   vl_api_mpls_route_add_del_t *mp;
8585   u32 sw_if_index = ~0, table_id = 0;
8586   u8 is_add = 1;
8587   u32 next_hop_weight = 1;
8588   u8 is_multipath = 0;
8589   u32 next_hop_table_id = 0;
8590   u8 next_hop_set = 0;
8591   ip4_address_t v4_next_hop_address = {
8592     .as_u32 = 0,
8593   };
8594   ip6_address_t v6_next_hop_address = { {0} };
8595   int count = 1;
8596   int j;
8597   f64 before = 0;
8598   u32 classify_table_index = ~0;
8599   u8 is_classify = 0;
8600   u8 resolve_host = 0, resolve_attached = 0;
8601   u8 is_interface_rx = 0;
8602   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8603   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8604   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8605   mpls_label_t local_label = MPLS_LABEL_INVALID;
8606   u8 is_eos = 0;
8607   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8608
8609   /* Parse args required to build the message */
8610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8611     {
8612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8613         ;
8614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8615         ;
8616       else if (unformat (i, "%d", &local_label))
8617         ;
8618       else if (unformat (i, "eos"))
8619         is_eos = 1;
8620       else if (unformat (i, "non-eos"))
8621         is_eos = 0;
8622       else if (unformat (i, "via %U", unformat_ip4_address,
8623                          &v4_next_hop_address))
8624         {
8625           next_hop_set = 1;
8626           next_hop_proto = DPO_PROTO_IP4;
8627         }
8628       else if (unformat (i, "via %U", unformat_ip6_address,
8629                          &v6_next_hop_address))
8630         {
8631           next_hop_set = 1;
8632           next_hop_proto = DPO_PROTO_IP6;
8633         }
8634       else if (unformat (i, "weight %d", &next_hop_weight))
8635         ;
8636       else if (unformat (i, "classify %d", &classify_table_index))
8637         {
8638           is_classify = 1;
8639         }
8640       else if (unformat (i, "del"))
8641         is_add = 0;
8642       else if (unformat (i, "add"))
8643         is_add = 1;
8644       else if (unformat (i, "resolve-via-host"))
8645         resolve_host = 1;
8646       else if (unformat (i, "resolve-via-attached"))
8647         resolve_attached = 1;
8648       else if (unformat (i, "multipath"))
8649         is_multipath = 1;
8650       else if (unformat (i, "count %d", &count))
8651         ;
8652       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8653         {
8654           next_hop_set = 1;
8655           next_hop_proto = DPO_PROTO_IP4;
8656         }
8657       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8658         {
8659           next_hop_set = 1;
8660           next_hop_proto = DPO_PROTO_IP6;
8661         }
8662       else
8663         if (unformat
8664             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
8665              &sw_if_index))
8666         {
8667           next_hop_set = 1;
8668           next_hop_proto = DPO_PROTO_ETHERNET;
8669           is_interface_rx = 1;
8670         }
8671       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
8672         {
8673           next_hop_set = 1;
8674           next_hop_proto = DPO_PROTO_ETHERNET;
8675           is_interface_rx = 1;
8676         }
8677       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
8678         next_hop_set = 1;
8679       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8680         next_hop_set = 1;
8681       else if (unformat (i, "out-label %d", &next_hop_out_label))
8682         {
8683           vl_api_fib_mpls_label_t fib_label = {
8684             .label = ntohl (next_hop_out_label),
8685             .ttl = 64,
8686             .exp = 0,
8687           };
8688           vec_add1 (next_hop_out_label_stack, fib_label);
8689         }
8690       else
8691         {
8692           clib_warning ("parse error '%U'", format_unformat_error, i);
8693           return -99;
8694         }
8695     }
8696
8697   if (!next_hop_set && !is_classify)
8698     {
8699       errmsg ("next hop / classify not set");
8700       return -99;
8701     }
8702
8703   if (MPLS_LABEL_INVALID == local_label)
8704     {
8705       errmsg ("missing label");
8706       return -99;
8707     }
8708
8709   if (count > 1)
8710     {
8711       /* Turn on async mode */
8712       vam->async_mode = 1;
8713       vam->async_errors = 0;
8714       before = vat_time_now (vam);
8715     }
8716
8717   for (j = 0; j < count; j++)
8718     {
8719       /* Construct the API message */
8720       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
8721           vec_len (next_hop_out_label_stack));
8722
8723       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8724       mp->mr_table_id = ntohl (table_id);
8725
8726       mp->mr_is_add = is_add;
8727       mp->mr_next_hop_proto = next_hop_proto;
8728       mp->mr_is_classify = is_classify;
8729       mp->mr_is_multipath = is_multipath;
8730       mp->mr_is_resolve_host = resolve_host;
8731       mp->mr_is_resolve_attached = resolve_attached;
8732       mp->mr_is_interface_rx = is_interface_rx;
8733       mp->mr_next_hop_weight = next_hop_weight;
8734       mp->mr_next_hop_preference = 0;
8735       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8736       mp->mr_classify_table_index = ntohl (classify_table_index);
8737       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8738       mp->mr_label = ntohl (local_label);
8739       mp->mr_eos = is_eos;
8740
8741       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8742       if (0 != mp->mr_next_hop_n_out_labels)
8743         {
8744           memcpy (mp->mr_next_hop_out_label_stack,
8745                   next_hop_out_label_stack,
8746                   vec_len (next_hop_out_label_stack) *
8747                   sizeof (vl_api_fib_mpls_label_t));
8748           vec_free (next_hop_out_label_stack);
8749         }
8750
8751       if (next_hop_set)
8752         {
8753           if (DPO_PROTO_IP4 == next_hop_proto)
8754             {
8755               clib_memcpy (mp->mr_next_hop,
8756                            &v4_next_hop_address,
8757                            sizeof (v4_next_hop_address));
8758             }
8759           else if (DPO_PROTO_IP6 == next_hop_proto)
8760
8761             {
8762               clib_memcpy (mp->mr_next_hop,
8763                            &v6_next_hop_address,
8764                            sizeof (v6_next_hop_address));
8765             }
8766         }
8767       local_label++;
8768
8769       /* send it... */
8770       S (mp);
8771       /* If we receive SIGTERM, stop now... */
8772       if (vam->do_exit)
8773         break;
8774     }
8775
8776   /* When testing multiple add/del ops, use a control-ping to sync */
8777   if (count > 1)
8778     {
8779       vl_api_control_ping_t *mp_ping;
8780       f64 after;
8781       f64 timeout;
8782
8783       /* Shut off async mode */
8784       vam->async_mode = 0;
8785
8786       MPING (CONTROL_PING, mp_ping);
8787       S (mp_ping);
8788
8789       timeout = vat_time_now (vam) + 1.0;
8790       while (vat_time_now (vam) < timeout)
8791         if (vam->result_ready == 1)
8792           goto out;
8793       vam->retval = -99;
8794
8795     out:
8796       if (vam->retval == -99)
8797         errmsg ("timeout");
8798
8799       if (vam->async_errors > 0)
8800         {
8801           errmsg ("%d asynchronous errors", vam->async_errors);
8802           vam->retval = -98;
8803         }
8804       vam->async_errors = 0;
8805       after = vat_time_now (vam);
8806
8807       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8808       if (j > 0)
8809         count = j;
8810
8811       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8812              count, after - before, count / (after - before));
8813     }
8814   else
8815     {
8816       int ret;
8817
8818       /* Wait for a reply... */
8819       W (ret);
8820       return ret;
8821     }
8822
8823   /* Return the good/bad news */
8824   return (vam->retval);
8825 }
8826
8827 static int
8828 api_mpls_ip_bind_unbind (vat_main_t * vam)
8829 {
8830   unformat_input_t *i = vam->input;
8831   vl_api_mpls_ip_bind_unbind_t *mp;
8832   u32 ip_table_id = 0;
8833   u8 is_bind = 1;
8834   u8 is_ip4 = 1;
8835   ip4_address_t v4_address;
8836   ip6_address_t v6_address;
8837   u32 address_length;
8838   u8 address_set = 0;
8839   mpls_label_t local_label = MPLS_LABEL_INVALID;
8840   int ret;
8841
8842   /* Parse args required to build the message */
8843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8844     {
8845       if (unformat (i, "%U/%d", unformat_ip4_address,
8846                     &v4_address, &address_length))
8847         {
8848           is_ip4 = 1;
8849           address_set = 1;
8850         }
8851       else if (unformat (i, "%U/%d", unformat_ip6_address,
8852                          &v6_address, &address_length))
8853         {
8854           is_ip4 = 0;
8855           address_set = 1;
8856         }
8857       else if (unformat (i, "%d", &local_label))
8858         ;
8859       else if (unformat (i, "table-id %d", &ip_table_id))
8860         ;
8861       else if (unformat (i, "unbind"))
8862         is_bind = 0;
8863       else if (unformat (i, "bind"))
8864         is_bind = 1;
8865       else
8866         {
8867           clib_warning ("parse error '%U'", format_unformat_error, i);
8868           return -99;
8869         }
8870     }
8871
8872   if (!address_set)
8873     {
8874       errmsg ("IP address not set");
8875       return -99;
8876     }
8877
8878   if (MPLS_LABEL_INVALID == local_label)
8879     {
8880       errmsg ("missing label");
8881       return -99;
8882     }
8883
8884   /* Construct the API message */
8885   M (MPLS_IP_BIND_UNBIND, mp);
8886
8887   mp->mb_is_bind = is_bind;
8888   mp->mb_is_ip4 = is_ip4;
8889   mp->mb_ip_table_id = ntohl (ip_table_id);
8890   mp->mb_mpls_table_id = 0;
8891   mp->mb_label = ntohl (local_label);
8892   mp->mb_address_length = address_length;
8893
8894   if (is_ip4)
8895     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8896   else
8897     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8898
8899   /* send it... */
8900   S (mp);
8901
8902   /* Wait for a reply... */
8903   W (ret);
8904   return ret;
8905 }
8906
8907 static int
8908 api_sr_mpls_policy_add (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_sr_mpls_policy_add_t *mp;
8912   u32 bsid = 0;
8913   u32 weight = 1;
8914   u8 type = 0;
8915   u8 n_segments = 0;
8916   u32 sid;
8917   u32 *segments = NULL;
8918   int ret;
8919
8920   /* Parse args required to build the message */
8921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8922     {
8923       if (unformat (i, "bsid %d", &bsid))
8924         ;
8925       else if (unformat (i, "weight %d", &weight))
8926         ;
8927       else if (unformat (i, "spray"))
8928         type = 1;
8929       else if (unformat (i, "next %d", &sid))
8930         {
8931           n_segments += 1;
8932           vec_add1 (segments, htonl (sid));
8933         }
8934       else
8935         {
8936           clib_warning ("parse error '%U'", format_unformat_error, i);
8937           return -99;
8938         }
8939     }
8940
8941   if (bsid == 0)
8942     {
8943       errmsg ("bsid not set");
8944       return -99;
8945     }
8946
8947   if (n_segments == 0)
8948     {
8949       errmsg ("no sid in segment stack");
8950       return -99;
8951     }
8952
8953   /* Construct the API message */
8954   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8955
8956   mp->bsid = htonl (bsid);
8957   mp->weight = htonl (weight);
8958   mp->type = type;
8959   mp->n_segments = n_segments;
8960   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8961   vec_free (segments);
8962
8963   /* send it... */
8964   S (mp);
8965
8966   /* Wait for a reply... */
8967   W (ret);
8968   return ret;
8969 }
8970
8971 static int
8972 api_sr_mpls_policy_del (vat_main_t * vam)
8973 {
8974   unformat_input_t *i = vam->input;
8975   vl_api_sr_mpls_policy_del_t *mp;
8976   u32 bsid = 0;
8977   int ret;
8978
8979   /* Parse args required to build the message */
8980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (i, "bsid %d", &bsid))
8983         ;
8984       else
8985         {
8986           clib_warning ("parse error '%U'", format_unformat_error, i);
8987           return -99;
8988         }
8989     }
8990
8991   if (bsid == 0)
8992     {
8993       errmsg ("bsid not set");
8994       return -99;
8995     }
8996
8997   /* Construct the API message */
8998   M (SR_MPLS_POLICY_DEL, mp);
8999
9000   mp->bsid = htonl (bsid);
9001
9002   /* send it... */
9003   S (mp);
9004
9005   /* Wait for a reply... */
9006   W (ret);
9007   return ret;
9008 }
9009
9010 static int
9011 api_bier_table_add_del (vat_main_t * vam)
9012 {
9013   unformat_input_t *i = vam->input;
9014   vl_api_bier_table_add_del_t *mp;
9015   u8 is_add = 1;
9016   u32 set = 0, sub_domain = 0, hdr_len = 3;
9017   mpls_label_t local_label = MPLS_LABEL_INVALID;
9018   int ret;
9019
9020   /* Parse args required to build the message */
9021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9022     {
9023       if (unformat (i, "sub-domain %d", &sub_domain))
9024         ;
9025       else if (unformat (i, "set %d", &set))
9026         ;
9027       else if (unformat (i, "label %d", &local_label))
9028         ;
9029       else if (unformat (i, "hdr-len %d", &hdr_len))
9030         ;
9031       else if (unformat (i, "add"))
9032         is_add = 1;
9033       else if (unformat (i, "del"))
9034         is_add = 0;
9035       else
9036         {
9037           clib_warning ("parse error '%U'", format_unformat_error, i);
9038           return -99;
9039         }
9040     }
9041
9042   if (MPLS_LABEL_INVALID == local_label)
9043     {
9044       errmsg ("missing label\n");
9045       return -99;
9046     }
9047
9048   /* Construct the API message */
9049   M (BIER_TABLE_ADD_DEL, mp);
9050
9051   mp->bt_is_add = is_add;
9052   mp->bt_label = ntohl (local_label);
9053   mp->bt_tbl_id.bt_set = set;
9054   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9055   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9056
9057   /* send it... */
9058   S (mp);
9059
9060   /* Wait for a reply... */
9061   W (ret);
9062
9063   return (ret);
9064 }
9065
9066 static int
9067 api_bier_route_add_del (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_bier_route_add_del_t *mp;
9071   u8 is_add = 1;
9072   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9073   ip4_address_t v4_next_hop_address;
9074   ip6_address_t v6_next_hop_address;
9075   u8 next_hop_set = 0;
9076   u8 next_hop_proto_is_ip4 = 1;
9077   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9078   int ret;
9079
9080   /* Parse args required to build the message */
9081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9082     {
9083       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9084         {
9085           next_hop_proto_is_ip4 = 1;
9086           next_hop_set = 1;
9087         }
9088       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9089         {
9090           next_hop_proto_is_ip4 = 0;
9091           next_hop_set = 1;
9092         }
9093       if (unformat (i, "sub-domain %d", &sub_domain))
9094         ;
9095       else if (unformat (i, "set %d", &set))
9096         ;
9097       else if (unformat (i, "hdr-len %d", &hdr_len))
9098         ;
9099       else if (unformat (i, "bp %d", &bp))
9100         ;
9101       else if (unformat (i, "add"))
9102         is_add = 1;
9103       else if (unformat (i, "del"))
9104         is_add = 0;
9105       else if (unformat (i, "out-label %d", &next_hop_out_label))
9106         ;
9107       else
9108         {
9109           clib_warning ("parse error '%U'", format_unformat_error, i);
9110           return -99;
9111         }
9112     }
9113
9114   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9115     {
9116       errmsg ("next hop / label set\n");
9117       return -99;
9118     }
9119   if (0 == bp)
9120     {
9121       errmsg ("bit=position not set\n");
9122       return -99;
9123     }
9124
9125   /* Construct the API message */
9126   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9127
9128   mp->br_is_add = is_add;
9129   mp->br_tbl_id.bt_set = set;
9130   mp->br_tbl_id.bt_sub_domain = sub_domain;
9131   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9132   mp->br_bp = ntohs (bp);
9133   mp->br_n_paths = 1;
9134   mp->br_paths[0].n_labels = 1;
9135   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9136   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9137
9138   if (next_hop_proto_is_ip4)
9139     {
9140       clib_memcpy (mp->br_paths[0].next_hop,
9141                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9142     }
9143   else
9144     {
9145       clib_memcpy (mp->br_paths[0].next_hop,
9146                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9147     }
9148
9149   /* send it... */
9150   S (mp);
9151
9152   /* Wait for a reply... */
9153   W (ret);
9154
9155   return (ret);
9156 }
9157
9158 static int
9159 api_proxy_arp_add_del (vat_main_t * vam)
9160 {
9161   unformat_input_t *i = vam->input;
9162   vl_api_proxy_arp_add_del_t *mp;
9163   u32 vrf_id = 0;
9164   u8 is_add = 1;
9165   ip4_address_t lo, hi;
9166   u8 range_set = 0;
9167   int ret;
9168
9169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9170     {
9171       if (unformat (i, "vrf %d", &vrf_id))
9172         ;
9173       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9174                          unformat_ip4_address, &hi))
9175         range_set = 1;
9176       else if (unformat (i, "del"))
9177         is_add = 0;
9178       else
9179         {
9180           clib_warning ("parse error '%U'", format_unformat_error, i);
9181           return -99;
9182         }
9183     }
9184
9185   if (range_set == 0)
9186     {
9187       errmsg ("address range not set");
9188       return -99;
9189     }
9190
9191   M (PROXY_ARP_ADD_DEL, mp);
9192
9193   mp->proxy.vrf_id = ntohl (vrf_id);
9194   mp->is_add = is_add;
9195   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9196   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9197
9198   S (mp);
9199   W (ret);
9200   return ret;
9201 }
9202
9203 static int
9204 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9205 {
9206   unformat_input_t *i = vam->input;
9207   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9208   u32 sw_if_index;
9209   u8 enable = 1;
9210   u8 sw_if_index_set = 0;
9211   int ret;
9212
9213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9214     {
9215       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9216         sw_if_index_set = 1;
9217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9218         sw_if_index_set = 1;
9219       else if (unformat (i, "enable"))
9220         enable = 1;
9221       else if (unformat (i, "disable"))
9222         enable = 0;
9223       else
9224         {
9225           clib_warning ("parse error '%U'", format_unformat_error, i);
9226           return -99;
9227         }
9228     }
9229
9230   if (sw_if_index_set == 0)
9231     {
9232       errmsg ("missing interface name or sw_if_index");
9233       return -99;
9234     }
9235
9236   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9237
9238   mp->sw_if_index = ntohl (sw_if_index);
9239   mp->enable_disable = enable;
9240
9241   S (mp);
9242   W (ret);
9243   return ret;
9244 }
9245
9246 static int
9247 api_mpls_tunnel_add_del (vat_main_t * vam)
9248 {
9249   unformat_input_t *i = vam->input;
9250   vl_api_mpls_tunnel_add_del_t *mp;
9251
9252   u8 is_add = 1;
9253   u8 l2_only = 0;
9254   u32 sw_if_index = ~0;
9255   u32 next_hop_sw_if_index = ~0;
9256   u32 next_hop_proto_is_ip4 = 1;
9257
9258   u32 next_hop_table_id = 0;
9259   ip4_address_t v4_next_hop_address = {
9260     .as_u32 = 0,
9261   };
9262   ip6_address_t v6_next_hop_address = { {0} };
9263   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9264   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9265   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9266   int ret;
9267
9268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9269     {
9270       if (unformat (i, "add"))
9271         is_add = 1;
9272       else
9273         if (unformat
9274             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
9275         is_add = 0;
9276       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9277         is_add = 0;
9278       else if (unformat (i, "via %U",
9279                          unformat_ip4_address, &v4_next_hop_address))
9280         {
9281           next_hop_proto_is_ip4 = 1;
9282         }
9283       else if (unformat (i, "via %U",
9284                          unformat_ip6_address, &v6_next_hop_address))
9285         {
9286           next_hop_proto_is_ip4 = 0;
9287         }
9288       else if (unformat (i, "via-label %d", &next_hop_via_label))
9289         ;
9290       else
9291         if (unformat
9292             (i, "%U", api_unformat_sw_if_index, vam, &next_hop_sw_if_index))
9293         ;
9294       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9295         ;
9296       else if (unformat (i, "l2-only"))
9297         l2_only = 1;
9298       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9299         ;
9300       else if (unformat (i, "out-label %d", &next_hop_out_label))
9301         {
9302           vl_api_fib_mpls_label_t fib_label = {
9303             .label = ntohl (next_hop_out_label),
9304             .ttl = 64,
9305             .exp = 0,
9306           };
9307           vec_add1 (next_hop_out_label_stack, fib_label);
9308         }
9309       else
9310         {
9311           clib_warning ("parse error '%U'", format_unformat_error, i);
9312           return -99;
9313         }
9314     }
9315
9316   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9317       vec_len (next_hop_out_label_stack));
9318
9319   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9320   mp->mt_sw_if_index = ntohl (sw_if_index);
9321   mp->mt_is_add = is_add;
9322   mp->mt_l2_only = l2_only;
9323   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9324   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9325   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9326   mp->mt_next_hop_weight = 1;
9327   mp->mt_next_hop_preference = 0;
9328
9329   mp->mt_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9330
9331   if (0 != mp->mt_next_hop_n_out_labels)
9332     {
9333       clib_memcpy (mp->mt_next_hop_out_label_stack,
9334                    next_hop_out_label_stack,
9335                    (vec_len (next_hop_out_label_stack) *
9336                     sizeof (vl_api_fib_mpls_label_t)));
9337       vec_free (next_hop_out_label_stack);
9338     }
9339
9340   if (next_hop_proto_is_ip4)
9341     {
9342       clib_memcpy (mp->mt_next_hop,
9343                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9344     }
9345   else
9346     {
9347       clib_memcpy (mp->mt_next_hop,
9348                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9349     }
9350
9351   S (mp);
9352   W (ret);
9353   return ret;
9354 }
9355
9356 static int
9357 api_sw_interface_set_unnumbered (vat_main_t * vam)
9358 {
9359   unformat_input_t *i = vam->input;
9360   vl_api_sw_interface_set_unnumbered_t *mp;
9361   u32 sw_if_index;
9362   u32 unnum_sw_index = ~0;
9363   u8 is_add = 1;
9364   u8 sw_if_index_set = 0;
9365   int ret;
9366
9367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9368     {
9369       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9370         sw_if_index_set = 1;
9371       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9372         sw_if_index_set = 1;
9373       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9374         ;
9375       else if (unformat (i, "del"))
9376         is_add = 0;
9377       else
9378         {
9379           clib_warning ("parse error '%U'", format_unformat_error, i);
9380           return -99;
9381         }
9382     }
9383
9384   if (sw_if_index_set == 0)
9385     {
9386       errmsg ("missing interface name or sw_if_index");
9387       return -99;
9388     }
9389
9390   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9391
9392   mp->sw_if_index = ntohl (sw_if_index);
9393   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9394   mp->is_add = is_add;
9395
9396   S (mp);
9397   W (ret);
9398   return ret;
9399 }
9400
9401 static int
9402 api_ip_neighbor_add_del (vat_main_t * vam)
9403 {
9404   unformat_input_t *i = vam->input;
9405   vl_api_ip_neighbor_add_del_t *mp;
9406   u32 sw_if_index;
9407   u8 sw_if_index_set = 0;
9408   u8 is_add = 1;
9409   u8 is_static = 0;
9410   u8 is_no_fib_entry = 0;
9411   u8 mac_address[6];
9412   u8 mac_set = 0;
9413   u8 v4_address_set = 0;
9414   u8 v6_address_set = 0;
9415   ip4_address_t v4address;
9416   ip6_address_t v6address;
9417   int ret;
9418
9419   clib_memset (mac_address, 0, sizeof (mac_address));
9420
9421   /* Parse args required to build the message */
9422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9423     {
9424       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9425         {
9426           mac_set = 1;
9427         }
9428       else if (unformat (i, "del"))
9429         is_add = 0;
9430       else
9431         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9432         sw_if_index_set = 1;
9433       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9434         sw_if_index_set = 1;
9435       else if (unformat (i, "is_static"))
9436         is_static = 1;
9437       else if (unformat (i, "no-fib-entry"))
9438         is_no_fib_entry = 1;
9439       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9440         v4_address_set = 1;
9441       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9442         v6_address_set = 1;
9443       else
9444         {
9445           clib_warning ("parse error '%U'", format_unformat_error, i);
9446           return -99;
9447         }
9448     }
9449
9450   if (sw_if_index_set == 0)
9451     {
9452       errmsg ("missing interface name or sw_if_index");
9453       return -99;
9454     }
9455   if (v4_address_set && v6_address_set)
9456     {
9457       errmsg ("both v4 and v6 addresses set");
9458       return -99;
9459     }
9460   if (!v4_address_set && !v6_address_set)
9461     {
9462       errmsg ("no address set");
9463       return -99;
9464     }
9465
9466   /* Construct the API message */
9467   M (IP_NEIGHBOR_ADD_DEL, mp);
9468
9469   mp->sw_if_index = ntohl (sw_if_index);
9470   mp->is_add = is_add;
9471   mp->is_static = is_static;
9472   mp->is_no_adj_fib = is_no_fib_entry;
9473   if (mac_set)
9474     clib_memcpy (mp->mac_address, mac_address, 6);
9475   if (v6_address_set)
9476     {
9477       mp->is_ipv6 = 1;
9478       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9479     }
9480   else
9481     {
9482       /* mp->is_ipv6 = 0; via clib_memset in M macro above */
9483       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9484     }
9485
9486   /* send it... */
9487   S (mp);
9488
9489   /* Wait for a reply, return good/bad news  */
9490   W (ret);
9491   return ret;
9492 }
9493
9494 static int
9495 api_create_vlan_subif (vat_main_t * vam)
9496 {
9497   unformat_input_t *i = vam->input;
9498   vl_api_create_vlan_subif_t *mp;
9499   u32 sw_if_index;
9500   u8 sw_if_index_set = 0;
9501   u32 vlan_id;
9502   u8 vlan_id_set = 0;
9503   int ret;
9504
9505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9506     {
9507       if (unformat (i, "sw_if_index %d", &sw_if_index))
9508         sw_if_index_set = 1;
9509       else
9510         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9511         sw_if_index_set = 1;
9512       else if (unformat (i, "vlan %d", &vlan_id))
9513         vlan_id_set = 1;
9514       else
9515         {
9516           clib_warning ("parse error '%U'", format_unformat_error, i);
9517           return -99;
9518         }
9519     }
9520
9521   if (sw_if_index_set == 0)
9522     {
9523       errmsg ("missing interface name or sw_if_index");
9524       return -99;
9525     }
9526
9527   if (vlan_id_set == 0)
9528     {
9529       errmsg ("missing vlan_id");
9530       return -99;
9531     }
9532   M (CREATE_VLAN_SUBIF, mp);
9533
9534   mp->sw_if_index = ntohl (sw_if_index);
9535   mp->vlan_id = ntohl (vlan_id);
9536
9537   S (mp);
9538   W (ret);
9539   return ret;
9540 }
9541
9542 #define foreach_create_subif_bit                \
9543 _(no_tags)                                      \
9544 _(one_tag)                                      \
9545 _(two_tags)                                     \
9546 _(dot1ad)                                       \
9547 _(exact_match)                                  \
9548 _(default_sub)                                  \
9549 _(outer_vlan_id_any)                            \
9550 _(inner_vlan_id_any)
9551
9552 static int
9553 api_create_subif (vat_main_t * vam)
9554 {
9555   unformat_input_t *i = vam->input;
9556   vl_api_create_subif_t *mp;
9557   u32 sw_if_index;
9558   u8 sw_if_index_set = 0;
9559   u32 sub_id;
9560   u8 sub_id_set = 0;
9561   u32 no_tags = 0;
9562   u32 one_tag = 0;
9563   u32 two_tags = 0;
9564   u32 dot1ad = 0;
9565   u32 exact_match = 0;
9566   u32 default_sub = 0;
9567   u32 outer_vlan_id_any = 0;
9568   u32 inner_vlan_id_any = 0;
9569   u32 tmp;
9570   u16 outer_vlan_id = 0;
9571   u16 inner_vlan_id = 0;
9572   int ret;
9573
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "sw_if_index %d", &sw_if_index))
9577         sw_if_index_set = 1;
9578       else
9579         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9580         sw_if_index_set = 1;
9581       else if (unformat (i, "sub_id %d", &sub_id))
9582         sub_id_set = 1;
9583       else if (unformat (i, "outer_vlan_id %d", &tmp))
9584         outer_vlan_id = tmp;
9585       else if (unformat (i, "inner_vlan_id %d", &tmp))
9586         inner_vlan_id = tmp;
9587
9588 #define _(a) else if (unformat (i, #a)) a = 1 ;
9589       foreach_create_subif_bit
9590 #undef _
9591         else
9592         {
9593           clib_warning ("parse error '%U'", format_unformat_error, i);
9594           return -99;
9595         }
9596     }
9597
9598   if (sw_if_index_set == 0)
9599     {
9600       errmsg ("missing interface name or sw_if_index");
9601       return -99;
9602     }
9603
9604   if (sub_id_set == 0)
9605     {
9606       errmsg ("missing sub_id");
9607       return -99;
9608     }
9609   M (CREATE_SUBIF, mp);
9610
9611   mp->sw_if_index = ntohl (sw_if_index);
9612   mp->sub_id = ntohl (sub_id);
9613
9614 #define _(a) mp->a = a;
9615   foreach_create_subif_bit;
9616 #undef _
9617
9618   mp->outer_vlan_id = ntohs (outer_vlan_id);
9619   mp->inner_vlan_id = ntohs (inner_vlan_id);
9620
9621   S (mp);
9622   W (ret);
9623   return ret;
9624 }
9625
9626 static int
9627 api_oam_add_del (vat_main_t * vam)
9628 {
9629   unformat_input_t *i = vam->input;
9630   vl_api_oam_add_del_t *mp;
9631   u32 vrf_id = 0;
9632   u8 is_add = 1;
9633   ip4_address_t src, dst;
9634   u8 src_set = 0;
9635   u8 dst_set = 0;
9636   int ret;
9637
9638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9639     {
9640       if (unformat (i, "vrf %d", &vrf_id))
9641         ;
9642       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9643         src_set = 1;
9644       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9645         dst_set = 1;
9646       else if (unformat (i, "del"))
9647         is_add = 0;
9648       else
9649         {
9650           clib_warning ("parse error '%U'", format_unformat_error, i);
9651           return -99;
9652         }
9653     }
9654
9655   if (src_set == 0)
9656     {
9657       errmsg ("missing src addr");
9658       return -99;
9659     }
9660
9661   if (dst_set == 0)
9662     {
9663       errmsg ("missing dst addr");
9664       return -99;
9665     }
9666
9667   M (OAM_ADD_DEL, mp);
9668
9669   mp->vrf_id = ntohl (vrf_id);
9670   mp->is_add = is_add;
9671   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9672   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9673
9674   S (mp);
9675   W (ret);
9676   return ret;
9677 }
9678
9679 static int
9680 api_reset_fib (vat_main_t * vam)
9681 {
9682   unformat_input_t *i = vam->input;
9683   vl_api_reset_fib_t *mp;
9684   u32 vrf_id = 0;
9685   u8 is_ipv6 = 0;
9686   u8 vrf_id_set = 0;
9687
9688   int ret;
9689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9690     {
9691       if (unformat (i, "vrf %d", &vrf_id))
9692         vrf_id_set = 1;
9693       else if (unformat (i, "ipv6"))
9694         is_ipv6 = 1;
9695       else
9696         {
9697           clib_warning ("parse error '%U'", format_unformat_error, i);
9698           return -99;
9699         }
9700     }
9701
9702   if (vrf_id_set == 0)
9703     {
9704       errmsg ("missing vrf id");
9705       return -99;
9706     }
9707
9708   M (RESET_FIB, mp);
9709
9710   mp->vrf_id = ntohl (vrf_id);
9711   mp->is_ipv6 = is_ipv6;
9712
9713   S (mp);
9714   W (ret);
9715   return ret;
9716 }
9717
9718 static int
9719 api_dhcp_proxy_config (vat_main_t * vam)
9720 {
9721   unformat_input_t *i = vam->input;
9722   vl_api_dhcp_proxy_config_t *mp;
9723   u32 rx_vrf_id = 0;
9724   u32 server_vrf_id = 0;
9725   u8 is_add = 1;
9726   u8 v4_address_set = 0;
9727   u8 v6_address_set = 0;
9728   ip4_address_t v4address;
9729   ip6_address_t v6address;
9730   u8 v4_src_address_set = 0;
9731   u8 v6_src_address_set = 0;
9732   ip4_address_t v4srcaddress;
9733   ip6_address_t v6srcaddress;
9734   int ret;
9735
9736   /* Parse args required to build the message */
9737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9738     {
9739       if (unformat (i, "del"))
9740         is_add = 0;
9741       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9742         ;
9743       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9744         ;
9745       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9746         v4_address_set = 1;
9747       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9748         v6_address_set = 1;
9749       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9750         v4_src_address_set = 1;
9751       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9752         v6_src_address_set = 1;
9753       else
9754         break;
9755     }
9756
9757   if (v4_address_set && v6_address_set)
9758     {
9759       errmsg ("both v4 and v6 server addresses set");
9760       return -99;
9761     }
9762   if (!v4_address_set && !v6_address_set)
9763     {
9764       errmsg ("no server addresses set");
9765       return -99;
9766     }
9767
9768   if (v4_src_address_set && v6_src_address_set)
9769     {
9770       errmsg ("both v4 and v6  src addresses set");
9771       return -99;
9772     }
9773   if (!v4_src_address_set && !v6_src_address_set)
9774     {
9775       errmsg ("no src addresses set");
9776       return -99;
9777     }
9778
9779   if (!(v4_src_address_set && v4_address_set) &&
9780       !(v6_src_address_set && v6_address_set))
9781     {
9782       errmsg ("no matching server and src addresses set");
9783       return -99;
9784     }
9785
9786   /* Construct the API message */
9787   M (DHCP_PROXY_CONFIG, mp);
9788
9789   mp->is_add = is_add;
9790   mp->rx_vrf_id = ntohl (rx_vrf_id);
9791   mp->server_vrf_id = ntohl (server_vrf_id);
9792   if (v6_address_set)
9793     {
9794       mp->is_ipv6 = 1;
9795       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9796       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9797     }
9798   else
9799     {
9800       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9801       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9802     }
9803
9804   /* send it... */
9805   S (mp);
9806
9807   /* Wait for a reply, return good/bad news  */
9808   W (ret);
9809   return ret;
9810 }
9811
9812 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9813 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9814
9815 static void
9816 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9817 {
9818   vat_main_t *vam = &vat_main;
9819   u32 i, count = mp->count;
9820   vl_api_dhcp_server_t *s;
9821
9822   if (mp->is_ipv6)
9823     print (vam->ofp,
9824            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9825            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9826            ntohl (mp->rx_vrf_id),
9827            format_ip6_address, mp->dhcp_src_address,
9828            mp->vss_type, mp->vss_vpn_ascii_id,
9829            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9830   else
9831     print (vam->ofp,
9832            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9833            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9834            ntohl (mp->rx_vrf_id),
9835            format_ip4_address, mp->dhcp_src_address,
9836            mp->vss_type, mp->vss_vpn_ascii_id,
9837            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9838
9839   for (i = 0; i < count; i++)
9840     {
9841       s = &mp->servers[i];
9842
9843       if (mp->is_ipv6)
9844         print (vam->ofp,
9845                " Server Table-ID %d, Server Address %U",
9846                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9847       else
9848         print (vam->ofp,
9849                " Server Table-ID %d, Server Address %U",
9850                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9851     }
9852 }
9853
9854 static void vl_api_dhcp_proxy_details_t_handler_json
9855   (vl_api_dhcp_proxy_details_t * mp)
9856 {
9857   vat_main_t *vam = &vat_main;
9858   vat_json_node_t *node = NULL;
9859   u32 i, count = mp->count;
9860   struct in_addr ip4;
9861   struct in6_addr ip6;
9862   vl_api_dhcp_server_t *s;
9863
9864   if (VAT_JSON_ARRAY != vam->json_tree.type)
9865     {
9866       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9867       vat_json_init_array (&vam->json_tree);
9868     }
9869   node = vat_json_array_add (&vam->json_tree);
9870
9871   vat_json_init_object (node);
9872   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9873   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
9874                              sizeof (mp->vss_type));
9875   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
9876                                    mp->vss_vpn_ascii_id);
9877   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9878   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9879
9880   if (mp->is_ipv6)
9881     {
9882       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9883       vat_json_object_add_ip6 (node, "src_address", ip6);
9884     }
9885   else
9886     {
9887       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9888       vat_json_object_add_ip4 (node, "src_address", ip4);
9889     }
9890
9891   for (i = 0; i < count; i++)
9892     {
9893       s = &mp->servers[i];
9894
9895       vat_json_object_add_uint (node, "server-table-id",
9896                                 ntohl (s->server_vrf_id));
9897
9898       if (mp->is_ipv6)
9899         {
9900           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9901           vat_json_object_add_ip4 (node, "src_address", ip4);
9902         }
9903       else
9904         {
9905           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9906           vat_json_object_add_ip6 (node, "server_address", ip6);
9907         }
9908     }
9909 }
9910
9911 static int
9912 api_dhcp_proxy_dump (vat_main_t * vam)
9913 {
9914   unformat_input_t *i = vam->input;
9915   vl_api_control_ping_t *mp_ping;
9916   vl_api_dhcp_proxy_dump_t *mp;
9917   u8 is_ipv6 = 0;
9918   int ret;
9919
9920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9921     {
9922       if (unformat (i, "ipv6"))
9923         is_ipv6 = 1;
9924       else
9925         {
9926           clib_warning ("parse error '%U'", format_unformat_error, i);
9927           return -99;
9928         }
9929     }
9930
9931   M (DHCP_PROXY_DUMP, mp);
9932
9933   mp->is_ip6 = is_ipv6;
9934   S (mp);
9935
9936   /* Use a control ping for synchronization */
9937   MPING (CONTROL_PING, mp_ping);
9938   S (mp_ping);
9939
9940   W (ret);
9941   return ret;
9942 }
9943
9944 static int
9945 api_dhcp_proxy_set_vss (vat_main_t * vam)
9946 {
9947   unformat_input_t *i = vam->input;
9948   vl_api_dhcp_proxy_set_vss_t *mp;
9949   u8 is_ipv6 = 0;
9950   u8 is_add = 1;
9951   u32 tbl_id = ~0;
9952   u8 vss_type = VSS_TYPE_DEFAULT;
9953   u8 *vpn_ascii_id = 0;
9954   u32 oui = 0;
9955   u32 fib_id = 0;
9956   int ret;
9957
9958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9959     {
9960       if (unformat (i, "tbl_id %d", &tbl_id))
9961         ;
9962       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
9963         vss_type = VSS_TYPE_ASCII;
9964       else if (unformat (i, "fib_id %d", &fib_id))
9965         vss_type = VSS_TYPE_VPN_ID;
9966       else if (unformat (i, "oui %d", &oui))
9967         vss_type = VSS_TYPE_VPN_ID;
9968       else if (unformat (i, "ipv6"))
9969         is_ipv6 = 1;
9970       else if (unformat (i, "del"))
9971         is_add = 0;
9972       else
9973         break;
9974     }
9975
9976   if (tbl_id == ~0)
9977     {
9978       errmsg ("missing tbl_id ");
9979       vec_free (vpn_ascii_id);
9980       return -99;
9981     }
9982
9983   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
9984     {
9985       errmsg ("vpn_ascii_id cannot be longer than 128 ");
9986       vec_free (vpn_ascii_id);
9987       return -99;
9988     }
9989
9990   M (DHCP_PROXY_SET_VSS, mp);
9991   mp->tbl_id = ntohl (tbl_id);
9992   mp->vss_type = vss_type;
9993   if (vpn_ascii_id)
9994     {
9995       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
9996       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
9997     }
9998   mp->vpn_index = ntohl (fib_id);
9999   mp->oui = ntohl (oui);
10000   mp->is_ipv6 = is_ipv6;
10001   mp->is_add = is_add;
10002
10003   S (mp);
10004   W (ret);
10005
10006   vec_free (vpn_ascii_id);
10007   return ret;
10008 }
10009
10010 static int
10011 api_dhcp_client_config (vat_main_t * vam)
10012 {
10013   unformat_input_t *i = vam->input;
10014   vl_api_dhcp_client_config_t *mp;
10015   u32 sw_if_index;
10016   u8 sw_if_index_set = 0;
10017   u8 is_add = 1;
10018   u8 *hostname = 0;
10019   u8 disable_event = 0;
10020   int ret;
10021
10022   /* Parse args required to build the message */
10023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10024     {
10025       if (unformat (i, "del"))
10026         is_add = 0;
10027       else
10028         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10029         sw_if_index_set = 1;
10030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10031         sw_if_index_set = 1;
10032       else if (unformat (i, "hostname %s", &hostname))
10033         ;
10034       else if (unformat (i, "disable_event"))
10035         disable_event = 1;
10036       else
10037         break;
10038     }
10039
10040   if (sw_if_index_set == 0)
10041     {
10042       errmsg ("missing interface name or sw_if_index");
10043       return -99;
10044     }
10045
10046   if (vec_len (hostname) > 63)
10047     {
10048       errmsg ("hostname too long");
10049     }
10050   vec_add1 (hostname, 0);
10051
10052   /* Construct the API message */
10053   M (DHCP_CLIENT_CONFIG, mp);
10054
10055   mp->is_add = is_add;
10056   mp->client.sw_if_index = htonl (sw_if_index);
10057   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10058   vec_free (hostname);
10059   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10060   mp->client.pid = htonl (getpid ());
10061
10062   /* send it... */
10063   S (mp);
10064
10065   /* Wait for a reply, return good/bad news  */
10066   W (ret);
10067   return ret;
10068 }
10069
10070 static int
10071 api_set_ip_flow_hash (vat_main_t * vam)
10072 {
10073   unformat_input_t *i = vam->input;
10074   vl_api_set_ip_flow_hash_t *mp;
10075   u32 vrf_id = 0;
10076   u8 is_ipv6 = 0;
10077   u8 vrf_id_set = 0;
10078   u8 src = 0;
10079   u8 dst = 0;
10080   u8 sport = 0;
10081   u8 dport = 0;
10082   u8 proto = 0;
10083   u8 reverse = 0;
10084   int ret;
10085
10086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10087     {
10088       if (unformat (i, "vrf %d", &vrf_id))
10089         vrf_id_set = 1;
10090       else if (unformat (i, "ipv6"))
10091         is_ipv6 = 1;
10092       else if (unformat (i, "src"))
10093         src = 1;
10094       else if (unformat (i, "dst"))
10095         dst = 1;
10096       else if (unformat (i, "sport"))
10097         sport = 1;
10098       else if (unformat (i, "dport"))
10099         dport = 1;
10100       else if (unformat (i, "proto"))
10101         proto = 1;
10102       else if (unformat (i, "reverse"))
10103         reverse = 1;
10104
10105       else
10106         {
10107           clib_warning ("parse error '%U'", format_unformat_error, i);
10108           return -99;
10109         }
10110     }
10111
10112   if (vrf_id_set == 0)
10113     {
10114       errmsg ("missing vrf id");
10115       return -99;
10116     }
10117
10118   M (SET_IP_FLOW_HASH, mp);
10119   mp->src = src;
10120   mp->dst = dst;
10121   mp->sport = sport;
10122   mp->dport = dport;
10123   mp->proto = proto;
10124   mp->reverse = reverse;
10125   mp->vrf_id = ntohl (vrf_id);
10126   mp->is_ipv6 = is_ipv6;
10127
10128   S (mp);
10129   W (ret);
10130   return ret;
10131 }
10132
10133 static int
10134 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10135 {
10136   unformat_input_t *i = vam->input;
10137   vl_api_sw_interface_ip6_enable_disable_t *mp;
10138   u32 sw_if_index;
10139   u8 sw_if_index_set = 0;
10140   u8 enable = 0;
10141   int ret;
10142
10143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10146         sw_if_index_set = 1;
10147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10148         sw_if_index_set = 1;
10149       else if (unformat (i, "enable"))
10150         enable = 1;
10151       else if (unformat (i, "disable"))
10152         enable = 0;
10153       else
10154         {
10155           clib_warning ("parse error '%U'", format_unformat_error, i);
10156           return -99;
10157         }
10158     }
10159
10160   if (sw_if_index_set == 0)
10161     {
10162       errmsg ("missing interface name or sw_if_index");
10163       return -99;
10164     }
10165
10166   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10167
10168   mp->sw_if_index = ntohl (sw_if_index);
10169   mp->enable = enable;
10170
10171   S (mp);
10172   W (ret);
10173   return ret;
10174 }
10175
10176 static int
10177 api_ip6nd_proxy_add_del (vat_main_t * vam)
10178 {
10179   unformat_input_t *i = vam->input;
10180   vl_api_ip6nd_proxy_add_del_t *mp;
10181   u32 sw_if_index = ~0;
10182   u8 v6_address_set = 0;
10183   ip6_address_t v6address;
10184   u8 is_del = 0;
10185   int ret;
10186
10187   /* Parse args required to build the message */
10188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10189     {
10190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10191         ;
10192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10193         ;
10194       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10195         v6_address_set = 1;
10196       if (unformat (i, "del"))
10197         is_del = 1;
10198       else
10199         {
10200           clib_warning ("parse error '%U'", format_unformat_error, i);
10201           return -99;
10202         }
10203     }
10204
10205   if (sw_if_index == ~0)
10206     {
10207       errmsg ("missing interface name or sw_if_index");
10208       return -99;
10209     }
10210   if (!v6_address_set)
10211     {
10212       errmsg ("no address set");
10213       return -99;
10214     }
10215
10216   /* Construct the API message */
10217   M (IP6ND_PROXY_ADD_DEL, mp);
10218
10219   mp->is_del = is_del;
10220   mp->sw_if_index = ntohl (sw_if_index);
10221   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10222
10223   /* send it... */
10224   S (mp);
10225
10226   /* Wait for a reply, return good/bad news  */
10227   W (ret);
10228   return ret;
10229 }
10230
10231 static int
10232 api_ip6nd_proxy_dump (vat_main_t * vam)
10233 {
10234   vl_api_ip6nd_proxy_dump_t *mp;
10235   vl_api_control_ping_t *mp_ping;
10236   int ret;
10237
10238   M (IP6ND_PROXY_DUMP, mp);
10239
10240   S (mp);
10241
10242   /* Use a control ping for synchronization */
10243   MPING (CONTROL_PING, mp_ping);
10244   S (mp_ping);
10245
10246   W (ret);
10247   return ret;
10248 }
10249
10250 static void vl_api_ip6nd_proxy_details_t_handler
10251   (vl_api_ip6nd_proxy_details_t * mp)
10252 {
10253   vat_main_t *vam = &vat_main;
10254
10255   print (vam->ofp, "host %U sw_if_index %d",
10256          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10257 }
10258
10259 static void vl_api_ip6nd_proxy_details_t_handler_json
10260   (vl_api_ip6nd_proxy_details_t * mp)
10261 {
10262   vat_main_t *vam = &vat_main;
10263   struct in6_addr ip6;
10264   vat_json_node_t *node = NULL;
10265
10266   if (VAT_JSON_ARRAY != vam->json_tree.type)
10267     {
10268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10269       vat_json_init_array (&vam->json_tree);
10270     }
10271   node = vat_json_array_add (&vam->json_tree);
10272
10273   vat_json_init_object (node);
10274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10275
10276   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10277   vat_json_object_add_ip6 (node, "host", ip6);
10278 }
10279
10280 static int
10281 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10282 {
10283   unformat_input_t *i = vam->input;
10284   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10285   u32 sw_if_index;
10286   u8 sw_if_index_set = 0;
10287   u32 address_length = 0;
10288   u8 v6_address_set = 0;
10289   ip6_address_t v6address;
10290   u8 use_default = 0;
10291   u8 no_advertise = 0;
10292   u8 off_link = 0;
10293   u8 no_autoconfig = 0;
10294   u8 no_onlink = 0;
10295   u8 is_no = 0;
10296   u32 val_lifetime = 0;
10297   u32 pref_lifetime = 0;
10298   int ret;
10299
10300   /* Parse args required to build the message */
10301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10302     {
10303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10304         sw_if_index_set = 1;
10305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10306         sw_if_index_set = 1;
10307       else if (unformat (i, "%U/%d",
10308                          unformat_ip6_address, &v6address, &address_length))
10309         v6_address_set = 1;
10310       else if (unformat (i, "val_life %d", &val_lifetime))
10311         ;
10312       else if (unformat (i, "pref_life %d", &pref_lifetime))
10313         ;
10314       else if (unformat (i, "def"))
10315         use_default = 1;
10316       else if (unformat (i, "noadv"))
10317         no_advertise = 1;
10318       else if (unformat (i, "offl"))
10319         off_link = 1;
10320       else if (unformat (i, "noauto"))
10321         no_autoconfig = 1;
10322       else if (unformat (i, "nolink"))
10323         no_onlink = 1;
10324       else if (unformat (i, "isno"))
10325         is_no = 1;
10326       else
10327         {
10328           clib_warning ("parse error '%U'", format_unformat_error, i);
10329           return -99;
10330         }
10331     }
10332
10333   if (sw_if_index_set == 0)
10334     {
10335       errmsg ("missing interface name or sw_if_index");
10336       return -99;
10337     }
10338   if (!v6_address_set)
10339     {
10340       errmsg ("no address set");
10341       return -99;
10342     }
10343
10344   /* Construct the API message */
10345   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10346
10347   mp->sw_if_index = ntohl (sw_if_index);
10348   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10349   mp->address_length = address_length;
10350   mp->use_default = use_default;
10351   mp->no_advertise = no_advertise;
10352   mp->off_link = off_link;
10353   mp->no_autoconfig = no_autoconfig;
10354   mp->no_onlink = no_onlink;
10355   mp->is_no = is_no;
10356   mp->val_lifetime = ntohl (val_lifetime);
10357   mp->pref_lifetime = ntohl (pref_lifetime);
10358
10359   /* send it... */
10360   S (mp);
10361
10362   /* Wait for a reply, return good/bad news  */
10363   W (ret);
10364   return ret;
10365 }
10366
10367 static int
10368 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10369 {
10370   unformat_input_t *i = vam->input;
10371   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10372   u32 sw_if_index;
10373   u8 sw_if_index_set = 0;
10374   u8 suppress = 0;
10375   u8 managed = 0;
10376   u8 other = 0;
10377   u8 ll_option = 0;
10378   u8 send_unicast = 0;
10379   u8 cease = 0;
10380   u8 is_no = 0;
10381   u8 default_router = 0;
10382   u32 max_interval = 0;
10383   u32 min_interval = 0;
10384   u32 lifetime = 0;
10385   u32 initial_count = 0;
10386   u32 initial_interval = 0;
10387   int ret;
10388
10389
10390   /* Parse args required to build the message */
10391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10392     {
10393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10394         sw_if_index_set = 1;
10395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10396         sw_if_index_set = 1;
10397       else if (unformat (i, "maxint %d", &max_interval))
10398         ;
10399       else if (unformat (i, "minint %d", &min_interval))
10400         ;
10401       else if (unformat (i, "life %d", &lifetime))
10402         ;
10403       else if (unformat (i, "count %d", &initial_count))
10404         ;
10405       else if (unformat (i, "interval %d", &initial_interval))
10406         ;
10407       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10408         suppress = 1;
10409       else if (unformat (i, "managed"))
10410         managed = 1;
10411       else if (unformat (i, "other"))
10412         other = 1;
10413       else if (unformat (i, "ll"))
10414         ll_option = 1;
10415       else if (unformat (i, "send"))
10416         send_unicast = 1;
10417       else if (unformat (i, "cease"))
10418         cease = 1;
10419       else if (unformat (i, "isno"))
10420         is_no = 1;
10421       else if (unformat (i, "def"))
10422         default_router = 1;
10423       else
10424         {
10425           clib_warning ("parse error '%U'", format_unformat_error, i);
10426           return -99;
10427         }
10428     }
10429
10430   if (sw_if_index_set == 0)
10431     {
10432       errmsg ("missing interface name or sw_if_index");
10433       return -99;
10434     }
10435
10436   /* Construct the API message */
10437   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10438
10439   mp->sw_if_index = ntohl (sw_if_index);
10440   mp->max_interval = ntohl (max_interval);
10441   mp->min_interval = ntohl (min_interval);
10442   mp->lifetime = ntohl (lifetime);
10443   mp->initial_count = ntohl (initial_count);
10444   mp->initial_interval = ntohl (initial_interval);
10445   mp->suppress = suppress;
10446   mp->managed = managed;
10447   mp->other = other;
10448   mp->ll_option = ll_option;
10449   mp->send_unicast = send_unicast;
10450   mp->cease = cease;
10451   mp->is_no = is_no;
10452   mp->default_router = default_router;
10453
10454   /* send it... */
10455   S (mp);
10456
10457   /* Wait for a reply, return good/bad news  */
10458   W (ret);
10459   return ret;
10460 }
10461
10462 static int
10463 api_set_arp_neighbor_limit (vat_main_t * vam)
10464 {
10465   unformat_input_t *i = vam->input;
10466   vl_api_set_arp_neighbor_limit_t *mp;
10467   u32 arp_nbr_limit;
10468   u8 limit_set = 0;
10469   u8 is_ipv6 = 0;
10470   int ret;
10471
10472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10473     {
10474       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10475         limit_set = 1;
10476       else if (unformat (i, "ipv6"))
10477         is_ipv6 = 1;
10478       else
10479         {
10480           clib_warning ("parse error '%U'", format_unformat_error, i);
10481           return -99;
10482         }
10483     }
10484
10485   if (limit_set == 0)
10486     {
10487       errmsg ("missing limit value");
10488       return -99;
10489     }
10490
10491   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10492
10493   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10494   mp->is_ipv6 = is_ipv6;
10495
10496   S (mp);
10497   W (ret);
10498   return ret;
10499 }
10500
10501 static int
10502 api_l2_patch_add_del (vat_main_t * vam)
10503 {
10504   unformat_input_t *i = vam->input;
10505   vl_api_l2_patch_add_del_t *mp;
10506   u32 rx_sw_if_index;
10507   u8 rx_sw_if_index_set = 0;
10508   u32 tx_sw_if_index;
10509   u8 tx_sw_if_index_set = 0;
10510   u8 is_add = 1;
10511   int ret;
10512
10513   /* Parse args required to build the message */
10514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10515     {
10516       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10517         rx_sw_if_index_set = 1;
10518       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10519         tx_sw_if_index_set = 1;
10520       else if (unformat (i, "rx"))
10521         {
10522           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10523             {
10524               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10525                             &rx_sw_if_index))
10526                 rx_sw_if_index_set = 1;
10527             }
10528           else
10529             break;
10530         }
10531       else if (unformat (i, "tx"))
10532         {
10533           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10534             {
10535               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10536                             &tx_sw_if_index))
10537                 tx_sw_if_index_set = 1;
10538             }
10539           else
10540             break;
10541         }
10542       else if (unformat (i, "del"))
10543         is_add = 0;
10544       else
10545         break;
10546     }
10547
10548   if (rx_sw_if_index_set == 0)
10549     {
10550       errmsg ("missing rx interface name or rx_sw_if_index");
10551       return -99;
10552     }
10553
10554   if (tx_sw_if_index_set == 0)
10555     {
10556       errmsg ("missing tx interface name or tx_sw_if_index");
10557       return -99;
10558     }
10559
10560   M (L2_PATCH_ADD_DEL, mp);
10561
10562   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10563   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10564   mp->is_add = is_add;
10565
10566   S (mp);
10567   W (ret);
10568   return ret;
10569 }
10570
10571 u8 is_del;
10572 u8 localsid_addr[16];
10573 u8 end_psp;
10574 u8 behavior;
10575 u32 sw_if_index;
10576 u32 vlan_index;
10577 u32 fib_table;
10578 u8 nh_addr[16];
10579
10580 static int
10581 api_sr_localsid_add_del (vat_main_t * vam)
10582 {
10583   unformat_input_t *i = vam->input;
10584   vl_api_sr_localsid_add_del_t *mp;
10585
10586   u8 is_del;
10587   ip6_address_t localsid;
10588   u8 end_psp = 0;
10589   u8 behavior = ~0;
10590   u32 sw_if_index;
10591   u32 fib_table = ~(u32) 0;
10592   ip6_address_t nh_addr6;
10593   ip4_address_t nh_addr4;
10594   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
10595   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
10596
10597   bool nexthop_set = 0;
10598
10599   int ret;
10600
10601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10602     {
10603       if (unformat (i, "del"))
10604         is_del = 1;
10605       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10606       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10607         nexthop_set = 1;
10608       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10609         nexthop_set = 1;
10610       else if (unformat (i, "behavior %u", &behavior));
10611       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10612       else if (unformat (i, "fib-table %u", &fib_table));
10613       else if (unformat (i, "end.psp %u", &behavior));
10614       else
10615         break;
10616     }
10617
10618   M (SR_LOCALSID_ADD_DEL, mp);
10619
10620   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10621   if (nexthop_set)
10622     {
10623       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10624       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10625     }
10626   mp->behavior = behavior;
10627   mp->sw_if_index = ntohl (sw_if_index);
10628   mp->fib_table = ntohl (fib_table);
10629   mp->end_psp = end_psp;
10630   mp->is_del = is_del;
10631
10632   S (mp);
10633   W (ret);
10634   return ret;
10635 }
10636
10637 static int
10638 api_ioam_enable (vat_main_t * vam)
10639 {
10640   unformat_input_t *input = vam->input;
10641   vl_api_ioam_enable_t *mp;
10642   u32 id = 0;
10643   int has_trace_option = 0;
10644   int has_pot_option = 0;
10645   int has_seqno_option = 0;
10646   int has_analyse_option = 0;
10647   int ret;
10648
10649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10650     {
10651       if (unformat (input, "trace"))
10652         has_trace_option = 1;
10653       else if (unformat (input, "pot"))
10654         has_pot_option = 1;
10655       else if (unformat (input, "seqno"))
10656         has_seqno_option = 1;
10657       else if (unformat (input, "analyse"))
10658         has_analyse_option = 1;
10659       else
10660         break;
10661     }
10662   M (IOAM_ENABLE, mp);
10663   mp->id = htons (id);
10664   mp->seqno = has_seqno_option;
10665   mp->analyse = has_analyse_option;
10666   mp->pot_enable = has_pot_option;
10667   mp->trace_enable = has_trace_option;
10668
10669   S (mp);
10670   W (ret);
10671   return ret;
10672 }
10673
10674
10675 static int
10676 api_ioam_disable (vat_main_t * vam)
10677 {
10678   vl_api_ioam_disable_t *mp;
10679   int ret;
10680
10681   M (IOAM_DISABLE, mp);
10682   S (mp);
10683   W (ret);
10684   return ret;
10685 }
10686
10687 #define foreach_tcp_proto_field                 \
10688 _(src_port)                                     \
10689 _(dst_port)
10690
10691 #define foreach_udp_proto_field                 \
10692 _(src_port)                                     \
10693 _(dst_port)
10694
10695 #define foreach_ip4_proto_field                 \
10696 _(src_address)                                  \
10697 _(dst_address)                                  \
10698 _(tos)                                          \
10699 _(length)                                       \
10700 _(fragment_id)                                  \
10701 _(ttl)                                          \
10702 _(protocol)                                     \
10703 _(checksum)
10704
10705 typedef struct
10706 {
10707   u16 src_port, dst_port;
10708 } tcpudp_header_t;
10709
10710 #if VPP_API_TEST_BUILTIN == 0
10711 uword
10712 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10713 {
10714   u8 **maskp = va_arg (*args, u8 **);
10715   u8 *mask = 0;
10716   u8 found_something = 0;
10717   tcp_header_t *tcp;
10718
10719 #define _(a) u8 a=0;
10720   foreach_tcp_proto_field;
10721 #undef _
10722
10723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10724     {
10725       if (0);
10726 #define _(a) else if (unformat (input, #a)) a=1;
10727       foreach_tcp_proto_field
10728 #undef _
10729         else
10730         break;
10731     }
10732
10733 #define _(a) found_something += a;
10734   foreach_tcp_proto_field;
10735 #undef _
10736
10737   if (found_something == 0)
10738     return 0;
10739
10740   vec_validate (mask, sizeof (*tcp) - 1);
10741
10742   tcp = (tcp_header_t *) mask;
10743
10744 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
10745   foreach_tcp_proto_field;
10746 #undef _
10747
10748   *maskp = mask;
10749   return 1;
10750 }
10751
10752 uword
10753 unformat_udp_mask (unformat_input_t * input, va_list * args)
10754 {
10755   u8 **maskp = va_arg (*args, u8 **);
10756   u8 *mask = 0;
10757   u8 found_something = 0;
10758   udp_header_t *udp;
10759
10760 #define _(a) u8 a=0;
10761   foreach_udp_proto_field;
10762 #undef _
10763
10764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10765     {
10766       if (0);
10767 #define _(a) else if (unformat (input, #a)) a=1;
10768       foreach_udp_proto_field
10769 #undef _
10770         else
10771         break;
10772     }
10773
10774 #define _(a) found_something += a;
10775   foreach_udp_proto_field;
10776 #undef _
10777
10778   if (found_something == 0)
10779     return 0;
10780
10781   vec_validate (mask, sizeof (*udp) - 1);
10782
10783   udp = (udp_header_t *) mask;
10784
10785 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10786   foreach_udp_proto_field;
10787 #undef _
10788
10789   *maskp = mask;
10790   return 1;
10791 }
10792
10793 uword
10794 unformat_l4_mask (unformat_input_t * input, va_list * args)
10795 {
10796   u8 **maskp = va_arg (*args, u8 **);
10797   u16 src_port = 0, dst_port = 0;
10798   tcpudp_header_t *tcpudp;
10799
10800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10801     {
10802       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10803         return 1;
10804       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10805         return 1;
10806       else if (unformat (input, "src_port"))
10807         src_port = 0xFFFF;
10808       else if (unformat (input, "dst_port"))
10809         dst_port = 0xFFFF;
10810       else
10811         return 0;
10812     }
10813
10814   if (!src_port && !dst_port)
10815     return 0;
10816
10817   u8 *mask = 0;
10818   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10819
10820   tcpudp = (tcpudp_header_t *) mask;
10821   tcpudp->src_port = src_port;
10822   tcpudp->dst_port = dst_port;
10823
10824   *maskp = mask;
10825
10826   return 1;
10827 }
10828
10829 uword
10830 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10831 {
10832   u8 **maskp = va_arg (*args, u8 **);
10833   u8 *mask = 0;
10834   u8 found_something = 0;
10835   ip4_header_t *ip;
10836
10837 #define _(a) u8 a=0;
10838   foreach_ip4_proto_field;
10839 #undef _
10840   u8 version = 0;
10841   u8 hdr_length = 0;
10842
10843
10844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10845     {
10846       if (unformat (input, "version"))
10847         version = 1;
10848       else if (unformat (input, "hdr_length"))
10849         hdr_length = 1;
10850       else if (unformat (input, "src"))
10851         src_address = 1;
10852       else if (unformat (input, "dst"))
10853         dst_address = 1;
10854       else if (unformat (input, "proto"))
10855         protocol = 1;
10856
10857 #define _(a) else if (unformat (input, #a)) a=1;
10858       foreach_ip4_proto_field
10859 #undef _
10860         else
10861         break;
10862     }
10863
10864 #define _(a) found_something += a;
10865   foreach_ip4_proto_field;
10866 #undef _
10867
10868   if (found_something == 0)
10869     return 0;
10870
10871   vec_validate (mask, sizeof (*ip) - 1);
10872
10873   ip = (ip4_header_t *) mask;
10874
10875 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10876   foreach_ip4_proto_field;
10877 #undef _
10878
10879   ip->ip_version_and_header_length = 0;
10880
10881   if (version)
10882     ip->ip_version_and_header_length |= 0xF0;
10883
10884   if (hdr_length)
10885     ip->ip_version_and_header_length |= 0x0F;
10886
10887   *maskp = mask;
10888   return 1;
10889 }
10890
10891 #define foreach_ip6_proto_field                 \
10892 _(src_address)                                  \
10893 _(dst_address)                                  \
10894 _(payload_length)                               \
10895 _(hop_limit)                                    \
10896 _(protocol)
10897
10898 uword
10899 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10900 {
10901   u8 **maskp = va_arg (*args, u8 **);
10902   u8 *mask = 0;
10903   u8 found_something = 0;
10904   ip6_header_t *ip;
10905   u32 ip_version_traffic_class_and_flow_label;
10906
10907 #define _(a) u8 a=0;
10908   foreach_ip6_proto_field;
10909 #undef _
10910   u8 version = 0;
10911   u8 traffic_class = 0;
10912   u8 flow_label = 0;
10913
10914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10915     {
10916       if (unformat (input, "version"))
10917         version = 1;
10918       else if (unformat (input, "traffic-class"))
10919         traffic_class = 1;
10920       else if (unformat (input, "flow-label"))
10921         flow_label = 1;
10922       else if (unformat (input, "src"))
10923         src_address = 1;
10924       else if (unformat (input, "dst"))
10925         dst_address = 1;
10926       else if (unformat (input, "proto"))
10927         protocol = 1;
10928
10929 #define _(a) else if (unformat (input, #a)) a=1;
10930       foreach_ip6_proto_field
10931 #undef _
10932         else
10933         break;
10934     }
10935
10936 #define _(a) found_something += a;
10937   foreach_ip6_proto_field;
10938 #undef _
10939
10940   if (found_something == 0)
10941     return 0;
10942
10943   vec_validate (mask, sizeof (*ip) - 1);
10944
10945   ip = (ip6_header_t *) mask;
10946
10947 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10948   foreach_ip6_proto_field;
10949 #undef _
10950
10951   ip_version_traffic_class_and_flow_label = 0;
10952
10953   if (version)
10954     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10955
10956   if (traffic_class)
10957     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10958
10959   if (flow_label)
10960     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10961
10962   ip->ip_version_traffic_class_and_flow_label =
10963     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10964
10965   *maskp = mask;
10966   return 1;
10967 }
10968
10969 uword
10970 unformat_l3_mask (unformat_input_t * input, va_list * args)
10971 {
10972   u8 **maskp = va_arg (*args, u8 **);
10973
10974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10975     {
10976       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10977         return 1;
10978       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10979         return 1;
10980       else
10981         break;
10982     }
10983   return 0;
10984 }
10985
10986 uword
10987 unformat_l2_mask (unformat_input_t * input, va_list * args)
10988 {
10989   u8 **maskp = va_arg (*args, u8 **);
10990   u8 *mask = 0;
10991   u8 src = 0;
10992   u8 dst = 0;
10993   u8 proto = 0;
10994   u8 tag1 = 0;
10995   u8 tag2 = 0;
10996   u8 ignore_tag1 = 0;
10997   u8 ignore_tag2 = 0;
10998   u8 cos1 = 0;
10999   u8 cos2 = 0;
11000   u8 dot1q = 0;
11001   u8 dot1ad = 0;
11002   int len = 14;
11003
11004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11005     {
11006       if (unformat (input, "src"))
11007         src = 1;
11008       else if (unformat (input, "dst"))
11009         dst = 1;
11010       else if (unformat (input, "proto"))
11011         proto = 1;
11012       else if (unformat (input, "tag1"))
11013         tag1 = 1;
11014       else if (unformat (input, "tag2"))
11015         tag2 = 1;
11016       else if (unformat (input, "ignore-tag1"))
11017         ignore_tag1 = 1;
11018       else if (unformat (input, "ignore-tag2"))
11019         ignore_tag2 = 1;
11020       else if (unformat (input, "cos1"))
11021         cos1 = 1;
11022       else if (unformat (input, "cos2"))
11023         cos2 = 1;
11024       else if (unformat (input, "dot1q"))
11025         dot1q = 1;
11026       else if (unformat (input, "dot1ad"))
11027         dot1ad = 1;
11028       else
11029         break;
11030     }
11031   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11032        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11033     return 0;
11034
11035   if (tag1 || ignore_tag1 || cos1 || dot1q)
11036     len = 18;
11037   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11038     len = 22;
11039
11040   vec_validate (mask, len - 1);
11041
11042   if (dst)
11043     clib_memset (mask, 0xff, 6);
11044
11045   if (src)
11046     clib_memset (mask + 6, 0xff, 6);
11047
11048   if (tag2 || dot1ad)
11049     {
11050       /* inner vlan tag */
11051       if (tag2)
11052         {
11053           mask[19] = 0xff;
11054           mask[18] = 0x0f;
11055         }
11056       if (cos2)
11057         mask[18] |= 0xe0;
11058       if (proto)
11059         mask[21] = mask[20] = 0xff;
11060       if (tag1)
11061         {
11062           mask[15] = 0xff;
11063           mask[14] = 0x0f;
11064         }
11065       if (cos1)
11066         mask[14] |= 0xe0;
11067       *maskp = mask;
11068       return 1;
11069     }
11070   if (tag1 | dot1q)
11071     {
11072       if (tag1)
11073         {
11074           mask[15] = 0xff;
11075           mask[14] = 0x0f;
11076         }
11077       if (cos1)
11078         mask[14] |= 0xe0;
11079       if (proto)
11080         mask[16] = mask[17] = 0xff;
11081
11082       *maskp = mask;
11083       return 1;
11084     }
11085   if (cos2)
11086     mask[18] |= 0xe0;
11087   if (cos1)
11088     mask[14] |= 0xe0;
11089   if (proto)
11090     mask[12] = mask[13] = 0xff;
11091
11092   *maskp = mask;
11093   return 1;
11094 }
11095
11096 uword
11097 unformat_classify_mask (unformat_input_t * input, va_list * args)
11098 {
11099   u8 **maskp = va_arg (*args, u8 **);
11100   u32 *skipp = va_arg (*args, u32 *);
11101   u32 *matchp = va_arg (*args, u32 *);
11102   u32 match;
11103   u8 *mask = 0;
11104   u8 *l2 = 0;
11105   u8 *l3 = 0;
11106   u8 *l4 = 0;
11107   int i;
11108
11109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11110     {
11111       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11112         ;
11113       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11114         ;
11115       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11116         ;
11117       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11118         ;
11119       else
11120         break;
11121     }
11122
11123   if (l4 && !l3)
11124     {
11125       vec_free (mask);
11126       vec_free (l2);
11127       vec_free (l4);
11128       return 0;
11129     }
11130
11131   if (mask || l2 || l3 || l4)
11132     {
11133       if (l2 || l3 || l4)
11134         {
11135           /* "With a free Ethernet header in every package" */
11136           if (l2 == 0)
11137             vec_validate (l2, 13);
11138           mask = l2;
11139           if (vec_len (l3))
11140             {
11141               vec_append (mask, l3);
11142               vec_free (l3);
11143             }
11144           if (vec_len (l4))
11145             {
11146               vec_append (mask, l4);
11147               vec_free (l4);
11148             }
11149         }
11150
11151       /* Scan forward looking for the first significant mask octet */
11152       for (i = 0; i < vec_len (mask); i++)
11153         if (mask[i])
11154           break;
11155
11156       /* compute (skip, match) params */
11157       *skipp = i / sizeof (u32x4);
11158       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11159
11160       /* Pad mask to an even multiple of the vector size */
11161       while (vec_len (mask) % sizeof (u32x4))
11162         vec_add1 (mask, 0);
11163
11164       match = vec_len (mask) / sizeof (u32x4);
11165
11166       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11167         {
11168           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11169           if (*tmp || *(tmp + 1))
11170             break;
11171           match--;
11172         }
11173       if (match == 0)
11174         clib_warning ("BUG: match 0");
11175
11176       _vec_len (mask) = match * sizeof (u32x4);
11177
11178       *matchp = match;
11179       *maskp = mask;
11180
11181       return 1;
11182     }
11183
11184   return 0;
11185 }
11186 #endif /* VPP_API_TEST_BUILTIN */
11187
11188 #define foreach_l2_next                         \
11189 _(drop, DROP)                                   \
11190 _(ethernet, ETHERNET_INPUT)                     \
11191 _(ip4, IP4_INPUT)                               \
11192 _(ip6, IP6_INPUT)
11193
11194 uword
11195 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11196 {
11197   u32 *miss_next_indexp = va_arg (*args, u32 *);
11198   u32 next_index = 0;
11199   u32 tmp;
11200
11201 #define _(n,N) \
11202   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11203   foreach_l2_next;
11204 #undef _
11205
11206   if (unformat (input, "%d", &tmp))
11207     {
11208       next_index = tmp;
11209       goto out;
11210     }
11211
11212   return 0;
11213
11214 out:
11215   *miss_next_indexp = next_index;
11216   return 1;
11217 }
11218
11219 #define foreach_ip_next                         \
11220 _(drop, DROP)                                   \
11221 _(local, LOCAL)                                 \
11222 _(rewrite, REWRITE)
11223
11224 uword
11225 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11226 {
11227   u32 *miss_next_indexp = va_arg (*args, u32 *);
11228   u32 next_index = 0;
11229   u32 tmp;
11230
11231 #define _(n,N) \
11232   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11233   foreach_ip_next;
11234 #undef _
11235
11236   if (unformat (input, "%d", &tmp))
11237     {
11238       next_index = tmp;
11239       goto out;
11240     }
11241
11242   return 0;
11243
11244 out:
11245   *miss_next_indexp = next_index;
11246   return 1;
11247 }
11248
11249 #define foreach_acl_next                        \
11250 _(deny, DENY)
11251
11252 uword
11253 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11254 {
11255   u32 *miss_next_indexp = va_arg (*args, u32 *);
11256   u32 next_index = 0;
11257   u32 tmp;
11258
11259 #define _(n,N) \
11260   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11261   foreach_acl_next;
11262 #undef _
11263
11264   if (unformat (input, "permit"))
11265     {
11266       next_index = ~0;
11267       goto out;
11268     }
11269   else if (unformat (input, "%d", &tmp))
11270     {
11271       next_index = tmp;
11272       goto out;
11273     }
11274
11275   return 0;
11276
11277 out:
11278   *miss_next_indexp = next_index;
11279   return 1;
11280 }
11281
11282 uword
11283 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11284 {
11285   u32 *r = va_arg (*args, u32 *);
11286
11287   if (unformat (input, "conform-color"))
11288     *r = POLICE_CONFORM;
11289   else if (unformat (input, "exceed-color"))
11290     *r = POLICE_EXCEED;
11291   else
11292     return 0;
11293
11294   return 1;
11295 }
11296
11297 static int
11298 api_classify_add_del_table (vat_main_t * vam)
11299 {
11300   unformat_input_t *i = vam->input;
11301   vl_api_classify_add_del_table_t *mp;
11302
11303   u32 nbuckets = 2;
11304   u32 skip = ~0;
11305   u32 match = ~0;
11306   int is_add = 1;
11307   int del_chain = 0;
11308   u32 table_index = ~0;
11309   u32 next_table_index = ~0;
11310   u32 miss_next_index = ~0;
11311   u32 memory_size = 32 << 20;
11312   u8 *mask = 0;
11313   u32 current_data_flag = 0;
11314   int current_data_offset = 0;
11315   int ret;
11316
11317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11318     {
11319       if (unformat (i, "del"))
11320         is_add = 0;
11321       else if (unformat (i, "del-chain"))
11322         {
11323           is_add = 0;
11324           del_chain = 1;
11325         }
11326       else if (unformat (i, "buckets %d", &nbuckets))
11327         ;
11328       else if (unformat (i, "memory_size %d", &memory_size))
11329         ;
11330       else if (unformat (i, "skip %d", &skip))
11331         ;
11332       else if (unformat (i, "match %d", &match))
11333         ;
11334       else if (unformat (i, "table %d", &table_index))
11335         ;
11336       else if (unformat (i, "mask %U", unformat_classify_mask,
11337                          &mask, &skip, &match))
11338         ;
11339       else if (unformat (i, "next-table %d", &next_table_index))
11340         ;
11341       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11342                          &miss_next_index))
11343         ;
11344       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11345                          &miss_next_index))
11346         ;
11347       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11348                          &miss_next_index))
11349         ;
11350       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11351         ;
11352       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11353         ;
11354       else
11355         break;
11356     }
11357
11358   if (is_add && mask == 0)
11359     {
11360       errmsg ("Mask required");
11361       return -99;
11362     }
11363
11364   if (is_add && skip == ~0)
11365     {
11366       errmsg ("skip count required");
11367       return -99;
11368     }
11369
11370   if (is_add && match == ~0)
11371     {
11372       errmsg ("match count required");
11373       return -99;
11374     }
11375
11376   if (!is_add && table_index == ~0)
11377     {
11378       errmsg ("table index required for delete");
11379       return -99;
11380     }
11381
11382   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11383
11384   mp->is_add = is_add;
11385   mp->del_chain = del_chain;
11386   mp->table_index = ntohl (table_index);
11387   mp->nbuckets = ntohl (nbuckets);
11388   mp->memory_size = ntohl (memory_size);
11389   mp->skip_n_vectors = ntohl (skip);
11390   mp->match_n_vectors = ntohl (match);
11391   mp->next_table_index = ntohl (next_table_index);
11392   mp->miss_next_index = ntohl (miss_next_index);
11393   mp->current_data_flag = ntohl (current_data_flag);
11394   mp->current_data_offset = ntohl (current_data_offset);
11395   mp->mask_len = ntohl (vec_len (mask));
11396   clib_memcpy (mp->mask, mask, vec_len (mask));
11397
11398   vec_free (mask);
11399
11400   S (mp);
11401   W (ret);
11402   return ret;
11403 }
11404
11405 #if VPP_API_TEST_BUILTIN == 0
11406 uword
11407 unformat_l4_match (unformat_input_t * input, va_list * args)
11408 {
11409   u8 **matchp = va_arg (*args, u8 **);
11410
11411   u8 *proto_header = 0;
11412   int src_port = 0;
11413   int dst_port = 0;
11414
11415   tcpudp_header_t h;
11416
11417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11418     {
11419       if (unformat (input, "src_port %d", &src_port))
11420         ;
11421       else if (unformat (input, "dst_port %d", &dst_port))
11422         ;
11423       else
11424         return 0;
11425     }
11426
11427   h.src_port = clib_host_to_net_u16 (src_port);
11428   h.dst_port = clib_host_to_net_u16 (dst_port);
11429   vec_validate (proto_header, sizeof (h) - 1);
11430   memcpy (proto_header, &h, sizeof (h));
11431
11432   *matchp = proto_header;
11433
11434   return 1;
11435 }
11436
11437 uword
11438 unformat_ip4_match (unformat_input_t * input, va_list * args)
11439 {
11440   u8 **matchp = va_arg (*args, u8 **);
11441   u8 *match = 0;
11442   ip4_header_t *ip;
11443   int version = 0;
11444   u32 version_val;
11445   int hdr_length = 0;
11446   u32 hdr_length_val;
11447   int src = 0, dst = 0;
11448   ip4_address_t src_val, dst_val;
11449   int proto = 0;
11450   u32 proto_val;
11451   int tos = 0;
11452   u32 tos_val;
11453   int length = 0;
11454   u32 length_val;
11455   int fragment_id = 0;
11456   u32 fragment_id_val;
11457   int ttl = 0;
11458   int ttl_val;
11459   int checksum = 0;
11460   u32 checksum_val;
11461
11462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11463     {
11464       if (unformat (input, "version %d", &version_val))
11465         version = 1;
11466       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11467         hdr_length = 1;
11468       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11469         src = 1;
11470       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11471         dst = 1;
11472       else if (unformat (input, "proto %d", &proto_val))
11473         proto = 1;
11474       else if (unformat (input, "tos %d", &tos_val))
11475         tos = 1;
11476       else if (unformat (input, "length %d", &length_val))
11477         length = 1;
11478       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11479         fragment_id = 1;
11480       else if (unformat (input, "ttl %d", &ttl_val))
11481         ttl = 1;
11482       else if (unformat (input, "checksum %d", &checksum_val))
11483         checksum = 1;
11484       else
11485         break;
11486     }
11487
11488   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11489       + ttl + checksum == 0)
11490     return 0;
11491
11492   /*
11493    * Aligned because we use the real comparison functions
11494    */
11495   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11496
11497   ip = (ip4_header_t *) match;
11498
11499   /* These are realistically matched in practice */
11500   if (src)
11501     ip->src_address.as_u32 = src_val.as_u32;
11502
11503   if (dst)
11504     ip->dst_address.as_u32 = dst_val.as_u32;
11505
11506   if (proto)
11507     ip->protocol = proto_val;
11508
11509
11510   /* These are not, but they're included for completeness */
11511   if (version)
11512     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11513
11514   if (hdr_length)
11515     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11516
11517   if (tos)
11518     ip->tos = tos_val;
11519
11520   if (length)
11521     ip->length = clib_host_to_net_u16 (length_val);
11522
11523   if (ttl)
11524     ip->ttl = ttl_val;
11525
11526   if (checksum)
11527     ip->checksum = clib_host_to_net_u16 (checksum_val);
11528
11529   *matchp = match;
11530   return 1;
11531 }
11532
11533 uword
11534 unformat_ip6_match (unformat_input_t * input, va_list * args)
11535 {
11536   u8 **matchp = va_arg (*args, u8 **);
11537   u8 *match = 0;
11538   ip6_header_t *ip;
11539   int version = 0;
11540   u32 version_val;
11541   u8 traffic_class = 0;
11542   u32 traffic_class_val = 0;
11543   u8 flow_label = 0;
11544   u8 flow_label_val;
11545   int src = 0, dst = 0;
11546   ip6_address_t src_val, dst_val;
11547   int proto = 0;
11548   u32 proto_val;
11549   int payload_length = 0;
11550   u32 payload_length_val;
11551   int hop_limit = 0;
11552   int hop_limit_val;
11553   u32 ip_version_traffic_class_and_flow_label;
11554
11555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11556     {
11557       if (unformat (input, "version %d", &version_val))
11558         version = 1;
11559       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11560         traffic_class = 1;
11561       else if (unformat (input, "flow_label %d", &flow_label_val))
11562         flow_label = 1;
11563       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11564         src = 1;
11565       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11566         dst = 1;
11567       else if (unformat (input, "proto %d", &proto_val))
11568         proto = 1;
11569       else if (unformat (input, "payload_length %d", &payload_length_val))
11570         payload_length = 1;
11571       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11572         hop_limit = 1;
11573       else
11574         break;
11575     }
11576
11577   if (version + traffic_class + flow_label + src + dst + proto +
11578       payload_length + hop_limit == 0)
11579     return 0;
11580
11581   /*
11582    * Aligned because we use the real comparison functions
11583    */
11584   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11585
11586   ip = (ip6_header_t *) match;
11587
11588   if (src)
11589     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11590
11591   if (dst)
11592     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11593
11594   if (proto)
11595     ip->protocol = proto_val;
11596
11597   ip_version_traffic_class_and_flow_label = 0;
11598
11599   if (version)
11600     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11601
11602   if (traffic_class)
11603     ip_version_traffic_class_and_flow_label |=
11604       (traffic_class_val & 0xFF) << 20;
11605
11606   if (flow_label)
11607     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11608
11609   ip->ip_version_traffic_class_and_flow_label =
11610     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11611
11612   if (payload_length)
11613     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11614
11615   if (hop_limit)
11616     ip->hop_limit = hop_limit_val;
11617
11618   *matchp = match;
11619   return 1;
11620 }
11621
11622 uword
11623 unformat_l3_match (unformat_input_t * input, va_list * args)
11624 {
11625   u8 **matchp = va_arg (*args, u8 **);
11626
11627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11628     {
11629       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11630         return 1;
11631       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11632         return 1;
11633       else
11634         break;
11635     }
11636   return 0;
11637 }
11638
11639 uword
11640 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11641 {
11642   u8 *tagp = va_arg (*args, u8 *);
11643   u32 tag;
11644
11645   if (unformat (input, "%d", &tag))
11646     {
11647       tagp[0] = (tag >> 8) & 0x0F;
11648       tagp[1] = tag & 0xFF;
11649       return 1;
11650     }
11651
11652   return 0;
11653 }
11654
11655 uword
11656 unformat_l2_match (unformat_input_t * input, va_list * args)
11657 {
11658   u8 **matchp = va_arg (*args, u8 **);
11659   u8 *match = 0;
11660   u8 src = 0;
11661   u8 src_val[6];
11662   u8 dst = 0;
11663   u8 dst_val[6];
11664   u8 proto = 0;
11665   u16 proto_val;
11666   u8 tag1 = 0;
11667   u8 tag1_val[2];
11668   u8 tag2 = 0;
11669   u8 tag2_val[2];
11670   int len = 14;
11671   u8 ignore_tag1 = 0;
11672   u8 ignore_tag2 = 0;
11673   u8 cos1 = 0;
11674   u8 cos2 = 0;
11675   u32 cos1_val = 0;
11676   u32 cos2_val = 0;
11677
11678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11681         src = 1;
11682       else
11683         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11684         dst = 1;
11685       else if (unformat (input, "proto %U",
11686                          unformat_ethernet_type_host_byte_order, &proto_val))
11687         proto = 1;
11688       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11689         tag1 = 1;
11690       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11691         tag2 = 1;
11692       else if (unformat (input, "ignore-tag1"))
11693         ignore_tag1 = 1;
11694       else if (unformat (input, "ignore-tag2"))
11695         ignore_tag2 = 1;
11696       else if (unformat (input, "cos1 %d", &cos1_val))
11697         cos1 = 1;
11698       else if (unformat (input, "cos2 %d", &cos2_val))
11699         cos2 = 1;
11700       else
11701         break;
11702     }
11703   if ((src + dst + proto + tag1 + tag2 +
11704        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11705     return 0;
11706
11707   if (tag1 || ignore_tag1 || cos1)
11708     len = 18;
11709   if (tag2 || ignore_tag2 || cos2)
11710     len = 22;
11711
11712   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11713
11714   if (dst)
11715     clib_memcpy (match, dst_val, 6);
11716
11717   if (src)
11718     clib_memcpy (match + 6, src_val, 6);
11719
11720   if (tag2)
11721     {
11722       /* inner vlan tag */
11723       match[19] = tag2_val[1];
11724       match[18] = tag2_val[0];
11725       if (cos2)
11726         match[18] |= (cos2_val & 0x7) << 5;
11727       if (proto)
11728         {
11729           match[21] = proto_val & 0xff;
11730           match[20] = proto_val >> 8;
11731         }
11732       if (tag1)
11733         {
11734           match[15] = tag1_val[1];
11735           match[14] = tag1_val[0];
11736         }
11737       if (cos1)
11738         match[14] |= (cos1_val & 0x7) << 5;
11739       *matchp = match;
11740       return 1;
11741     }
11742   if (tag1)
11743     {
11744       match[15] = tag1_val[1];
11745       match[14] = tag1_val[0];
11746       if (proto)
11747         {
11748           match[17] = proto_val & 0xff;
11749           match[16] = proto_val >> 8;
11750         }
11751       if (cos1)
11752         match[14] |= (cos1_val & 0x7) << 5;
11753
11754       *matchp = match;
11755       return 1;
11756     }
11757   if (cos2)
11758     match[18] |= (cos2_val & 0x7) << 5;
11759   if (cos1)
11760     match[14] |= (cos1_val & 0x7) << 5;
11761   if (proto)
11762     {
11763       match[13] = proto_val & 0xff;
11764       match[12] = proto_val >> 8;
11765     }
11766
11767   *matchp = match;
11768   return 1;
11769 }
11770
11771 uword
11772 unformat_qos_source (unformat_input_t * input, va_list * args)
11773 {
11774   int *qs = va_arg (*args, int *);
11775
11776   if (unformat (input, "ip"))
11777     *qs = QOS_SOURCE_IP;
11778   else if (unformat (input, "mpls"))
11779     *qs = QOS_SOURCE_MPLS;
11780   else if (unformat (input, "ext"))
11781     *qs = QOS_SOURCE_EXT;
11782   else if (unformat (input, "vlan"))
11783     *qs = QOS_SOURCE_VLAN;
11784   else
11785     return 0;
11786
11787   return 1;
11788 }
11789 #endif
11790
11791 uword
11792 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11793 {
11794   u8 **matchp = va_arg (*args, u8 **);
11795   u32 skip_n_vectors = va_arg (*args, u32);
11796   u32 match_n_vectors = va_arg (*args, u32);
11797
11798   u8 *match = 0;
11799   u8 *l2 = 0;
11800   u8 *l3 = 0;
11801   u8 *l4 = 0;
11802
11803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11804     {
11805       if (unformat (input, "hex %U", unformat_hex_string, &match))
11806         ;
11807       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11808         ;
11809       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11810         ;
11811       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11812         ;
11813       else
11814         break;
11815     }
11816
11817   if (l4 && !l3)
11818     {
11819       vec_free (match);
11820       vec_free (l2);
11821       vec_free (l4);
11822       return 0;
11823     }
11824
11825   if (match || l2 || l3 || l4)
11826     {
11827       if (l2 || l3 || l4)
11828         {
11829           /* "Win a free Ethernet header in every packet" */
11830           if (l2 == 0)
11831             vec_validate_aligned (l2, 13, sizeof (u32x4));
11832           match = l2;
11833           if (vec_len (l3))
11834             {
11835               vec_append_aligned (match, l3, sizeof (u32x4));
11836               vec_free (l3);
11837             }
11838           if (vec_len (l4))
11839             {
11840               vec_append_aligned (match, l4, sizeof (u32x4));
11841               vec_free (l4);
11842             }
11843         }
11844
11845       /* Make sure the vector is big enough even if key is all 0's */
11846       vec_validate_aligned
11847         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11848          sizeof (u32x4));
11849
11850       /* Set size, include skipped vectors */
11851       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11852
11853       *matchp = match;
11854
11855       return 1;
11856     }
11857
11858   return 0;
11859 }
11860
11861 static int
11862 api_classify_add_del_session (vat_main_t * vam)
11863 {
11864   unformat_input_t *i = vam->input;
11865   vl_api_classify_add_del_session_t *mp;
11866   int is_add = 1;
11867   u32 table_index = ~0;
11868   u32 hit_next_index = ~0;
11869   u32 opaque_index = ~0;
11870   u8 *match = 0;
11871   i32 advance = 0;
11872   u32 skip_n_vectors = 0;
11873   u32 match_n_vectors = 0;
11874   u32 action = 0;
11875   u32 metadata = 0;
11876   int ret;
11877
11878   /*
11879    * Warning: you have to supply skip_n and match_n
11880    * because the API client cant simply look at the classify
11881    * table object.
11882    */
11883
11884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11885     {
11886       if (unformat (i, "del"))
11887         is_add = 0;
11888       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11889                          &hit_next_index))
11890         ;
11891       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11892                          &hit_next_index))
11893         ;
11894       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11895                          &hit_next_index))
11896         ;
11897       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11898         ;
11899       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11900         ;
11901       else if (unformat (i, "opaque-index %d", &opaque_index))
11902         ;
11903       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11904         ;
11905       else if (unformat (i, "match_n %d", &match_n_vectors))
11906         ;
11907       else if (unformat (i, "match %U", api_unformat_classify_match,
11908                          &match, skip_n_vectors, match_n_vectors))
11909         ;
11910       else if (unformat (i, "advance %d", &advance))
11911         ;
11912       else if (unformat (i, "table-index %d", &table_index))
11913         ;
11914       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11915         action = 1;
11916       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11917         action = 2;
11918       else if (unformat (i, "action %d", &action))
11919         ;
11920       else if (unformat (i, "metadata %d", &metadata))
11921         ;
11922       else
11923         break;
11924     }
11925
11926   if (table_index == ~0)
11927     {
11928       errmsg ("Table index required");
11929       return -99;
11930     }
11931
11932   if (is_add && match == 0)
11933     {
11934       errmsg ("Match value required");
11935       return -99;
11936     }
11937
11938   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11939
11940   mp->is_add = is_add;
11941   mp->table_index = ntohl (table_index);
11942   mp->hit_next_index = ntohl (hit_next_index);
11943   mp->opaque_index = ntohl (opaque_index);
11944   mp->advance = ntohl (advance);
11945   mp->action = action;
11946   mp->metadata = ntohl (metadata);
11947   mp->match_len = ntohl (vec_len (match));
11948   clib_memcpy (mp->match, match, vec_len (match));
11949   vec_free (match);
11950
11951   S (mp);
11952   W (ret);
11953   return ret;
11954 }
11955
11956 static int
11957 api_classify_set_interface_ip_table (vat_main_t * vam)
11958 {
11959   unformat_input_t *i = vam->input;
11960   vl_api_classify_set_interface_ip_table_t *mp;
11961   u32 sw_if_index;
11962   int sw_if_index_set;
11963   u32 table_index = ~0;
11964   u8 is_ipv6 = 0;
11965   int ret;
11966
11967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11968     {
11969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11970         sw_if_index_set = 1;
11971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11972         sw_if_index_set = 1;
11973       else if (unformat (i, "table %d", &table_index))
11974         ;
11975       else
11976         {
11977           clib_warning ("parse error '%U'", format_unformat_error, i);
11978           return -99;
11979         }
11980     }
11981
11982   if (sw_if_index_set == 0)
11983     {
11984       errmsg ("missing interface name or sw_if_index");
11985       return -99;
11986     }
11987
11988
11989   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11990
11991   mp->sw_if_index = ntohl (sw_if_index);
11992   mp->table_index = ntohl (table_index);
11993   mp->is_ipv6 = is_ipv6;
11994
11995   S (mp);
11996   W (ret);
11997   return ret;
11998 }
11999
12000 static int
12001 api_classify_set_interface_l2_tables (vat_main_t * vam)
12002 {
12003   unformat_input_t *i = vam->input;
12004   vl_api_classify_set_interface_l2_tables_t *mp;
12005   u32 sw_if_index;
12006   int sw_if_index_set;
12007   u32 ip4_table_index = ~0;
12008   u32 ip6_table_index = ~0;
12009   u32 other_table_index = ~0;
12010   u32 is_input = 1;
12011   int ret;
12012
12013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12014     {
12015       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12016         sw_if_index_set = 1;
12017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12018         sw_if_index_set = 1;
12019       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12020         ;
12021       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12022         ;
12023       else if (unformat (i, "other-table %d", &other_table_index))
12024         ;
12025       else if (unformat (i, "is-input %d", &is_input))
12026         ;
12027       else
12028         {
12029           clib_warning ("parse error '%U'", format_unformat_error, i);
12030           return -99;
12031         }
12032     }
12033
12034   if (sw_if_index_set == 0)
12035     {
12036       errmsg ("missing interface name or sw_if_index");
12037       return -99;
12038     }
12039
12040
12041   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12042
12043   mp->sw_if_index = ntohl (sw_if_index);
12044   mp->ip4_table_index = ntohl (ip4_table_index);
12045   mp->ip6_table_index = ntohl (ip6_table_index);
12046   mp->other_table_index = ntohl (other_table_index);
12047   mp->is_input = (u8) is_input;
12048
12049   S (mp);
12050   W (ret);
12051   return ret;
12052 }
12053
12054 static int
12055 api_set_ipfix_exporter (vat_main_t * vam)
12056 {
12057   unformat_input_t *i = vam->input;
12058   vl_api_set_ipfix_exporter_t *mp;
12059   ip4_address_t collector_address;
12060   u8 collector_address_set = 0;
12061   u32 collector_port = ~0;
12062   ip4_address_t src_address;
12063   u8 src_address_set = 0;
12064   u32 vrf_id = ~0;
12065   u32 path_mtu = ~0;
12066   u32 template_interval = ~0;
12067   u8 udp_checksum = 0;
12068   int ret;
12069
12070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12071     {
12072       if (unformat (i, "collector_address %U", unformat_ip4_address,
12073                     &collector_address))
12074         collector_address_set = 1;
12075       else if (unformat (i, "collector_port %d", &collector_port))
12076         ;
12077       else if (unformat (i, "src_address %U", unformat_ip4_address,
12078                          &src_address))
12079         src_address_set = 1;
12080       else if (unformat (i, "vrf_id %d", &vrf_id))
12081         ;
12082       else if (unformat (i, "path_mtu %d", &path_mtu))
12083         ;
12084       else if (unformat (i, "template_interval %d", &template_interval))
12085         ;
12086       else if (unformat (i, "udp_checksum"))
12087         udp_checksum = 1;
12088       else
12089         break;
12090     }
12091
12092   if (collector_address_set == 0)
12093     {
12094       errmsg ("collector_address required");
12095       return -99;
12096     }
12097
12098   if (src_address_set == 0)
12099     {
12100       errmsg ("src_address required");
12101       return -99;
12102     }
12103
12104   M (SET_IPFIX_EXPORTER, mp);
12105
12106   memcpy (mp->collector_address, collector_address.data,
12107           sizeof (collector_address.data));
12108   mp->collector_port = htons ((u16) collector_port);
12109   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12110   mp->vrf_id = htonl (vrf_id);
12111   mp->path_mtu = htonl (path_mtu);
12112   mp->template_interval = htonl (template_interval);
12113   mp->udp_checksum = udp_checksum;
12114
12115   S (mp);
12116   W (ret);
12117   return ret;
12118 }
12119
12120 static int
12121 api_set_ipfix_classify_stream (vat_main_t * vam)
12122 {
12123   unformat_input_t *i = vam->input;
12124   vl_api_set_ipfix_classify_stream_t *mp;
12125   u32 domain_id = 0;
12126   u32 src_port = UDP_DST_PORT_ipfix;
12127   int ret;
12128
12129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12130     {
12131       if (unformat (i, "domain %d", &domain_id))
12132         ;
12133       else if (unformat (i, "src_port %d", &src_port))
12134         ;
12135       else
12136         {
12137           errmsg ("unknown input `%U'", format_unformat_error, i);
12138           return -99;
12139         }
12140     }
12141
12142   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12143
12144   mp->domain_id = htonl (domain_id);
12145   mp->src_port = htons ((u16) src_port);
12146
12147   S (mp);
12148   W (ret);
12149   return ret;
12150 }
12151
12152 static int
12153 api_ipfix_classify_table_add_del (vat_main_t * vam)
12154 {
12155   unformat_input_t *i = vam->input;
12156   vl_api_ipfix_classify_table_add_del_t *mp;
12157   int is_add = -1;
12158   u32 classify_table_index = ~0;
12159   u8 ip_version = 0;
12160   u8 transport_protocol = 255;
12161   int ret;
12162
12163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12164     {
12165       if (unformat (i, "add"))
12166         is_add = 1;
12167       else if (unformat (i, "del"))
12168         is_add = 0;
12169       else if (unformat (i, "table %d", &classify_table_index))
12170         ;
12171       else if (unformat (i, "ip4"))
12172         ip_version = 4;
12173       else if (unformat (i, "ip6"))
12174         ip_version = 6;
12175       else if (unformat (i, "tcp"))
12176         transport_protocol = 6;
12177       else if (unformat (i, "udp"))
12178         transport_protocol = 17;
12179       else
12180         {
12181           errmsg ("unknown input `%U'", format_unformat_error, i);
12182           return -99;
12183         }
12184     }
12185
12186   if (is_add == -1)
12187     {
12188       errmsg ("expecting: add|del");
12189       return -99;
12190     }
12191   if (classify_table_index == ~0)
12192     {
12193       errmsg ("classifier table not specified");
12194       return -99;
12195     }
12196   if (ip_version == 0)
12197     {
12198       errmsg ("IP version not specified");
12199       return -99;
12200     }
12201
12202   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12203
12204   mp->is_add = is_add;
12205   mp->table_id = htonl (classify_table_index);
12206   mp->ip_version = ip_version;
12207   mp->transport_protocol = transport_protocol;
12208
12209   S (mp);
12210   W (ret);
12211   return ret;
12212 }
12213
12214 static int
12215 api_get_node_index (vat_main_t * vam)
12216 {
12217   unformat_input_t *i = vam->input;
12218   vl_api_get_node_index_t *mp;
12219   u8 *name = 0;
12220   int ret;
12221
12222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12223     {
12224       if (unformat (i, "node %s", &name))
12225         ;
12226       else
12227         break;
12228     }
12229   if (name == 0)
12230     {
12231       errmsg ("node name required");
12232       return -99;
12233     }
12234   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12235     {
12236       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12237       return -99;
12238     }
12239
12240   M (GET_NODE_INDEX, mp);
12241   clib_memcpy (mp->node_name, name, vec_len (name));
12242   vec_free (name);
12243
12244   S (mp);
12245   W (ret);
12246   return ret;
12247 }
12248
12249 static int
12250 api_get_next_index (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   vl_api_get_next_index_t *mp;
12254   u8 *node_name = 0, *next_node_name = 0;
12255   int ret;
12256
12257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12258     {
12259       if (unformat (i, "node-name %s", &node_name))
12260         ;
12261       else if (unformat (i, "next-node-name %s", &next_node_name))
12262         break;
12263     }
12264
12265   if (node_name == 0)
12266     {
12267       errmsg ("node name required");
12268       return -99;
12269     }
12270   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12271     {
12272       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12273       return -99;
12274     }
12275
12276   if (next_node_name == 0)
12277     {
12278       errmsg ("next node name required");
12279       return -99;
12280     }
12281   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12282     {
12283       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12284       return -99;
12285     }
12286
12287   M (GET_NEXT_INDEX, mp);
12288   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12289   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12290   vec_free (node_name);
12291   vec_free (next_node_name);
12292
12293   S (mp);
12294   W (ret);
12295   return ret;
12296 }
12297
12298 static int
12299 api_add_node_next (vat_main_t * vam)
12300 {
12301   unformat_input_t *i = vam->input;
12302   vl_api_add_node_next_t *mp;
12303   u8 *name = 0;
12304   u8 *next = 0;
12305   int ret;
12306
12307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12308     {
12309       if (unformat (i, "node %s", &name))
12310         ;
12311       else if (unformat (i, "next %s", &next))
12312         ;
12313       else
12314         break;
12315     }
12316   if (name == 0)
12317     {
12318       errmsg ("node name required");
12319       return -99;
12320     }
12321   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12322     {
12323       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12324       return -99;
12325     }
12326   if (next == 0)
12327     {
12328       errmsg ("next node required");
12329       return -99;
12330     }
12331   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12332     {
12333       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12334       return -99;
12335     }
12336
12337   M (ADD_NODE_NEXT, mp);
12338   clib_memcpy (mp->node_name, name, vec_len (name));
12339   clib_memcpy (mp->next_name, next, vec_len (next));
12340   vec_free (name);
12341   vec_free (next);
12342
12343   S (mp);
12344   W (ret);
12345   return ret;
12346 }
12347
12348 static int
12349 api_l2tpv3_create_tunnel (vat_main_t * vam)
12350 {
12351   unformat_input_t *i = vam->input;
12352   ip6_address_t client_address, our_address;
12353   int client_address_set = 0;
12354   int our_address_set = 0;
12355   u32 local_session_id = 0;
12356   u32 remote_session_id = 0;
12357   u64 local_cookie = 0;
12358   u64 remote_cookie = 0;
12359   u8 l2_sublayer_present = 0;
12360   vl_api_l2tpv3_create_tunnel_t *mp;
12361   int ret;
12362
12363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12364     {
12365       if (unformat (i, "client_address %U", unformat_ip6_address,
12366                     &client_address))
12367         client_address_set = 1;
12368       else if (unformat (i, "our_address %U", unformat_ip6_address,
12369                          &our_address))
12370         our_address_set = 1;
12371       else if (unformat (i, "local_session_id %d", &local_session_id))
12372         ;
12373       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12374         ;
12375       else if (unformat (i, "local_cookie %lld", &local_cookie))
12376         ;
12377       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12378         ;
12379       else if (unformat (i, "l2-sublayer-present"))
12380         l2_sublayer_present = 1;
12381       else
12382         break;
12383     }
12384
12385   if (client_address_set == 0)
12386     {
12387       errmsg ("client_address required");
12388       return -99;
12389     }
12390
12391   if (our_address_set == 0)
12392     {
12393       errmsg ("our_address required");
12394       return -99;
12395     }
12396
12397   M (L2TPV3_CREATE_TUNNEL, mp);
12398
12399   clib_memcpy (mp->client_address, client_address.as_u8,
12400                sizeof (mp->client_address));
12401
12402   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12403
12404   mp->local_session_id = ntohl (local_session_id);
12405   mp->remote_session_id = ntohl (remote_session_id);
12406   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12407   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12408   mp->l2_sublayer_present = l2_sublayer_present;
12409   mp->is_ipv6 = 1;
12410
12411   S (mp);
12412   W (ret);
12413   return ret;
12414 }
12415
12416 static int
12417 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12418 {
12419   unformat_input_t *i = vam->input;
12420   u32 sw_if_index;
12421   u8 sw_if_index_set = 0;
12422   u64 new_local_cookie = 0;
12423   u64 new_remote_cookie = 0;
12424   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12425   int ret;
12426
12427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12428     {
12429       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12430         sw_if_index_set = 1;
12431       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12432         sw_if_index_set = 1;
12433       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12434         ;
12435       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12436         ;
12437       else
12438         break;
12439     }
12440
12441   if (sw_if_index_set == 0)
12442     {
12443       errmsg ("missing interface name or sw_if_index");
12444       return -99;
12445     }
12446
12447   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12448
12449   mp->sw_if_index = ntohl (sw_if_index);
12450   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12451   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12452
12453   S (mp);
12454   W (ret);
12455   return ret;
12456 }
12457
12458 static int
12459 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12460 {
12461   unformat_input_t *i = vam->input;
12462   vl_api_l2tpv3_interface_enable_disable_t *mp;
12463   u32 sw_if_index;
12464   u8 sw_if_index_set = 0;
12465   u8 enable_disable = 1;
12466   int ret;
12467
12468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12471         sw_if_index_set = 1;
12472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12473         sw_if_index_set = 1;
12474       else if (unformat (i, "enable"))
12475         enable_disable = 1;
12476       else if (unformat (i, "disable"))
12477         enable_disable = 0;
12478       else
12479         break;
12480     }
12481
12482   if (sw_if_index_set == 0)
12483     {
12484       errmsg ("missing interface name or sw_if_index");
12485       return -99;
12486     }
12487
12488   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12489
12490   mp->sw_if_index = ntohl (sw_if_index);
12491   mp->enable_disable = enable_disable;
12492
12493   S (mp);
12494   W (ret);
12495   return ret;
12496 }
12497
12498 static int
12499 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12500 {
12501   unformat_input_t *i = vam->input;
12502   vl_api_l2tpv3_set_lookup_key_t *mp;
12503   u8 key = ~0;
12504   int ret;
12505
12506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12507     {
12508       if (unformat (i, "lookup_v6_src"))
12509         key = L2T_LOOKUP_SRC_ADDRESS;
12510       else if (unformat (i, "lookup_v6_dst"))
12511         key = L2T_LOOKUP_DST_ADDRESS;
12512       else if (unformat (i, "lookup_session_id"))
12513         key = L2T_LOOKUP_SESSION_ID;
12514       else
12515         break;
12516     }
12517
12518   if (key == (u8) ~ 0)
12519     {
12520       errmsg ("l2tp session lookup key unset");
12521       return -99;
12522     }
12523
12524   M (L2TPV3_SET_LOOKUP_KEY, mp);
12525
12526   mp->key = key;
12527
12528   S (mp);
12529   W (ret);
12530   return ret;
12531 }
12532
12533 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12534   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12535 {
12536   vat_main_t *vam = &vat_main;
12537
12538   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12539          format_ip6_address, mp->our_address,
12540          format_ip6_address, mp->client_address,
12541          clib_net_to_host_u32 (mp->sw_if_index));
12542
12543   print (vam->ofp,
12544          "   local cookies %016llx %016llx remote cookie %016llx",
12545          clib_net_to_host_u64 (mp->local_cookie[0]),
12546          clib_net_to_host_u64 (mp->local_cookie[1]),
12547          clib_net_to_host_u64 (mp->remote_cookie));
12548
12549   print (vam->ofp, "   local session-id %d remote session-id %d",
12550          clib_net_to_host_u32 (mp->local_session_id),
12551          clib_net_to_host_u32 (mp->remote_session_id));
12552
12553   print (vam->ofp, "   l2 specific sublayer %s\n",
12554          mp->l2_sublayer_present ? "preset" : "absent");
12555
12556 }
12557
12558 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12559   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12560 {
12561   vat_main_t *vam = &vat_main;
12562   vat_json_node_t *node = NULL;
12563   struct in6_addr addr;
12564
12565   if (VAT_JSON_ARRAY != vam->json_tree.type)
12566     {
12567       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12568       vat_json_init_array (&vam->json_tree);
12569     }
12570   node = vat_json_array_add (&vam->json_tree);
12571
12572   vat_json_init_object (node);
12573
12574   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12575   vat_json_object_add_ip6 (node, "our_address", addr);
12576   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12577   vat_json_object_add_ip6 (node, "client_address", addr);
12578
12579   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12580   vat_json_init_array (lc);
12581   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12582   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12583   vat_json_object_add_uint (node, "remote_cookie",
12584                             clib_net_to_host_u64 (mp->remote_cookie));
12585
12586   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12587   vat_json_object_add_uint (node, "local_session_id",
12588                             clib_net_to_host_u32 (mp->local_session_id));
12589   vat_json_object_add_uint (node, "remote_session_id",
12590                             clib_net_to_host_u32 (mp->remote_session_id));
12591   vat_json_object_add_string_copy (node, "l2_sublayer",
12592                                    mp->l2_sublayer_present ? (u8 *) "present"
12593                                    : (u8 *) "absent");
12594 }
12595
12596 static int
12597 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12598 {
12599   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12600   vl_api_control_ping_t *mp_ping;
12601   int ret;
12602
12603   /* Get list of l2tpv3-tunnel interfaces */
12604   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12605   S (mp);
12606
12607   /* Use a control ping for synchronization */
12608   MPING (CONTROL_PING, mp_ping);
12609   S (mp_ping);
12610
12611   W (ret);
12612   return ret;
12613 }
12614
12615
12616 static void vl_api_sw_interface_tap_details_t_handler
12617   (vl_api_sw_interface_tap_details_t * mp)
12618 {
12619   vat_main_t *vam = &vat_main;
12620
12621   print (vam->ofp, "%-16s %d",
12622          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12623 }
12624
12625 static void vl_api_sw_interface_tap_details_t_handler_json
12626   (vl_api_sw_interface_tap_details_t * mp)
12627 {
12628   vat_main_t *vam = &vat_main;
12629   vat_json_node_t *node = NULL;
12630
12631   if (VAT_JSON_ARRAY != vam->json_tree.type)
12632     {
12633       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12634       vat_json_init_array (&vam->json_tree);
12635     }
12636   node = vat_json_array_add (&vam->json_tree);
12637
12638   vat_json_init_object (node);
12639   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12640   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12641 }
12642
12643 static int
12644 api_sw_interface_tap_dump (vat_main_t * vam)
12645 {
12646   vl_api_sw_interface_tap_dump_t *mp;
12647   vl_api_control_ping_t *mp_ping;
12648   int ret;
12649
12650   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12651   /* Get list of tap interfaces */
12652   M (SW_INTERFACE_TAP_DUMP, mp);
12653   S (mp);
12654
12655   /* Use a control ping for synchronization */
12656   MPING (CONTROL_PING, mp_ping);
12657   S (mp_ping);
12658
12659   W (ret);
12660   return ret;
12661 }
12662
12663 static void vl_api_sw_interface_tap_v2_details_t_handler
12664   (vl_api_sw_interface_tap_v2_details_t * mp)
12665 {
12666   vat_main_t *vam = &vat_main;
12667
12668   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12669                     mp->host_ip4_prefix_len);
12670   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12671                     mp->host_ip6_prefix_len);
12672
12673   print (vam->ofp,
12674          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12675          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12676          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12677          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12678          mp->host_bridge, ip4, ip6);
12679
12680   vec_free (ip4);
12681   vec_free (ip6);
12682 }
12683
12684 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12685   (vl_api_sw_interface_tap_v2_details_t * mp)
12686 {
12687   vat_main_t *vam = &vat_main;
12688   vat_json_node_t *node = NULL;
12689
12690   if (VAT_JSON_ARRAY != vam->json_tree.type)
12691     {
12692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12693       vat_json_init_array (&vam->json_tree);
12694     }
12695   node = vat_json_array_add (&vam->json_tree);
12696
12697   vat_json_init_object (node);
12698   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12699   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12700   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12701   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12702   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12703   vat_json_object_add_string_copy (node, "host_mac_addr",
12704                                    format (0, "%U", format_ethernet_address,
12705                                            &mp->host_mac_addr));
12706   vat_json_object_add_string_copy (node, "host_namespace",
12707                                    mp->host_namespace);
12708   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12709   vat_json_object_add_string_copy (node, "host_ip4_addr",
12710                                    format (0, "%U/%d", format_ip4_address,
12711                                            mp->host_ip4_addr,
12712                                            mp->host_ip4_prefix_len));
12713   vat_json_object_add_string_copy (node, "host_ip6_addr",
12714                                    format (0, "%U/%d", format_ip6_address,
12715                                            mp->host_ip6_addr,
12716                                            mp->host_ip6_prefix_len));
12717
12718 }
12719
12720 static int
12721 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12722 {
12723   vl_api_sw_interface_tap_v2_dump_t *mp;
12724   vl_api_control_ping_t *mp_ping;
12725   int ret;
12726
12727   print (vam->ofp,
12728          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12729          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12730          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12731          "host_ip6_addr");
12732
12733   /* Get list of tap interfaces */
12734   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12735   S (mp);
12736
12737   /* Use a control ping for synchronization */
12738   MPING (CONTROL_PING, mp_ping);
12739   S (mp_ping);
12740
12741   W (ret);
12742   return ret;
12743 }
12744
12745 static int
12746 api_vxlan_offload_rx (vat_main_t * vam)
12747 {
12748   unformat_input_t *line_input = vam->input;
12749   vl_api_vxlan_offload_rx_t *mp;
12750   u32 hw_if_index = ~0, rx_if_index = ~0;
12751   u8 is_add = 1;
12752   int ret;
12753
12754   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12755     {
12756       if (unformat (line_input, "del"))
12757         is_add = 0;
12758       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12759                          &hw_if_index))
12760         ;
12761       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12762         ;
12763       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12764                          &rx_if_index))
12765         ;
12766       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12767         ;
12768       else
12769         {
12770           errmsg ("parse error '%U'", format_unformat_error, line_input);
12771           return -99;
12772         }
12773     }
12774
12775   if (hw_if_index == ~0)
12776     {
12777       errmsg ("no hw interface");
12778       return -99;
12779     }
12780
12781   if (rx_if_index == ~0)
12782     {
12783       errmsg ("no rx tunnel");
12784       return -99;
12785     }
12786
12787   M (VXLAN_OFFLOAD_RX, mp);
12788
12789   mp->hw_if_index = ntohl (hw_if_index);
12790   mp->sw_if_index = ntohl (rx_if_index);
12791   mp->enable = is_add;
12792
12793   S (mp);
12794   W (ret);
12795   return ret;
12796 }
12797
12798 static uword unformat_vxlan_decap_next
12799   (unformat_input_t * input, va_list * args)
12800 {
12801   u32 *result = va_arg (*args, u32 *);
12802   u32 tmp;
12803
12804   if (unformat (input, "l2"))
12805     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12806   else if (unformat (input, "%d", &tmp))
12807     *result = tmp;
12808   else
12809     return 0;
12810   return 1;
12811 }
12812
12813 static int
12814 api_vxlan_add_del_tunnel (vat_main_t * vam)
12815 {
12816   unformat_input_t *line_input = vam->input;
12817   vl_api_vxlan_add_del_tunnel_t *mp;
12818   ip46_address_t src, dst;
12819   u8 is_add = 1;
12820   u8 ipv4_set = 0, ipv6_set = 0;
12821   u8 src_set = 0;
12822   u8 dst_set = 0;
12823   u8 grp_set = 0;
12824   u32 instance = ~0;
12825   u32 mcast_sw_if_index = ~0;
12826   u32 encap_vrf_id = 0;
12827   u32 decap_next_index = ~0;
12828   u32 vni = 0;
12829   int ret;
12830
12831   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12832   clib_memset (&src, 0, sizeof src);
12833   clib_memset (&dst, 0, sizeof dst);
12834
12835   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12836     {
12837       if (unformat (line_input, "del"))
12838         is_add = 0;
12839       else if (unformat (line_input, "instance %d", &instance))
12840         ;
12841       else
12842         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12843         {
12844           ipv4_set = 1;
12845           src_set = 1;
12846         }
12847       else
12848         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12849         {
12850           ipv4_set = 1;
12851           dst_set = 1;
12852         }
12853       else
12854         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12855         {
12856           ipv6_set = 1;
12857           src_set = 1;
12858         }
12859       else
12860         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12861         {
12862           ipv6_set = 1;
12863           dst_set = 1;
12864         }
12865       else if (unformat (line_input, "group %U %U",
12866                          unformat_ip4_address, &dst.ip4,
12867                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12868         {
12869           grp_set = dst_set = 1;
12870           ipv4_set = 1;
12871         }
12872       else if (unformat (line_input, "group %U",
12873                          unformat_ip4_address, &dst.ip4))
12874         {
12875           grp_set = dst_set = 1;
12876           ipv4_set = 1;
12877         }
12878       else if (unformat (line_input, "group %U %U",
12879                          unformat_ip6_address, &dst.ip6,
12880                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12881         {
12882           grp_set = dst_set = 1;
12883           ipv6_set = 1;
12884         }
12885       else if (unformat (line_input, "group %U",
12886                          unformat_ip6_address, &dst.ip6))
12887         {
12888           grp_set = dst_set = 1;
12889           ipv6_set = 1;
12890         }
12891       else
12892         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12893         ;
12894       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12895         ;
12896       else if (unformat (line_input, "decap-next %U",
12897                          unformat_vxlan_decap_next, &decap_next_index))
12898         ;
12899       else if (unformat (line_input, "vni %d", &vni))
12900         ;
12901       else
12902         {
12903           errmsg ("parse error '%U'", format_unformat_error, line_input);
12904           return -99;
12905         }
12906     }
12907
12908   if (src_set == 0)
12909     {
12910       errmsg ("tunnel src address not specified");
12911       return -99;
12912     }
12913   if (dst_set == 0)
12914     {
12915       errmsg ("tunnel dst address not specified");
12916       return -99;
12917     }
12918
12919   if (grp_set && !ip46_address_is_multicast (&dst))
12920     {
12921       errmsg ("tunnel group address not multicast");
12922       return -99;
12923     }
12924   if (grp_set && mcast_sw_if_index == ~0)
12925     {
12926       errmsg ("tunnel nonexistent multicast device");
12927       return -99;
12928     }
12929   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12930     {
12931       errmsg ("tunnel dst address must be unicast");
12932       return -99;
12933     }
12934
12935
12936   if (ipv4_set && ipv6_set)
12937     {
12938       errmsg ("both IPv4 and IPv6 addresses specified");
12939       return -99;
12940     }
12941
12942   if ((vni == 0) || (vni >> 24))
12943     {
12944       errmsg ("vni not specified or out of range");
12945       return -99;
12946     }
12947
12948   M (VXLAN_ADD_DEL_TUNNEL, mp);
12949
12950   if (ipv6_set)
12951     {
12952       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12953       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12954     }
12955   else
12956     {
12957       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12958       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12959     }
12960
12961   mp->instance = htonl (instance);
12962   mp->encap_vrf_id = ntohl (encap_vrf_id);
12963   mp->decap_next_index = ntohl (decap_next_index);
12964   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12965   mp->vni = ntohl (vni);
12966   mp->is_add = is_add;
12967   mp->is_ipv6 = ipv6_set;
12968
12969   S (mp);
12970   W (ret);
12971   return ret;
12972 }
12973
12974 static void vl_api_vxlan_tunnel_details_t_handler
12975   (vl_api_vxlan_tunnel_details_t * mp)
12976 {
12977   vat_main_t *vam = &vat_main;
12978   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12979   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12980
12981   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12982          ntohl (mp->sw_if_index),
12983          ntohl (mp->instance),
12984          format_ip46_address, &src, IP46_TYPE_ANY,
12985          format_ip46_address, &dst, IP46_TYPE_ANY,
12986          ntohl (mp->encap_vrf_id),
12987          ntohl (mp->decap_next_index), ntohl (mp->vni),
12988          ntohl (mp->mcast_sw_if_index));
12989 }
12990
12991 static void vl_api_vxlan_tunnel_details_t_handler_json
12992   (vl_api_vxlan_tunnel_details_t * mp)
12993 {
12994   vat_main_t *vam = &vat_main;
12995   vat_json_node_t *node = NULL;
12996
12997   if (VAT_JSON_ARRAY != vam->json_tree.type)
12998     {
12999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13000       vat_json_init_array (&vam->json_tree);
13001     }
13002   node = vat_json_array_add (&vam->json_tree);
13003
13004   vat_json_init_object (node);
13005   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13006
13007   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13008
13009   if (mp->is_ipv6)
13010     {
13011       struct in6_addr ip6;
13012
13013       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13014       vat_json_object_add_ip6 (node, "src_address", ip6);
13015       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13016       vat_json_object_add_ip6 (node, "dst_address", ip6);
13017     }
13018   else
13019     {
13020       struct in_addr ip4;
13021
13022       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13023       vat_json_object_add_ip4 (node, "src_address", ip4);
13024       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13025       vat_json_object_add_ip4 (node, "dst_address", ip4);
13026     }
13027   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13028   vat_json_object_add_uint (node, "decap_next_index",
13029                             ntohl (mp->decap_next_index));
13030   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13031   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13032   vat_json_object_add_uint (node, "mcast_sw_if_index",
13033                             ntohl (mp->mcast_sw_if_index));
13034 }
13035
13036 static int
13037 api_vxlan_tunnel_dump (vat_main_t * vam)
13038 {
13039   unformat_input_t *i = vam->input;
13040   vl_api_vxlan_tunnel_dump_t *mp;
13041   vl_api_control_ping_t *mp_ping;
13042   u32 sw_if_index;
13043   u8 sw_if_index_set = 0;
13044   int ret;
13045
13046   /* Parse args required to build the message */
13047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13048     {
13049       if (unformat (i, "sw_if_index %d", &sw_if_index))
13050         sw_if_index_set = 1;
13051       else
13052         break;
13053     }
13054
13055   if (sw_if_index_set == 0)
13056     {
13057       sw_if_index = ~0;
13058     }
13059
13060   if (!vam->json_output)
13061     {
13062       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13063              "sw_if_index", "instance", "src_address", "dst_address",
13064              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13065     }
13066
13067   /* Get list of vxlan-tunnel interfaces */
13068   M (VXLAN_TUNNEL_DUMP, mp);
13069
13070   mp->sw_if_index = htonl (sw_if_index);
13071
13072   S (mp);
13073
13074   /* Use a control ping for synchronization */
13075   MPING (CONTROL_PING, mp_ping);
13076   S (mp_ping);
13077
13078   W (ret);
13079   return ret;
13080 }
13081
13082 static uword unformat_geneve_decap_next
13083   (unformat_input_t * input, va_list * args)
13084 {
13085   u32 *result = va_arg (*args, u32 *);
13086   u32 tmp;
13087
13088   if (unformat (input, "l2"))
13089     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13090   else if (unformat (input, "%d", &tmp))
13091     *result = tmp;
13092   else
13093     return 0;
13094   return 1;
13095 }
13096
13097 static int
13098 api_geneve_add_del_tunnel (vat_main_t * vam)
13099 {
13100   unformat_input_t *line_input = vam->input;
13101   vl_api_geneve_add_del_tunnel_t *mp;
13102   ip46_address_t src, dst;
13103   u8 is_add = 1;
13104   u8 ipv4_set = 0, ipv6_set = 0;
13105   u8 src_set = 0;
13106   u8 dst_set = 0;
13107   u8 grp_set = 0;
13108   u32 mcast_sw_if_index = ~0;
13109   u32 encap_vrf_id = 0;
13110   u32 decap_next_index = ~0;
13111   u32 vni = 0;
13112   int ret;
13113
13114   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13115   clib_memset (&src, 0, sizeof src);
13116   clib_memset (&dst, 0, sizeof dst);
13117
13118   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13119     {
13120       if (unformat (line_input, "del"))
13121         is_add = 0;
13122       else
13123         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13124         {
13125           ipv4_set = 1;
13126           src_set = 1;
13127         }
13128       else
13129         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13130         {
13131           ipv4_set = 1;
13132           dst_set = 1;
13133         }
13134       else
13135         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13136         {
13137           ipv6_set = 1;
13138           src_set = 1;
13139         }
13140       else
13141         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13142         {
13143           ipv6_set = 1;
13144           dst_set = 1;
13145         }
13146       else if (unformat (line_input, "group %U %U",
13147                          unformat_ip4_address, &dst.ip4,
13148                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13149         {
13150           grp_set = dst_set = 1;
13151           ipv4_set = 1;
13152         }
13153       else if (unformat (line_input, "group %U",
13154                          unformat_ip4_address, &dst.ip4))
13155         {
13156           grp_set = dst_set = 1;
13157           ipv4_set = 1;
13158         }
13159       else if (unformat (line_input, "group %U %U",
13160                          unformat_ip6_address, &dst.ip6,
13161                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13162         {
13163           grp_set = dst_set = 1;
13164           ipv6_set = 1;
13165         }
13166       else if (unformat (line_input, "group %U",
13167                          unformat_ip6_address, &dst.ip6))
13168         {
13169           grp_set = dst_set = 1;
13170           ipv6_set = 1;
13171         }
13172       else
13173         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13174         ;
13175       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13176         ;
13177       else if (unformat (line_input, "decap-next %U",
13178                          unformat_geneve_decap_next, &decap_next_index))
13179         ;
13180       else if (unformat (line_input, "vni %d", &vni))
13181         ;
13182       else
13183         {
13184           errmsg ("parse error '%U'", format_unformat_error, line_input);
13185           return -99;
13186         }
13187     }
13188
13189   if (src_set == 0)
13190     {
13191       errmsg ("tunnel src address not specified");
13192       return -99;
13193     }
13194   if (dst_set == 0)
13195     {
13196       errmsg ("tunnel dst address not specified");
13197       return -99;
13198     }
13199
13200   if (grp_set && !ip46_address_is_multicast (&dst))
13201     {
13202       errmsg ("tunnel group address not multicast");
13203       return -99;
13204     }
13205   if (grp_set && mcast_sw_if_index == ~0)
13206     {
13207       errmsg ("tunnel nonexistent multicast device");
13208       return -99;
13209     }
13210   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13211     {
13212       errmsg ("tunnel dst address must be unicast");
13213       return -99;
13214     }
13215
13216
13217   if (ipv4_set && ipv6_set)
13218     {
13219       errmsg ("both IPv4 and IPv6 addresses specified");
13220       return -99;
13221     }
13222
13223   if ((vni == 0) || (vni >> 24))
13224     {
13225       errmsg ("vni not specified or out of range");
13226       return -99;
13227     }
13228
13229   M (GENEVE_ADD_DEL_TUNNEL, mp);
13230
13231   if (ipv6_set)
13232     {
13233       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13234       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13235     }
13236   else
13237     {
13238       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13239       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13240     }
13241   mp->encap_vrf_id = ntohl (encap_vrf_id);
13242   mp->decap_next_index = ntohl (decap_next_index);
13243   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13244   mp->vni = ntohl (vni);
13245   mp->is_add = is_add;
13246   mp->is_ipv6 = ipv6_set;
13247
13248   S (mp);
13249   W (ret);
13250   return ret;
13251 }
13252
13253 static void vl_api_geneve_tunnel_details_t_handler
13254   (vl_api_geneve_tunnel_details_t * mp)
13255 {
13256   vat_main_t *vam = &vat_main;
13257   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13258   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13259
13260   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13261          ntohl (mp->sw_if_index),
13262          format_ip46_address, &src, IP46_TYPE_ANY,
13263          format_ip46_address, &dst, IP46_TYPE_ANY,
13264          ntohl (mp->encap_vrf_id),
13265          ntohl (mp->decap_next_index), ntohl (mp->vni),
13266          ntohl (mp->mcast_sw_if_index));
13267 }
13268
13269 static void vl_api_geneve_tunnel_details_t_handler_json
13270   (vl_api_geneve_tunnel_details_t * mp)
13271 {
13272   vat_main_t *vam = &vat_main;
13273   vat_json_node_t *node = NULL;
13274
13275   if (VAT_JSON_ARRAY != vam->json_tree.type)
13276     {
13277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13278       vat_json_init_array (&vam->json_tree);
13279     }
13280   node = vat_json_array_add (&vam->json_tree);
13281
13282   vat_json_init_object (node);
13283   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13284   if (mp->is_ipv6)
13285     {
13286       struct in6_addr ip6;
13287
13288       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13289       vat_json_object_add_ip6 (node, "src_address", ip6);
13290       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13291       vat_json_object_add_ip6 (node, "dst_address", ip6);
13292     }
13293   else
13294     {
13295       struct in_addr ip4;
13296
13297       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13298       vat_json_object_add_ip4 (node, "src_address", ip4);
13299       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13300       vat_json_object_add_ip4 (node, "dst_address", ip4);
13301     }
13302   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13303   vat_json_object_add_uint (node, "decap_next_index",
13304                             ntohl (mp->decap_next_index));
13305   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13306   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13307   vat_json_object_add_uint (node, "mcast_sw_if_index",
13308                             ntohl (mp->mcast_sw_if_index));
13309 }
13310
13311 static int
13312 api_geneve_tunnel_dump (vat_main_t * vam)
13313 {
13314   unformat_input_t *i = vam->input;
13315   vl_api_geneve_tunnel_dump_t *mp;
13316   vl_api_control_ping_t *mp_ping;
13317   u32 sw_if_index;
13318   u8 sw_if_index_set = 0;
13319   int ret;
13320
13321   /* Parse args required to build the message */
13322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13323     {
13324       if (unformat (i, "sw_if_index %d", &sw_if_index))
13325         sw_if_index_set = 1;
13326       else
13327         break;
13328     }
13329
13330   if (sw_if_index_set == 0)
13331     {
13332       sw_if_index = ~0;
13333     }
13334
13335   if (!vam->json_output)
13336     {
13337       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13338              "sw_if_index", "local_address", "remote_address",
13339              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13340     }
13341
13342   /* Get list of geneve-tunnel interfaces */
13343   M (GENEVE_TUNNEL_DUMP, mp);
13344
13345   mp->sw_if_index = htonl (sw_if_index);
13346
13347   S (mp);
13348
13349   /* Use a control ping for synchronization */
13350   M (CONTROL_PING, mp_ping);
13351   S (mp_ping);
13352
13353   W (ret);
13354   return ret;
13355 }
13356
13357 static int
13358 api_gre_add_del_tunnel (vat_main_t * vam)
13359 {
13360   unformat_input_t *line_input = vam->input;
13361   vl_api_gre_add_del_tunnel_t *mp;
13362   ip4_address_t src4, dst4;
13363   ip6_address_t src6, dst6;
13364   u8 is_add = 1;
13365   u8 ipv4_set = 0;
13366   u8 ipv6_set = 0;
13367   u8 t_type = GRE_TUNNEL_TYPE_L3;
13368   u8 src_set = 0;
13369   u8 dst_set = 0;
13370   u32 outer_fib_id = 0;
13371   u32 session_id = 0;
13372   u32 instance = ~0;
13373   int ret;
13374
13375   clib_memset (&src4, 0, sizeof src4);
13376   clib_memset (&dst4, 0, sizeof dst4);
13377   clib_memset (&src6, 0, sizeof src6);
13378   clib_memset (&dst6, 0, sizeof dst6);
13379
13380   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13381     {
13382       if (unformat (line_input, "del"))
13383         is_add = 0;
13384       else if (unformat (line_input, "instance %d", &instance))
13385         ;
13386       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13387         {
13388           src_set = 1;
13389           ipv4_set = 1;
13390         }
13391       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13392         {
13393           dst_set = 1;
13394           ipv4_set = 1;
13395         }
13396       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13397         {
13398           src_set = 1;
13399           ipv6_set = 1;
13400         }
13401       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13402         {
13403           dst_set = 1;
13404           ipv6_set = 1;
13405         }
13406       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13407         ;
13408       else if (unformat (line_input, "teb"))
13409         t_type = GRE_TUNNEL_TYPE_TEB;
13410       else if (unformat (line_input, "erspan %d", &session_id))
13411         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13412       else
13413         {
13414           errmsg ("parse error '%U'", format_unformat_error, line_input);
13415           return -99;
13416         }
13417     }
13418
13419   if (src_set == 0)
13420     {
13421       errmsg ("tunnel src address not specified");
13422       return -99;
13423     }
13424   if (dst_set == 0)
13425     {
13426       errmsg ("tunnel dst address not specified");
13427       return -99;
13428     }
13429   if (ipv4_set && ipv6_set)
13430     {
13431       errmsg ("both IPv4 and IPv6 addresses specified");
13432       return -99;
13433     }
13434
13435
13436   M (GRE_ADD_DEL_TUNNEL, mp);
13437
13438   if (ipv4_set)
13439     {
13440       clib_memcpy (&mp->src_address, &src4, 4);
13441       clib_memcpy (&mp->dst_address, &dst4, 4);
13442     }
13443   else
13444     {
13445       clib_memcpy (&mp->src_address, &src6, 16);
13446       clib_memcpy (&mp->dst_address, &dst6, 16);
13447     }
13448   mp->instance = htonl (instance);
13449   mp->outer_fib_id = htonl (outer_fib_id);
13450   mp->is_add = is_add;
13451   mp->session_id = htons ((u16) session_id);
13452   mp->tunnel_type = t_type;
13453   mp->is_ipv6 = ipv6_set;
13454
13455   S (mp);
13456   W (ret);
13457   return ret;
13458 }
13459
13460 static void vl_api_gre_tunnel_details_t_handler
13461   (vl_api_gre_tunnel_details_t * mp)
13462 {
13463   vat_main_t *vam = &vat_main;
13464   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13465   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13466
13467   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13468          ntohl (mp->sw_if_index),
13469          ntohl (mp->instance),
13470          format_ip46_address, &src, IP46_TYPE_ANY,
13471          format_ip46_address, &dst, IP46_TYPE_ANY,
13472          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13473 }
13474
13475 static void vl_api_gre_tunnel_details_t_handler_json
13476   (vl_api_gre_tunnel_details_t * mp)
13477 {
13478   vat_main_t *vam = &vat_main;
13479   vat_json_node_t *node = NULL;
13480   struct in_addr ip4;
13481   struct in6_addr ip6;
13482
13483   if (VAT_JSON_ARRAY != vam->json_tree.type)
13484     {
13485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13486       vat_json_init_array (&vam->json_tree);
13487     }
13488   node = vat_json_array_add (&vam->json_tree);
13489
13490   vat_json_init_object (node);
13491   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13492   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13493   if (!mp->is_ipv6)
13494     {
13495       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13496       vat_json_object_add_ip4 (node, "src_address", ip4);
13497       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13498       vat_json_object_add_ip4 (node, "dst_address", ip4);
13499     }
13500   else
13501     {
13502       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13503       vat_json_object_add_ip6 (node, "src_address", ip6);
13504       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13505       vat_json_object_add_ip6 (node, "dst_address", ip6);
13506     }
13507   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13508   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13509   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13510   vat_json_object_add_uint (node, "session_id", mp->session_id);
13511 }
13512
13513 static int
13514 api_gre_tunnel_dump (vat_main_t * vam)
13515 {
13516   unformat_input_t *i = vam->input;
13517   vl_api_gre_tunnel_dump_t *mp;
13518   vl_api_control_ping_t *mp_ping;
13519   u32 sw_if_index;
13520   u8 sw_if_index_set = 0;
13521   int ret;
13522
13523   /* Parse args required to build the message */
13524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13525     {
13526       if (unformat (i, "sw_if_index %d", &sw_if_index))
13527         sw_if_index_set = 1;
13528       else
13529         break;
13530     }
13531
13532   if (sw_if_index_set == 0)
13533     {
13534       sw_if_index = ~0;
13535     }
13536
13537   if (!vam->json_output)
13538     {
13539       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13540              "sw_if_index", "instance", "src_address", "dst_address",
13541              "tunnel_type", "outer_fib_id", "session_id");
13542     }
13543
13544   /* Get list of gre-tunnel interfaces */
13545   M (GRE_TUNNEL_DUMP, mp);
13546
13547   mp->sw_if_index = htonl (sw_if_index);
13548
13549   S (mp);
13550
13551   /* Use a control ping for synchronization */
13552   MPING (CONTROL_PING, mp_ping);
13553   S (mp_ping);
13554
13555   W (ret);
13556   return ret;
13557 }
13558
13559 static int
13560 api_l2_fib_clear_table (vat_main_t * vam)
13561 {
13562 //  unformat_input_t * i = vam->input;
13563   vl_api_l2_fib_clear_table_t *mp;
13564   int ret;
13565
13566   M (L2_FIB_CLEAR_TABLE, mp);
13567
13568   S (mp);
13569   W (ret);
13570   return ret;
13571 }
13572
13573 static int
13574 api_l2_interface_efp_filter (vat_main_t * vam)
13575 {
13576   unformat_input_t *i = vam->input;
13577   vl_api_l2_interface_efp_filter_t *mp;
13578   u32 sw_if_index;
13579   u8 enable = 1;
13580   u8 sw_if_index_set = 0;
13581   int ret;
13582
13583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13584     {
13585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13586         sw_if_index_set = 1;
13587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13588         sw_if_index_set = 1;
13589       else if (unformat (i, "enable"))
13590         enable = 1;
13591       else if (unformat (i, "disable"))
13592         enable = 0;
13593       else
13594         {
13595           clib_warning ("parse error '%U'", format_unformat_error, i);
13596           return -99;
13597         }
13598     }
13599
13600   if (sw_if_index_set == 0)
13601     {
13602       errmsg ("missing sw_if_index");
13603       return -99;
13604     }
13605
13606   M (L2_INTERFACE_EFP_FILTER, mp);
13607
13608   mp->sw_if_index = ntohl (sw_if_index);
13609   mp->enable_disable = enable;
13610
13611   S (mp);
13612   W (ret);
13613   return ret;
13614 }
13615
13616 #define foreach_vtr_op                          \
13617 _("disable",  L2_VTR_DISABLED)                  \
13618 _("push-1",  L2_VTR_PUSH_1)                     \
13619 _("push-2",  L2_VTR_PUSH_2)                     \
13620 _("pop-1",  L2_VTR_POP_1)                       \
13621 _("pop-2",  L2_VTR_POP_2)                       \
13622 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13623 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13624 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13625 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13626
13627 static int
13628 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13629 {
13630   unformat_input_t *i = vam->input;
13631   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13632   u32 sw_if_index;
13633   u8 sw_if_index_set = 0;
13634   u8 vtr_op_set = 0;
13635   u32 vtr_op = 0;
13636   u32 push_dot1q = 1;
13637   u32 tag1 = ~0;
13638   u32 tag2 = ~0;
13639   int ret;
13640
13641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13642     {
13643       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13644         sw_if_index_set = 1;
13645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13646         sw_if_index_set = 1;
13647       else if (unformat (i, "vtr_op %d", &vtr_op))
13648         vtr_op_set = 1;
13649 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13650       foreach_vtr_op
13651 #undef _
13652         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13653         ;
13654       else if (unformat (i, "tag1 %d", &tag1))
13655         ;
13656       else if (unformat (i, "tag2 %d", &tag2))
13657         ;
13658       else
13659         {
13660           clib_warning ("parse error '%U'", format_unformat_error, i);
13661           return -99;
13662         }
13663     }
13664
13665   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13666     {
13667       errmsg ("missing vtr operation or sw_if_index");
13668       return -99;
13669     }
13670
13671   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13672   mp->sw_if_index = ntohl (sw_if_index);
13673   mp->vtr_op = ntohl (vtr_op);
13674   mp->push_dot1q = ntohl (push_dot1q);
13675   mp->tag1 = ntohl (tag1);
13676   mp->tag2 = ntohl (tag2);
13677
13678   S (mp);
13679   W (ret);
13680   return ret;
13681 }
13682
13683 static int
13684 api_create_vhost_user_if (vat_main_t * vam)
13685 {
13686   unformat_input_t *i = vam->input;
13687   vl_api_create_vhost_user_if_t *mp;
13688   u8 *file_name;
13689   u8 is_server = 0;
13690   u8 file_name_set = 0;
13691   u32 custom_dev_instance = ~0;
13692   u8 hwaddr[6];
13693   u8 use_custom_mac = 0;
13694   u8 disable_mrg_rxbuf = 0;
13695   u8 disable_indirect_desc = 0;
13696   u8 *tag = 0;
13697   int ret;
13698
13699   /* Shut up coverity */
13700   clib_memset (hwaddr, 0, sizeof (hwaddr));
13701
13702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13703     {
13704       if (unformat (i, "socket %s", &file_name))
13705         {
13706           file_name_set = 1;
13707         }
13708       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13709         ;
13710       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13711         use_custom_mac = 1;
13712       else if (unformat (i, "server"))
13713         is_server = 1;
13714       else if (unformat (i, "disable_mrg_rxbuf"))
13715         disable_mrg_rxbuf = 1;
13716       else if (unformat (i, "disable_indirect_desc"))
13717         disable_indirect_desc = 1;
13718       else if (unformat (i, "tag %s", &tag))
13719         ;
13720       else
13721         break;
13722     }
13723
13724   if (file_name_set == 0)
13725     {
13726       errmsg ("missing socket file name");
13727       return -99;
13728     }
13729
13730   if (vec_len (file_name) > 255)
13731     {
13732       errmsg ("socket file name too long");
13733       return -99;
13734     }
13735   vec_add1 (file_name, 0);
13736
13737   M (CREATE_VHOST_USER_IF, mp);
13738
13739   mp->is_server = is_server;
13740   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
13741   mp->disable_indirect_desc = disable_indirect_desc;
13742   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13743   vec_free (file_name);
13744   if (custom_dev_instance != ~0)
13745     {
13746       mp->renumber = 1;
13747       mp->custom_dev_instance = ntohl (custom_dev_instance);
13748     }
13749
13750   mp->use_custom_mac = use_custom_mac;
13751   clib_memcpy (mp->mac_address, hwaddr, 6);
13752   if (tag)
13753     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13754   vec_free (tag);
13755
13756   S (mp);
13757   W (ret);
13758   return ret;
13759 }
13760
13761 static int
13762 api_modify_vhost_user_if (vat_main_t * vam)
13763 {
13764   unformat_input_t *i = vam->input;
13765   vl_api_modify_vhost_user_if_t *mp;
13766   u8 *file_name;
13767   u8 is_server = 0;
13768   u8 file_name_set = 0;
13769   u32 custom_dev_instance = ~0;
13770   u8 sw_if_index_set = 0;
13771   u32 sw_if_index = (u32) ~ 0;
13772   int ret;
13773
13774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13775     {
13776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13777         sw_if_index_set = 1;
13778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13779         sw_if_index_set = 1;
13780       else if (unformat (i, "socket %s", &file_name))
13781         {
13782           file_name_set = 1;
13783         }
13784       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13785         ;
13786       else if (unformat (i, "server"))
13787         is_server = 1;
13788       else
13789         break;
13790     }
13791
13792   if (sw_if_index_set == 0)
13793     {
13794       errmsg ("missing sw_if_index or interface name");
13795       return -99;
13796     }
13797
13798   if (file_name_set == 0)
13799     {
13800       errmsg ("missing socket file name");
13801       return -99;
13802     }
13803
13804   if (vec_len (file_name) > 255)
13805     {
13806       errmsg ("socket file name too long");
13807       return -99;
13808     }
13809   vec_add1 (file_name, 0);
13810
13811   M (MODIFY_VHOST_USER_IF, mp);
13812
13813   mp->sw_if_index = ntohl (sw_if_index);
13814   mp->is_server = is_server;
13815   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13816   vec_free (file_name);
13817   if (custom_dev_instance != ~0)
13818     {
13819       mp->renumber = 1;
13820       mp->custom_dev_instance = ntohl (custom_dev_instance);
13821     }
13822
13823   S (mp);
13824   W (ret);
13825   return ret;
13826 }
13827
13828 static int
13829 api_delete_vhost_user_if (vat_main_t * vam)
13830 {
13831   unformat_input_t *i = vam->input;
13832   vl_api_delete_vhost_user_if_t *mp;
13833   u32 sw_if_index = ~0;
13834   u8 sw_if_index_set = 0;
13835   int ret;
13836
13837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13840         sw_if_index_set = 1;
13841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13842         sw_if_index_set = 1;
13843       else
13844         break;
13845     }
13846
13847   if (sw_if_index_set == 0)
13848     {
13849       errmsg ("missing sw_if_index or interface name");
13850       return -99;
13851     }
13852
13853
13854   M (DELETE_VHOST_USER_IF, mp);
13855
13856   mp->sw_if_index = ntohl (sw_if_index);
13857
13858   S (mp);
13859   W (ret);
13860   return ret;
13861 }
13862
13863 static void vl_api_sw_interface_vhost_user_details_t_handler
13864   (vl_api_sw_interface_vhost_user_details_t * mp)
13865 {
13866   vat_main_t *vam = &vat_main;
13867
13868   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13869          (char *) mp->interface_name,
13870          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13871          clib_net_to_host_u64 (mp->features), mp->is_server,
13872          ntohl (mp->num_regions), (char *) mp->sock_filename);
13873   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13874 }
13875
13876 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13877   (vl_api_sw_interface_vhost_user_details_t * mp)
13878 {
13879   vat_main_t *vam = &vat_main;
13880   vat_json_node_t *node = NULL;
13881
13882   if (VAT_JSON_ARRAY != vam->json_tree.type)
13883     {
13884       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13885       vat_json_init_array (&vam->json_tree);
13886     }
13887   node = vat_json_array_add (&vam->json_tree);
13888
13889   vat_json_init_object (node);
13890   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13891   vat_json_object_add_string_copy (node, "interface_name",
13892                                    mp->interface_name);
13893   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13894                             ntohl (mp->virtio_net_hdr_sz));
13895   vat_json_object_add_uint (node, "features",
13896                             clib_net_to_host_u64 (mp->features));
13897   vat_json_object_add_uint (node, "is_server", mp->is_server);
13898   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13899   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13900   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13901 }
13902
13903 static int
13904 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13905 {
13906   vl_api_sw_interface_vhost_user_dump_t *mp;
13907   vl_api_control_ping_t *mp_ping;
13908   int ret;
13909   print (vam->ofp,
13910          "Interface name            idx hdr_sz features server regions filename");
13911
13912   /* Get list of vhost-user interfaces */
13913   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13914   S (mp);
13915
13916   /* Use a control ping for synchronization */
13917   MPING (CONTROL_PING, mp_ping);
13918   S (mp_ping);
13919
13920   W (ret);
13921   return ret;
13922 }
13923
13924 static int
13925 api_show_version (vat_main_t * vam)
13926 {
13927   vl_api_show_version_t *mp;
13928   int ret;
13929
13930   M (SHOW_VERSION, mp);
13931
13932   S (mp);
13933   W (ret);
13934   return ret;
13935 }
13936
13937
13938 static int
13939 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13940 {
13941   unformat_input_t *line_input = vam->input;
13942   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13943   ip4_address_t local4, remote4;
13944   ip6_address_t local6, remote6;
13945   u8 is_add = 1;
13946   u8 ipv4_set = 0, ipv6_set = 0;
13947   u8 local_set = 0;
13948   u8 remote_set = 0;
13949   u8 grp_set = 0;
13950   u32 mcast_sw_if_index = ~0;
13951   u32 encap_vrf_id = 0;
13952   u32 decap_vrf_id = 0;
13953   u8 protocol = ~0;
13954   u32 vni;
13955   u8 vni_set = 0;
13956   int ret;
13957
13958   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13959   clib_memset (&local4, 0, sizeof local4);
13960   clib_memset (&remote4, 0, sizeof remote4);
13961   clib_memset (&local6, 0, sizeof local6);
13962   clib_memset (&remote6, 0, sizeof remote6);
13963
13964   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13965     {
13966       if (unformat (line_input, "del"))
13967         is_add = 0;
13968       else if (unformat (line_input, "local %U",
13969                          unformat_ip4_address, &local4))
13970         {
13971           local_set = 1;
13972           ipv4_set = 1;
13973         }
13974       else if (unformat (line_input, "remote %U",
13975                          unformat_ip4_address, &remote4))
13976         {
13977           remote_set = 1;
13978           ipv4_set = 1;
13979         }
13980       else if (unformat (line_input, "local %U",
13981                          unformat_ip6_address, &local6))
13982         {
13983           local_set = 1;
13984           ipv6_set = 1;
13985         }
13986       else if (unformat (line_input, "remote %U",
13987                          unformat_ip6_address, &remote6))
13988         {
13989           remote_set = 1;
13990           ipv6_set = 1;
13991         }
13992       else if (unformat (line_input, "group %U %U",
13993                          unformat_ip4_address, &remote4,
13994                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13995         {
13996           grp_set = remote_set = 1;
13997           ipv4_set = 1;
13998         }
13999       else if (unformat (line_input, "group %U",
14000                          unformat_ip4_address, &remote4))
14001         {
14002           grp_set = remote_set = 1;
14003           ipv4_set = 1;
14004         }
14005       else if (unformat (line_input, "group %U %U",
14006                          unformat_ip6_address, &remote6,
14007                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14008         {
14009           grp_set = remote_set = 1;
14010           ipv6_set = 1;
14011         }
14012       else if (unformat (line_input, "group %U",
14013                          unformat_ip6_address, &remote6))
14014         {
14015           grp_set = remote_set = 1;
14016           ipv6_set = 1;
14017         }
14018       else
14019         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14020         ;
14021       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14022         ;
14023       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14024         ;
14025       else if (unformat (line_input, "vni %d", &vni))
14026         vni_set = 1;
14027       else if (unformat (line_input, "next-ip4"))
14028         protocol = 1;
14029       else if (unformat (line_input, "next-ip6"))
14030         protocol = 2;
14031       else if (unformat (line_input, "next-ethernet"))
14032         protocol = 3;
14033       else if (unformat (line_input, "next-nsh"))
14034         protocol = 4;
14035       else
14036         {
14037           errmsg ("parse error '%U'", format_unformat_error, line_input);
14038           return -99;
14039         }
14040     }
14041
14042   if (local_set == 0)
14043     {
14044       errmsg ("tunnel local address not specified");
14045       return -99;
14046     }
14047   if (remote_set == 0)
14048     {
14049       errmsg ("tunnel remote address not specified");
14050       return -99;
14051     }
14052   if (grp_set && mcast_sw_if_index == ~0)
14053     {
14054       errmsg ("tunnel nonexistent multicast device");
14055       return -99;
14056     }
14057   if (ipv4_set && ipv6_set)
14058     {
14059       errmsg ("both IPv4 and IPv6 addresses specified");
14060       return -99;
14061     }
14062
14063   if (vni_set == 0)
14064     {
14065       errmsg ("vni not specified");
14066       return -99;
14067     }
14068
14069   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14070
14071
14072   if (ipv6_set)
14073     {
14074       clib_memcpy (&mp->local, &local6, sizeof (local6));
14075       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14076     }
14077   else
14078     {
14079       clib_memcpy (&mp->local, &local4, sizeof (local4));
14080       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14081     }
14082
14083   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14084   mp->encap_vrf_id = ntohl (encap_vrf_id);
14085   mp->decap_vrf_id = ntohl (decap_vrf_id);
14086   mp->protocol = protocol;
14087   mp->vni = ntohl (vni);
14088   mp->is_add = is_add;
14089   mp->is_ipv6 = ipv6_set;
14090
14091   S (mp);
14092   W (ret);
14093   return ret;
14094 }
14095
14096 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14097   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14098 {
14099   vat_main_t *vam = &vat_main;
14100   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14101   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14102
14103   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14104          ntohl (mp->sw_if_index),
14105          format_ip46_address, &local, IP46_TYPE_ANY,
14106          format_ip46_address, &remote, IP46_TYPE_ANY,
14107          ntohl (mp->vni), mp->protocol,
14108          ntohl (mp->mcast_sw_if_index),
14109          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14110 }
14111
14112
14113 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14114   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14115 {
14116   vat_main_t *vam = &vat_main;
14117   vat_json_node_t *node = NULL;
14118   struct in_addr ip4;
14119   struct in6_addr ip6;
14120
14121   if (VAT_JSON_ARRAY != vam->json_tree.type)
14122     {
14123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14124       vat_json_init_array (&vam->json_tree);
14125     }
14126   node = vat_json_array_add (&vam->json_tree);
14127
14128   vat_json_init_object (node);
14129   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14130   if (mp->is_ipv6)
14131     {
14132       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14133       vat_json_object_add_ip6 (node, "local", ip6);
14134       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14135       vat_json_object_add_ip6 (node, "remote", ip6);
14136     }
14137   else
14138     {
14139       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14140       vat_json_object_add_ip4 (node, "local", ip4);
14141       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14142       vat_json_object_add_ip4 (node, "remote", ip4);
14143     }
14144   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14145   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14146   vat_json_object_add_uint (node, "mcast_sw_if_index",
14147                             ntohl (mp->mcast_sw_if_index));
14148   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14149   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14150   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14151 }
14152
14153 static int
14154 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14155 {
14156   unformat_input_t *i = vam->input;
14157   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14158   vl_api_control_ping_t *mp_ping;
14159   u32 sw_if_index;
14160   u8 sw_if_index_set = 0;
14161   int ret;
14162
14163   /* Parse args required to build the message */
14164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14165     {
14166       if (unformat (i, "sw_if_index %d", &sw_if_index))
14167         sw_if_index_set = 1;
14168       else
14169         break;
14170     }
14171
14172   if (sw_if_index_set == 0)
14173     {
14174       sw_if_index = ~0;
14175     }
14176
14177   if (!vam->json_output)
14178     {
14179       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14180              "sw_if_index", "local", "remote", "vni",
14181              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14182     }
14183
14184   /* Get list of vxlan-tunnel interfaces */
14185   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14186
14187   mp->sw_if_index = htonl (sw_if_index);
14188
14189   S (mp);
14190
14191   /* Use a control ping for synchronization */
14192   MPING (CONTROL_PING, mp_ping);
14193   S (mp_ping);
14194
14195   W (ret);
14196   return ret;
14197 }
14198
14199 static void vl_api_l2_fib_table_details_t_handler
14200   (vl_api_l2_fib_table_details_t * mp)
14201 {
14202   vat_main_t *vam = &vat_main;
14203
14204   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14205          "       %d       %d     %d",
14206          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14207          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14208          mp->bvi_mac);
14209 }
14210
14211 static void vl_api_l2_fib_table_details_t_handler_json
14212   (vl_api_l2_fib_table_details_t * mp)
14213 {
14214   vat_main_t *vam = &vat_main;
14215   vat_json_node_t *node = NULL;
14216
14217   if (VAT_JSON_ARRAY != vam->json_tree.type)
14218     {
14219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14220       vat_json_init_array (&vam->json_tree);
14221     }
14222   node = vat_json_array_add (&vam->json_tree);
14223
14224   vat_json_init_object (node);
14225   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14226   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14227   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14228   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14229   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14230   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14231 }
14232
14233 static int
14234 api_l2_fib_table_dump (vat_main_t * vam)
14235 {
14236   unformat_input_t *i = vam->input;
14237   vl_api_l2_fib_table_dump_t *mp;
14238   vl_api_control_ping_t *mp_ping;
14239   u32 bd_id;
14240   u8 bd_id_set = 0;
14241   int ret;
14242
14243   /* Parse args required to build the message */
14244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14245     {
14246       if (unformat (i, "bd_id %d", &bd_id))
14247         bd_id_set = 1;
14248       else
14249         break;
14250     }
14251
14252   if (bd_id_set == 0)
14253     {
14254       errmsg ("missing bridge domain");
14255       return -99;
14256     }
14257
14258   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14259
14260   /* Get list of l2 fib entries */
14261   M (L2_FIB_TABLE_DUMP, mp);
14262
14263   mp->bd_id = ntohl (bd_id);
14264   S (mp);
14265
14266   /* Use a control ping for synchronization */
14267   MPING (CONTROL_PING, mp_ping);
14268   S (mp_ping);
14269
14270   W (ret);
14271   return ret;
14272 }
14273
14274
14275 static int
14276 api_interface_name_renumber (vat_main_t * vam)
14277 {
14278   unformat_input_t *line_input = vam->input;
14279   vl_api_interface_name_renumber_t *mp;
14280   u32 sw_if_index = ~0;
14281   u32 new_show_dev_instance = ~0;
14282   int ret;
14283
14284   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14285     {
14286       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14287                     &sw_if_index))
14288         ;
14289       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14290         ;
14291       else if (unformat (line_input, "new_show_dev_instance %d",
14292                          &new_show_dev_instance))
14293         ;
14294       else
14295         break;
14296     }
14297
14298   if (sw_if_index == ~0)
14299     {
14300       errmsg ("missing interface name or sw_if_index");
14301       return -99;
14302     }
14303
14304   if (new_show_dev_instance == ~0)
14305     {
14306       errmsg ("missing new_show_dev_instance");
14307       return -99;
14308     }
14309
14310   M (INTERFACE_NAME_RENUMBER, mp);
14311
14312   mp->sw_if_index = ntohl (sw_if_index);
14313   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14314
14315   S (mp);
14316   W (ret);
14317   return ret;
14318 }
14319
14320 static int
14321 api_ip_probe_neighbor (vat_main_t * vam)
14322 {
14323   unformat_input_t *i = vam->input;
14324   vl_api_ip_probe_neighbor_t *mp;
14325   u8 int_set = 0;
14326   u8 adr_set = 0;
14327   u8 is_ipv6 = 0;
14328   u8 dst_adr[16];
14329   u32 sw_if_index;
14330   int ret;
14331
14332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14333     {
14334       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14335         int_set = 1;
14336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14337         int_set = 1;
14338       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14339         adr_set = 1;
14340       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14341         {
14342           adr_set = 1;
14343           is_ipv6 = 1;
14344         }
14345       else
14346         break;
14347     }
14348
14349   if (int_set == 0)
14350     {
14351       errmsg ("missing interface");
14352       return -99;
14353     }
14354
14355   if (adr_set == 0)
14356     {
14357       errmsg ("missing addresses");
14358       return -99;
14359     }
14360
14361   M (IP_PROBE_NEIGHBOR, mp);
14362
14363   mp->sw_if_index = ntohl (sw_if_index);
14364   mp->is_ipv6 = is_ipv6;
14365   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14366
14367   S (mp);
14368   W (ret);
14369   return ret;
14370 }
14371
14372 static int
14373 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14374 {
14375   unformat_input_t *i = vam->input;
14376   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14377   u8 mode = IP_SCAN_V46_NEIGHBORS;
14378   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14379   int ret;
14380
14381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14382     {
14383       if (unformat (i, "ip4"))
14384         mode = IP_SCAN_V4_NEIGHBORS;
14385       else if (unformat (i, "ip6"))
14386         mode = IP_SCAN_V6_NEIGHBORS;
14387       if (unformat (i, "both"))
14388         mode = IP_SCAN_V46_NEIGHBORS;
14389       else if (unformat (i, "disable"))
14390         mode = IP_SCAN_DISABLED;
14391       else if (unformat (i, "interval %d", &interval))
14392         ;
14393       else if (unformat (i, "max-time %d", &time))
14394         ;
14395       else if (unformat (i, "max-update %d", &update))
14396         ;
14397       else if (unformat (i, "delay %d", &delay))
14398         ;
14399       else if (unformat (i, "stale %d", &stale))
14400         ;
14401       else
14402         break;
14403     }
14404
14405   if (interval > 255)
14406     {
14407       errmsg ("interval cannot exceed 255 minutes.");
14408       return -99;
14409     }
14410   if (time > 255)
14411     {
14412       errmsg ("max-time cannot exceed 255 usec.");
14413       return -99;
14414     }
14415   if (update > 255)
14416     {
14417       errmsg ("max-update cannot exceed 255.");
14418       return -99;
14419     }
14420   if (delay > 255)
14421     {
14422       errmsg ("delay cannot exceed 255 msec.");
14423       return -99;
14424     }
14425   if (stale > 255)
14426     {
14427       errmsg ("stale cannot exceed 255 minutes.");
14428       return -99;
14429     }
14430
14431   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14432   mp->mode = mode;
14433   mp->scan_interval = interval;
14434   mp->max_proc_time = time;
14435   mp->max_update = update;
14436   mp->scan_int_delay = delay;
14437   mp->stale_threshold = stale;
14438
14439   S (mp);
14440   W (ret);
14441   return ret;
14442 }
14443
14444 static int
14445 api_want_ip4_arp_events (vat_main_t * vam)
14446 {
14447   unformat_input_t *line_input = vam->input;
14448   vl_api_want_ip4_arp_events_t *mp;
14449   ip4_address_t address;
14450   int address_set = 0;
14451   u32 enable_disable = 1;
14452   int ret;
14453
14454   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14455     {
14456       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14457         address_set = 1;
14458       else if (unformat (line_input, "del"))
14459         enable_disable = 0;
14460       else
14461         break;
14462     }
14463
14464   if (address_set == 0)
14465     {
14466       errmsg ("missing addresses");
14467       return -99;
14468     }
14469
14470   M (WANT_IP4_ARP_EVENTS, mp);
14471   mp->enable_disable = enable_disable;
14472   mp->pid = htonl (getpid ());
14473   mp->address = address.as_u32;
14474
14475   S (mp);
14476   W (ret);
14477   return ret;
14478 }
14479
14480 static int
14481 api_want_ip6_nd_events (vat_main_t * vam)
14482 {
14483   unformat_input_t *line_input = vam->input;
14484   vl_api_want_ip6_nd_events_t *mp;
14485   ip6_address_t address;
14486   int address_set = 0;
14487   u32 enable_disable = 1;
14488   int ret;
14489
14490   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14491     {
14492       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14493         address_set = 1;
14494       else if (unformat (line_input, "del"))
14495         enable_disable = 0;
14496       else
14497         break;
14498     }
14499
14500   if (address_set == 0)
14501     {
14502       errmsg ("missing addresses");
14503       return -99;
14504     }
14505
14506   M (WANT_IP6_ND_EVENTS, mp);
14507   mp->enable_disable = enable_disable;
14508   mp->pid = htonl (getpid ());
14509   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14510
14511   S (mp);
14512   W (ret);
14513   return ret;
14514 }
14515
14516 static int
14517 api_want_l2_macs_events (vat_main_t * vam)
14518 {
14519   unformat_input_t *line_input = vam->input;
14520   vl_api_want_l2_macs_events_t *mp;
14521   u8 enable_disable = 1;
14522   u32 scan_delay = 0;
14523   u32 max_macs_in_event = 0;
14524   u32 learn_limit = 0;
14525   int ret;
14526
14527   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (line_input, "learn-limit %d", &learn_limit))
14530         ;
14531       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14532         ;
14533       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14534         ;
14535       else if (unformat (line_input, "disable"))
14536         enable_disable = 0;
14537       else
14538         break;
14539     }
14540
14541   M (WANT_L2_MACS_EVENTS, mp);
14542   mp->enable_disable = enable_disable;
14543   mp->pid = htonl (getpid ());
14544   mp->learn_limit = htonl (learn_limit);
14545   mp->scan_delay = (u8) scan_delay;
14546   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14547   S (mp);
14548   W (ret);
14549   return ret;
14550 }
14551
14552 static int
14553 api_input_acl_set_interface (vat_main_t * vam)
14554 {
14555   unformat_input_t *i = vam->input;
14556   vl_api_input_acl_set_interface_t *mp;
14557   u32 sw_if_index;
14558   int sw_if_index_set;
14559   u32 ip4_table_index = ~0;
14560   u32 ip6_table_index = ~0;
14561   u32 l2_table_index = ~0;
14562   u8 is_add = 1;
14563   int ret;
14564
14565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14566     {
14567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14568         sw_if_index_set = 1;
14569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14570         sw_if_index_set = 1;
14571       else if (unformat (i, "del"))
14572         is_add = 0;
14573       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14574         ;
14575       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14576         ;
14577       else if (unformat (i, "l2-table %d", &l2_table_index))
14578         ;
14579       else
14580         {
14581           clib_warning ("parse error '%U'", format_unformat_error, i);
14582           return -99;
14583         }
14584     }
14585
14586   if (sw_if_index_set == 0)
14587     {
14588       errmsg ("missing interface name or sw_if_index");
14589       return -99;
14590     }
14591
14592   M (INPUT_ACL_SET_INTERFACE, mp);
14593
14594   mp->sw_if_index = ntohl (sw_if_index);
14595   mp->ip4_table_index = ntohl (ip4_table_index);
14596   mp->ip6_table_index = ntohl (ip6_table_index);
14597   mp->l2_table_index = ntohl (l2_table_index);
14598   mp->is_add = is_add;
14599
14600   S (mp);
14601   W (ret);
14602   return ret;
14603 }
14604
14605 static int
14606 api_output_acl_set_interface (vat_main_t * vam)
14607 {
14608   unformat_input_t *i = vam->input;
14609   vl_api_output_acl_set_interface_t *mp;
14610   u32 sw_if_index;
14611   int sw_if_index_set;
14612   u32 ip4_table_index = ~0;
14613   u32 ip6_table_index = ~0;
14614   u32 l2_table_index = ~0;
14615   u8 is_add = 1;
14616   int ret;
14617
14618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14619     {
14620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14621         sw_if_index_set = 1;
14622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14623         sw_if_index_set = 1;
14624       else if (unformat (i, "del"))
14625         is_add = 0;
14626       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14627         ;
14628       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14629         ;
14630       else if (unformat (i, "l2-table %d", &l2_table_index))
14631         ;
14632       else
14633         {
14634           clib_warning ("parse error '%U'", format_unformat_error, i);
14635           return -99;
14636         }
14637     }
14638
14639   if (sw_if_index_set == 0)
14640     {
14641       errmsg ("missing interface name or sw_if_index");
14642       return -99;
14643     }
14644
14645   M (OUTPUT_ACL_SET_INTERFACE, mp);
14646
14647   mp->sw_if_index = ntohl (sw_if_index);
14648   mp->ip4_table_index = ntohl (ip4_table_index);
14649   mp->ip6_table_index = ntohl (ip6_table_index);
14650   mp->l2_table_index = ntohl (l2_table_index);
14651   mp->is_add = is_add;
14652
14653   S (mp);
14654   W (ret);
14655   return ret;
14656 }
14657
14658 static int
14659 api_ip_address_dump (vat_main_t * vam)
14660 {
14661   unformat_input_t *i = vam->input;
14662   vl_api_ip_address_dump_t *mp;
14663   vl_api_control_ping_t *mp_ping;
14664   u32 sw_if_index = ~0;
14665   u8 sw_if_index_set = 0;
14666   u8 ipv4_set = 0;
14667   u8 ipv6_set = 0;
14668   int ret;
14669
14670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14671     {
14672       if (unformat (i, "sw_if_index %d", &sw_if_index))
14673         sw_if_index_set = 1;
14674       else
14675         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14676         sw_if_index_set = 1;
14677       else if (unformat (i, "ipv4"))
14678         ipv4_set = 1;
14679       else if (unformat (i, "ipv6"))
14680         ipv6_set = 1;
14681       else
14682         break;
14683     }
14684
14685   if (ipv4_set && ipv6_set)
14686     {
14687       errmsg ("ipv4 and ipv6 flags cannot be both set");
14688       return -99;
14689     }
14690
14691   if ((!ipv4_set) && (!ipv6_set))
14692     {
14693       errmsg ("no ipv4 nor ipv6 flag set");
14694       return -99;
14695     }
14696
14697   if (sw_if_index_set == 0)
14698     {
14699       errmsg ("missing interface name or sw_if_index");
14700       return -99;
14701     }
14702
14703   vam->current_sw_if_index = sw_if_index;
14704   vam->is_ipv6 = ipv6_set;
14705
14706   M (IP_ADDRESS_DUMP, mp);
14707   mp->sw_if_index = ntohl (sw_if_index);
14708   mp->is_ipv6 = ipv6_set;
14709   S (mp);
14710
14711   /* Use a control ping for synchronization */
14712   MPING (CONTROL_PING, mp_ping);
14713   S (mp_ping);
14714
14715   W (ret);
14716   return ret;
14717 }
14718
14719 static int
14720 api_ip_dump (vat_main_t * vam)
14721 {
14722   vl_api_ip_dump_t *mp;
14723   vl_api_control_ping_t *mp_ping;
14724   unformat_input_t *in = vam->input;
14725   int ipv4_set = 0;
14726   int ipv6_set = 0;
14727   int is_ipv6;
14728   int i;
14729   int ret;
14730
14731   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (in, "ipv4"))
14734         ipv4_set = 1;
14735       else if (unformat (in, "ipv6"))
14736         ipv6_set = 1;
14737       else
14738         break;
14739     }
14740
14741   if (ipv4_set && ipv6_set)
14742     {
14743       errmsg ("ipv4 and ipv6 flags cannot be both set");
14744       return -99;
14745     }
14746
14747   if ((!ipv4_set) && (!ipv6_set))
14748     {
14749       errmsg ("no ipv4 nor ipv6 flag set");
14750       return -99;
14751     }
14752
14753   is_ipv6 = ipv6_set;
14754   vam->is_ipv6 = is_ipv6;
14755
14756   /* free old data */
14757   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14758     {
14759       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14760     }
14761   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14762
14763   M (IP_DUMP, mp);
14764   mp->is_ipv6 = ipv6_set;
14765   S (mp);
14766
14767   /* Use a control ping for synchronization */
14768   MPING (CONTROL_PING, mp_ping);
14769   S (mp_ping);
14770
14771   W (ret);
14772   return ret;
14773 }
14774
14775 static int
14776 api_ipsec_spd_add_del (vat_main_t * vam)
14777 {
14778   unformat_input_t *i = vam->input;
14779   vl_api_ipsec_spd_add_del_t *mp;
14780   u32 spd_id = ~0;
14781   u8 is_add = 1;
14782   int ret;
14783
14784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14785     {
14786       if (unformat (i, "spd_id %d", &spd_id))
14787         ;
14788       else if (unformat (i, "del"))
14789         is_add = 0;
14790       else
14791         {
14792           clib_warning ("parse error '%U'", format_unformat_error, i);
14793           return -99;
14794         }
14795     }
14796   if (spd_id == ~0)
14797     {
14798       errmsg ("spd_id must be set");
14799       return -99;
14800     }
14801
14802   M (IPSEC_SPD_ADD_DEL, mp);
14803
14804   mp->spd_id = ntohl (spd_id);
14805   mp->is_add = is_add;
14806
14807   S (mp);
14808   W (ret);
14809   return ret;
14810 }
14811
14812 static int
14813 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14814 {
14815   unformat_input_t *i = vam->input;
14816   vl_api_ipsec_interface_add_del_spd_t *mp;
14817   u32 sw_if_index;
14818   u8 sw_if_index_set = 0;
14819   u32 spd_id = (u32) ~ 0;
14820   u8 is_add = 1;
14821   int ret;
14822
14823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14824     {
14825       if (unformat (i, "del"))
14826         is_add = 0;
14827       else if (unformat (i, "spd_id %d", &spd_id))
14828         ;
14829       else
14830         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14831         sw_if_index_set = 1;
14832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14833         sw_if_index_set = 1;
14834       else
14835         {
14836           clib_warning ("parse error '%U'", format_unformat_error, i);
14837           return -99;
14838         }
14839
14840     }
14841
14842   if (spd_id == (u32) ~ 0)
14843     {
14844       errmsg ("spd_id must be set");
14845       return -99;
14846     }
14847
14848   if (sw_if_index_set == 0)
14849     {
14850       errmsg ("missing interface name or sw_if_index");
14851       return -99;
14852     }
14853
14854   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14855
14856   mp->spd_id = ntohl (spd_id);
14857   mp->sw_if_index = ntohl (sw_if_index);
14858   mp->is_add = is_add;
14859
14860   S (mp);
14861   W (ret);
14862   return ret;
14863 }
14864
14865 static int
14866 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14867 {
14868   unformat_input_t *i = vam->input;
14869   vl_api_ipsec_spd_add_del_entry_t *mp;
14870   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14871   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14872   i32 priority = 0;
14873   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14874   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14875   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14876   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14877   int ret;
14878
14879   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14880   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14881   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14882   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14883   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14884   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14885
14886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14887     {
14888       if (unformat (i, "del"))
14889         is_add = 0;
14890       if (unformat (i, "outbound"))
14891         is_outbound = 1;
14892       if (unformat (i, "inbound"))
14893         is_outbound = 0;
14894       else if (unformat (i, "spd_id %d", &spd_id))
14895         ;
14896       else if (unformat (i, "sa_id %d", &sa_id))
14897         ;
14898       else if (unformat (i, "priority %d", &priority))
14899         ;
14900       else if (unformat (i, "protocol %d", &protocol))
14901         ;
14902       else if (unformat (i, "lport_start %d", &lport_start))
14903         ;
14904       else if (unformat (i, "lport_stop %d", &lport_stop))
14905         ;
14906       else if (unformat (i, "rport_start %d", &rport_start))
14907         ;
14908       else if (unformat (i, "rport_stop %d", &rport_stop))
14909         ;
14910       else
14911         if (unformat
14912             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14913         {
14914           is_ipv6 = 0;
14915           is_ip_any = 0;
14916         }
14917       else
14918         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14919         {
14920           is_ipv6 = 0;
14921           is_ip_any = 0;
14922         }
14923       else
14924         if (unformat
14925             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14926         {
14927           is_ipv6 = 0;
14928           is_ip_any = 0;
14929         }
14930       else
14931         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14932         {
14933           is_ipv6 = 0;
14934           is_ip_any = 0;
14935         }
14936       else
14937         if (unformat
14938             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14939         {
14940           is_ipv6 = 1;
14941           is_ip_any = 0;
14942         }
14943       else
14944         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14945         {
14946           is_ipv6 = 1;
14947           is_ip_any = 0;
14948         }
14949       else
14950         if (unformat
14951             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14952         {
14953           is_ipv6 = 1;
14954           is_ip_any = 0;
14955         }
14956       else
14957         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14958         {
14959           is_ipv6 = 1;
14960           is_ip_any = 0;
14961         }
14962       else
14963         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14964         {
14965           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14966             {
14967               clib_warning ("unsupported action: 'resolve'");
14968               return -99;
14969             }
14970         }
14971       else
14972         {
14973           clib_warning ("parse error '%U'", format_unformat_error, i);
14974           return -99;
14975         }
14976
14977     }
14978
14979   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14980
14981   mp->spd_id = ntohl (spd_id);
14982   mp->priority = ntohl (priority);
14983   mp->is_outbound = is_outbound;
14984
14985   mp->is_ipv6 = is_ipv6;
14986   if (is_ipv6 || is_ip_any)
14987     {
14988       clib_memcpy (mp->remote_address_start, &raddr6_start,
14989                    sizeof (ip6_address_t));
14990       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14991                    sizeof (ip6_address_t));
14992       clib_memcpy (mp->local_address_start, &laddr6_start,
14993                    sizeof (ip6_address_t));
14994       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14995                    sizeof (ip6_address_t));
14996     }
14997   else
14998     {
14999       clib_memcpy (mp->remote_address_start, &raddr4_start,
15000                    sizeof (ip4_address_t));
15001       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15002                    sizeof (ip4_address_t));
15003       clib_memcpy (mp->local_address_start, &laddr4_start,
15004                    sizeof (ip4_address_t));
15005       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15006                    sizeof (ip4_address_t));
15007     }
15008   mp->protocol = (u8) protocol;
15009   mp->local_port_start = ntohs ((u16) lport_start);
15010   mp->local_port_stop = ntohs ((u16) lport_stop);
15011   mp->remote_port_start = ntohs ((u16) rport_start);
15012   mp->remote_port_stop = ntohs ((u16) rport_stop);
15013   mp->policy = (u8) policy;
15014   mp->sa_id = ntohl (sa_id);
15015   mp->is_add = is_add;
15016   mp->is_ip_any = is_ip_any;
15017   S (mp);
15018   W (ret);
15019   return ret;
15020 }
15021
15022 static int
15023 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15024 {
15025   unformat_input_t *i = vam->input;
15026   vl_api_ipsec_sad_add_del_entry_t *mp;
15027   u32 sad_id = 0, spi = 0;
15028   u8 *ck = 0, *ik = 0;
15029   u8 is_add = 1;
15030
15031   u8 protocol = IPSEC_PROTOCOL_AH;
15032   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15033   u32 crypto_alg = 0, integ_alg = 0;
15034   ip4_address_t tun_src4;
15035   ip4_address_t tun_dst4;
15036   ip6_address_t tun_src6;
15037   ip6_address_t tun_dst6;
15038   int ret;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "del"))
15043         is_add = 0;
15044       else if (unformat (i, "sad_id %d", &sad_id))
15045         ;
15046       else if (unformat (i, "spi %d", &spi))
15047         ;
15048       else if (unformat (i, "esp"))
15049         protocol = IPSEC_PROTOCOL_ESP;
15050       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15051         {
15052           is_tunnel = 1;
15053           is_tunnel_ipv6 = 0;
15054         }
15055       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15056         {
15057           is_tunnel = 1;
15058           is_tunnel_ipv6 = 0;
15059         }
15060       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15061         {
15062           is_tunnel = 1;
15063           is_tunnel_ipv6 = 1;
15064         }
15065       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15066         {
15067           is_tunnel = 1;
15068           is_tunnel_ipv6 = 1;
15069         }
15070       else
15071         if (unformat
15072             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15073         {
15074           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15075             {
15076               clib_warning ("unsupported crypto-alg: '%U'",
15077                             format_ipsec_crypto_alg, crypto_alg);
15078               return -99;
15079             }
15080         }
15081       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15082         ;
15083       else
15084         if (unformat
15085             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15086         {
15087           if (integ_alg >= IPSEC_INTEG_N_ALG)
15088             {
15089               clib_warning ("unsupported integ-alg: '%U'",
15090                             format_ipsec_integ_alg, integ_alg);
15091               return -99;
15092             }
15093         }
15094       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15095         ;
15096       else
15097         {
15098           clib_warning ("parse error '%U'", format_unformat_error, i);
15099           return -99;
15100         }
15101
15102     }
15103
15104   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15105
15106   mp->sad_id = ntohl (sad_id);
15107   mp->is_add = is_add;
15108   mp->protocol = protocol;
15109   mp->spi = ntohl (spi);
15110   mp->is_tunnel = is_tunnel;
15111   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15112   mp->crypto_algorithm = crypto_alg;
15113   mp->integrity_algorithm = integ_alg;
15114   mp->crypto_key_length = vec_len (ck);
15115   mp->integrity_key_length = vec_len (ik);
15116
15117   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15118     mp->crypto_key_length = sizeof (mp->crypto_key);
15119
15120   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15121     mp->integrity_key_length = sizeof (mp->integrity_key);
15122
15123   if (ck)
15124     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15125   if (ik)
15126     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15127
15128   if (is_tunnel)
15129     {
15130       if (is_tunnel_ipv6)
15131         {
15132           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15133                        sizeof (ip6_address_t));
15134           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15135                        sizeof (ip6_address_t));
15136         }
15137       else
15138         {
15139           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15140                        sizeof (ip4_address_t));
15141           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15142                        sizeof (ip4_address_t));
15143         }
15144     }
15145
15146   S (mp);
15147   W (ret);
15148   return ret;
15149 }
15150
15151 static int
15152 api_ipsec_sa_set_key (vat_main_t * vam)
15153 {
15154   unformat_input_t *i = vam->input;
15155   vl_api_ipsec_sa_set_key_t *mp;
15156   u32 sa_id;
15157   u8 *ck = 0, *ik = 0;
15158   int ret;
15159
15160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15161     {
15162       if (unformat (i, "sa_id %d", &sa_id))
15163         ;
15164       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15165         ;
15166       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15167         ;
15168       else
15169         {
15170           clib_warning ("parse error '%U'", format_unformat_error, i);
15171           return -99;
15172         }
15173     }
15174
15175   M (IPSEC_SA_SET_KEY, mp);
15176
15177   mp->sa_id = ntohl (sa_id);
15178   mp->crypto_key_length = vec_len (ck);
15179   mp->integrity_key_length = vec_len (ik);
15180
15181   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15182     mp->crypto_key_length = sizeof (mp->crypto_key);
15183
15184   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15185     mp->integrity_key_length = sizeof (mp->integrity_key);
15186
15187   if (ck)
15188     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15189   if (ik)
15190     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15191
15192   S (mp);
15193   W (ret);
15194   return ret;
15195 }
15196
15197 static int
15198 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15199 {
15200   unformat_input_t *i = vam->input;
15201   vl_api_ipsec_tunnel_if_add_del_t *mp;
15202   u32 local_spi = 0, remote_spi = 0;
15203   u32 crypto_alg = 0, integ_alg = 0;
15204   u8 *lck = NULL, *rck = NULL;
15205   u8 *lik = NULL, *rik = NULL;
15206   ip4_address_t local_ip = { {0} };
15207   ip4_address_t remote_ip = { {0} };
15208   u8 is_add = 1;
15209   u8 esn = 0;
15210   u8 anti_replay = 0;
15211   u8 renumber = 0;
15212   u32 instance = ~0;
15213   int ret;
15214
15215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15216     {
15217       if (unformat (i, "del"))
15218         is_add = 0;
15219       else if (unformat (i, "esn"))
15220         esn = 1;
15221       else if (unformat (i, "anti_replay"))
15222         anti_replay = 1;
15223       else if (unformat (i, "local_spi %d", &local_spi))
15224         ;
15225       else if (unformat (i, "remote_spi %d", &remote_spi))
15226         ;
15227       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15228         ;
15229       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15230         ;
15231       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15232         ;
15233       else
15234         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15235         ;
15236       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15237         ;
15238       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15239         ;
15240       else
15241         if (unformat
15242             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15243         {
15244           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15245             {
15246               errmsg ("unsupported crypto-alg: '%U'\n",
15247                       format_ipsec_crypto_alg, crypto_alg);
15248               return -99;
15249             }
15250         }
15251       else
15252         if (unformat
15253             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15254         {
15255           if (integ_alg >= IPSEC_INTEG_N_ALG)
15256             {
15257               errmsg ("unsupported integ-alg: '%U'\n",
15258                       format_ipsec_integ_alg, integ_alg);
15259               return -99;
15260             }
15261         }
15262       else if (unformat (i, "instance %u", &instance))
15263         renumber = 1;
15264       else
15265         {
15266           errmsg ("parse error '%U'\n", format_unformat_error, i);
15267           return -99;
15268         }
15269     }
15270
15271   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15272
15273   mp->is_add = is_add;
15274   mp->esn = esn;
15275   mp->anti_replay = anti_replay;
15276
15277   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15278   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15279
15280   mp->local_spi = htonl (local_spi);
15281   mp->remote_spi = htonl (remote_spi);
15282   mp->crypto_alg = (u8) crypto_alg;
15283
15284   mp->local_crypto_key_len = 0;
15285   if (lck)
15286     {
15287       mp->local_crypto_key_len = vec_len (lck);
15288       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15289         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15290       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15291     }
15292
15293   mp->remote_crypto_key_len = 0;
15294   if (rck)
15295     {
15296       mp->remote_crypto_key_len = vec_len (rck);
15297       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15298         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15299       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15300     }
15301
15302   mp->integ_alg = (u8) integ_alg;
15303
15304   mp->local_integ_key_len = 0;
15305   if (lik)
15306     {
15307       mp->local_integ_key_len = vec_len (lik);
15308       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15309         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15310       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15311     }
15312
15313   mp->remote_integ_key_len = 0;
15314   if (rik)
15315     {
15316       mp->remote_integ_key_len = vec_len (rik);
15317       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15318         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15319       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15320     }
15321
15322   if (renumber)
15323     {
15324       mp->renumber = renumber;
15325       mp->show_instance = ntohl (instance);
15326     }
15327
15328   S (mp);
15329   W (ret);
15330   return ret;
15331 }
15332
15333 static void
15334 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15335 {
15336   vat_main_t *vam = &vat_main;
15337
15338   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15339          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15340          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15341          "tunnel_src_addr %U tunnel_dst_addr %U "
15342          "salt %u seq_outbound %lu last_seq_inbound %lu "
15343          "replay_window %lu total_data_size %lu\n",
15344          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15345          mp->protocol,
15346          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15347          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15348          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15349          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15350          mp->tunnel_src_addr,
15351          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15352          mp->tunnel_dst_addr,
15353          ntohl (mp->salt),
15354          clib_net_to_host_u64 (mp->seq_outbound),
15355          clib_net_to_host_u64 (mp->last_seq_inbound),
15356          clib_net_to_host_u64 (mp->replay_window),
15357          clib_net_to_host_u64 (mp->total_data_size));
15358 }
15359
15360 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15361 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15362
15363 static void vl_api_ipsec_sa_details_t_handler_json
15364   (vl_api_ipsec_sa_details_t * mp)
15365 {
15366   vat_main_t *vam = &vat_main;
15367   vat_json_node_t *node = NULL;
15368   struct in_addr src_ip4, dst_ip4;
15369   struct in6_addr src_ip6, dst_ip6;
15370
15371   if (VAT_JSON_ARRAY != vam->json_tree.type)
15372     {
15373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15374       vat_json_init_array (&vam->json_tree);
15375     }
15376   node = vat_json_array_add (&vam->json_tree);
15377
15378   vat_json_init_object (node);
15379   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15380   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15381   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15382   vat_json_object_add_uint (node, "proto", mp->protocol);
15383   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15384   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15385   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15386   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15387   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15388   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15389   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15390                              mp->crypto_key_len);
15391   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15392                              mp->integ_key_len);
15393   if (mp->is_tunnel_ip6)
15394     {
15395       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15396       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15397       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15398       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15399     }
15400   else
15401     {
15402       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15403       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15404       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15405       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15406     }
15407   vat_json_object_add_uint (node, "replay_window",
15408                             clib_net_to_host_u64 (mp->replay_window));
15409   vat_json_object_add_uint (node, "total_data_size",
15410                             clib_net_to_host_u64 (mp->total_data_size));
15411
15412 }
15413
15414 static int
15415 api_ipsec_sa_dump (vat_main_t * vam)
15416 {
15417   unformat_input_t *i = vam->input;
15418   vl_api_ipsec_sa_dump_t *mp;
15419   vl_api_control_ping_t *mp_ping;
15420   u32 sa_id = ~0;
15421   int ret;
15422
15423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15424     {
15425       if (unformat (i, "sa_id %d", &sa_id))
15426         ;
15427       else
15428         {
15429           clib_warning ("parse error '%U'", format_unformat_error, i);
15430           return -99;
15431         }
15432     }
15433
15434   M (IPSEC_SA_DUMP, mp);
15435
15436   mp->sa_id = ntohl (sa_id);
15437
15438   S (mp);
15439
15440   /* Use a control ping for synchronization */
15441   M (CONTROL_PING, mp_ping);
15442   S (mp_ping);
15443
15444   W (ret);
15445   return ret;
15446 }
15447
15448 static int
15449 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15450 {
15451   unformat_input_t *i = vam->input;
15452   vl_api_ipsec_tunnel_if_set_key_t *mp;
15453   u32 sw_if_index = ~0;
15454   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15455   u8 *key = 0;
15456   u32 alg = ~0;
15457   int ret;
15458
15459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15460     {
15461       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15462         ;
15463       else
15464         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15465         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15466       else
15467         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15468         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15469       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15470         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15471       else
15472         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15473         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15474       else if (unformat (i, "%U", unformat_hex_string, &key))
15475         ;
15476       else
15477         {
15478           clib_warning ("parse error '%U'", format_unformat_error, i);
15479           return -99;
15480         }
15481     }
15482
15483   if (sw_if_index == ~0)
15484     {
15485       errmsg ("interface must be specified");
15486       return -99;
15487     }
15488
15489   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15490     {
15491       errmsg ("key type must be specified");
15492       return -99;
15493     }
15494
15495   if (alg == ~0)
15496     {
15497       errmsg ("algorithm must be specified");
15498       return -99;
15499     }
15500
15501   if (vec_len (key) == 0)
15502     {
15503       errmsg ("key must be specified");
15504       return -99;
15505     }
15506
15507   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15508
15509   mp->sw_if_index = htonl (sw_if_index);
15510   mp->alg = alg;
15511   mp->key_type = key_type;
15512   mp->key_len = vec_len (key);
15513   clib_memcpy (mp->key, key, vec_len (key));
15514
15515   S (mp);
15516   W (ret);
15517
15518   return ret;
15519 }
15520
15521 static int
15522 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15523 {
15524   unformat_input_t *i = vam->input;
15525   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15526   u32 sw_if_index = ~0;
15527   u32 sa_id = ~0;
15528   u8 is_outbound = (u8) ~ 0;
15529   int ret;
15530
15531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15532     {
15533       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15534         ;
15535       else if (unformat (i, "sa_id %d", &sa_id))
15536         ;
15537       else if (unformat (i, "outbound"))
15538         is_outbound = 1;
15539       else if (unformat (i, "inbound"))
15540         is_outbound = 0;
15541       else
15542         {
15543           clib_warning ("parse error '%U'", format_unformat_error, i);
15544           return -99;
15545         }
15546     }
15547
15548   if (sw_if_index == ~0)
15549     {
15550       errmsg ("interface must be specified");
15551       return -99;
15552     }
15553
15554   if (sa_id == ~0)
15555     {
15556       errmsg ("SA ID must be specified");
15557       return -99;
15558     }
15559
15560   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15561
15562   mp->sw_if_index = htonl (sw_if_index);
15563   mp->sa_id = htonl (sa_id);
15564   mp->is_outbound = is_outbound;
15565
15566   S (mp);
15567   W (ret);
15568
15569   return ret;
15570 }
15571
15572 static int
15573 api_ikev2_profile_add_del (vat_main_t * vam)
15574 {
15575   unformat_input_t *i = vam->input;
15576   vl_api_ikev2_profile_add_del_t *mp;
15577   u8 is_add = 1;
15578   u8 *name = 0;
15579   int ret;
15580
15581   const char *valid_chars = "a-zA-Z0-9_";
15582
15583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15584     {
15585       if (unformat (i, "del"))
15586         is_add = 0;
15587       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15588         vec_add1 (name, 0);
15589       else
15590         {
15591           errmsg ("parse error '%U'", format_unformat_error, i);
15592           return -99;
15593         }
15594     }
15595
15596   if (!vec_len (name))
15597     {
15598       errmsg ("profile name must be specified");
15599       return -99;
15600     }
15601
15602   if (vec_len (name) > 64)
15603     {
15604       errmsg ("profile name too long");
15605       return -99;
15606     }
15607
15608   M (IKEV2_PROFILE_ADD_DEL, mp);
15609
15610   clib_memcpy (mp->name, name, vec_len (name));
15611   mp->is_add = is_add;
15612   vec_free (name);
15613
15614   S (mp);
15615   W (ret);
15616   return ret;
15617 }
15618
15619 static int
15620 api_ikev2_profile_set_auth (vat_main_t * vam)
15621 {
15622   unformat_input_t *i = vam->input;
15623   vl_api_ikev2_profile_set_auth_t *mp;
15624   u8 *name = 0;
15625   u8 *data = 0;
15626   u32 auth_method = 0;
15627   u8 is_hex = 0;
15628   int ret;
15629
15630   const char *valid_chars = "a-zA-Z0-9_";
15631
15632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15633     {
15634       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15635         vec_add1 (name, 0);
15636       else if (unformat (i, "auth_method %U",
15637                          unformat_ikev2_auth_method, &auth_method))
15638         ;
15639       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15640         is_hex = 1;
15641       else if (unformat (i, "auth_data %v", &data))
15642         ;
15643       else
15644         {
15645           errmsg ("parse error '%U'", format_unformat_error, i);
15646           return -99;
15647         }
15648     }
15649
15650   if (!vec_len (name))
15651     {
15652       errmsg ("profile name must be specified");
15653       return -99;
15654     }
15655
15656   if (vec_len (name) > 64)
15657     {
15658       errmsg ("profile name too long");
15659       return -99;
15660     }
15661
15662   if (!vec_len (data))
15663     {
15664       errmsg ("auth_data must be specified");
15665       return -99;
15666     }
15667
15668   if (!auth_method)
15669     {
15670       errmsg ("auth_method must be specified");
15671       return -99;
15672     }
15673
15674   M (IKEV2_PROFILE_SET_AUTH, mp);
15675
15676   mp->is_hex = is_hex;
15677   mp->auth_method = (u8) auth_method;
15678   mp->data_len = vec_len (data);
15679   clib_memcpy (mp->name, name, vec_len (name));
15680   clib_memcpy (mp->data, data, vec_len (data));
15681   vec_free (name);
15682   vec_free (data);
15683
15684   S (mp);
15685   W (ret);
15686   return ret;
15687 }
15688
15689 static int
15690 api_ikev2_profile_set_id (vat_main_t * vam)
15691 {
15692   unformat_input_t *i = vam->input;
15693   vl_api_ikev2_profile_set_id_t *mp;
15694   u8 *name = 0;
15695   u8 *data = 0;
15696   u8 is_local = 0;
15697   u32 id_type = 0;
15698   ip4_address_t ip4;
15699   int ret;
15700
15701   const char *valid_chars = "a-zA-Z0-9_";
15702
15703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15704     {
15705       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15706         vec_add1 (name, 0);
15707       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15708         ;
15709       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15710         {
15711           data = vec_new (u8, 4);
15712           clib_memcpy (data, ip4.as_u8, 4);
15713         }
15714       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15715         ;
15716       else if (unformat (i, "id_data %v", &data))
15717         ;
15718       else if (unformat (i, "local"))
15719         is_local = 1;
15720       else if (unformat (i, "remote"))
15721         is_local = 0;
15722       else
15723         {
15724           errmsg ("parse error '%U'", format_unformat_error, i);
15725           return -99;
15726         }
15727     }
15728
15729   if (!vec_len (name))
15730     {
15731       errmsg ("profile name must be specified");
15732       return -99;
15733     }
15734
15735   if (vec_len (name) > 64)
15736     {
15737       errmsg ("profile name too long");
15738       return -99;
15739     }
15740
15741   if (!vec_len (data))
15742     {
15743       errmsg ("id_data must be specified");
15744       return -99;
15745     }
15746
15747   if (!id_type)
15748     {
15749       errmsg ("id_type must be specified");
15750       return -99;
15751     }
15752
15753   M (IKEV2_PROFILE_SET_ID, mp);
15754
15755   mp->is_local = is_local;
15756   mp->id_type = (u8) id_type;
15757   mp->data_len = vec_len (data);
15758   clib_memcpy (mp->name, name, vec_len (name));
15759   clib_memcpy (mp->data, data, vec_len (data));
15760   vec_free (name);
15761   vec_free (data);
15762
15763   S (mp);
15764   W (ret);
15765   return ret;
15766 }
15767
15768 static int
15769 api_ikev2_profile_set_ts (vat_main_t * vam)
15770 {
15771   unformat_input_t *i = vam->input;
15772   vl_api_ikev2_profile_set_ts_t *mp;
15773   u8 *name = 0;
15774   u8 is_local = 0;
15775   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15776   ip4_address_t start_addr, end_addr;
15777
15778   const char *valid_chars = "a-zA-Z0-9_";
15779   int ret;
15780
15781   start_addr.as_u32 = 0;
15782   end_addr.as_u32 = (u32) ~ 0;
15783
15784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15785     {
15786       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15787         vec_add1 (name, 0);
15788       else if (unformat (i, "protocol %d", &proto))
15789         ;
15790       else if (unformat (i, "start_port %d", &start_port))
15791         ;
15792       else if (unformat (i, "end_port %d", &end_port))
15793         ;
15794       else
15795         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15796         ;
15797       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15798         ;
15799       else if (unformat (i, "local"))
15800         is_local = 1;
15801       else if (unformat (i, "remote"))
15802         is_local = 0;
15803       else
15804         {
15805           errmsg ("parse error '%U'", format_unformat_error, i);
15806           return -99;
15807         }
15808     }
15809
15810   if (!vec_len (name))
15811     {
15812       errmsg ("profile name must be specified");
15813       return -99;
15814     }
15815
15816   if (vec_len (name) > 64)
15817     {
15818       errmsg ("profile name too long");
15819       return -99;
15820     }
15821
15822   M (IKEV2_PROFILE_SET_TS, mp);
15823
15824   mp->is_local = is_local;
15825   mp->proto = (u8) proto;
15826   mp->start_port = (u16) start_port;
15827   mp->end_port = (u16) end_port;
15828   mp->start_addr = start_addr.as_u32;
15829   mp->end_addr = end_addr.as_u32;
15830   clib_memcpy (mp->name, name, vec_len (name));
15831   vec_free (name);
15832
15833   S (mp);
15834   W (ret);
15835   return ret;
15836 }
15837
15838 static int
15839 api_ikev2_set_local_key (vat_main_t * vam)
15840 {
15841   unformat_input_t *i = vam->input;
15842   vl_api_ikev2_set_local_key_t *mp;
15843   u8 *file = 0;
15844   int ret;
15845
15846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15847     {
15848       if (unformat (i, "file %v", &file))
15849         vec_add1 (file, 0);
15850       else
15851         {
15852           errmsg ("parse error '%U'", format_unformat_error, i);
15853           return -99;
15854         }
15855     }
15856
15857   if (!vec_len (file))
15858     {
15859       errmsg ("RSA key file must be specified");
15860       return -99;
15861     }
15862
15863   if (vec_len (file) > 256)
15864     {
15865       errmsg ("file name too long");
15866       return -99;
15867     }
15868
15869   M (IKEV2_SET_LOCAL_KEY, mp);
15870
15871   clib_memcpy (mp->key_file, file, vec_len (file));
15872   vec_free (file);
15873
15874   S (mp);
15875   W (ret);
15876   return ret;
15877 }
15878
15879 static int
15880 api_ikev2_set_responder (vat_main_t * vam)
15881 {
15882   unformat_input_t *i = vam->input;
15883   vl_api_ikev2_set_responder_t *mp;
15884   int ret;
15885   u8 *name = 0;
15886   u32 sw_if_index = ~0;
15887   ip4_address_t address;
15888
15889   const char *valid_chars = "a-zA-Z0-9_";
15890
15891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15892     {
15893       if (unformat
15894           (i, "%U interface %d address %U", unformat_token, valid_chars,
15895            &name, &sw_if_index, unformat_ip4_address, &address))
15896         vec_add1 (name, 0);
15897       else
15898         {
15899           errmsg ("parse error '%U'", format_unformat_error, i);
15900           return -99;
15901         }
15902     }
15903
15904   if (!vec_len (name))
15905     {
15906       errmsg ("profile name must be specified");
15907       return -99;
15908     }
15909
15910   if (vec_len (name) > 64)
15911     {
15912       errmsg ("profile name too long");
15913       return -99;
15914     }
15915
15916   M (IKEV2_SET_RESPONDER, mp);
15917
15918   clib_memcpy (mp->name, name, vec_len (name));
15919   vec_free (name);
15920
15921   mp->sw_if_index = sw_if_index;
15922   clib_memcpy (mp->address, &address, sizeof (address));
15923
15924   S (mp);
15925   W (ret);
15926   return ret;
15927 }
15928
15929 static int
15930 api_ikev2_set_ike_transforms (vat_main_t * vam)
15931 {
15932   unformat_input_t *i = vam->input;
15933   vl_api_ikev2_set_ike_transforms_t *mp;
15934   int ret;
15935   u8 *name = 0;
15936   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15937
15938   const char *valid_chars = "a-zA-Z0-9_";
15939
15940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15941     {
15942       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15943                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15944         vec_add1 (name, 0);
15945       else
15946         {
15947           errmsg ("parse error '%U'", format_unformat_error, i);
15948           return -99;
15949         }
15950     }
15951
15952   if (!vec_len (name))
15953     {
15954       errmsg ("profile name must be specified");
15955       return -99;
15956     }
15957
15958   if (vec_len (name) > 64)
15959     {
15960       errmsg ("profile name too long");
15961       return -99;
15962     }
15963
15964   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15965
15966   clib_memcpy (mp->name, name, vec_len (name));
15967   vec_free (name);
15968   mp->crypto_alg = crypto_alg;
15969   mp->crypto_key_size = crypto_key_size;
15970   mp->integ_alg = integ_alg;
15971   mp->dh_group = dh_group;
15972
15973   S (mp);
15974   W (ret);
15975   return ret;
15976 }
15977
15978
15979 static int
15980 api_ikev2_set_esp_transforms (vat_main_t * vam)
15981 {
15982   unformat_input_t *i = vam->input;
15983   vl_api_ikev2_set_esp_transforms_t *mp;
15984   int ret;
15985   u8 *name = 0;
15986   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15987
15988   const char *valid_chars = "a-zA-Z0-9_";
15989
15990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15991     {
15992       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15993                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15994         vec_add1 (name, 0);
15995       else
15996         {
15997           errmsg ("parse error '%U'", format_unformat_error, i);
15998           return -99;
15999         }
16000     }
16001
16002   if (!vec_len (name))
16003     {
16004       errmsg ("profile name must be specified");
16005       return -99;
16006     }
16007
16008   if (vec_len (name) > 64)
16009     {
16010       errmsg ("profile name too long");
16011       return -99;
16012     }
16013
16014   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16015
16016   clib_memcpy (mp->name, name, vec_len (name));
16017   vec_free (name);
16018   mp->crypto_alg = crypto_alg;
16019   mp->crypto_key_size = crypto_key_size;
16020   mp->integ_alg = integ_alg;
16021   mp->dh_group = dh_group;
16022
16023   S (mp);
16024   W (ret);
16025   return ret;
16026 }
16027
16028 static int
16029 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16030 {
16031   unformat_input_t *i = vam->input;
16032   vl_api_ikev2_set_sa_lifetime_t *mp;
16033   int ret;
16034   u8 *name = 0;
16035   u64 lifetime, lifetime_maxdata;
16036   u32 lifetime_jitter, handover;
16037
16038   const char *valid_chars = "a-zA-Z0-9_";
16039
16040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16041     {
16042       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16043                     &lifetime, &lifetime_jitter, &handover,
16044                     &lifetime_maxdata))
16045         vec_add1 (name, 0);
16046       else
16047         {
16048           errmsg ("parse error '%U'", format_unformat_error, i);
16049           return -99;
16050         }
16051     }
16052
16053   if (!vec_len (name))
16054     {
16055       errmsg ("profile name must be specified");
16056       return -99;
16057     }
16058
16059   if (vec_len (name) > 64)
16060     {
16061       errmsg ("profile name too long");
16062       return -99;
16063     }
16064
16065   M (IKEV2_SET_SA_LIFETIME, mp);
16066
16067   clib_memcpy (mp->name, name, vec_len (name));
16068   vec_free (name);
16069   mp->lifetime = lifetime;
16070   mp->lifetime_jitter = lifetime_jitter;
16071   mp->handover = handover;
16072   mp->lifetime_maxdata = lifetime_maxdata;
16073
16074   S (mp);
16075   W (ret);
16076   return ret;
16077 }
16078
16079 static int
16080 api_ikev2_initiate_sa_init (vat_main_t * vam)
16081 {
16082   unformat_input_t *i = vam->input;
16083   vl_api_ikev2_initiate_sa_init_t *mp;
16084   int ret;
16085   u8 *name = 0;
16086
16087   const char *valid_chars = "a-zA-Z0-9_";
16088
16089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16090     {
16091       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16092         vec_add1 (name, 0);
16093       else
16094         {
16095           errmsg ("parse error '%U'", format_unformat_error, i);
16096           return -99;
16097         }
16098     }
16099
16100   if (!vec_len (name))
16101     {
16102       errmsg ("profile name must be specified");
16103       return -99;
16104     }
16105
16106   if (vec_len (name) > 64)
16107     {
16108       errmsg ("profile name too long");
16109       return -99;
16110     }
16111
16112   M (IKEV2_INITIATE_SA_INIT, mp);
16113
16114   clib_memcpy (mp->name, name, vec_len (name));
16115   vec_free (name);
16116
16117   S (mp);
16118   W (ret);
16119   return ret;
16120 }
16121
16122 static int
16123 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16124 {
16125   unformat_input_t *i = vam->input;
16126   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16127   int ret;
16128   u64 ispi;
16129
16130
16131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16132     {
16133       if (unformat (i, "%lx", &ispi))
16134         ;
16135       else
16136         {
16137           errmsg ("parse error '%U'", format_unformat_error, i);
16138           return -99;
16139         }
16140     }
16141
16142   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16143
16144   mp->ispi = ispi;
16145
16146   S (mp);
16147   W (ret);
16148   return ret;
16149 }
16150
16151 static int
16152 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16153 {
16154   unformat_input_t *i = vam->input;
16155   vl_api_ikev2_initiate_del_child_sa_t *mp;
16156   int ret;
16157   u32 ispi;
16158
16159
16160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16161     {
16162       if (unformat (i, "%x", &ispi))
16163         ;
16164       else
16165         {
16166           errmsg ("parse error '%U'", format_unformat_error, i);
16167           return -99;
16168         }
16169     }
16170
16171   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16172
16173   mp->ispi = ispi;
16174
16175   S (mp);
16176   W (ret);
16177   return ret;
16178 }
16179
16180 static int
16181 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16182 {
16183   unformat_input_t *i = vam->input;
16184   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16185   int ret;
16186   u32 ispi;
16187
16188
16189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (i, "%x", &ispi))
16192         ;
16193       else
16194         {
16195           errmsg ("parse error '%U'", format_unformat_error, i);
16196           return -99;
16197         }
16198     }
16199
16200   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16201
16202   mp->ispi = ispi;
16203
16204   S (mp);
16205   W (ret);
16206   return ret;
16207 }
16208
16209 static int
16210 api_get_first_msg_id (vat_main_t * vam)
16211 {
16212   vl_api_get_first_msg_id_t *mp;
16213   unformat_input_t *i = vam->input;
16214   u8 *name;
16215   u8 name_set = 0;
16216   int ret;
16217
16218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16219     {
16220       if (unformat (i, "client %s", &name))
16221         name_set = 1;
16222       else
16223         break;
16224     }
16225
16226   if (name_set == 0)
16227     {
16228       errmsg ("missing client name");
16229       return -99;
16230     }
16231   vec_add1 (name, 0);
16232
16233   if (vec_len (name) > 63)
16234     {
16235       errmsg ("client name too long");
16236       return -99;
16237     }
16238
16239   M (GET_FIRST_MSG_ID, mp);
16240   clib_memcpy (mp->name, name, vec_len (name));
16241   S (mp);
16242   W (ret);
16243   return ret;
16244 }
16245
16246 static int
16247 api_cop_interface_enable_disable (vat_main_t * vam)
16248 {
16249   unformat_input_t *line_input = vam->input;
16250   vl_api_cop_interface_enable_disable_t *mp;
16251   u32 sw_if_index = ~0;
16252   u8 enable_disable = 1;
16253   int ret;
16254
16255   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16256     {
16257       if (unformat (line_input, "disable"))
16258         enable_disable = 0;
16259       if (unformat (line_input, "enable"))
16260         enable_disable = 1;
16261       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16262                          vam, &sw_if_index))
16263         ;
16264       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16265         ;
16266       else
16267         break;
16268     }
16269
16270   if (sw_if_index == ~0)
16271     {
16272       errmsg ("missing interface name or sw_if_index");
16273       return -99;
16274     }
16275
16276   /* Construct the API message */
16277   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16278   mp->sw_if_index = ntohl (sw_if_index);
16279   mp->enable_disable = enable_disable;
16280
16281   /* send it... */
16282   S (mp);
16283   /* Wait for the reply */
16284   W (ret);
16285   return ret;
16286 }
16287
16288 static int
16289 api_cop_whitelist_enable_disable (vat_main_t * vam)
16290 {
16291   unformat_input_t *line_input = vam->input;
16292   vl_api_cop_whitelist_enable_disable_t *mp;
16293   u32 sw_if_index = ~0;
16294   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16295   u32 fib_id = 0;
16296   int ret;
16297
16298   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16299     {
16300       if (unformat (line_input, "ip4"))
16301         ip4 = 1;
16302       else if (unformat (line_input, "ip6"))
16303         ip6 = 1;
16304       else if (unformat (line_input, "default"))
16305         default_cop = 1;
16306       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16307                          vam, &sw_if_index))
16308         ;
16309       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16310         ;
16311       else if (unformat (line_input, "fib-id %d", &fib_id))
16312         ;
16313       else
16314         break;
16315     }
16316
16317   if (sw_if_index == ~0)
16318     {
16319       errmsg ("missing interface name or sw_if_index");
16320       return -99;
16321     }
16322
16323   /* Construct the API message */
16324   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16325   mp->sw_if_index = ntohl (sw_if_index);
16326   mp->fib_id = ntohl (fib_id);
16327   mp->ip4 = ip4;
16328   mp->ip6 = ip6;
16329   mp->default_cop = default_cop;
16330
16331   /* send it... */
16332   S (mp);
16333   /* Wait for the reply */
16334   W (ret);
16335   return ret;
16336 }
16337
16338 static int
16339 api_get_node_graph (vat_main_t * vam)
16340 {
16341   vl_api_get_node_graph_t *mp;
16342   int ret;
16343
16344   M (GET_NODE_GRAPH, mp);
16345
16346   /* send it... */
16347   S (mp);
16348   /* Wait for the reply */
16349   W (ret);
16350   return ret;
16351 }
16352
16353 /* *INDENT-OFF* */
16354 /** Used for parsing LISP eids */
16355 typedef CLIB_PACKED(struct{
16356   u8 addr[16];   /**< eid address */
16357   u32 len;       /**< prefix length if IP */
16358   u8 type;      /**< type of eid */
16359 }) lisp_eid_vat_t;
16360 /* *INDENT-ON* */
16361
16362 static uword
16363 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16364 {
16365   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16366
16367   clib_memset (a, 0, sizeof (a[0]));
16368
16369   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16370     {
16371       a->type = 0;              /* ipv4 type */
16372     }
16373   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16374     {
16375       a->type = 1;              /* ipv6 type */
16376     }
16377   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16378     {
16379       a->type = 2;              /* mac type */
16380     }
16381   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16382     {
16383       a->type = 3;              /* NSH type */
16384       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16385       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16386     }
16387   else
16388     {
16389       return 0;
16390     }
16391
16392   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16393     {
16394       return 0;
16395     }
16396
16397   return 1;
16398 }
16399
16400 static int
16401 lisp_eid_size_vat (u8 type)
16402 {
16403   switch (type)
16404     {
16405     case 0:
16406       return 4;
16407     case 1:
16408       return 16;
16409     case 2:
16410       return 6;
16411     case 3:
16412       return 5;
16413     }
16414   return 0;
16415 }
16416
16417 static void
16418 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16419 {
16420   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16421 }
16422
16423 static int
16424 api_one_add_del_locator_set (vat_main_t * vam)
16425 {
16426   unformat_input_t *input = vam->input;
16427   vl_api_one_add_del_locator_set_t *mp;
16428   u8 is_add = 1;
16429   u8 *locator_set_name = NULL;
16430   u8 locator_set_name_set = 0;
16431   vl_api_local_locator_t locator, *locators = 0;
16432   u32 sw_if_index, priority, weight;
16433   u32 data_len = 0;
16434
16435   int ret;
16436   /* Parse args required to build the message */
16437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16438     {
16439       if (unformat (input, "del"))
16440         {
16441           is_add = 0;
16442         }
16443       else if (unformat (input, "locator-set %s", &locator_set_name))
16444         {
16445           locator_set_name_set = 1;
16446         }
16447       else if (unformat (input, "sw_if_index %u p %u w %u",
16448                          &sw_if_index, &priority, &weight))
16449         {
16450           locator.sw_if_index = htonl (sw_if_index);
16451           locator.priority = priority;
16452           locator.weight = weight;
16453           vec_add1 (locators, locator);
16454         }
16455       else
16456         if (unformat
16457             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16458              &sw_if_index, &priority, &weight))
16459         {
16460           locator.sw_if_index = htonl (sw_if_index);
16461           locator.priority = priority;
16462           locator.weight = weight;
16463           vec_add1 (locators, locator);
16464         }
16465       else
16466         break;
16467     }
16468
16469   if (locator_set_name_set == 0)
16470     {
16471       errmsg ("missing locator-set name");
16472       vec_free (locators);
16473       return -99;
16474     }
16475
16476   if (vec_len (locator_set_name) > 64)
16477     {
16478       errmsg ("locator-set name too long");
16479       vec_free (locator_set_name);
16480       vec_free (locators);
16481       return -99;
16482     }
16483   vec_add1 (locator_set_name, 0);
16484
16485   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16486
16487   /* Construct the API message */
16488   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16489
16490   mp->is_add = is_add;
16491   clib_memcpy (mp->locator_set_name, locator_set_name,
16492                vec_len (locator_set_name));
16493   vec_free (locator_set_name);
16494
16495   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16496   if (locators)
16497     clib_memcpy (mp->locators, locators, data_len);
16498   vec_free (locators);
16499
16500   /* send it... */
16501   S (mp);
16502
16503   /* Wait for a reply... */
16504   W (ret);
16505   return ret;
16506 }
16507
16508 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16509
16510 static int
16511 api_one_add_del_locator (vat_main_t * vam)
16512 {
16513   unformat_input_t *input = vam->input;
16514   vl_api_one_add_del_locator_t *mp;
16515   u32 tmp_if_index = ~0;
16516   u32 sw_if_index = ~0;
16517   u8 sw_if_index_set = 0;
16518   u8 sw_if_index_if_name_set = 0;
16519   u32 priority = ~0;
16520   u8 priority_set = 0;
16521   u32 weight = ~0;
16522   u8 weight_set = 0;
16523   u8 is_add = 1;
16524   u8 *locator_set_name = NULL;
16525   u8 locator_set_name_set = 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         {
16533           is_add = 0;
16534         }
16535       else if (unformat (input, "locator-set %s", &locator_set_name))
16536         {
16537           locator_set_name_set = 1;
16538         }
16539       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16540                          &tmp_if_index))
16541         {
16542           sw_if_index_if_name_set = 1;
16543           sw_if_index = tmp_if_index;
16544         }
16545       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16546         {
16547           sw_if_index_set = 1;
16548           sw_if_index = tmp_if_index;
16549         }
16550       else if (unformat (input, "p %d", &priority))
16551         {
16552           priority_set = 1;
16553         }
16554       else if (unformat (input, "w %d", &weight))
16555         {
16556           weight_set = 1;
16557         }
16558       else
16559         break;
16560     }
16561
16562   if (locator_set_name_set == 0)
16563     {
16564       errmsg ("missing locator-set name");
16565       return -99;
16566     }
16567
16568   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16569     {
16570       errmsg ("missing sw_if_index");
16571       vec_free (locator_set_name);
16572       return -99;
16573     }
16574
16575   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16576     {
16577       errmsg ("cannot use both params interface name and sw_if_index");
16578       vec_free (locator_set_name);
16579       return -99;
16580     }
16581
16582   if (priority_set == 0)
16583     {
16584       errmsg ("missing locator-set priority");
16585       vec_free (locator_set_name);
16586       return -99;
16587     }
16588
16589   if (weight_set == 0)
16590     {
16591       errmsg ("missing locator-set weight");
16592       vec_free (locator_set_name);
16593       return -99;
16594     }
16595
16596   if (vec_len (locator_set_name) > 64)
16597     {
16598       errmsg ("locator-set name too long");
16599       vec_free (locator_set_name);
16600       return -99;
16601     }
16602   vec_add1 (locator_set_name, 0);
16603
16604   /* Construct the API message */
16605   M (ONE_ADD_DEL_LOCATOR, mp);
16606
16607   mp->is_add = is_add;
16608   mp->sw_if_index = ntohl (sw_if_index);
16609   mp->priority = priority;
16610   mp->weight = weight;
16611   clib_memcpy (mp->locator_set_name, locator_set_name,
16612                vec_len (locator_set_name));
16613   vec_free (locator_set_name);
16614
16615   /* send it... */
16616   S (mp);
16617
16618   /* Wait for a reply... */
16619   W (ret);
16620   return ret;
16621 }
16622
16623 #define api_lisp_add_del_locator api_one_add_del_locator
16624
16625 uword
16626 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16627 {
16628   u32 *key_id = va_arg (*args, u32 *);
16629   u8 *s = 0;
16630
16631   if (unformat (input, "%s", &s))
16632     {
16633       if (!strcmp ((char *) s, "sha1"))
16634         key_id[0] = HMAC_SHA_1_96;
16635       else if (!strcmp ((char *) s, "sha256"))
16636         key_id[0] = HMAC_SHA_256_128;
16637       else
16638         {
16639           clib_warning ("invalid key_id: '%s'", s);
16640           key_id[0] = HMAC_NO_KEY;
16641         }
16642     }
16643   else
16644     return 0;
16645
16646   vec_free (s);
16647   return 1;
16648 }
16649
16650 static int
16651 api_one_add_del_local_eid (vat_main_t * vam)
16652 {
16653   unformat_input_t *input = vam->input;
16654   vl_api_one_add_del_local_eid_t *mp;
16655   u8 is_add = 1;
16656   u8 eid_set = 0;
16657   lisp_eid_vat_t _eid, *eid = &_eid;
16658   u8 *locator_set_name = 0;
16659   u8 locator_set_name_set = 0;
16660   u32 vni = 0;
16661   u16 key_id = 0;
16662   u8 *key = 0;
16663   int ret;
16664
16665   /* Parse args required to build the message */
16666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16667     {
16668       if (unformat (input, "del"))
16669         {
16670           is_add = 0;
16671         }
16672       else if (unformat (input, "vni %d", &vni))
16673         {
16674           ;
16675         }
16676       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16677         {
16678           eid_set = 1;
16679         }
16680       else if (unformat (input, "locator-set %s", &locator_set_name))
16681         {
16682           locator_set_name_set = 1;
16683         }
16684       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16685         ;
16686       else if (unformat (input, "secret-key %_%v%_", &key))
16687         ;
16688       else
16689         break;
16690     }
16691
16692   if (locator_set_name_set == 0)
16693     {
16694       errmsg ("missing locator-set name");
16695       return -99;
16696     }
16697
16698   if (0 == eid_set)
16699     {
16700       errmsg ("EID address not set!");
16701       vec_free (locator_set_name);
16702       return -99;
16703     }
16704
16705   if (key && (0 == key_id))
16706     {
16707       errmsg ("invalid key_id!");
16708       return -99;
16709     }
16710
16711   if (vec_len (key) > 64)
16712     {
16713       errmsg ("key too long");
16714       vec_free (key);
16715       return -99;
16716     }
16717
16718   if (vec_len (locator_set_name) > 64)
16719     {
16720       errmsg ("locator-set name too long");
16721       vec_free (locator_set_name);
16722       return -99;
16723     }
16724   vec_add1 (locator_set_name, 0);
16725
16726   /* Construct the API message */
16727   M (ONE_ADD_DEL_LOCAL_EID, mp);
16728
16729   mp->is_add = is_add;
16730   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16731   mp->eid_type = eid->type;
16732   mp->prefix_len = eid->len;
16733   mp->vni = clib_host_to_net_u32 (vni);
16734   mp->key_id = clib_host_to_net_u16 (key_id);
16735   clib_memcpy (mp->locator_set_name, locator_set_name,
16736                vec_len (locator_set_name));
16737   clib_memcpy (mp->key, key, vec_len (key));
16738
16739   vec_free (locator_set_name);
16740   vec_free (key);
16741
16742   /* send it... */
16743   S (mp);
16744
16745   /* Wait for a reply... */
16746   W (ret);
16747   return ret;
16748 }
16749
16750 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16751
16752 static int
16753 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16754 {
16755   u32 dp_table = 0, vni = 0;;
16756   unformat_input_t *input = vam->input;
16757   vl_api_gpe_add_del_fwd_entry_t *mp;
16758   u8 is_add = 1;
16759   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16760   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16761   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16762   u32 action = ~0, w;
16763   ip4_address_t rmt_rloc4, lcl_rloc4;
16764   ip6_address_t rmt_rloc6, lcl_rloc6;
16765   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16766   int ret;
16767
16768   clib_memset (&rloc, 0, sizeof (rloc));
16769
16770   /* Parse args required to build the message */
16771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16772     {
16773       if (unformat (input, "del"))
16774         is_add = 0;
16775       else if (unformat (input, "add"))
16776         is_add = 1;
16777       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16778         {
16779           rmt_eid_set = 1;
16780         }
16781       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16782         {
16783           lcl_eid_set = 1;
16784         }
16785       else if (unformat (input, "vrf %d", &dp_table))
16786         ;
16787       else if (unformat (input, "bd %d", &dp_table))
16788         ;
16789       else if (unformat (input, "vni %d", &vni))
16790         ;
16791       else if (unformat (input, "w %d", &w))
16792         {
16793           if (!curr_rloc)
16794             {
16795               errmsg ("No RLOC configured for setting priority/weight!");
16796               return -99;
16797             }
16798           curr_rloc->weight = w;
16799         }
16800       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16801                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16802         {
16803           rloc.is_ip4 = 1;
16804
16805           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16806           rloc.weight = 0;
16807           vec_add1 (lcl_locs, rloc);
16808
16809           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16810           vec_add1 (rmt_locs, rloc);
16811           /* weight saved in rmt loc */
16812           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16813         }
16814       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16815                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16816         {
16817           rloc.is_ip4 = 0;
16818           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16819           rloc.weight = 0;
16820           vec_add1 (lcl_locs, rloc);
16821
16822           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16823           vec_add1 (rmt_locs, rloc);
16824           /* weight saved in rmt loc */
16825           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16826         }
16827       else if (unformat (input, "action %d", &action))
16828         {
16829           ;
16830         }
16831       else
16832         {
16833           clib_warning ("parse error '%U'", format_unformat_error, input);
16834           return -99;
16835         }
16836     }
16837
16838   if (!rmt_eid_set)
16839     {
16840       errmsg ("remote eid addresses not set");
16841       return -99;
16842     }
16843
16844   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16845     {
16846       errmsg ("eid types don't match");
16847       return -99;
16848     }
16849
16850   if (0 == rmt_locs && (u32) ~ 0 == action)
16851     {
16852       errmsg ("action not set for negative mapping");
16853       return -99;
16854     }
16855
16856   /* Construct the API message */
16857   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16858       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16859
16860   mp->is_add = is_add;
16861   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16862   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16863   mp->eid_type = rmt_eid->type;
16864   mp->dp_table = clib_host_to_net_u32 (dp_table);
16865   mp->vni = clib_host_to_net_u32 (vni);
16866   mp->rmt_len = rmt_eid->len;
16867   mp->lcl_len = lcl_eid->len;
16868   mp->action = action;
16869
16870   if (0 != rmt_locs && 0 != lcl_locs)
16871     {
16872       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16873       clib_memcpy (mp->locs, lcl_locs,
16874                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16875
16876       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16877       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16878                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16879     }
16880   vec_free (lcl_locs);
16881   vec_free (rmt_locs);
16882
16883   /* send it... */
16884   S (mp);
16885
16886   /* Wait for a reply... */
16887   W (ret);
16888   return ret;
16889 }
16890
16891 static int
16892 api_one_add_del_map_server (vat_main_t * vam)
16893 {
16894   unformat_input_t *input = vam->input;
16895   vl_api_one_add_del_map_server_t *mp;
16896   u8 is_add = 1;
16897   u8 ipv4_set = 0;
16898   u8 ipv6_set = 0;
16899   ip4_address_t ipv4;
16900   ip6_address_t ipv6;
16901   int ret;
16902
16903   /* Parse args required to build the message */
16904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16905     {
16906       if (unformat (input, "del"))
16907         {
16908           is_add = 0;
16909         }
16910       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16911         {
16912           ipv4_set = 1;
16913         }
16914       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16915         {
16916           ipv6_set = 1;
16917         }
16918       else
16919         break;
16920     }
16921
16922   if (ipv4_set && ipv6_set)
16923     {
16924       errmsg ("both eid v4 and v6 addresses set");
16925       return -99;
16926     }
16927
16928   if (!ipv4_set && !ipv6_set)
16929     {
16930       errmsg ("eid addresses not set");
16931       return -99;
16932     }
16933
16934   /* Construct the API message */
16935   M (ONE_ADD_DEL_MAP_SERVER, mp);
16936
16937   mp->is_add = is_add;
16938   if (ipv6_set)
16939     {
16940       mp->is_ipv6 = 1;
16941       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16942     }
16943   else
16944     {
16945       mp->is_ipv6 = 0;
16946       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16947     }
16948
16949   /* send it... */
16950   S (mp);
16951
16952   /* Wait for a reply... */
16953   W (ret);
16954   return ret;
16955 }
16956
16957 #define api_lisp_add_del_map_server api_one_add_del_map_server
16958
16959 static int
16960 api_one_add_del_map_resolver (vat_main_t * vam)
16961 {
16962   unformat_input_t *input = vam->input;
16963   vl_api_one_add_del_map_resolver_t *mp;
16964   u8 is_add = 1;
16965   u8 ipv4_set = 0;
16966   u8 ipv6_set = 0;
16967   ip4_address_t ipv4;
16968   ip6_address_t ipv6;
16969   int ret;
16970
16971   /* Parse args required to build the message */
16972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16973     {
16974       if (unformat (input, "del"))
16975         {
16976           is_add = 0;
16977         }
16978       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16979         {
16980           ipv4_set = 1;
16981         }
16982       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16983         {
16984           ipv6_set = 1;
16985         }
16986       else
16987         break;
16988     }
16989
16990   if (ipv4_set && ipv6_set)
16991     {
16992       errmsg ("both eid v4 and v6 addresses set");
16993       return -99;
16994     }
16995
16996   if (!ipv4_set && !ipv6_set)
16997     {
16998       errmsg ("eid addresses not set");
16999       return -99;
17000     }
17001
17002   /* Construct the API message */
17003   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17004
17005   mp->is_add = is_add;
17006   if (ipv6_set)
17007     {
17008       mp->is_ipv6 = 1;
17009       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17010     }
17011   else
17012     {
17013       mp->is_ipv6 = 0;
17014       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17015     }
17016
17017   /* send it... */
17018   S (mp);
17019
17020   /* Wait for a reply... */
17021   W (ret);
17022   return ret;
17023 }
17024
17025 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17026
17027 static int
17028 api_lisp_gpe_enable_disable (vat_main_t * vam)
17029 {
17030   unformat_input_t *input = vam->input;
17031   vl_api_gpe_enable_disable_t *mp;
17032   u8 is_set = 0;
17033   u8 is_en = 1;
17034   int ret;
17035
17036   /* Parse args required to build the message */
17037   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17038     {
17039       if (unformat (input, "enable"))
17040         {
17041           is_set = 1;
17042           is_en = 1;
17043         }
17044       else if (unformat (input, "disable"))
17045         {
17046           is_set = 1;
17047           is_en = 0;
17048         }
17049       else
17050         break;
17051     }
17052
17053   if (is_set == 0)
17054     {
17055       errmsg ("Value not set");
17056       return -99;
17057     }
17058
17059   /* Construct the API message */
17060   M (GPE_ENABLE_DISABLE, mp);
17061
17062   mp->is_en = is_en;
17063
17064   /* send it... */
17065   S (mp);
17066
17067   /* Wait for a reply... */
17068   W (ret);
17069   return ret;
17070 }
17071
17072 static int
17073 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17074 {
17075   unformat_input_t *input = vam->input;
17076   vl_api_one_rloc_probe_enable_disable_t *mp;
17077   u8 is_set = 0;
17078   u8 is_en = 0;
17079   int ret;
17080
17081   /* Parse args required to build the message */
17082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17083     {
17084       if (unformat (input, "enable"))
17085         {
17086           is_set = 1;
17087           is_en = 1;
17088         }
17089       else if (unformat (input, "disable"))
17090         is_set = 1;
17091       else
17092         break;
17093     }
17094
17095   if (!is_set)
17096     {
17097       errmsg ("Value not set");
17098       return -99;
17099     }
17100
17101   /* Construct the API message */
17102   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17103
17104   mp->is_enabled = is_en;
17105
17106   /* send it... */
17107   S (mp);
17108
17109   /* Wait for a reply... */
17110   W (ret);
17111   return ret;
17112 }
17113
17114 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17115
17116 static int
17117 api_one_map_register_enable_disable (vat_main_t * vam)
17118 {
17119   unformat_input_t *input = vam->input;
17120   vl_api_one_map_register_enable_disable_t *mp;
17121   u8 is_set = 0;
17122   u8 is_en = 0;
17123   int ret;
17124
17125   /* Parse args required to build the message */
17126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17127     {
17128       if (unformat (input, "enable"))
17129         {
17130           is_set = 1;
17131           is_en = 1;
17132         }
17133       else if (unformat (input, "disable"))
17134         is_set = 1;
17135       else
17136         break;
17137     }
17138
17139   if (!is_set)
17140     {
17141       errmsg ("Value not set");
17142       return -99;
17143     }
17144
17145   /* Construct the API message */
17146   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17147
17148   mp->is_enabled = is_en;
17149
17150   /* send it... */
17151   S (mp);
17152
17153   /* Wait for a reply... */
17154   W (ret);
17155   return ret;
17156 }
17157
17158 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17159
17160 static int
17161 api_one_enable_disable (vat_main_t * vam)
17162 {
17163   unformat_input_t *input = vam->input;
17164   vl_api_one_enable_disable_t *mp;
17165   u8 is_set = 0;
17166   u8 is_en = 0;
17167   int ret;
17168
17169   /* Parse args required to build the message */
17170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17171     {
17172       if (unformat (input, "enable"))
17173         {
17174           is_set = 1;
17175           is_en = 1;
17176         }
17177       else if (unformat (input, "disable"))
17178         {
17179           is_set = 1;
17180         }
17181       else
17182         break;
17183     }
17184
17185   if (!is_set)
17186     {
17187       errmsg ("Value not set");
17188       return -99;
17189     }
17190
17191   /* Construct the API message */
17192   M (ONE_ENABLE_DISABLE, mp);
17193
17194   mp->is_en = is_en;
17195
17196   /* send it... */
17197   S (mp);
17198
17199   /* Wait for a reply... */
17200   W (ret);
17201   return ret;
17202 }
17203
17204 #define api_lisp_enable_disable api_one_enable_disable
17205
17206 static int
17207 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17208 {
17209   unformat_input_t *input = vam->input;
17210   vl_api_one_enable_disable_xtr_mode_t *mp;
17211   u8 is_set = 0;
17212   u8 is_en = 0;
17213   int ret;
17214
17215   /* Parse args required to build the message */
17216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17217     {
17218       if (unformat (input, "enable"))
17219         {
17220           is_set = 1;
17221           is_en = 1;
17222         }
17223       else if (unformat (input, "disable"))
17224         {
17225           is_set = 1;
17226         }
17227       else
17228         break;
17229     }
17230
17231   if (!is_set)
17232     {
17233       errmsg ("Value not set");
17234       return -99;
17235     }
17236
17237   /* Construct the API message */
17238   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17239
17240   mp->is_en = is_en;
17241
17242   /* send it... */
17243   S (mp);
17244
17245   /* Wait for a reply... */
17246   W (ret);
17247   return ret;
17248 }
17249
17250 static int
17251 api_one_show_xtr_mode (vat_main_t * vam)
17252 {
17253   vl_api_one_show_xtr_mode_t *mp;
17254   int ret;
17255
17256   /* Construct the API message */
17257   M (ONE_SHOW_XTR_MODE, mp);
17258
17259   /* send it... */
17260   S (mp);
17261
17262   /* Wait for a reply... */
17263   W (ret);
17264   return ret;
17265 }
17266
17267 static int
17268 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17269 {
17270   unformat_input_t *input = vam->input;
17271   vl_api_one_enable_disable_pitr_mode_t *mp;
17272   u8 is_set = 0;
17273   u8 is_en = 0;
17274   int ret;
17275
17276   /* Parse args required to build the message */
17277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17278     {
17279       if (unformat (input, "enable"))
17280         {
17281           is_set = 1;
17282           is_en = 1;
17283         }
17284       else if (unformat (input, "disable"))
17285         {
17286           is_set = 1;
17287         }
17288       else
17289         break;
17290     }
17291
17292   if (!is_set)
17293     {
17294       errmsg ("Value not set");
17295       return -99;
17296     }
17297
17298   /* Construct the API message */
17299   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17300
17301   mp->is_en = is_en;
17302
17303   /* send it... */
17304   S (mp);
17305
17306   /* Wait for a reply... */
17307   W (ret);
17308   return ret;
17309 }
17310
17311 static int
17312 api_one_show_pitr_mode (vat_main_t * vam)
17313 {
17314   vl_api_one_show_pitr_mode_t *mp;
17315   int ret;
17316
17317   /* Construct the API message */
17318   M (ONE_SHOW_PITR_MODE, mp);
17319
17320   /* send it... */
17321   S (mp);
17322
17323   /* Wait for a reply... */
17324   W (ret);
17325   return ret;
17326 }
17327
17328 static int
17329 api_one_enable_disable_petr_mode (vat_main_t * vam)
17330 {
17331   unformat_input_t *input = vam->input;
17332   vl_api_one_enable_disable_petr_mode_t *mp;
17333   u8 is_set = 0;
17334   u8 is_en = 0;
17335   int ret;
17336
17337   /* Parse args required to build the message */
17338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17339     {
17340       if (unformat (input, "enable"))
17341         {
17342           is_set = 1;
17343           is_en = 1;
17344         }
17345       else if (unformat (input, "disable"))
17346         {
17347           is_set = 1;
17348         }
17349       else
17350         break;
17351     }
17352
17353   if (!is_set)
17354     {
17355       errmsg ("Value not set");
17356       return -99;
17357     }
17358
17359   /* Construct the API message */
17360   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17361
17362   mp->is_en = is_en;
17363
17364   /* send it... */
17365   S (mp);
17366
17367   /* Wait for a reply... */
17368   W (ret);
17369   return ret;
17370 }
17371
17372 static int
17373 api_one_show_petr_mode (vat_main_t * vam)
17374 {
17375   vl_api_one_show_petr_mode_t *mp;
17376   int ret;
17377
17378   /* Construct the API message */
17379   M (ONE_SHOW_PETR_MODE, mp);
17380
17381   /* send it... */
17382   S (mp);
17383
17384   /* Wait for a reply... */
17385   W (ret);
17386   return ret;
17387 }
17388
17389 static int
17390 api_show_one_map_register_state (vat_main_t * vam)
17391 {
17392   vl_api_show_one_map_register_state_t *mp;
17393   int ret;
17394
17395   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17396
17397   /* send */
17398   S (mp);
17399
17400   /* wait for reply */
17401   W (ret);
17402   return ret;
17403 }
17404
17405 #define api_show_lisp_map_register_state api_show_one_map_register_state
17406
17407 static int
17408 api_show_one_rloc_probe_state (vat_main_t * vam)
17409 {
17410   vl_api_show_one_rloc_probe_state_t *mp;
17411   int ret;
17412
17413   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17414
17415   /* send */
17416   S (mp);
17417
17418   /* wait for reply */
17419   W (ret);
17420   return ret;
17421 }
17422
17423 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17424
17425 static int
17426 api_one_add_del_ndp_entry (vat_main_t * vam)
17427 {
17428   vl_api_one_add_del_ndp_entry_t *mp;
17429   unformat_input_t *input = vam->input;
17430   u8 is_add = 1;
17431   u8 mac_set = 0;
17432   u8 bd_set = 0;
17433   u8 ip_set = 0;
17434   u8 mac[6] = { 0, };
17435   u8 ip6[16] = { 0, };
17436   u32 bd = ~0;
17437   int ret;
17438
17439   /* Parse args required to build the message */
17440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17441     {
17442       if (unformat (input, "del"))
17443         is_add = 0;
17444       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17445         mac_set = 1;
17446       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17447         ip_set = 1;
17448       else if (unformat (input, "bd %d", &bd))
17449         bd_set = 1;
17450       else
17451         {
17452           errmsg ("parse error '%U'", format_unformat_error, input);
17453           return -99;
17454         }
17455     }
17456
17457   if (!bd_set || !ip_set || (!mac_set && is_add))
17458     {
17459       errmsg ("Missing BD, IP or MAC!");
17460       return -99;
17461     }
17462
17463   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17464   mp->is_add = is_add;
17465   clib_memcpy (mp->mac, mac, 6);
17466   mp->bd = clib_host_to_net_u32 (bd);
17467   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17468
17469   /* send */
17470   S (mp);
17471
17472   /* wait for reply */
17473   W (ret);
17474   return ret;
17475 }
17476
17477 static int
17478 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17479 {
17480   vl_api_one_add_del_l2_arp_entry_t *mp;
17481   unformat_input_t *input = vam->input;
17482   u8 is_add = 1;
17483   u8 mac_set = 0;
17484   u8 bd_set = 0;
17485   u8 ip_set = 0;
17486   u8 mac[6] = { 0, };
17487   u32 ip4 = 0, bd = ~0;
17488   int ret;
17489
17490   /* Parse args required to build the message */
17491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17492     {
17493       if (unformat (input, "del"))
17494         is_add = 0;
17495       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17496         mac_set = 1;
17497       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17498         ip_set = 1;
17499       else if (unformat (input, "bd %d", &bd))
17500         bd_set = 1;
17501       else
17502         {
17503           errmsg ("parse error '%U'", format_unformat_error, input);
17504           return -99;
17505         }
17506     }
17507
17508   if (!bd_set || !ip_set || (!mac_set && is_add))
17509     {
17510       errmsg ("Missing BD, IP or MAC!");
17511       return -99;
17512     }
17513
17514   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17515   mp->is_add = is_add;
17516   clib_memcpy (mp->mac, mac, 6);
17517   mp->bd = clib_host_to_net_u32 (bd);
17518   mp->ip4 = ip4;
17519
17520   /* send */
17521   S (mp);
17522
17523   /* wait for reply */
17524   W (ret);
17525   return ret;
17526 }
17527
17528 static int
17529 api_one_ndp_bd_get (vat_main_t * vam)
17530 {
17531   vl_api_one_ndp_bd_get_t *mp;
17532   int ret;
17533
17534   M (ONE_NDP_BD_GET, mp);
17535
17536   /* send */
17537   S (mp);
17538
17539   /* wait for reply */
17540   W (ret);
17541   return ret;
17542 }
17543
17544 static int
17545 api_one_ndp_entries_get (vat_main_t * vam)
17546 {
17547   vl_api_one_ndp_entries_get_t *mp;
17548   unformat_input_t *input = vam->input;
17549   u8 bd_set = 0;
17550   u32 bd = ~0;
17551   int ret;
17552
17553   /* Parse args required to build the message */
17554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17555     {
17556       if (unformat (input, "bd %d", &bd))
17557         bd_set = 1;
17558       else
17559         {
17560           errmsg ("parse error '%U'", format_unformat_error, input);
17561           return -99;
17562         }
17563     }
17564
17565   if (!bd_set)
17566     {
17567       errmsg ("Expected bridge domain!");
17568       return -99;
17569     }
17570
17571   M (ONE_NDP_ENTRIES_GET, mp);
17572   mp->bd = clib_host_to_net_u32 (bd);
17573
17574   /* send */
17575   S (mp);
17576
17577   /* wait for reply */
17578   W (ret);
17579   return ret;
17580 }
17581
17582 static int
17583 api_one_l2_arp_bd_get (vat_main_t * vam)
17584 {
17585   vl_api_one_l2_arp_bd_get_t *mp;
17586   int ret;
17587
17588   M (ONE_L2_ARP_BD_GET, mp);
17589
17590   /* send */
17591   S (mp);
17592
17593   /* wait for reply */
17594   W (ret);
17595   return ret;
17596 }
17597
17598 static int
17599 api_one_l2_arp_entries_get (vat_main_t * vam)
17600 {
17601   vl_api_one_l2_arp_entries_get_t *mp;
17602   unformat_input_t *input = vam->input;
17603   u8 bd_set = 0;
17604   u32 bd = ~0;
17605   int ret;
17606
17607   /* Parse args required to build the message */
17608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17609     {
17610       if (unformat (input, "bd %d", &bd))
17611         bd_set = 1;
17612       else
17613         {
17614           errmsg ("parse error '%U'", format_unformat_error, input);
17615           return -99;
17616         }
17617     }
17618
17619   if (!bd_set)
17620     {
17621       errmsg ("Expected bridge domain!");
17622       return -99;
17623     }
17624
17625   M (ONE_L2_ARP_ENTRIES_GET, mp);
17626   mp->bd = clib_host_to_net_u32 (bd);
17627
17628   /* send */
17629   S (mp);
17630
17631   /* wait for reply */
17632   W (ret);
17633   return ret;
17634 }
17635
17636 static int
17637 api_one_stats_enable_disable (vat_main_t * vam)
17638 {
17639   vl_api_one_stats_enable_disable_t *mp;
17640   unformat_input_t *input = vam->input;
17641   u8 is_set = 0;
17642   u8 is_en = 0;
17643   int ret;
17644
17645   /* Parse args required to build the message */
17646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17647     {
17648       if (unformat (input, "enable"))
17649         {
17650           is_set = 1;
17651           is_en = 1;
17652         }
17653       else if (unformat (input, "disable"))
17654         {
17655           is_set = 1;
17656         }
17657       else
17658         break;
17659     }
17660
17661   if (!is_set)
17662     {
17663       errmsg ("Value not set");
17664       return -99;
17665     }
17666
17667   M (ONE_STATS_ENABLE_DISABLE, mp);
17668   mp->is_en = is_en;
17669
17670   /* send */
17671   S (mp);
17672
17673   /* wait for reply */
17674   W (ret);
17675   return ret;
17676 }
17677
17678 static int
17679 api_show_one_stats_enable_disable (vat_main_t * vam)
17680 {
17681   vl_api_show_one_stats_enable_disable_t *mp;
17682   int ret;
17683
17684   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17685
17686   /* send */
17687   S (mp);
17688
17689   /* wait for reply */
17690   W (ret);
17691   return ret;
17692 }
17693
17694 static int
17695 api_show_one_map_request_mode (vat_main_t * vam)
17696 {
17697   vl_api_show_one_map_request_mode_t *mp;
17698   int ret;
17699
17700   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17701
17702   /* send */
17703   S (mp);
17704
17705   /* wait for reply */
17706   W (ret);
17707   return ret;
17708 }
17709
17710 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17711
17712 static int
17713 api_one_map_request_mode (vat_main_t * vam)
17714 {
17715   unformat_input_t *input = vam->input;
17716   vl_api_one_map_request_mode_t *mp;
17717   u8 mode = 0;
17718   int ret;
17719
17720   /* Parse args required to build the message */
17721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17722     {
17723       if (unformat (input, "dst-only"))
17724         mode = 0;
17725       else if (unformat (input, "src-dst"))
17726         mode = 1;
17727       else
17728         {
17729           errmsg ("parse error '%U'", format_unformat_error, input);
17730           return -99;
17731         }
17732     }
17733
17734   M (ONE_MAP_REQUEST_MODE, mp);
17735
17736   mp->mode = mode;
17737
17738   /* send */
17739   S (mp);
17740
17741   /* wait for reply */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 #define api_lisp_map_request_mode api_one_map_request_mode
17747
17748 /**
17749  * Enable/disable ONE proxy ITR.
17750  *
17751  * @param vam vpp API test context
17752  * @return return code
17753  */
17754 static int
17755 api_one_pitr_set_locator_set (vat_main_t * vam)
17756 {
17757   u8 ls_name_set = 0;
17758   unformat_input_t *input = vam->input;
17759   vl_api_one_pitr_set_locator_set_t *mp;
17760   u8 is_add = 1;
17761   u8 *ls_name = 0;
17762   int ret;
17763
17764   /* Parse args required to build the message */
17765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17766     {
17767       if (unformat (input, "del"))
17768         is_add = 0;
17769       else if (unformat (input, "locator-set %s", &ls_name))
17770         ls_name_set = 1;
17771       else
17772         {
17773           errmsg ("parse error '%U'", format_unformat_error, input);
17774           return -99;
17775         }
17776     }
17777
17778   if (!ls_name_set)
17779     {
17780       errmsg ("locator-set name not set!");
17781       return -99;
17782     }
17783
17784   M (ONE_PITR_SET_LOCATOR_SET, mp);
17785
17786   mp->is_add = is_add;
17787   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17788   vec_free (ls_name);
17789
17790   /* send */
17791   S (mp);
17792
17793   /* wait for reply */
17794   W (ret);
17795   return ret;
17796 }
17797
17798 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17799
17800 static int
17801 api_one_nsh_set_locator_set (vat_main_t * vam)
17802 {
17803   u8 ls_name_set = 0;
17804   unformat_input_t *input = vam->input;
17805   vl_api_one_nsh_set_locator_set_t *mp;
17806   u8 is_add = 1;
17807   u8 *ls_name = 0;
17808   int ret;
17809
17810   /* Parse args required to build the message */
17811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17812     {
17813       if (unformat (input, "del"))
17814         is_add = 0;
17815       else if (unformat (input, "ls %s", &ls_name))
17816         ls_name_set = 1;
17817       else
17818         {
17819           errmsg ("parse error '%U'", format_unformat_error, input);
17820           return -99;
17821         }
17822     }
17823
17824   if (!ls_name_set && is_add)
17825     {
17826       errmsg ("locator-set name not set!");
17827       return -99;
17828     }
17829
17830   M (ONE_NSH_SET_LOCATOR_SET, mp);
17831
17832   mp->is_add = is_add;
17833   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17834   vec_free (ls_name);
17835
17836   /* send */
17837   S (mp);
17838
17839   /* wait for reply */
17840   W (ret);
17841   return ret;
17842 }
17843
17844 static int
17845 api_show_one_pitr (vat_main_t * vam)
17846 {
17847   vl_api_show_one_pitr_t *mp;
17848   int ret;
17849
17850   if (!vam->json_output)
17851     {
17852       print (vam->ofp, "%=20s", "lisp status:");
17853     }
17854
17855   M (SHOW_ONE_PITR, mp);
17856   /* send it... */
17857   S (mp);
17858
17859   /* Wait for a reply... */
17860   W (ret);
17861   return ret;
17862 }
17863
17864 #define api_show_lisp_pitr api_show_one_pitr
17865
17866 static int
17867 api_one_use_petr (vat_main_t * vam)
17868 {
17869   unformat_input_t *input = vam->input;
17870   vl_api_one_use_petr_t *mp;
17871   u8 is_add = 0;
17872   ip_address_t ip;
17873   int ret;
17874
17875   clib_memset (&ip, 0, sizeof (ip));
17876
17877   /* Parse args required to build the message */
17878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17879     {
17880       if (unformat (input, "disable"))
17881         is_add = 0;
17882       else
17883         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17884         {
17885           is_add = 1;
17886           ip_addr_version (&ip) = IP4;
17887         }
17888       else
17889         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17890         {
17891           is_add = 1;
17892           ip_addr_version (&ip) = IP6;
17893         }
17894       else
17895         {
17896           errmsg ("parse error '%U'", format_unformat_error, input);
17897           return -99;
17898         }
17899     }
17900
17901   M (ONE_USE_PETR, mp);
17902
17903   mp->is_add = is_add;
17904   if (is_add)
17905     {
17906       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17907       if (mp->is_ip4)
17908         clib_memcpy (mp->address, &ip, 4);
17909       else
17910         clib_memcpy (mp->address, &ip, 16);
17911     }
17912
17913   /* send */
17914   S (mp);
17915
17916   /* wait for reply */
17917   W (ret);
17918   return ret;
17919 }
17920
17921 #define api_lisp_use_petr api_one_use_petr
17922
17923 static int
17924 api_show_one_nsh_mapping (vat_main_t * vam)
17925 {
17926   vl_api_show_one_use_petr_t *mp;
17927   int ret;
17928
17929   if (!vam->json_output)
17930     {
17931       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17932     }
17933
17934   M (SHOW_ONE_NSH_MAPPING, mp);
17935   /* send it... */
17936   S (mp);
17937
17938   /* Wait for a reply... */
17939   W (ret);
17940   return ret;
17941 }
17942
17943 static int
17944 api_show_one_use_petr (vat_main_t * vam)
17945 {
17946   vl_api_show_one_use_petr_t *mp;
17947   int ret;
17948
17949   if (!vam->json_output)
17950     {
17951       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17952     }
17953
17954   M (SHOW_ONE_USE_PETR, mp);
17955   /* send it... */
17956   S (mp);
17957
17958   /* Wait for a reply... */
17959   W (ret);
17960   return ret;
17961 }
17962
17963 #define api_show_lisp_use_petr api_show_one_use_petr
17964
17965 /**
17966  * Add/delete mapping between vni and vrf
17967  */
17968 static int
17969 api_one_eid_table_add_del_map (vat_main_t * vam)
17970 {
17971   unformat_input_t *input = vam->input;
17972   vl_api_one_eid_table_add_del_map_t *mp;
17973   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17974   u32 vni, vrf, bd_index;
17975   int ret;
17976
17977   /* Parse args required to build the message */
17978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17979     {
17980       if (unformat (input, "del"))
17981         is_add = 0;
17982       else if (unformat (input, "vrf %d", &vrf))
17983         vrf_set = 1;
17984       else if (unformat (input, "bd_index %d", &bd_index))
17985         bd_index_set = 1;
17986       else if (unformat (input, "vni %d", &vni))
17987         vni_set = 1;
17988       else
17989         break;
17990     }
17991
17992   if (!vni_set || (!vrf_set && !bd_index_set))
17993     {
17994       errmsg ("missing arguments!");
17995       return -99;
17996     }
17997
17998   if (vrf_set && bd_index_set)
17999     {
18000       errmsg ("error: both vrf and bd entered!");
18001       return -99;
18002     }
18003
18004   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18005
18006   mp->is_add = is_add;
18007   mp->vni = htonl (vni);
18008   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18009   mp->is_l2 = bd_index_set;
18010
18011   /* send */
18012   S (mp);
18013
18014   /* wait for reply */
18015   W (ret);
18016   return ret;
18017 }
18018
18019 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18020
18021 uword
18022 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18023 {
18024   u32 *action = va_arg (*args, u32 *);
18025   u8 *s = 0;
18026
18027   if (unformat (input, "%s", &s))
18028     {
18029       if (!strcmp ((char *) s, "no-action"))
18030         action[0] = 0;
18031       else if (!strcmp ((char *) s, "natively-forward"))
18032         action[0] = 1;
18033       else if (!strcmp ((char *) s, "send-map-request"))
18034         action[0] = 2;
18035       else if (!strcmp ((char *) s, "drop"))
18036         action[0] = 3;
18037       else
18038         {
18039           clib_warning ("invalid action: '%s'", s);
18040           action[0] = 3;
18041         }
18042     }
18043   else
18044     return 0;
18045
18046   vec_free (s);
18047   return 1;
18048 }
18049
18050 /**
18051  * Add/del remote mapping to/from ONE control plane
18052  *
18053  * @param vam vpp API test context
18054  * @return return code
18055  */
18056 static int
18057 api_one_add_del_remote_mapping (vat_main_t * vam)
18058 {
18059   unformat_input_t *input = vam->input;
18060   vl_api_one_add_del_remote_mapping_t *mp;
18061   u32 vni = 0;
18062   lisp_eid_vat_t _eid, *eid = &_eid;
18063   lisp_eid_vat_t _seid, *seid = &_seid;
18064   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18065   u32 action = ~0, p, w, data_len;
18066   ip4_address_t rloc4;
18067   ip6_address_t rloc6;
18068   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18069   int ret;
18070
18071   clib_memset (&rloc, 0, sizeof (rloc));
18072
18073   /* Parse args required to build the message */
18074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18075     {
18076       if (unformat (input, "del-all"))
18077         {
18078           del_all = 1;
18079         }
18080       else if (unformat (input, "del"))
18081         {
18082           is_add = 0;
18083         }
18084       else if (unformat (input, "add"))
18085         {
18086           is_add = 1;
18087         }
18088       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18089         {
18090           eid_set = 1;
18091         }
18092       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18093         {
18094           seid_set = 1;
18095         }
18096       else if (unformat (input, "vni %d", &vni))
18097         {
18098           ;
18099         }
18100       else if (unformat (input, "p %d w %d", &p, &w))
18101         {
18102           if (!curr_rloc)
18103             {
18104               errmsg ("No RLOC configured for setting priority/weight!");
18105               return -99;
18106             }
18107           curr_rloc->priority = p;
18108           curr_rloc->weight = w;
18109         }
18110       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18111         {
18112           rloc.is_ip4 = 1;
18113           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18114           vec_add1 (rlocs, rloc);
18115           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18116         }
18117       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18118         {
18119           rloc.is_ip4 = 0;
18120           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18121           vec_add1 (rlocs, rloc);
18122           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18123         }
18124       else if (unformat (input, "action %U",
18125                          unformat_negative_mapping_action, &action))
18126         {
18127           ;
18128         }
18129       else
18130         {
18131           clib_warning ("parse error '%U'", format_unformat_error, input);
18132           return -99;
18133         }
18134     }
18135
18136   if (0 == eid_set)
18137     {
18138       errmsg ("missing params!");
18139       return -99;
18140     }
18141
18142   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18143     {
18144       errmsg ("no action set for negative map-reply!");
18145       return -99;
18146     }
18147
18148   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18149
18150   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18151   mp->is_add = is_add;
18152   mp->vni = htonl (vni);
18153   mp->action = (u8) action;
18154   mp->is_src_dst = seid_set;
18155   mp->eid_len = eid->len;
18156   mp->seid_len = seid->len;
18157   mp->del_all = del_all;
18158   mp->eid_type = eid->type;
18159   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18160   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18161
18162   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18163   clib_memcpy (mp->rlocs, rlocs, data_len);
18164   vec_free (rlocs);
18165
18166   /* send it... */
18167   S (mp);
18168
18169   /* Wait for a reply... */
18170   W (ret);
18171   return ret;
18172 }
18173
18174 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18175
18176 /**
18177  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18178  * forwarding entries in data-plane accordingly.
18179  *
18180  * @param vam vpp API test context
18181  * @return return code
18182  */
18183 static int
18184 api_one_add_del_adjacency (vat_main_t * vam)
18185 {
18186   unformat_input_t *input = vam->input;
18187   vl_api_one_add_del_adjacency_t *mp;
18188   u32 vni = 0;
18189   ip4_address_t leid4, reid4;
18190   ip6_address_t leid6, reid6;
18191   u8 reid_mac[6] = { 0 };
18192   u8 leid_mac[6] = { 0 };
18193   u8 reid_type, leid_type;
18194   u32 leid_len = 0, reid_len = 0, len;
18195   u8 is_add = 1;
18196   int ret;
18197
18198   leid_type = reid_type = (u8) ~ 0;
18199
18200   /* Parse args required to build the message */
18201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18202     {
18203       if (unformat (input, "del"))
18204         {
18205           is_add = 0;
18206         }
18207       else if (unformat (input, "add"))
18208         {
18209           is_add = 1;
18210         }
18211       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18212                          &reid4, &len))
18213         {
18214           reid_type = 0;        /* ipv4 */
18215           reid_len = len;
18216         }
18217       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18218                          &reid6, &len))
18219         {
18220           reid_type = 1;        /* ipv6 */
18221           reid_len = len;
18222         }
18223       else if (unformat (input, "reid %U", unformat_ethernet_address,
18224                          reid_mac))
18225         {
18226           reid_type = 2;        /* mac */
18227         }
18228       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18229                          &leid4, &len))
18230         {
18231           leid_type = 0;        /* ipv4 */
18232           leid_len = len;
18233         }
18234       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18235                          &leid6, &len))
18236         {
18237           leid_type = 1;        /* ipv6 */
18238           leid_len = len;
18239         }
18240       else if (unformat (input, "leid %U", unformat_ethernet_address,
18241                          leid_mac))
18242         {
18243           leid_type = 2;        /* mac */
18244         }
18245       else if (unformat (input, "vni %d", &vni))
18246         {
18247           ;
18248         }
18249       else
18250         {
18251           errmsg ("parse error '%U'", format_unformat_error, input);
18252           return -99;
18253         }
18254     }
18255
18256   if ((u8) ~ 0 == reid_type)
18257     {
18258       errmsg ("missing params!");
18259       return -99;
18260     }
18261
18262   if (leid_type != reid_type)
18263     {
18264       errmsg ("remote and local EIDs are of different types!");
18265       return -99;
18266     }
18267
18268   M (ONE_ADD_DEL_ADJACENCY, mp);
18269   mp->is_add = is_add;
18270   mp->vni = htonl (vni);
18271   mp->leid_len = leid_len;
18272   mp->reid_len = reid_len;
18273   mp->eid_type = reid_type;
18274
18275   switch (mp->eid_type)
18276     {
18277     case 0:
18278       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18279       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18280       break;
18281     case 1:
18282       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18283       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18284       break;
18285     case 2:
18286       clib_memcpy (mp->leid, leid_mac, 6);
18287       clib_memcpy (mp->reid, reid_mac, 6);
18288       break;
18289     default:
18290       errmsg ("unknown EID type %d!", mp->eid_type);
18291       return 0;
18292     }
18293
18294   /* send it... */
18295   S (mp);
18296
18297   /* Wait for a reply... */
18298   W (ret);
18299   return ret;
18300 }
18301
18302 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18303
18304 uword
18305 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18306 {
18307   u32 *mode = va_arg (*args, u32 *);
18308
18309   if (unformat (input, "lisp"))
18310     *mode = 0;
18311   else if (unformat (input, "vxlan"))
18312     *mode = 1;
18313   else
18314     return 0;
18315
18316   return 1;
18317 }
18318
18319 static int
18320 api_gpe_get_encap_mode (vat_main_t * vam)
18321 {
18322   vl_api_gpe_get_encap_mode_t *mp;
18323   int ret;
18324
18325   /* Construct the API message */
18326   M (GPE_GET_ENCAP_MODE, mp);
18327
18328   /* send it... */
18329   S (mp);
18330
18331   /* Wait for a reply... */
18332   W (ret);
18333   return ret;
18334 }
18335
18336 static int
18337 api_gpe_set_encap_mode (vat_main_t * vam)
18338 {
18339   unformat_input_t *input = vam->input;
18340   vl_api_gpe_set_encap_mode_t *mp;
18341   int ret;
18342   u32 mode = 0;
18343
18344   /* Parse args required to build the message */
18345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18346     {
18347       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18348         ;
18349       else
18350         break;
18351     }
18352
18353   /* Construct the API message */
18354   M (GPE_SET_ENCAP_MODE, mp);
18355
18356   mp->mode = mode;
18357
18358   /* send it... */
18359   S (mp);
18360
18361   /* Wait for a reply... */
18362   W (ret);
18363   return ret;
18364 }
18365
18366 static int
18367 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18368 {
18369   unformat_input_t *input = vam->input;
18370   vl_api_gpe_add_del_iface_t *mp;
18371   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18372   u32 dp_table = 0, vni = 0;
18373   int ret;
18374
18375   /* Parse args required to build the message */
18376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18377     {
18378       if (unformat (input, "up"))
18379         {
18380           action_set = 1;
18381           is_add = 1;
18382         }
18383       else if (unformat (input, "down"))
18384         {
18385           action_set = 1;
18386           is_add = 0;
18387         }
18388       else if (unformat (input, "table_id %d", &dp_table))
18389         {
18390           dp_table_set = 1;
18391         }
18392       else if (unformat (input, "bd_id %d", &dp_table))
18393         {
18394           dp_table_set = 1;
18395           is_l2 = 1;
18396         }
18397       else if (unformat (input, "vni %d", &vni))
18398         {
18399           vni_set = 1;
18400         }
18401       else
18402         break;
18403     }
18404
18405   if (action_set == 0)
18406     {
18407       errmsg ("Action not set");
18408       return -99;
18409     }
18410   if (dp_table_set == 0 || vni_set == 0)
18411     {
18412       errmsg ("vni and dp_table must be set");
18413       return -99;
18414     }
18415
18416   /* Construct the API message */
18417   M (GPE_ADD_DEL_IFACE, mp);
18418
18419   mp->is_add = is_add;
18420   mp->dp_table = clib_host_to_net_u32 (dp_table);
18421   mp->is_l2 = is_l2;
18422   mp->vni = clib_host_to_net_u32 (vni);
18423
18424   /* send it... */
18425   S (mp);
18426
18427   /* Wait for a reply... */
18428   W (ret);
18429   return ret;
18430 }
18431
18432 static int
18433 api_one_map_register_fallback_threshold (vat_main_t * vam)
18434 {
18435   unformat_input_t *input = vam->input;
18436   vl_api_one_map_register_fallback_threshold_t *mp;
18437   u32 value = 0;
18438   u8 is_set = 0;
18439   int ret;
18440
18441   /* Parse args required to build the message */
18442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18443     {
18444       if (unformat (input, "%u", &value))
18445         is_set = 1;
18446       else
18447         {
18448           clib_warning ("parse error '%U'", format_unformat_error, input);
18449           return -99;
18450         }
18451     }
18452
18453   if (!is_set)
18454     {
18455       errmsg ("fallback threshold value is missing!");
18456       return -99;
18457     }
18458
18459   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18460   mp->value = clib_host_to_net_u32 (value);
18461
18462   /* send it... */
18463   S (mp);
18464
18465   /* Wait for a reply... */
18466   W (ret);
18467   return ret;
18468 }
18469
18470 static int
18471 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18472 {
18473   vl_api_show_one_map_register_fallback_threshold_t *mp;
18474   int ret;
18475
18476   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18477
18478   /* send it... */
18479   S (mp);
18480
18481   /* Wait for a reply... */
18482   W (ret);
18483   return ret;
18484 }
18485
18486 uword
18487 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18488 {
18489   u32 *proto = va_arg (*args, u32 *);
18490
18491   if (unformat (input, "udp"))
18492     *proto = 1;
18493   else if (unformat (input, "api"))
18494     *proto = 2;
18495   else
18496     return 0;
18497
18498   return 1;
18499 }
18500
18501 static int
18502 api_one_set_transport_protocol (vat_main_t * vam)
18503 {
18504   unformat_input_t *input = vam->input;
18505   vl_api_one_set_transport_protocol_t *mp;
18506   u8 is_set = 0;
18507   u32 protocol = 0;
18508   int ret;
18509
18510   /* Parse args required to build the message */
18511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18512     {
18513       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18514         is_set = 1;
18515       else
18516         {
18517           clib_warning ("parse error '%U'", format_unformat_error, input);
18518           return -99;
18519         }
18520     }
18521
18522   if (!is_set)
18523     {
18524       errmsg ("Transport protocol missing!");
18525       return -99;
18526     }
18527
18528   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18529   mp->protocol = (u8) protocol;
18530
18531   /* send it... */
18532   S (mp);
18533
18534   /* Wait for a reply... */
18535   W (ret);
18536   return ret;
18537 }
18538
18539 static int
18540 api_one_get_transport_protocol (vat_main_t * vam)
18541 {
18542   vl_api_one_get_transport_protocol_t *mp;
18543   int ret;
18544
18545   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18546
18547   /* send it... */
18548   S (mp);
18549
18550   /* Wait for a reply... */
18551   W (ret);
18552   return ret;
18553 }
18554
18555 static int
18556 api_one_map_register_set_ttl (vat_main_t * vam)
18557 {
18558   unformat_input_t *input = vam->input;
18559   vl_api_one_map_register_set_ttl_t *mp;
18560   u32 ttl = 0;
18561   u8 is_set = 0;
18562   int ret;
18563
18564   /* Parse args required to build the message */
18565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18566     {
18567       if (unformat (input, "%u", &ttl))
18568         is_set = 1;
18569       else
18570         {
18571           clib_warning ("parse error '%U'", format_unformat_error, input);
18572           return -99;
18573         }
18574     }
18575
18576   if (!is_set)
18577     {
18578       errmsg ("TTL value missing!");
18579       return -99;
18580     }
18581
18582   M (ONE_MAP_REGISTER_SET_TTL, mp);
18583   mp->ttl = clib_host_to_net_u32 (ttl);
18584
18585   /* send it... */
18586   S (mp);
18587
18588   /* Wait for a reply... */
18589   W (ret);
18590   return ret;
18591 }
18592
18593 static int
18594 api_show_one_map_register_ttl (vat_main_t * vam)
18595 {
18596   vl_api_show_one_map_register_ttl_t *mp;
18597   int ret;
18598
18599   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18600
18601   /* send it... */
18602   S (mp);
18603
18604   /* Wait for a reply... */
18605   W (ret);
18606   return ret;
18607 }
18608
18609 /**
18610  * Add/del map request itr rlocs from ONE control plane and updates
18611  *
18612  * @param vam vpp API test context
18613  * @return return code
18614  */
18615 static int
18616 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18617 {
18618   unformat_input_t *input = vam->input;
18619   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18620   u8 *locator_set_name = 0;
18621   u8 locator_set_name_set = 0;
18622   u8 is_add = 1;
18623   int ret;
18624
18625   /* Parse args required to build the message */
18626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (input, "del"))
18629         {
18630           is_add = 0;
18631         }
18632       else if (unformat (input, "%_%v%_", &locator_set_name))
18633         {
18634           locator_set_name_set = 1;
18635         }
18636       else
18637         {
18638           clib_warning ("parse error '%U'", format_unformat_error, input);
18639           return -99;
18640         }
18641     }
18642
18643   if (is_add && !locator_set_name_set)
18644     {
18645       errmsg ("itr-rloc is not set!");
18646       return -99;
18647     }
18648
18649   if (is_add && vec_len (locator_set_name) > 64)
18650     {
18651       errmsg ("itr-rloc locator-set name too long");
18652       vec_free (locator_set_name);
18653       return -99;
18654     }
18655
18656   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18657   mp->is_add = is_add;
18658   if (is_add)
18659     {
18660       clib_memcpy (mp->locator_set_name, locator_set_name,
18661                    vec_len (locator_set_name));
18662     }
18663   else
18664     {
18665       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18666     }
18667   vec_free (locator_set_name);
18668
18669   /* send it... */
18670   S (mp);
18671
18672   /* Wait for a reply... */
18673   W (ret);
18674   return ret;
18675 }
18676
18677 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18678
18679 static int
18680 api_one_locator_dump (vat_main_t * vam)
18681 {
18682   unformat_input_t *input = vam->input;
18683   vl_api_one_locator_dump_t *mp;
18684   vl_api_control_ping_t *mp_ping;
18685   u8 is_index_set = 0, is_name_set = 0;
18686   u8 *ls_name = 0;
18687   u32 ls_index = ~0;
18688   int ret;
18689
18690   /* Parse args required to build the message */
18691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18692     {
18693       if (unformat (input, "ls_name %_%v%_", &ls_name))
18694         {
18695           is_name_set = 1;
18696         }
18697       else if (unformat (input, "ls_index %d", &ls_index))
18698         {
18699           is_index_set = 1;
18700         }
18701       else
18702         {
18703           errmsg ("parse error '%U'", format_unformat_error, input);
18704           return -99;
18705         }
18706     }
18707
18708   if (!is_index_set && !is_name_set)
18709     {
18710       errmsg ("error: expected one of index or name!");
18711       return -99;
18712     }
18713
18714   if (is_index_set && is_name_set)
18715     {
18716       errmsg ("error: only one param expected!");
18717       return -99;
18718     }
18719
18720   if (vec_len (ls_name) > 62)
18721     {
18722       errmsg ("error: locator set name too long!");
18723       return -99;
18724     }
18725
18726   if (!vam->json_output)
18727     {
18728       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18729     }
18730
18731   M (ONE_LOCATOR_DUMP, mp);
18732   mp->is_index_set = is_index_set;
18733
18734   if (is_index_set)
18735     mp->ls_index = clib_host_to_net_u32 (ls_index);
18736   else
18737     {
18738       vec_add1 (ls_name, 0);
18739       strncpy ((char *) mp->ls_name, (char *) ls_name,
18740                sizeof (mp->ls_name) - 1);
18741     }
18742
18743   /* send it... */
18744   S (mp);
18745
18746   /* Use a control ping for synchronization */
18747   MPING (CONTROL_PING, mp_ping);
18748   S (mp_ping);
18749
18750   /* Wait for a reply... */
18751   W (ret);
18752   return ret;
18753 }
18754
18755 #define api_lisp_locator_dump api_one_locator_dump
18756
18757 static int
18758 api_one_locator_set_dump (vat_main_t * vam)
18759 {
18760   vl_api_one_locator_set_dump_t *mp;
18761   vl_api_control_ping_t *mp_ping;
18762   unformat_input_t *input = vam->input;
18763   u8 filter = 0;
18764   int ret;
18765
18766   /* Parse args required to build the message */
18767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18768     {
18769       if (unformat (input, "local"))
18770         {
18771           filter = 1;
18772         }
18773       else if (unformat (input, "remote"))
18774         {
18775           filter = 2;
18776         }
18777       else
18778         {
18779           errmsg ("parse error '%U'", format_unformat_error, input);
18780           return -99;
18781         }
18782     }
18783
18784   if (!vam->json_output)
18785     {
18786       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18787     }
18788
18789   M (ONE_LOCATOR_SET_DUMP, mp);
18790
18791   mp->filter = filter;
18792
18793   /* send it... */
18794   S (mp);
18795
18796   /* Use a control ping for synchronization */
18797   MPING (CONTROL_PING, mp_ping);
18798   S (mp_ping);
18799
18800   /* Wait for a reply... */
18801   W (ret);
18802   return ret;
18803 }
18804
18805 #define api_lisp_locator_set_dump api_one_locator_set_dump
18806
18807 static int
18808 api_one_eid_table_map_dump (vat_main_t * vam)
18809 {
18810   u8 is_l2 = 0;
18811   u8 mode_set = 0;
18812   unformat_input_t *input = vam->input;
18813   vl_api_one_eid_table_map_dump_t *mp;
18814   vl_api_control_ping_t *mp_ping;
18815   int ret;
18816
18817   /* Parse args required to build the message */
18818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18819     {
18820       if (unformat (input, "l2"))
18821         {
18822           is_l2 = 1;
18823           mode_set = 1;
18824         }
18825       else if (unformat (input, "l3"))
18826         {
18827           is_l2 = 0;
18828           mode_set = 1;
18829         }
18830       else
18831         {
18832           errmsg ("parse error '%U'", format_unformat_error, input);
18833           return -99;
18834         }
18835     }
18836
18837   if (!mode_set)
18838     {
18839       errmsg ("expected one of 'l2' or 'l3' parameter!");
18840       return -99;
18841     }
18842
18843   if (!vam->json_output)
18844     {
18845       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18846     }
18847
18848   M (ONE_EID_TABLE_MAP_DUMP, mp);
18849   mp->is_l2 = is_l2;
18850
18851   /* send it... */
18852   S (mp);
18853
18854   /* Use a control ping for synchronization */
18855   MPING (CONTROL_PING, mp_ping);
18856   S (mp_ping);
18857
18858   /* Wait for a reply... */
18859   W (ret);
18860   return ret;
18861 }
18862
18863 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18864
18865 static int
18866 api_one_eid_table_vni_dump (vat_main_t * vam)
18867 {
18868   vl_api_one_eid_table_vni_dump_t *mp;
18869   vl_api_control_ping_t *mp_ping;
18870   int ret;
18871
18872   if (!vam->json_output)
18873     {
18874       print (vam->ofp, "VNI");
18875     }
18876
18877   M (ONE_EID_TABLE_VNI_DUMP, mp);
18878
18879   /* send it... */
18880   S (mp);
18881
18882   /* Use a control ping for synchronization */
18883   MPING (CONTROL_PING, mp_ping);
18884   S (mp_ping);
18885
18886   /* Wait for a reply... */
18887   W (ret);
18888   return ret;
18889 }
18890
18891 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18892
18893 static int
18894 api_one_eid_table_dump (vat_main_t * vam)
18895 {
18896   unformat_input_t *i = vam->input;
18897   vl_api_one_eid_table_dump_t *mp;
18898   vl_api_control_ping_t *mp_ping;
18899   struct in_addr ip4;
18900   struct in6_addr ip6;
18901   u8 mac[6];
18902   u8 eid_type = ~0, eid_set = 0;
18903   u32 prefix_length = ~0, t, vni = 0;
18904   u8 filter = 0;
18905   int ret;
18906   lisp_nsh_api_t nsh;
18907
18908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18909     {
18910       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18911         {
18912           eid_set = 1;
18913           eid_type = 0;
18914           prefix_length = t;
18915         }
18916       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18917         {
18918           eid_set = 1;
18919           eid_type = 1;
18920           prefix_length = t;
18921         }
18922       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18923         {
18924           eid_set = 1;
18925           eid_type = 2;
18926         }
18927       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18928         {
18929           eid_set = 1;
18930           eid_type = 3;
18931         }
18932       else if (unformat (i, "vni %d", &t))
18933         {
18934           vni = t;
18935         }
18936       else if (unformat (i, "local"))
18937         {
18938           filter = 1;
18939         }
18940       else if (unformat (i, "remote"))
18941         {
18942           filter = 2;
18943         }
18944       else
18945         {
18946           errmsg ("parse error '%U'", format_unformat_error, i);
18947           return -99;
18948         }
18949     }
18950
18951   if (!vam->json_output)
18952     {
18953       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18954              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18955     }
18956
18957   M (ONE_EID_TABLE_DUMP, mp);
18958
18959   mp->filter = filter;
18960   if (eid_set)
18961     {
18962       mp->eid_set = 1;
18963       mp->vni = htonl (vni);
18964       mp->eid_type = eid_type;
18965       switch (eid_type)
18966         {
18967         case 0:
18968           mp->prefix_length = prefix_length;
18969           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18970           break;
18971         case 1:
18972           mp->prefix_length = prefix_length;
18973           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18974           break;
18975         case 2:
18976           clib_memcpy (mp->eid, mac, sizeof (mac));
18977           break;
18978         case 3:
18979           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18980           break;
18981         default:
18982           errmsg ("unknown EID type %d!", eid_type);
18983           return -99;
18984         }
18985     }
18986
18987   /* send it... */
18988   S (mp);
18989
18990   /* Use a control ping for synchronization */
18991   MPING (CONTROL_PING, mp_ping);
18992   S (mp_ping);
18993
18994   /* Wait for a reply... */
18995   W (ret);
18996   return ret;
18997 }
18998
18999 #define api_lisp_eid_table_dump api_one_eid_table_dump
19000
19001 static int
19002 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19003 {
19004   unformat_input_t *i = vam->input;
19005   vl_api_gpe_fwd_entries_get_t *mp;
19006   u8 vni_set = 0;
19007   u32 vni = ~0;
19008   int ret;
19009
19010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19011     {
19012       if (unformat (i, "vni %d", &vni))
19013         {
19014           vni_set = 1;
19015         }
19016       else
19017         {
19018           errmsg ("parse error '%U'", format_unformat_error, i);
19019           return -99;
19020         }
19021     }
19022
19023   if (!vni_set)
19024     {
19025       errmsg ("vni not set!");
19026       return -99;
19027     }
19028
19029   if (!vam->json_output)
19030     {
19031       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19032              "leid", "reid");
19033     }
19034
19035   M (GPE_FWD_ENTRIES_GET, mp);
19036   mp->vni = clib_host_to_net_u32 (vni);
19037
19038   /* send it... */
19039   S (mp);
19040
19041   /* Wait for a reply... */
19042   W (ret);
19043   return ret;
19044 }
19045
19046 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19047 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19048 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19049 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19050 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19051 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19052 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19053 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19054
19055 static int
19056 api_one_adjacencies_get (vat_main_t * vam)
19057 {
19058   unformat_input_t *i = vam->input;
19059   vl_api_one_adjacencies_get_t *mp;
19060   u8 vni_set = 0;
19061   u32 vni = ~0;
19062   int ret;
19063
19064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19065     {
19066       if (unformat (i, "vni %d", &vni))
19067         {
19068           vni_set = 1;
19069         }
19070       else
19071         {
19072           errmsg ("parse error '%U'", format_unformat_error, i);
19073           return -99;
19074         }
19075     }
19076
19077   if (!vni_set)
19078     {
19079       errmsg ("vni not set!");
19080       return -99;
19081     }
19082
19083   if (!vam->json_output)
19084     {
19085       print (vam->ofp, "%s %40s", "leid", "reid");
19086     }
19087
19088   M (ONE_ADJACENCIES_GET, mp);
19089   mp->vni = clib_host_to_net_u32 (vni);
19090
19091   /* send it... */
19092   S (mp);
19093
19094   /* Wait for a reply... */
19095   W (ret);
19096   return ret;
19097 }
19098
19099 #define api_lisp_adjacencies_get api_one_adjacencies_get
19100
19101 static int
19102 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19103 {
19104   unformat_input_t *i = vam->input;
19105   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19106   int ret;
19107   u8 ip_family_set = 0, is_ip4 = 1;
19108
19109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19110     {
19111       if (unformat (i, "ip4"))
19112         {
19113           ip_family_set = 1;
19114           is_ip4 = 1;
19115         }
19116       else if (unformat (i, "ip6"))
19117         {
19118           ip_family_set = 1;
19119           is_ip4 = 0;
19120         }
19121       else
19122         {
19123           errmsg ("parse error '%U'", format_unformat_error, i);
19124           return -99;
19125         }
19126     }
19127
19128   if (!ip_family_set)
19129     {
19130       errmsg ("ip family not set!");
19131       return -99;
19132     }
19133
19134   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19135   mp->is_ip4 = is_ip4;
19136
19137   /* send it... */
19138   S (mp);
19139
19140   /* Wait for a reply... */
19141   W (ret);
19142   return ret;
19143 }
19144
19145 static int
19146 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19147 {
19148   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19149   int ret;
19150
19151   if (!vam->json_output)
19152     {
19153       print (vam->ofp, "VNIs");
19154     }
19155
19156   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19157
19158   /* send it... */
19159   S (mp);
19160
19161   /* Wait for a reply... */
19162   W (ret);
19163   return ret;
19164 }
19165
19166 static int
19167 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19168 {
19169   unformat_input_t *i = vam->input;
19170   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19171   int ret = 0;
19172   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19173   struct in_addr ip4;
19174   struct in6_addr ip6;
19175   u32 table_id = 0, nh_sw_if_index = ~0;
19176
19177   clib_memset (&ip4, 0, sizeof (ip4));
19178   clib_memset (&ip6, 0, sizeof (ip6));
19179
19180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19181     {
19182       if (unformat (i, "del"))
19183         is_add = 0;
19184       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19185                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19186         {
19187           ip_set = 1;
19188           is_ip4 = 1;
19189         }
19190       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19191                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19192         {
19193           ip_set = 1;
19194           is_ip4 = 0;
19195         }
19196       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19197         {
19198           ip_set = 1;
19199           is_ip4 = 1;
19200           nh_sw_if_index = ~0;
19201         }
19202       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19203         {
19204           ip_set = 1;
19205           is_ip4 = 0;
19206           nh_sw_if_index = ~0;
19207         }
19208       else if (unformat (i, "table %d", &table_id))
19209         ;
19210       else
19211         {
19212           errmsg ("parse error '%U'", format_unformat_error, i);
19213           return -99;
19214         }
19215     }
19216
19217   if (!ip_set)
19218     {
19219       errmsg ("nh addr not set!");
19220       return -99;
19221     }
19222
19223   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19224   mp->is_add = is_add;
19225   mp->table_id = clib_host_to_net_u32 (table_id);
19226   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19227   mp->is_ip4 = is_ip4;
19228   if (is_ip4)
19229     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19230   else
19231     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19232
19233   /* send it... */
19234   S (mp);
19235
19236   /* Wait for a reply... */
19237   W (ret);
19238   return ret;
19239 }
19240
19241 static int
19242 api_one_map_server_dump (vat_main_t * vam)
19243 {
19244   vl_api_one_map_server_dump_t *mp;
19245   vl_api_control_ping_t *mp_ping;
19246   int ret;
19247
19248   if (!vam->json_output)
19249     {
19250       print (vam->ofp, "%=20s", "Map server");
19251     }
19252
19253   M (ONE_MAP_SERVER_DUMP, mp);
19254   /* send it... */
19255   S (mp);
19256
19257   /* Use a control ping for synchronization */
19258   MPING (CONTROL_PING, mp_ping);
19259   S (mp_ping);
19260
19261   /* Wait for a reply... */
19262   W (ret);
19263   return ret;
19264 }
19265
19266 #define api_lisp_map_server_dump api_one_map_server_dump
19267
19268 static int
19269 api_one_map_resolver_dump (vat_main_t * vam)
19270 {
19271   vl_api_one_map_resolver_dump_t *mp;
19272   vl_api_control_ping_t *mp_ping;
19273   int ret;
19274
19275   if (!vam->json_output)
19276     {
19277       print (vam->ofp, "%=20s", "Map resolver");
19278     }
19279
19280   M (ONE_MAP_RESOLVER_DUMP, mp);
19281   /* send it... */
19282   S (mp);
19283
19284   /* Use a control ping for synchronization */
19285   MPING (CONTROL_PING, mp_ping);
19286   S (mp_ping);
19287
19288   /* Wait for a reply... */
19289   W (ret);
19290   return ret;
19291 }
19292
19293 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19294
19295 static int
19296 api_one_stats_flush (vat_main_t * vam)
19297 {
19298   vl_api_one_stats_flush_t *mp;
19299   int ret = 0;
19300
19301   M (ONE_STATS_FLUSH, mp);
19302   S (mp);
19303   W (ret);
19304   return ret;
19305 }
19306
19307 static int
19308 api_one_stats_dump (vat_main_t * vam)
19309 {
19310   vl_api_one_stats_dump_t *mp;
19311   vl_api_control_ping_t *mp_ping;
19312   int ret;
19313
19314   M (ONE_STATS_DUMP, mp);
19315   /* send it... */
19316   S (mp);
19317
19318   /* Use a control ping for synchronization */
19319   MPING (CONTROL_PING, mp_ping);
19320   S (mp_ping);
19321
19322   /* Wait for a reply... */
19323   W (ret);
19324   return ret;
19325 }
19326
19327 static int
19328 api_show_one_status (vat_main_t * vam)
19329 {
19330   vl_api_show_one_status_t *mp;
19331   int ret;
19332
19333   if (!vam->json_output)
19334     {
19335       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19336     }
19337
19338   M (SHOW_ONE_STATUS, mp);
19339   /* send it... */
19340   S (mp);
19341   /* Wait for a reply... */
19342   W (ret);
19343   return ret;
19344 }
19345
19346 #define api_show_lisp_status api_show_one_status
19347
19348 static int
19349 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19350 {
19351   vl_api_gpe_fwd_entry_path_dump_t *mp;
19352   vl_api_control_ping_t *mp_ping;
19353   unformat_input_t *i = vam->input;
19354   u32 fwd_entry_index = ~0;
19355   int ret;
19356
19357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19358     {
19359       if (unformat (i, "index %d", &fwd_entry_index))
19360         ;
19361       else
19362         break;
19363     }
19364
19365   if (~0 == fwd_entry_index)
19366     {
19367       errmsg ("no index specified!");
19368       return -99;
19369     }
19370
19371   if (!vam->json_output)
19372     {
19373       print (vam->ofp, "first line");
19374     }
19375
19376   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19377
19378   /* send it... */
19379   S (mp);
19380   /* Use a control ping for synchronization */
19381   MPING (CONTROL_PING, mp_ping);
19382   S (mp_ping);
19383
19384   /* Wait for a reply... */
19385   W (ret);
19386   return ret;
19387 }
19388
19389 static int
19390 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19391 {
19392   vl_api_one_get_map_request_itr_rlocs_t *mp;
19393   int ret;
19394
19395   if (!vam->json_output)
19396     {
19397       print (vam->ofp, "%=20s", "itr-rlocs:");
19398     }
19399
19400   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19401   /* send it... */
19402   S (mp);
19403   /* Wait for a reply... */
19404   W (ret);
19405   return ret;
19406 }
19407
19408 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19409
19410 static int
19411 api_af_packet_create (vat_main_t * vam)
19412 {
19413   unformat_input_t *i = vam->input;
19414   vl_api_af_packet_create_t *mp;
19415   u8 *host_if_name = 0;
19416   u8 hw_addr[6];
19417   u8 random_hw_addr = 1;
19418   int ret;
19419
19420   clib_memset (hw_addr, 0, sizeof (hw_addr));
19421
19422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19423     {
19424       if (unformat (i, "name %s", &host_if_name))
19425         vec_add1 (host_if_name, 0);
19426       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19427         random_hw_addr = 0;
19428       else
19429         break;
19430     }
19431
19432   if (!vec_len (host_if_name))
19433     {
19434       errmsg ("host-interface name must be specified");
19435       return -99;
19436     }
19437
19438   if (vec_len (host_if_name) > 64)
19439     {
19440       errmsg ("host-interface name too long");
19441       return -99;
19442     }
19443
19444   M (AF_PACKET_CREATE, mp);
19445
19446   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19447   clib_memcpy (mp->hw_addr, hw_addr, 6);
19448   mp->use_random_hw_addr = random_hw_addr;
19449   vec_free (host_if_name);
19450
19451   S (mp);
19452
19453   /* *INDENT-OFF* */
19454   W2 (ret,
19455       ({
19456         if (ret == 0)
19457           fprintf (vam->ofp ? vam->ofp : stderr,
19458                    " new sw_if_index = %d\n", vam->sw_if_index);
19459       }));
19460   /* *INDENT-ON* */
19461   return ret;
19462 }
19463
19464 static int
19465 api_af_packet_delete (vat_main_t * vam)
19466 {
19467   unformat_input_t *i = vam->input;
19468   vl_api_af_packet_delete_t *mp;
19469   u8 *host_if_name = 0;
19470   int ret;
19471
19472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19473     {
19474       if (unformat (i, "name %s", &host_if_name))
19475         vec_add1 (host_if_name, 0);
19476       else
19477         break;
19478     }
19479
19480   if (!vec_len (host_if_name))
19481     {
19482       errmsg ("host-interface name must be specified");
19483       return -99;
19484     }
19485
19486   if (vec_len (host_if_name) > 64)
19487     {
19488       errmsg ("host-interface name too long");
19489       return -99;
19490     }
19491
19492   M (AF_PACKET_DELETE, mp);
19493
19494   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19495   vec_free (host_if_name);
19496
19497   S (mp);
19498   W (ret);
19499   return ret;
19500 }
19501
19502 static void vl_api_af_packet_details_t_handler
19503   (vl_api_af_packet_details_t * mp)
19504 {
19505   vat_main_t *vam = &vat_main;
19506
19507   print (vam->ofp, "%-16s %d",
19508          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19509 }
19510
19511 static void vl_api_af_packet_details_t_handler_json
19512   (vl_api_af_packet_details_t * mp)
19513 {
19514   vat_main_t *vam = &vat_main;
19515   vat_json_node_t *node = NULL;
19516
19517   if (VAT_JSON_ARRAY != vam->json_tree.type)
19518     {
19519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19520       vat_json_init_array (&vam->json_tree);
19521     }
19522   node = vat_json_array_add (&vam->json_tree);
19523
19524   vat_json_init_object (node);
19525   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19526   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19527 }
19528
19529 static int
19530 api_af_packet_dump (vat_main_t * vam)
19531 {
19532   vl_api_af_packet_dump_t *mp;
19533   vl_api_control_ping_t *mp_ping;
19534   int ret;
19535
19536   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19537   /* Get list of tap interfaces */
19538   M (AF_PACKET_DUMP, mp);
19539   S (mp);
19540
19541   /* Use a control ping for synchronization */
19542   MPING (CONTROL_PING, mp_ping);
19543   S (mp_ping);
19544
19545   W (ret);
19546   return ret;
19547 }
19548
19549 static int
19550 api_policer_add_del (vat_main_t * vam)
19551 {
19552   unformat_input_t *i = vam->input;
19553   vl_api_policer_add_del_t *mp;
19554   u8 is_add = 1;
19555   u8 *name = 0;
19556   u32 cir = 0;
19557   u32 eir = 0;
19558   u64 cb = 0;
19559   u64 eb = 0;
19560   u8 rate_type = 0;
19561   u8 round_type = 0;
19562   u8 type = 0;
19563   u8 color_aware = 0;
19564   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19565   int ret;
19566
19567   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19568   conform_action.dscp = 0;
19569   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19570   exceed_action.dscp = 0;
19571   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19572   violate_action.dscp = 0;
19573
19574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19575     {
19576       if (unformat (i, "del"))
19577         is_add = 0;
19578       else if (unformat (i, "name %s", &name))
19579         vec_add1 (name, 0);
19580       else if (unformat (i, "cir %u", &cir))
19581         ;
19582       else if (unformat (i, "eir %u", &eir))
19583         ;
19584       else if (unformat (i, "cb %u", &cb))
19585         ;
19586       else if (unformat (i, "eb %u", &eb))
19587         ;
19588       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19589                          &rate_type))
19590         ;
19591       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19592                          &round_type))
19593         ;
19594       else if (unformat (i, "type %U", unformat_policer_type, &type))
19595         ;
19596       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19597                          &conform_action))
19598         ;
19599       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19600                          &exceed_action))
19601         ;
19602       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19603                          &violate_action))
19604         ;
19605       else if (unformat (i, "color-aware"))
19606         color_aware = 1;
19607       else
19608         break;
19609     }
19610
19611   if (!vec_len (name))
19612     {
19613       errmsg ("policer name must be specified");
19614       return -99;
19615     }
19616
19617   if (vec_len (name) > 64)
19618     {
19619       errmsg ("policer name too long");
19620       return -99;
19621     }
19622
19623   M (POLICER_ADD_DEL, mp);
19624
19625   clib_memcpy (mp->name, name, vec_len (name));
19626   vec_free (name);
19627   mp->is_add = is_add;
19628   mp->cir = ntohl (cir);
19629   mp->eir = ntohl (eir);
19630   mp->cb = clib_net_to_host_u64 (cb);
19631   mp->eb = clib_net_to_host_u64 (eb);
19632   mp->rate_type = rate_type;
19633   mp->round_type = round_type;
19634   mp->type = type;
19635   mp->conform_action_type = conform_action.action_type;
19636   mp->conform_dscp = conform_action.dscp;
19637   mp->exceed_action_type = exceed_action.action_type;
19638   mp->exceed_dscp = exceed_action.dscp;
19639   mp->violate_action_type = violate_action.action_type;
19640   mp->violate_dscp = violate_action.dscp;
19641   mp->color_aware = color_aware;
19642
19643   S (mp);
19644   W (ret);
19645   return ret;
19646 }
19647
19648 static int
19649 api_policer_dump (vat_main_t * vam)
19650 {
19651   unformat_input_t *i = vam->input;
19652   vl_api_policer_dump_t *mp;
19653   vl_api_control_ping_t *mp_ping;
19654   u8 *match_name = 0;
19655   u8 match_name_valid = 0;
19656   int ret;
19657
19658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19659     {
19660       if (unformat (i, "name %s", &match_name))
19661         {
19662           vec_add1 (match_name, 0);
19663           match_name_valid = 1;
19664         }
19665       else
19666         break;
19667     }
19668
19669   M (POLICER_DUMP, mp);
19670   mp->match_name_valid = match_name_valid;
19671   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19672   vec_free (match_name);
19673   /* send it... */
19674   S (mp);
19675
19676   /* Use a control ping for synchronization */
19677   MPING (CONTROL_PING, mp_ping);
19678   S (mp_ping);
19679
19680   /* Wait for a reply... */
19681   W (ret);
19682   return ret;
19683 }
19684
19685 static int
19686 api_policer_classify_set_interface (vat_main_t * vam)
19687 {
19688   unformat_input_t *i = vam->input;
19689   vl_api_policer_classify_set_interface_t *mp;
19690   u32 sw_if_index;
19691   int sw_if_index_set;
19692   u32 ip4_table_index = ~0;
19693   u32 ip6_table_index = ~0;
19694   u32 l2_table_index = ~0;
19695   u8 is_add = 1;
19696   int ret;
19697
19698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19699     {
19700       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19701         sw_if_index_set = 1;
19702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19703         sw_if_index_set = 1;
19704       else if (unformat (i, "del"))
19705         is_add = 0;
19706       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19707         ;
19708       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19709         ;
19710       else if (unformat (i, "l2-table %d", &l2_table_index))
19711         ;
19712       else
19713         {
19714           clib_warning ("parse error '%U'", format_unformat_error, i);
19715           return -99;
19716         }
19717     }
19718
19719   if (sw_if_index_set == 0)
19720     {
19721       errmsg ("missing interface name or sw_if_index");
19722       return -99;
19723     }
19724
19725   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19726
19727   mp->sw_if_index = ntohl (sw_if_index);
19728   mp->ip4_table_index = ntohl (ip4_table_index);
19729   mp->ip6_table_index = ntohl (ip6_table_index);
19730   mp->l2_table_index = ntohl (l2_table_index);
19731   mp->is_add = is_add;
19732
19733   S (mp);
19734   W (ret);
19735   return ret;
19736 }
19737
19738 static int
19739 api_policer_classify_dump (vat_main_t * vam)
19740 {
19741   unformat_input_t *i = vam->input;
19742   vl_api_policer_classify_dump_t *mp;
19743   vl_api_control_ping_t *mp_ping;
19744   u8 type = POLICER_CLASSIFY_N_TABLES;
19745   int ret;
19746
19747   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19748     ;
19749   else
19750     {
19751       errmsg ("classify table type must be specified");
19752       return -99;
19753     }
19754
19755   if (!vam->json_output)
19756     {
19757       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19758     }
19759
19760   M (POLICER_CLASSIFY_DUMP, mp);
19761   mp->type = type;
19762   /* send it... */
19763   S (mp);
19764
19765   /* Use a control ping for synchronization */
19766   MPING (CONTROL_PING, mp_ping);
19767   S (mp_ping);
19768
19769   /* Wait for a reply... */
19770   W (ret);
19771   return ret;
19772 }
19773
19774 static int
19775 api_netmap_create (vat_main_t * vam)
19776 {
19777   unformat_input_t *i = vam->input;
19778   vl_api_netmap_create_t *mp;
19779   u8 *if_name = 0;
19780   u8 hw_addr[6];
19781   u8 random_hw_addr = 1;
19782   u8 is_pipe = 0;
19783   u8 is_master = 0;
19784   int ret;
19785
19786   clib_memset (hw_addr, 0, sizeof (hw_addr));
19787
19788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19789     {
19790       if (unformat (i, "name %s", &if_name))
19791         vec_add1 (if_name, 0);
19792       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19793         random_hw_addr = 0;
19794       else if (unformat (i, "pipe"))
19795         is_pipe = 1;
19796       else if (unformat (i, "master"))
19797         is_master = 1;
19798       else if (unformat (i, "slave"))
19799         is_master = 0;
19800       else
19801         break;
19802     }
19803
19804   if (!vec_len (if_name))
19805     {
19806       errmsg ("interface name must be specified");
19807       return -99;
19808     }
19809
19810   if (vec_len (if_name) > 64)
19811     {
19812       errmsg ("interface name too long");
19813       return -99;
19814     }
19815
19816   M (NETMAP_CREATE, mp);
19817
19818   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19819   clib_memcpy (mp->hw_addr, hw_addr, 6);
19820   mp->use_random_hw_addr = random_hw_addr;
19821   mp->is_pipe = is_pipe;
19822   mp->is_master = is_master;
19823   vec_free (if_name);
19824
19825   S (mp);
19826   W (ret);
19827   return ret;
19828 }
19829
19830 static int
19831 api_netmap_delete (vat_main_t * vam)
19832 {
19833   unformat_input_t *i = vam->input;
19834   vl_api_netmap_delete_t *mp;
19835   u8 *if_name = 0;
19836   int ret;
19837
19838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19839     {
19840       if (unformat (i, "name %s", &if_name))
19841         vec_add1 (if_name, 0);
19842       else
19843         break;
19844     }
19845
19846   if (!vec_len (if_name))
19847     {
19848       errmsg ("interface name must be specified");
19849       return -99;
19850     }
19851
19852   if (vec_len (if_name) > 64)
19853     {
19854       errmsg ("interface name too long");
19855       return -99;
19856     }
19857
19858   M (NETMAP_DELETE, mp);
19859
19860   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19861   vec_free (if_name);
19862
19863   S (mp);
19864   W (ret);
19865   return ret;
19866 }
19867
19868 static void
19869 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
19870 {
19871   if (fp->afi == IP46_TYPE_IP6)
19872     print (vam->ofp,
19873            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19874            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19875            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19876            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19877            format_ip6_address, fp->next_hop);
19878   else if (fp->afi == IP46_TYPE_IP4)
19879     print (vam->ofp,
19880            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19881            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19882            fp->weight, ntohl (fp->sw_if_index), fp->is_local,
19883            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19884            format_ip4_address, fp->next_hop);
19885 }
19886
19887 static void
19888 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19889                                  vl_api_fib_path_t * fp)
19890 {
19891   struct in_addr ip4;
19892   struct in6_addr ip6;
19893
19894   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19895   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19896   vat_json_object_add_uint (node, "is_local", fp->is_local);
19897   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19898   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19899   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19900   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19901   if (fp->afi == IP46_TYPE_IP4)
19902     {
19903       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19904       vat_json_object_add_ip4 (node, "next_hop", ip4);
19905     }
19906   else if (fp->afi == IP46_TYPE_IP6)
19907     {
19908       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19909       vat_json_object_add_ip6 (node, "next_hop", ip6);
19910     }
19911 }
19912
19913 static void
19914 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19915 {
19916   vat_main_t *vam = &vat_main;
19917   int count = ntohl (mp->mt_count);
19918   vl_api_fib_path_t *fp;
19919   i32 i;
19920
19921   print (vam->ofp, "[%d]: sw_if_index %d via:",
19922          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19923   fp = mp->mt_paths;
19924   for (i = 0; i < count; i++)
19925     {
19926       vl_api_mpls_fib_path_print (vam, fp);
19927       fp++;
19928     }
19929
19930   print (vam->ofp, "");
19931 }
19932
19933 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19934 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19935
19936 static void
19937 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19938 {
19939   vat_main_t *vam = &vat_main;
19940   vat_json_node_t *node = NULL;
19941   int count = ntohl (mp->mt_count);
19942   vl_api_fib_path_t *fp;
19943   i32 i;
19944
19945   if (VAT_JSON_ARRAY != vam->json_tree.type)
19946     {
19947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19948       vat_json_init_array (&vam->json_tree);
19949     }
19950   node = vat_json_array_add (&vam->json_tree);
19951
19952   vat_json_init_object (node);
19953   vat_json_object_add_uint (node, "tunnel_index",
19954                             ntohl (mp->mt_tunnel_index));
19955   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19956
19957   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19958
19959   fp = mp->mt_paths;
19960   for (i = 0; i < count; i++)
19961     {
19962       vl_api_mpls_fib_path_json_print (node, fp);
19963       fp++;
19964     }
19965 }
19966
19967 static int
19968 api_mpls_tunnel_dump (vat_main_t * vam)
19969 {
19970   vl_api_mpls_tunnel_dump_t *mp;
19971   vl_api_control_ping_t *mp_ping;
19972   u32 sw_if_index = ~0;
19973   int ret;
19974
19975   /* Parse args required to build the message */
19976   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19977     {
19978       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
19979         ;
19980     }
19981
19982   print (vam->ofp, "  sw_if_index %d", sw_if_index);
19983
19984   M (MPLS_TUNNEL_DUMP, mp);
19985   mp->sw_if_index = htonl (sw_if_index);
19986   S (mp);
19987
19988   /* Use a control ping for synchronization */
19989   MPING (CONTROL_PING, mp_ping);
19990   S (mp_ping);
19991
19992   W (ret);
19993   return ret;
19994 }
19995
19996 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19997 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19998
19999
20000 static void
20001 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20002 {
20003   vat_main_t *vam = &vat_main;
20004   int count = ntohl (mp->count);
20005   vl_api_fib_path_t *fp;
20006   int i;
20007
20008   print (vam->ofp,
20009          "table-id %d, label %u, ess_bit %u",
20010          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20011   fp = mp->path;
20012   for (i = 0; i < count; i++)
20013     {
20014       vl_api_mpls_fib_path_print (vam, fp);
20015       fp++;
20016     }
20017 }
20018
20019 static void vl_api_mpls_fib_details_t_handler_json
20020   (vl_api_mpls_fib_details_t * mp)
20021 {
20022   vat_main_t *vam = &vat_main;
20023   int count = ntohl (mp->count);
20024   vat_json_node_t *node = NULL;
20025   vl_api_fib_path_t *fp;
20026   int i;
20027
20028   if (VAT_JSON_ARRAY != vam->json_tree.type)
20029     {
20030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20031       vat_json_init_array (&vam->json_tree);
20032     }
20033   node = vat_json_array_add (&vam->json_tree);
20034
20035   vat_json_init_object (node);
20036   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20037   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20038   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20039   vat_json_object_add_uint (node, "path_count", count);
20040   fp = mp->path;
20041   for (i = 0; i < count; i++)
20042     {
20043       vl_api_mpls_fib_path_json_print (node, fp);
20044       fp++;
20045     }
20046 }
20047
20048 static int
20049 api_mpls_fib_dump (vat_main_t * vam)
20050 {
20051   vl_api_mpls_fib_dump_t *mp;
20052   vl_api_control_ping_t *mp_ping;
20053   int ret;
20054
20055   M (MPLS_FIB_DUMP, mp);
20056   S (mp);
20057
20058   /* Use a control ping for synchronization */
20059   MPING (CONTROL_PING, mp_ping);
20060   S (mp_ping);
20061
20062   W (ret);
20063   return ret;
20064 }
20065
20066 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20067 #define vl_api_ip_fib_details_t_print vl_noop_handler
20068
20069 static void
20070 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20071 {
20072   vat_main_t *vam = &vat_main;
20073   int count = ntohl (mp->count);
20074   vl_api_fib_path_t *fp;
20075   int i;
20076
20077   print (vam->ofp,
20078          "table-id %d, prefix %U/%d stats-index %d",
20079          ntohl (mp->table_id), format_ip4_address, mp->address,
20080          mp->address_length, ntohl (mp->stats_index));
20081   fp = mp->path;
20082   for (i = 0; i < count; i++)
20083     {
20084       if (fp->afi == IP46_TYPE_IP6)
20085         print (vam->ofp,
20086                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20087                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20088                "next_hop_table %d",
20089                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20090                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20091                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20092       else if (fp->afi == IP46_TYPE_IP4)
20093         print (vam->ofp,
20094                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20095                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20096                "next_hop_table %d",
20097                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20098                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20099                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20100       fp++;
20101     }
20102 }
20103
20104 static void vl_api_ip_fib_details_t_handler_json
20105   (vl_api_ip_fib_details_t * mp)
20106 {
20107   vat_main_t *vam = &vat_main;
20108   int count = ntohl (mp->count);
20109   vat_json_node_t *node = NULL;
20110   struct in_addr ip4;
20111   struct in6_addr ip6;
20112   vl_api_fib_path_t *fp;
20113   int i;
20114
20115   if (VAT_JSON_ARRAY != vam->json_tree.type)
20116     {
20117       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20118       vat_json_init_array (&vam->json_tree);
20119     }
20120   node = vat_json_array_add (&vam->json_tree);
20121
20122   vat_json_init_object (node);
20123   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20124   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20125   vat_json_object_add_ip4 (node, "prefix", ip4);
20126   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20127   vat_json_object_add_uint (node, "path_count", count);
20128   fp = mp->path;
20129   for (i = 0; i < count; i++)
20130     {
20131       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20132       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20133       vat_json_object_add_uint (node, "is_local", fp->is_local);
20134       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20135       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20136       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20137       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20138       if (fp->afi == IP46_TYPE_IP4)
20139         {
20140           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20141           vat_json_object_add_ip4 (node, "next_hop", ip4);
20142         }
20143       else if (fp->afi == IP46_TYPE_IP6)
20144         {
20145           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20146           vat_json_object_add_ip6 (node, "next_hop", ip6);
20147         }
20148     }
20149 }
20150
20151 static int
20152 api_ip_fib_dump (vat_main_t * vam)
20153 {
20154   vl_api_ip_fib_dump_t *mp;
20155   vl_api_control_ping_t *mp_ping;
20156   int ret;
20157
20158   M (IP_FIB_DUMP, mp);
20159   S (mp);
20160
20161   /* Use a control ping for synchronization */
20162   MPING (CONTROL_PING, mp_ping);
20163   S (mp_ping);
20164
20165   W (ret);
20166   return ret;
20167 }
20168
20169 static int
20170 api_ip_mfib_dump (vat_main_t * vam)
20171 {
20172   vl_api_ip_mfib_dump_t *mp;
20173   vl_api_control_ping_t *mp_ping;
20174   int ret;
20175
20176   M (IP_MFIB_DUMP, mp);
20177   S (mp);
20178
20179   /* Use a control ping for synchronization */
20180   MPING (CONTROL_PING, mp_ping);
20181   S (mp_ping);
20182
20183   W (ret);
20184   return ret;
20185 }
20186
20187 static void vl_api_ip_neighbor_details_t_handler
20188   (vl_api_ip_neighbor_details_t * mp)
20189 {
20190   vat_main_t *vam = &vat_main;
20191
20192   print (vam->ofp, "%c %U %U",
20193          (mp->is_static) ? 'S' : 'D',
20194          format_ethernet_address, &mp->mac_address,
20195          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20196          &mp->ip_address);
20197 }
20198
20199 static void vl_api_ip_neighbor_details_t_handler_json
20200   (vl_api_ip_neighbor_details_t * mp)
20201 {
20202
20203   vat_main_t *vam = &vat_main;
20204   vat_json_node_t *node;
20205   struct in_addr ip4;
20206   struct in6_addr ip6;
20207
20208   if (VAT_JSON_ARRAY != vam->json_tree.type)
20209     {
20210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20211       vat_json_init_array (&vam->json_tree);
20212     }
20213   node = vat_json_array_add (&vam->json_tree);
20214
20215   vat_json_init_object (node);
20216   vat_json_object_add_string_copy (node, "flag",
20217                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20218                                    "dynamic");
20219
20220   vat_json_object_add_string_copy (node, "link_layer",
20221                                    format (0, "%U", format_ethernet_address,
20222                                            &mp->mac_address));
20223
20224   if (mp->is_ipv6)
20225     {
20226       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20227       vat_json_object_add_ip6 (node, "ip_address", ip6);
20228     }
20229   else
20230     {
20231       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20232       vat_json_object_add_ip4 (node, "ip_address", ip4);
20233     }
20234 }
20235
20236 static int
20237 api_ip_neighbor_dump (vat_main_t * vam)
20238 {
20239   unformat_input_t *i = vam->input;
20240   vl_api_ip_neighbor_dump_t *mp;
20241   vl_api_control_ping_t *mp_ping;
20242   u8 is_ipv6 = 0;
20243   u32 sw_if_index = ~0;
20244   int ret;
20245
20246   /* Parse args required to build the message */
20247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20248     {
20249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20250         ;
20251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20252         ;
20253       else if (unformat (i, "ip6"))
20254         is_ipv6 = 1;
20255       else
20256         break;
20257     }
20258
20259   if (sw_if_index == ~0)
20260     {
20261       errmsg ("missing interface name or sw_if_index");
20262       return -99;
20263     }
20264
20265   M (IP_NEIGHBOR_DUMP, mp);
20266   mp->is_ipv6 = (u8) is_ipv6;
20267   mp->sw_if_index = ntohl (sw_if_index);
20268   S (mp);
20269
20270   /* Use a control ping for synchronization */
20271   MPING (CONTROL_PING, mp_ping);
20272   S (mp_ping);
20273
20274   W (ret);
20275   return ret;
20276 }
20277
20278 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20279 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20280
20281 static void
20282 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20283 {
20284   vat_main_t *vam = &vat_main;
20285   int count = ntohl (mp->count);
20286   vl_api_fib_path_t *fp;
20287   int i;
20288
20289   print (vam->ofp,
20290          "table-id %d, prefix %U/%d stats-index %d",
20291          ntohl (mp->table_id), format_ip6_address, mp->address,
20292          mp->address_length, ntohl (mp->stats_index));
20293   fp = mp->path;
20294   for (i = 0; i < count; i++)
20295     {
20296       if (fp->afi == IP46_TYPE_IP6)
20297         print (vam->ofp,
20298                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20299                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20300                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20301                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20302                format_ip6_address, fp->next_hop);
20303       else if (fp->afi == IP46_TYPE_IP4)
20304         print (vam->ofp,
20305                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20306                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20307                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20308                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20309                format_ip4_address, fp->next_hop);
20310       fp++;
20311     }
20312 }
20313
20314 static void vl_api_ip6_fib_details_t_handler_json
20315   (vl_api_ip6_fib_details_t * mp)
20316 {
20317   vat_main_t *vam = &vat_main;
20318   int count = ntohl (mp->count);
20319   vat_json_node_t *node = NULL;
20320   struct in_addr ip4;
20321   struct in6_addr ip6;
20322   vl_api_fib_path_t *fp;
20323   int i;
20324
20325   if (VAT_JSON_ARRAY != vam->json_tree.type)
20326     {
20327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20328       vat_json_init_array (&vam->json_tree);
20329     }
20330   node = vat_json_array_add (&vam->json_tree);
20331
20332   vat_json_init_object (node);
20333   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20334   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20335   vat_json_object_add_ip6 (node, "prefix", ip6);
20336   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20337   vat_json_object_add_uint (node, "path_count", count);
20338   fp = mp->path;
20339   for (i = 0; i < count; i++)
20340     {
20341       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20342       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20343       vat_json_object_add_uint (node, "is_local", fp->is_local);
20344       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20345       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20346       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20347       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20348       if (fp->afi == IP46_TYPE_IP4)
20349         {
20350           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20351           vat_json_object_add_ip4 (node, "next_hop", ip4);
20352         }
20353       else if (fp->afi == IP46_TYPE_IP6)
20354         {
20355           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20356           vat_json_object_add_ip6 (node, "next_hop", ip6);
20357         }
20358     }
20359 }
20360
20361 static int
20362 api_ip6_fib_dump (vat_main_t * vam)
20363 {
20364   vl_api_ip6_fib_dump_t *mp;
20365   vl_api_control_ping_t *mp_ping;
20366   int ret;
20367
20368   M (IP6_FIB_DUMP, mp);
20369   S (mp);
20370
20371   /* Use a control ping for synchronization */
20372   MPING (CONTROL_PING, mp_ping);
20373   S (mp_ping);
20374
20375   W (ret);
20376   return ret;
20377 }
20378
20379 static int
20380 api_ip6_mfib_dump (vat_main_t * vam)
20381 {
20382   vl_api_ip6_mfib_dump_t *mp;
20383   vl_api_control_ping_t *mp_ping;
20384   int ret;
20385
20386   M (IP6_MFIB_DUMP, mp);
20387   S (mp);
20388
20389   /* Use a control ping for synchronization */
20390   MPING (CONTROL_PING, mp_ping);
20391   S (mp_ping);
20392
20393   W (ret);
20394   return ret;
20395 }
20396
20397 int
20398 api_classify_table_ids (vat_main_t * vam)
20399 {
20400   vl_api_classify_table_ids_t *mp;
20401   int ret;
20402
20403   /* Construct the API message */
20404   M (CLASSIFY_TABLE_IDS, mp);
20405   mp->context = 0;
20406
20407   S (mp);
20408   W (ret);
20409   return ret;
20410 }
20411
20412 int
20413 api_classify_table_by_interface (vat_main_t * vam)
20414 {
20415   unformat_input_t *input = vam->input;
20416   vl_api_classify_table_by_interface_t *mp;
20417
20418   u32 sw_if_index = ~0;
20419   int ret;
20420   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20421     {
20422       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20423         ;
20424       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20425         ;
20426       else
20427         break;
20428     }
20429   if (sw_if_index == ~0)
20430     {
20431       errmsg ("missing interface name or sw_if_index");
20432       return -99;
20433     }
20434
20435   /* Construct the API message */
20436   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20437   mp->context = 0;
20438   mp->sw_if_index = ntohl (sw_if_index);
20439
20440   S (mp);
20441   W (ret);
20442   return ret;
20443 }
20444
20445 int
20446 api_classify_table_info (vat_main_t * vam)
20447 {
20448   unformat_input_t *input = vam->input;
20449   vl_api_classify_table_info_t *mp;
20450
20451   u32 table_id = ~0;
20452   int ret;
20453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20454     {
20455       if (unformat (input, "table_id %d", &table_id))
20456         ;
20457       else
20458         break;
20459     }
20460   if (table_id == ~0)
20461     {
20462       errmsg ("missing table id");
20463       return -99;
20464     }
20465
20466   /* Construct the API message */
20467   M (CLASSIFY_TABLE_INFO, mp);
20468   mp->context = 0;
20469   mp->table_id = ntohl (table_id);
20470
20471   S (mp);
20472   W (ret);
20473   return ret;
20474 }
20475
20476 int
20477 api_classify_session_dump (vat_main_t * vam)
20478 {
20479   unformat_input_t *input = vam->input;
20480   vl_api_classify_session_dump_t *mp;
20481   vl_api_control_ping_t *mp_ping;
20482
20483   u32 table_id = ~0;
20484   int ret;
20485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20486     {
20487       if (unformat (input, "table_id %d", &table_id))
20488         ;
20489       else
20490         break;
20491     }
20492   if (table_id == ~0)
20493     {
20494       errmsg ("missing table id");
20495       return -99;
20496     }
20497
20498   /* Construct the API message */
20499   M (CLASSIFY_SESSION_DUMP, mp);
20500   mp->context = 0;
20501   mp->table_id = ntohl (table_id);
20502   S (mp);
20503
20504   /* Use a control ping for synchronization */
20505   MPING (CONTROL_PING, mp_ping);
20506   S (mp_ping);
20507
20508   W (ret);
20509   return ret;
20510 }
20511
20512 static void
20513 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20514 {
20515   vat_main_t *vam = &vat_main;
20516
20517   print (vam->ofp, "collector_address %U, collector_port %d, "
20518          "src_address %U, vrf_id %d, path_mtu %u, "
20519          "template_interval %u, udp_checksum %d",
20520          format_ip4_address, mp->collector_address,
20521          ntohs (mp->collector_port),
20522          format_ip4_address, mp->src_address,
20523          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20524          ntohl (mp->template_interval), mp->udp_checksum);
20525
20526   vam->retval = 0;
20527   vam->result_ready = 1;
20528 }
20529
20530 static void
20531   vl_api_ipfix_exporter_details_t_handler_json
20532   (vl_api_ipfix_exporter_details_t * mp)
20533 {
20534   vat_main_t *vam = &vat_main;
20535   vat_json_node_t node;
20536   struct in_addr collector_address;
20537   struct in_addr src_address;
20538
20539   vat_json_init_object (&node);
20540   clib_memcpy (&collector_address, &mp->collector_address,
20541                sizeof (collector_address));
20542   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20543   vat_json_object_add_uint (&node, "collector_port",
20544                             ntohs (mp->collector_port));
20545   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20546   vat_json_object_add_ip4 (&node, "src_address", src_address);
20547   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20548   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20549   vat_json_object_add_uint (&node, "template_interval",
20550                             ntohl (mp->template_interval));
20551   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20552
20553   vat_json_print (vam->ofp, &node);
20554   vat_json_free (&node);
20555   vam->retval = 0;
20556   vam->result_ready = 1;
20557 }
20558
20559 int
20560 api_ipfix_exporter_dump (vat_main_t * vam)
20561 {
20562   vl_api_ipfix_exporter_dump_t *mp;
20563   int ret;
20564
20565   /* Construct the API message */
20566   M (IPFIX_EXPORTER_DUMP, mp);
20567   mp->context = 0;
20568
20569   S (mp);
20570   W (ret);
20571   return ret;
20572 }
20573
20574 static int
20575 api_ipfix_classify_stream_dump (vat_main_t * vam)
20576 {
20577   vl_api_ipfix_classify_stream_dump_t *mp;
20578   int ret;
20579
20580   /* Construct the API message */
20581   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20582   mp->context = 0;
20583
20584   S (mp);
20585   W (ret);
20586   return ret;
20587   /* NOTREACHED */
20588   return 0;
20589 }
20590
20591 static void
20592   vl_api_ipfix_classify_stream_details_t_handler
20593   (vl_api_ipfix_classify_stream_details_t * mp)
20594 {
20595   vat_main_t *vam = &vat_main;
20596   print (vam->ofp, "domain_id %d, src_port %d",
20597          ntohl (mp->domain_id), ntohs (mp->src_port));
20598   vam->retval = 0;
20599   vam->result_ready = 1;
20600 }
20601
20602 static void
20603   vl_api_ipfix_classify_stream_details_t_handler_json
20604   (vl_api_ipfix_classify_stream_details_t * mp)
20605 {
20606   vat_main_t *vam = &vat_main;
20607   vat_json_node_t node;
20608
20609   vat_json_init_object (&node);
20610   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20611   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20612
20613   vat_json_print (vam->ofp, &node);
20614   vat_json_free (&node);
20615   vam->retval = 0;
20616   vam->result_ready = 1;
20617 }
20618
20619 static int
20620 api_ipfix_classify_table_dump (vat_main_t * vam)
20621 {
20622   vl_api_ipfix_classify_table_dump_t *mp;
20623   vl_api_control_ping_t *mp_ping;
20624   int ret;
20625
20626   if (!vam->json_output)
20627     {
20628       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20629              "transport_protocol");
20630     }
20631
20632   /* Construct the API message */
20633   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20634
20635   /* send it... */
20636   S (mp);
20637
20638   /* Use a control ping for synchronization */
20639   MPING (CONTROL_PING, mp_ping);
20640   S (mp_ping);
20641
20642   W (ret);
20643   return ret;
20644 }
20645
20646 static void
20647   vl_api_ipfix_classify_table_details_t_handler
20648   (vl_api_ipfix_classify_table_details_t * mp)
20649 {
20650   vat_main_t *vam = &vat_main;
20651   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20652          mp->transport_protocol);
20653 }
20654
20655 static void
20656   vl_api_ipfix_classify_table_details_t_handler_json
20657   (vl_api_ipfix_classify_table_details_t * mp)
20658 {
20659   vat_json_node_t *node = NULL;
20660   vat_main_t *vam = &vat_main;
20661
20662   if (VAT_JSON_ARRAY != vam->json_tree.type)
20663     {
20664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20665       vat_json_init_array (&vam->json_tree);
20666     }
20667
20668   node = vat_json_array_add (&vam->json_tree);
20669   vat_json_init_object (node);
20670
20671   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20672   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20673   vat_json_object_add_uint (node, "transport_protocol",
20674                             mp->transport_protocol);
20675 }
20676
20677 static int
20678 api_sw_interface_span_enable_disable (vat_main_t * vam)
20679 {
20680   unformat_input_t *i = vam->input;
20681   vl_api_sw_interface_span_enable_disable_t *mp;
20682   u32 src_sw_if_index = ~0;
20683   u32 dst_sw_if_index = ~0;
20684   u8 state = 3;
20685   int ret;
20686   u8 is_l2 = 0;
20687
20688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20689     {
20690       if (unformat
20691           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20692         ;
20693       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20694         ;
20695       else
20696         if (unformat
20697             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20698         ;
20699       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20700         ;
20701       else if (unformat (i, "disable"))
20702         state = 0;
20703       else if (unformat (i, "rx"))
20704         state = 1;
20705       else if (unformat (i, "tx"))
20706         state = 2;
20707       else if (unformat (i, "both"))
20708         state = 3;
20709       else if (unformat (i, "l2"))
20710         is_l2 = 1;
20711       else
20712         break;
20713     }
20714
20715   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20716
20717   mp->sw_if_index_from = htonl (src_sw_if_index);
20718   mp->sw_if_index_to = htonl (dst_sw_if_index);
20719   mp->state = state;
20720   mp->is_l2 = is_l2;
20721
20722   S (mp);
20723   W (ret);
20724   return ret;
20725 }
20726
20727 static void
20728 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20729                                             * mp)
20730 {
20731   vat_main_t *vam = &vat_main;
20732   u8 *sw_if_from_name = 0;
20733   u8 *sw_if_to_name = 0;
20734   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20735   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20736   char *states[] = { "none", "rx", "tx", "both" };
20737   hash_pair_t *p;
20738
20739   /* *INDENT-OFF* */
20740   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20741   ({
20742     if ((u32) p->value[0] == sw_if_index_from)
20743       {
20744         sw_if_from_name = (u8 *)(p->key);
20745         if (sw_if_to_name)
20746           break;
20747       }
20748     if ((u32) p->value[0] == sw_if_index_to)
20749       {
20750         sw_if_to_name = (u8 *)(p->key);
20751         if (sw_if_from_name)
20752           break;
20753       }
20754   }));
20755   /* *INDENT-ON* */
20756   print (vam->ofp, "%20s => %20s (%s) %s",
20757          sw_if_from_name, sw_if_to_name, states[mp->state],
20758          mp->is_l2 ? "l2" : "device");
20759 }
20760
20761 static void
20762   vl_api_sw_interface_span_details_t_handler_json
20763   (vl_api_sw_interface_span_details_t * mp)
20764 {
20765   vat_main_t *vam = &vat_main;
20766   vat_json_node_t *node = NULL;
20767   u8 *sw_if_from_name = 0;
20768   u8 *sw_if_to_name = 0;
20769   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20770   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20771   hash_pair_t *p;
20772
20773   /* *INDENT-OFF* */
20774   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20775   ({
20776     if ((u32) p->value[0] == sw_if_index_from)
20777       {
20778         sw_if_from_name = (u8 *)(p->key);
20779         if (sw_if_to_name)
20780           break;
20781       }
20782     if ((u32) p->value[0] == sw_if_index_to)
20783       {
20784         sw_if_to_name = (u8 *)(p->key);
20785         if (sw_if_from_name)
20786           break;
20787       }
20788   }));
20789   /* *INDENT-ON* */
20790
20791   if (VAT_JSON_ARRAY != vam->json_tree.type)
20792     {
20793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20794       vat_json_init_array (&vam->json_tree);
20795     }
20796   node = vat_json_array_add (&vam->json_tree);
20797
20798   vat_json_init_object (node);
20799   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20800   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20801   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20802   if (0 != sw_if_to_name)
20803     {
20804       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20805     }
20806   vat_json_object_add_uint (node, "state", mp->state);
20807   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
20808 }
20809
20810 static int
20811 api_sw_interface_span_dump (vat_main_t * vam)
20812 {
20813   unformat_input_t *input = vam->input;
20814   vl_api_sw_interface_span_dump_t *mp;
20815   vl_api_control_ping_t *mp_ping;
20816   u8 is_l2 = 0;
20817   int ret;
20818
20819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20820     {
20821       if (unformat (input, "l2"))
20822         is_l2 = 1;
20823       else
20824         break;
20825     }
20826
20827   M (SW_INTERFACE_SPAN_DUMP, mp);
20828   mp->is_l2 = is_l2;
20829   S (mp);
20830
20831   /* Use a control ping for synchronization */
20832   MPING (CONTROL_PING, mp_ping);
20833   S (mp_ping);
20834
20835   W (ret);
20836   return ret;
20837 }
20838
20839 int
20840 api_pg_create_interface (vat_main_t * vam)
20841 {
20842   unformat_input_t *input = vam->input;
20843   vl_api_pg_create_interface_t *mp;
20844
20845   u32 if_id = ~0;
20846   int ret;
20847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20848     {
20849       if (unformat (input, "if_id %d", &if_id))
20850         ;
20851       else
20852         break;
20853     }
20854   if (if_id == ~0)
20855     {
20856       errmsg ("missing pg interface index");
20857       return -99;
20858     }
20859
20860   /* Construct the API message */
20861   M (PG_CREATE_INTERFACE, mp);
20862   mp->context = 0;
20863   mp->interface_id = ntohl (if_id);
20864
20865   S (mp);
20866   W (ret);
20867   return ret;
20868 }
20869
20870 int
20871 api_pg_capture (vat_main_t * vam)
20872 {
20873   unformat_input_t *input = vam->input;
20874   vl_api_pg_capture_t *mp;
20875
20876   u32 if_id = ~0;
20877   u8 enable = 1;
20878   u32 count = 1;
20879   u8 pcap_file_set = 0;
20880   u8 *pcap_file = 0;
20881   int ret;
20882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20883     {
20884       if (unformat (input, "if_id %d", &if_id))
20885         ;
20886       else if (unformat (input, "pcap %s", &pcap_file))
20887         pcap_file_set = 1;
20888       else if (unformat (input, "count %d", &count))
20889         ;
20890       else if (unformat (input, "disable"))
20891         enable = 0;
20892       else
20893         break;
20894     }
20895   if (if_id == ~0)
20896     {
20897       errmsg ("missing pg interface index");
20898       return -99;
20899     }
20900   if (pcap_file_set > 0)
20901     {
20902       if (vec_len (pcap_file) > 255)
20903         {
20904           errmsg ("pcap file name is too long");
20905           return -99;
20906         }
20907     }
20908
20909   u32 name_len = vec_len (pcap_file);
20910   /* Construct the API message */
20911   M (PG_CAPTURE, mp);
20912   mp->context = 0;
20913   mp->interface_id = ntohl (if_id);
20914   mp->is_enabled = enable;
20915   mp->count = ntohl (count);
20916   mp->pcap_name_length = ntohl (name_len);
20917   if (pcap_file_set != 0)
20918     {
20919       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20920     }
20921   vec_free (pcap_file);
20922
20923   S (mp);
20924   W (ret);
20925   return ret;
20926 }
20927
20928 int
20929 api_pg_enable_disable (vat_main_t * vam)
20930 {
20931   unformat_input_t *input = vam->input;
20932   vl_api_pg_enable_disable_t *mp;
20933
20934   u8 enable = 1;
20935   u8 stream_name_set = 0;
20936   u8 *stream_name = 0;
20937   int ret;
20938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20939     {
20940       if (unformat (input, "stream %s", &stream_name))
20941         stream_name_set = 1;
20942       else if (unformat (input, "disable"))
20943         enable = 0;
20944       else
20945         break;
20946     }
20947
20948   if (stream_name_set > 0)
20949     {
20950       if (vec_len (stream_name) > 255)
20951         {
20952           errmsg ("stream name too long");
20953           return -99;
20954         }
20955     }
20956
20957   u32 name_len = vec_len (stream_name);
20958   /* Construct the API message */
20959   M (PG_ENABLE_DISABLE, mp);
20960   mp->context = 0;
20961   mp->is_enabled = enable;
20962   if (stream_name_set != 0)
20963     {
20964       mp->stream_name_length = ntohl (name_len);
20965       clib_memcpy (mp->stream_name, stream_name, name_len);
20966     }
20967   vec_free (stream_name);
20968
20969   S (mp);
20970   W (ret);
20971   return ret;
20972 }
20973
20974 int
20975 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20976 {
20977   unformat_input_t *input = vam->input;
20978   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20979
20980   u16 *low_ports = 0;
20981   u16 *high_ports = 0;
20982   u16 this_low;
20983   u16 this_hi;
20984   ip4_address_t ip4_addr;
20985   ip6_address_t ip6_addr;
20986   u32 length;
20987   u32 tmp, tmp2;
20988   u8 prefix_set = 0;
20989   u32 vrf_id = ~0;
20990   u8 is_add = 1;
20991   u8 is_ipv6 = 0;
20992   int ret;
20993
20994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20995     {
20996       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20997         {
20998           prefix_set = 1;
20999         }
21000       else
21001         if (unformat
21002             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21003         {
21004           prefix_set = 1;
21005           is_ipv6 = 1;
21006         }
21007       else if (unformat (input, "vrf %d", &vrf_id))
21008         ;
21009       else if (unformat (input, "del"))
21010         is_add = 0;
21011       else if (unformat (input, "port %d", &tmp))
21012         {
21013           if (tmp == 0 || tmp > 65535)
21014             {
21015               errmsg ("port %d out of range", tmp);
21016               return -99;
21017             }
21018           this_low = tmp;
21019           this_hi = this_low + 1;
21020           vec_add1 (low_ports, this_low);
21021           vec_add1 (high_ports, this_hi);
21022         }
21023       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21024         {
21025           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21026             {
21027               errmsg ("incorrect range parameters");
21028               return -99;
21029             }
21030           this_low = tmp;
21031           /* Note: in debug CLI +1 is added to high before
21032              passing to real fn that does "the work"
21033              (ip_source_and_port_range_check_add_del).
21034              This fn is a wrapper around the binary API fn a
21035              control plane will call, which expects this increment
21036              to have occurred. Hence letting the binary API control
21037              plane fn do the increment for consistency between VAT
21038              and other control planes.
21039            */
21040           this_hi = tmp2;
21041           vec_add1 (low_ports, this_low);
21042           vec_add1 (high_ports, this_hi);
21043         }
21044       else
21045         break;
21046     }
21047
21048   if (prefix_set == 0)
21049     {
21050       errmsg ("<address>/<mask> not specified");
21051       return -99;
21052     }
21053
21054   if (vrf_id == ~0)
21055     {
21056       errmsg ("VRF ID required, not specified");
21057       return -99;
21058     }
21059
21060   if (vrf_id == 0)
21061     {
21062       errmsg
21063         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21064       return -99;
21065     }
21066
21067   if (vec_len (low_ports) == 0)
21068     {
21069       errmsg ("At least one port or port range required");
21070       return -99;
21071     }
21072
21073   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21074
21075   mp->is_add = is_add;
21076
21077   if (is_ipv6)
21078     {
21079       mp->is_ipv6 = 1;
21080       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21081     }
21082   else
21083     {
21084       mp->is_ipv6 = 0;
21085       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21086     }
21087
21088   mp->mask_length = length;
21089   mp->number_of_ranges = vec_len (low_ports);
21090
21091   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21092   vec_free (low_ports);
21093
21094   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21095   vec_free (high_ports);
21096
21097   mp->vrf_id = ntohl (vrf_id);
21098
21099   S (mp);
21100   W (ret);
21101   return ret;
21102 }
21103
21104 int
21105 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21106 {
21107   unformat_input_t *input = vam->input;
21108   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21109   u32 sw_if_index = ~0;
21110   int vrf_set = 0;
21111   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21112   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21113   u8 is_add = 1;
21114   int ret;
21115
21116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21117     {
21118       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21119         ;
21120       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21121         ;
21122       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21123         vrf_set = 1;
21124       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21125         vrf_set = 1;
21126       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21127         vrf_set = 1;
21128       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21129         vrf_set = 1;
21130       else if (unformat (input, "del"))
21131         is_add = 0;
21132       else
21133         break;
21134     }
21135
21136   if (sw_if_index == ~0)
21137     {
21138       errmsg ("Interface required but not specified");
21139       return -99;
21140     }
21141
21142   if (vrf_set == 0)
21143     {
21144       errmsg ("VRF ID required but not specified");
21145       return -99;
21146     }
21147
21148   if (tcp_out_vrf_id == 0
21149       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21150     {
21151       errmsg
21152         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21153       return -99;
21154     }
21155
21156   /* Construct the API message */
21157   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21158
21159   mp->sw_if_index = ntohl (sw_if_index);
21160   mp->is_add = is_add;
21161   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21162   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21163   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21164   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21165
21166   /* send it... */
21167   S (mp);
21168
21169   /* Wait for a reply... */
21170   W (ret);
21171   return ret;
21172 }
21173
21174 static int
21175 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21176 {
21177   unformat_input_t *i = vam->input;
21178   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21179   u32 local_sa_id = 0;
21180   u32 remote_sa_id = 0;
21181   ip4_address_t src_address;
21182   ip4_address_t dst_address;
21183   u8 is_add = 1;
21184   int ret;
21185
21186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21187     {
21188       if (unformat (i, "local_sa %d", &local_sa_id))
21189         ;
21190       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21191         ;
21192       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21193         ;
21194       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21195         ;
21196       else if (unformat (i, "del"))
21197         is_add = 0;
21198       else
21199         {
21200           clib_warning ("parse error '%U'", format_unformat_error, i);
21201           return -99;
21202         }
21203     }
21204
21205   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21206
21207   mp->local_sa_id = ntohl (local_sa_id);
21208   mp->remote_sa_id = ntohl (remote_sa_id);
21209   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21210   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21211   mp->is_add = is_add;
21212
21213   S (mp);
21214   W (ret);
21215   return ret;
21216 }
21217
21218 static int
21219 api_set_punt (vat_main_t * vam)
21220 {
21221   unformat_input_t *i = vam->input;
21222   vl_api_set_punt_t *mp;
21223   u32 ipv = ~0;
21224   u32 protocol = ~0;
21225   u32 port = ~0;
21226   int is_add = 1;
21227   int ret;
21228
21229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21230     {
21231       if (unformat (i, "ip %d", &ipv))
21232         ;
21233       else if (unformat (i, "protocol %d", &protocol))
21234         ;
21235       else if (unformat (i, "port %d", &port))
21236         ;
21237       else if (unformat (i, "del"))
21238         is_add = 0;
21239       else
21240         {
21241           clib_warning ("parse error '%U'", format_unformat_error, i);
21242           return -99;
21243         }
21244     }
21245
21246   M (SET_PUNT, mp);
21247
21248   mp->is_add = (u8) is_add;
21249   mp->punt.ipv = (u8) ipv;
21250   mp->punt.l4_protocol = (u8) protocol;
21251   mp->punt.l4_port = htons ((u16) port);
21252
21253   S (mp);
21254   W (ret);
21255   return ret;
21256 }
21257
21258 static void vl_api_ipsec_gre_tunnel_details_t_handler
21259   (vl_api_ipsec_gre_tunnel_details_t * mp)
21260 {
21261   vat_main_t *vam = &vat_main;
21262
21263   print (vam->ofp, "%11d%15U%15U%14d%14d",
21264          ntohl (mp->sw_if_index),
21265          format_ip4_address, &mp->src_address,
21266          format_ip4_address, &mp->dst_address,
21267          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21268 }
21269
21270 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21271   (vl_api_ipsec_gre_tunnel_details_t * mp)
21272 {
21273   vat_main_t *vam = &vat_main;
21274   vat_json_node_t *node = NULL;
21275   struct in_addr ip4;
21276
21277   if (VAT_JSON_ARRAY != vam->json_tree.type)
21278     {
21279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21280       vat_json_init_array (&vam->json_tree);
21281     }
21282   node = vat_json_array_add (&vam->json_tree);
21283
21284   vat_json_init_object (node);
21285   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21286   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21287   vat_json_object_add_ip4 (node, "src_address", ip4);
21288   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21289   vat_json_object_add_ip4 (node, "dst_address", ip4);
21290   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21291   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21292 }
21293
21294 static int
21295 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21296 {
21297   unformat_input_t *i = vam->input;
21298   vl_api_ipsec_gre_tunnel_dump_t *mp;
21299   vl_api_control_ping_t *mp_ping;
21300   u32 sw_if_index;
21301   u8 sw_if_index_set = 0;
21302   int ret;
21303
21304   /* Parse args required to build the message */
21305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21306     {
21307       if (unformat (i, "sw_if_index %d", &sw_if_index))
21308         sw_if_index_set = 1;
21309       else
21310         break;
21311     }
21312
21313   if (sw_if_index_set == 0)
21314     {
21315       sw_if_index = ~0;
21316     }
21317
21318   if (!vam->json_output)
21319     {
21320       print (vam->ofp, "%11s%15s%15s%14s%14s",
21321              "sw_if_index", "src_address", "dst_address",
21322              "local_sa_id", "remote_sa_id");
21323     }
21324
21325   /* Get list of gre-tunnel interfaces */
21326   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21327
21328   mp->sw_if_index = htonl (sw_if_index);
21329
21330   S (mp);
21331
21332   /* Use a control ping for synchronization */
21333   MPING (CONTROL_PING, mp_ping);
21334   S (mp_ping);
21335
21336   W (ret);
21337   return ret;
21338 }
21339
21340 static int
21341 api_delete_subif (vat_main_t * vam)
21342 {
21343   unformat_input_t *i = vam->input;
21344   vl_api_delete_subif_t *mp;
21345   u32 sw_if_index = ~0;
21346   int ret;
21347
21348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21349     {
21350       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21351         ;
21352       if (unformat (i, "sw_if_index %d", &sw_if_index))
21353         ;
21354       else
21355         break;
21356     }
21357
21358   if (sw_if_index == ~0)
21359     {
21360       errmsg ("missing sw_if_index");
21361       return -99;
21362     }
21363
21364   /* Construct the API message */
21365   M (DELETE_SUBIF, mp);
21366   mp->sw_if_index = ntohl (sw_if_index);
21367
21368   S (mp);
21369   W (ret);
21370   return ret;
21371 }
21372
21373 #define foreach_pbb_vtr_op      \
21374 _("disable",  L2_VTR_DISABLED)  \
21375 _("pop",  L2_VTR_POP_2)         \
21376 _("push",  L2_VTR_PUSH_2)
21377
21378 static int
21379 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21380 {
21381   unformat_input_t *i = vam->input;
21382   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21383   u32 sw_if_index = ~0, vtr_op = ~0;
21384   u16 outer_tag = ~0;
21385   u8 dmac[6], smac[6];
21386   u8 dmac_set = 0, smac_set = 0;
21387   u16 vlanid = 0;
21388   u32 sid = ~0;
21389   u32 tmp;
21390   int ret;
21391
21392   /* Shut up coverity */
21393   clib_memset (dmac, 0, sizeof (dmac));
21394   clib_memset (smac, 0, sizeof (smac));
21395
21396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21397     {
21398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21399         ;
21400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21401         ;
21402       else if (unformat (i, "vtr_op %d", &vtr_op))
21403         ;
21404 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21405       foreach_pbb_vtr_op
21406 #undef _
21407         else if (unformat (i, "translate_pbb_stag"))
21408         {
21409           if (unformat (i, "%d", &tmp))
21410             {
21411               vtr_op = L2_VTR_TRANSLATE_2_1;
21412               outer_tag = tmp;
21413             }
21414           else
21415             {
21416               errmsg
21417                 ("translate_pbb_stag operation requires outer tag definition");
21418               return -99;
21419             }
21420         }
21421       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21422         dmac_set++;
21423       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21424         smac_set++;
21425       else if (unformat (i, "sid %d", &sid))
21426         ;
21427       else if (unformat (i, "vlanid %d", &tmp))
21428         vlanid = tmp;
21429       else
21430         {
21431           clib_warning ("parse error '%U'", format_unformat_error, i);
21432           return -99;
21433         }
21434     }
21435
21436   if ((sw_if_index == ~0) || (vtr_op == ~0))
21437     {
21438       errmsg ("missing sw_if_index or vtr operation");
21439       return -99;
21440     }
21441   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21442       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21443     {
21444       errmsg
21445         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21446       return -99;
21447     }
21448
21449   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21450   mp->sw_if_index = ntohl (sw_if_index);
21451   mp->vtr_op = ntohl (vtr_op);
21452   mp->outer_tag = ntohs (outer_tag);
21453   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21454   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21455   mp->b_vlanid = ntohs (vlanid);
21456   mp->i_sid = ntohl (sid);
21457
21458   S (mp);
21459   W (ret);
21460   return ret;
21461 }
21462
21463 static int
21464 api_flow_classify_set_interface (vat_main_t * vam)
21465 {
21466   unformat_input_t *i = vam->input;
21467   vl_api_flow_classify_set_interface_t *mp;
21468   u32 sw_if_index;
21469   int sw_if_index_set;
21470   u32 ip4_table_index = ~0;
21471   u32 ip6_table_index = ~0;
21472   u8 is_add = 1;
21473   int ret;
21474
21475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21476     {
21477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21478         sw_if_index_set = 1;
21479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21480         sw_if_index_set = 1;
21481       else if (unformat (i, "del"))
21482         is_add = 0;
21483       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21484         ;
21485       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21486         ;
21487       else
21488         {
21489           clib_warning ("parse error '%U'", format_unformat_error, i);
21490           return -99;
21491         }
21492     }
21493
21494   if (sw_if_index_set == 0)
21495     {
21496       errmsg ("missing interface name or sw_if_index");
21497       return -99;
21498     }
21499
21500   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21501
21502   mp->sw_if_index = ntohl (sw_if_index);
21503   mp->ip4_table_index = ntohl (ip4_table_index);
21504   mp->ip6_table_index = ntohl (ip6_table_index);
21505   mp->is_add = is_add;
21506
21507   S (mp);
21508   W (ret);
21509   return ret;
21510 }
21511
21512 static int
21513 api_flow_classify_dump (vat_main_t * vam)
21514 {
21515   unformat_input_t *i = vam->input;
21516   vl_api_flow_classify_dump_t *mp;
21517   vl_api_control_ping_t *mp_ping;
21518   u8 type = FLOW_CLASSIFY_N_TABLES;
21519   int ret;
21520
21521   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21522     ;
21523   else
21524     {
21525       errmsg ("classify table type must be specified");
21526       return -99;
21527     }
21528
21529   if (!vam->json_output)
21530     {
21531       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21532     }
21533
21534   M (FLOW_CLASSIFY_DUMP, mp);
21535   mp->type = type;
21536   /* send it... */
21537   S (mp);
21538
21539   /* Use a control ping for synchronization */
21540   MPING (CONTROL_PING, mp_ping);
21541   S (mp_ping);
21542
21543   /* Wait for a reply... */
21544   W (ret);
21545   return ret;
21546 }
21547
21548 static int
21549 api_feature_enable_disable (vat_main_t * vam)
21550 {
21551   unformat_input_t *i = vam->input;
21552   vl_api_feature_enable_disable_t *mp;
21553   u8 *arc_name = 0;
21554   u8 *feature_name = 0;
21555   u32 sw_if_index = ~0;
21556   u8 enable = 1;
21557   int ret;
21558
21559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21560     {
21561       if (unformat (i, "arc_name %s", &arc_name))
21562         ;
21563       else if (unformat (i, "feature_name %s", &feature_name))
21564         ;
21565       else
21566         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21567         ;
21568       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21569         ;
21570       else if (unformat (i, "disable"))
21571         enable = 0;
21572       else
21573         break;
21574     }
21575
21576   if (arc_name == 0)
21577     {
21578       errmsg ("missing arc name");
21579       return -99;
21580     }
21581   if (vec_len (arc_name) > 63)
21582     {
21583       errmsg ("arc name too long");
21584     }
21585
21586   if (feature_name == 0)
21587     {
21588       errmsg ("missing feature name");
21589       return -99;
21590     }
21591   if (vec_len (feature_name) > 63)
21592     {
21593       errmsg ("feature name too long");
21594     }
21595
21596   if (sw_if_index == ~0)
21597     {
21598       errmsg ("missing interface name or sw_if_index");
21599       return -99;
21600     }
21601
21602   /* Construct the API message */
21603   M (FEATURE_ENABLE_DISABLE, mp);
21604   mp->sw_if_index = ntohl (sw_if_index);
21605   mp->enable = enable;
21606   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21607   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21608   vec_free (arc_name);
21609   vec_free (feature_name);
21610
21611   S (mp);
21612   W (ret);
21613   return ret;
21614 }
21615
21616 static int
21617 api_sw_interface_tag_add_del (vat_main_t * vam)
21618 {
21619   unformat_input_t *i = vam->input;
21620   vl_api_sw_interface_tag_add_del_t *mp;
21621   u32 sw_if_index = ~0;
21622   u8 *tag = 0;
21623   u8 enable = 1;
21624   int ret;
21625
21626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21627     {
21628       if (unformat (i, "tag %s", &tag))
21629         ;
21630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21631         ;
21632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21633         ;
21634       else if (unformat (i, "del"))
21635         enable = 0;
21636       else
21637         break;
21638     }
21639
21640   if (sw_if_index == ~0)
21641     {
21642       errmsg ("missing interface name or sw_if_index");
21643       return -99;
21644     }
21645
21646   if (enable && (tag == 0))
21647     {
21648       errmsg ("no tag specified");
21649       return -99;
21650     }
21651
21652   /* Construct the API message */
21653   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21654   mp->sw_if_index = ntohl (sw_if_index);
21655   mp->is_add = enable;
21656   if (enable)
21657     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21658   vec_free (tag);
21659
21660   S (mp);
21661   W (ret);
21662   return ret;
21663 }
21664
21665 static void vl_api_l2_xconnect_details_t_handler
21666   (vl_api_l2_xconnect_details_t * mp)
21667 {
21668   vat_main_t *vam = &vat_main;
21669
21670   print (vam->ofp, "%15d%15d",
21671          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21672 }
21673
21674 static void vl_api_l2_xconnect_details_t_handler_json
21675   (vl_api_l2_xconnect_details_t * mp)
21676 {
21677   vat_main_t *vam = &vat_main;
21678   vat_json_node_t *node = NULL;
21679
21680   if (VAT_JSON_ARRAY != vam->json_tree.type)
21681     {
21682       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21683       vat_json_init_array (&vam->json_tree);
21684     }
21685   node = vat_json_array_add (&vam->json_tree);
21686
21687   vat_json_init_object (node);
21688   vat_json_object_add_uint (node, "rx_sw_if_index",
21689                             ntohl (mp->rx_sw_if_index));
21690   vat_json_object_add_uint (node, "tx_sw_if_index",
21691                             ntohl (mp->tx_sw_if_index));
21692 }
21693
21694 static int
21695 api_l2_xconnect_dump (vat_main_t * vam)
21696 {
21697   vl_api_l2_xconnect_dump_t *mp;
21698   vl_api_control_ping_t *mp_ping;
21699   int ret;
21700
21701   if (!vam->json_output)
21702     {
21703       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21704     }
21705
21706   M (L2_XCONNECT_DUMP, mp);
21707
21708   S (mp);
21709
21710   /* Use a control ping for synchronization */
21711   MPING (CONTROL_PING, mp_ping);
21712   S (mp_ping);
21713
21714   W (ret);
21715   return ret;
21716 }
21717
21718 static int
21719 api_hw_interface_set_mtu (vat_main_t * vam)
21720 {
21721   unformat_input_t *i = vam->input;
21722   vl_api_hw_interface_set_mtu_t *mp;
21723   u32 sw_if_index = ~0;
21724   u32 mtu = 0;
21725   int ret;
21726
21727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21728     {
21729       if (unformat (i, "mtu %d", &mtu))
21730         ;
21731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21732         ;
21733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21734         ;
21735       else
21736         break;
21737     }
21738
21739   if (sw_if_index == ~0)
21740     {
21741       errmsg ("missing interface name or sw_if_index");
21742       return -99;
21743     }
21744
21745   if (mtu == 0)
21746     {
21747       errmsg ("no mtu specified");
21748       return -99;
21749     }
21750
21751   /* Construct the API message */
21752   M (HW_INTERFACE_SET_MTU, mp);
21753   mp->sw_if_index = ntohl (sw_if_index);
21754   mp->mtu = ntohs ((u16) mtu);
21755
21756   S (mp);
21757   W (ret);
21758   return ret;
21759 }
21760
21761 static int
21762 api_p2p_ethernet_add (vat_main_t * vam)
21763 {
21764   unformat_input_t *i = vam->input;
21765   vl_api_p2p_ethernet_add_t *mp;
21766   u32 parent_if_index = ~0;
21767   u32 sub_id = ~0;
21768   u8 remote_mac[6];
21769   u8 mac_set = 0;
21770   int ret;
21771
21772   clib_memset (remote_mac, 0, sizeof (remote_mac));
21773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21774     {
21775       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21776         ;
21777       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21778         ;
21779       else
21780         if (unformat
21781             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21782         mac_set++;
21783       else if (unformat (i, "sub_id %d", &sub_id))
21784         ;
21785       else
21786         {
21787           clib_warning ("parse error '%U'", format_unformat_error, i);
21788           return -99;
21789         }
21790     }
21791
21792   if (parent_if_index == ~0)
21793     {
21794       errmsg ("missing interface name or sw_if_index");
21795       return -99;
21796     }
21797   if (mac_set == 0)
21798     {
21799       errmsg ("missing remote mac address");
21800       return -99;
21801     }
21802   if (sub_id == ~0)
21803     {
21804       errmsg ("missing sub-interface id");
21805       return -99;
21806     }
21807
21808   M (P2P_ETHERNET_ADD, mp);
21809   mp->parent_if_index = ntohl (parent_if_index);
21810   mp->subif_id = ntohl (sub_id);
21811   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21812
21813   S (mp);
21814   W (ret);
21815   return ret;
21816 }
21817
21818 static int
21819 api_p2p_ethernet_del (vat_main_t * vam)
21820 {
21821   unformat_input_t *i = vam->input;
21822   vl_api_p2p_ethernet_del_t *mp;
21823   u32 parent_if_index = ~0;
21824   u8 remote_mac[6];
21825   u8 mac_set = 0;
21826   int ret;
21827
21828   clib_memset (remote_mac, 0, sizeof (remote_mac));
21829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21830     {
21831       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21832         ;
21833       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21834         ;
21835       else
21836         if (unformat
21837             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21838         mac_set++;
21839       else
21840         {
21841           clib_warning ("parse error '%U'", format_unformat_error, i);
21842           return -99;
21843         }
21844     }
21845
21846   if (parent_if_index == ~0)
21847     {
21848       errmsg ("missing interface name or sw_if_index");
21849       return -99;
21850     }
21851   if (mac_set == 0)
21852     {
21853       errmsg ("missing remote mac address");
21854       return -99;
21855     }
21856
21857   M (P2P_ETHERNET_DEL, mp);
21858   mp->parent_if_index = ntohl (parent_if_index);
21859   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21860
21861   S (mp);
21862   W (ret);
21863   return ret;
21864 }
21865
21866 static int
21867 api_lldp_config (vat_main_t * vam)
21868 {
21869   unformat_input_t *i = vam->input;
21870   vl_api_lldp_config_t *mp;
21871   int tx_hold = 0;
21872   int tx_interval = 0;
21873   u8 *sys_name = NULL;
21874   int ret;
21875
21876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21877     {
21878       if (unformat (i, "system-name %s", &sys_name))
21879         ;
21880       else if (unformat (i, "tx-hold %d", &tx_hold))
21881         ;
21882       else if (unformat (i, "tx-interval %d", &tx_interval))
21883         ;
21884       else
21885         {
21886           clib_warning ("parse error '%U'", format_unformat_error, i);
21887           return -99;
21888         }
21889     }
21890
21891   vec_add1 (sys_name, 0);
21892
21893   M (LLDP_CONFIG, mp);
21894   mp->tx_hold = htonl (tx_hold);
21895   mp->tx_interval = htonl (tx_interval);
21896   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21897   vec_free (sys_name);
21898
21899   S (mp);
21900   W (ret);
21901   return ret;
21902 }
21903
21904 static int
21905 api_sw_interface_set_lldp (vat_main_t * vam)
21906 {
21907   unformat_input_t *i = vam->input;
21908   vl_api_sw_interface_set_lldp_t *mp;
21909   u32 sw_if_index = ~0;
21910   u32 enable = 1;
21911   u8 *port_desc = NULL, *mgmt_oid = NULL;
21912   ip4_address_t ip4_addr;
21913   ip6_address_t ip6_addr;
21914   int ret;
21915
21916   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
21917   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
21918
21919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21920     {
21921       if (unformat (i, "disable"))
21922         enable = 0;
21923       else
21924         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21925         ;
21926       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21927         ;
21928       else if (unformat (i, "port-desc %s", &port_desc))
21929         ;
21930       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21931         ;
21932       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21933         ;
21934       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21935         ;
21936       else
21937         break;
21938     }
21939
21940   if (sw_if_index == ~0)
21941     {
21942       errmsg ("missing interface name or sw_if_index");
21943       return -99;
21944     }
21945
21946   /* Construct the API message */
21947   vec_add1 (port_desc, 0);
21948   vec_add1 (mgmt_oid, 0);
21949   M (SW_INTERFACE_SET_LLDP, mp);
21950   mp->sw_if_index = ntohl (sw_if_index);
21951   mp->enable = enable;
21952   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21953   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21954   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21955   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21956   vec_free (port_desc);
21957   vec_free (mgmt_oid);
21958
21959   S (mp);
21960   W (ret);
21961   return ret;
21962 }
21963
21964 static int
21965 api_tcp_configure_src_addresses (vat_main_t * vam)
21966 {
21967   vl_api_tcp_configure_src_addresses_t *mp;
21968   unformat_input_t *i = vam->input;
21969   ip4_address_t v4first, v4last;
21970   ip6_address_t v6first, v6last;
21971   u8 range_set = 0;
21972   u32 vrf_id = 0;
21973   int ret;
21974
21975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21976     {
21977       if (unformat (i, "%U - %U",
21978                     unformat_ip4_address, &v4first,
21979                     unformat_ip4_address, &v4last))
21980         {
21981           if (range_set)
21982             {
21983               errmsg ("one range per message (range already set)");
21984               return -99;
21985             }
21986           range_set = 1;
21987         }
21988       else if (unformat (i, "%U - %U",
21989                          unformat_ip6_address, &v6first,
21990                          unformat_ip6_address, &v6last))
21991         {
21992           if (range_set)
21993             {
21994               errmsg ("one range per message (range already set)");
21995               return -99;
21996             }
21997           range_set = 2;
21998         }
21999       else if (unformat (i, "vrf %d", &vrf_id))
22000         ;
22001       else
22002         break;
22003     }
22004
22005   if (range_set == 0)
22006     {
22007       errmsg ("address range not set");
22008       return -99;
22009     }
22010
22011   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22012   mp->vrf_id = ntohl (vrf_id);
22013   /* ipv6? */
22014   if (range_set == 2)
22015     {
22016       mp->is_ipv6 = 1;
22017       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22018       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22019     }
22020   else
22021     {
22022       mp->is_ipv6 = 0;
22023       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22024       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22025     }
22026   S (mp);
22027   W (ret);
22028   return ret;
22029 }
22030
22031 static void vl_api_app_namespace_add_del_reply_t_handler
22032   (vl_api_app_namespace_add_del_reply_t * mp)
22033 {
22034   vat_main_t *vam = &vat_main;
22035   i32 retval = ntohl (mp->retval);
22036   if (vam->async_mode)
22037     {
22038       vam->async_errors += (retval < 0);
22039     }
22040   else
22041     {
22042       vam->retval = retval;
22043       if (retval == 0)
22044         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22045       vam->result_ready = 1;
22046     }
22047 }
22048
22049 static void vl_api_app_namespace_add_del_reply_t_handler_json
22050   (vl_api_app_namespace_add_del_reply_t * mp)
22051 {
22052   vat_main_t *vam = &vat_main;
22053   vat_json_node_t node;
22054
22055   vat_json_init_object (&node);
22056   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22057   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22058
22059   vat_json_print (vam->ofp, &node);
22060   vat_json_free (&node);
22061
22062   vam->retval = ntohl (mp->retval);
22063   vam->result_ready = 1;
22064 }
22065
22066 static int
22067 api_app_namespace_add_del (vat_main_t * vam)
22068 {
22069   vl_api_app_namespace_add_del_t *mp;
22070   unformat_input_t *i = vam->input;
22071   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22072   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22073   u64 secret;
22074   int ret;
22075
22076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22077     {
22078       if (unformat (i, "id %_%v%_", &ns_id))
22079         ;
22080       else if (unformat (i, "secret %lu", &secret))
22081         secret_set = 1;
22082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22083         sw_if_index_set = 1;
22084       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22085         ;
22086       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22087         ;
22088       else
22089         break;
22090     }
22091   if (!ns_id || !secret_set || !sw_if_index_set)
22092     {
22093       errmsg ("namespace id, secret and sw_if_index must be set");
22094       return -99;
22095     }
22096   if (vec_len (ns_id) > 64)
22097     {
22098       errmsg ("namespace id too long");
22099       return -99;
22100     }
22101   M (APP_NAMESPACE_ADD_DEL, mp);
22102
22103   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22104   mp->namespace_id_len = vec_len (ns_id);
22105   mp->secret = clib_host_to_net_u64 (secret);
22106   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22107   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22108   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22109   vec_free (ns_id);
22110   S (mp);
22111   W (ret);
22112   return ret;
22113 }
22114
22115 static int
22116 api_sock_init_shm (vat_main_t * vam)
22117 {
22118 #if VPP_API_TEST_BUILTIN == 0
22119   unformat_input_t *i = vam->input;
22120   vl_api_shm_elem_config_t *config = 0;
22121   u64 size = 64 << 20;
22122   int rv;
22123
22124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22125     {
22126       if (unformat (i, "size %U", unformat_memory_size, &size))
22127         ;
22128       else
22129         break;
22130     }
22131
22132   /*
22133    * Canned custom ring allocator config.
22134    * Should probably parse all of this
22135    */
22136   vec_validate (config, 6);
22137   config[0].type = VL_API_VLIB_RING;
22138   config[0].size = 256;
22139   config[0].count = 32;
22140
22141   config[1].type = VL_API_VLIB_RING;
22142   config[1].size = 1024;
22143   config[1].count = 16;
22144
22145   config[2].type = VL_API_VLIB_RING;
22146   config[2].size = 4096;
22147   config[2].count = 2;
22148
22149   config[3].type = VL_API_CLIENT_RING;
22150   config[3].size = 256;
22151   config[3].count = 32;
22152
22153   config[4].type = VL_API_CLIENT_RING;
22154   config[4].size = 1024;
22155   config[4].count = 16;
22156
22157   config[5].type = VL_API_CLIENT_RING;
22158   config[5].size = 4096;
22159   config[5].count = 2;
22160
22161   config[6].type = VL_API_QUEUE;
22162   config[6].count = 128;
22163   config[6].size = sizeof (uword);
22164
22165   rv = vl_socket_client_init_shm (config);
22166   if (!rv)
22167     vam->client_index_invalid = 1;
22168   return rv;
22169 #else
22170   return -99;
22171 #endif
22172 }
22173
22174 static int
22175 api_dns_enable_disable (vat_main_t * vam)
22176 {
22177   unformat_input_t *line_input = vam->input;
22178   vl_api_dns_enable_disable_t *mp;
22179   u8 enable_disable = 1;
22180   int ret;
22181
22182   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22183     {
22184       if (unformat (line_input, "disable"))
22185         enable_disable = 0;
22186       if (unformat (line_input, "enable"))
22187         enable_disable = 1;
22188       else
22189         break;
22190     }
22191
22192   /* Construct the API message */
22193   M (DNS_ENABLE_DISABLE, mp);
22194   mp->enable = enable_disable;
22195
22196   /* send it... */
22197   S (mp);
22198   /* Wait for the reply */
22199   W (ret);
22200   return ret;
22201 }
22202
22203 static int
22204 api_dns_resolve_name (vat_main_t * vam)
22205 {
22206   unformat_input_t *line_input = vam->input;
22207   vl_api_dns_resolve_name_t *mp;
22208   u8 *name = 0;
22209   int ret;
22210
22211   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22212     {
22213       if (unformat (line_input, "%s", &name))
22214         ;
22215       else
22216         break;
22217     }
22218
22219   if (vec_len (name) > 127)
22220     {
22221       errmsg ("name too long");
22222       return -99;
22223     }
22224
22225   /* Construct the API message */
22226   M (DNS_RESOLVE_NAME, mp);
22227   memcpy (mp->name, name, vec_len (name));
22228   vec_free (name);
22229
22230   /* send it... */
22231   S (mp);
22232   /* Wait for the reply */
22233   W (ret);
22234   return ret;
22235 }
22236
22237 static int
22238 api_dns_resolve_ip (vat_main_t * vam)
22239 {
22240   unformat_input_t *line_input = vam->input;
22241   vl_api_dns_resolve_ip_t *mp;
22242   int is_ip6 = -1;
22243   ip4_address_t addr4;
22244   ip6_address_t addr6;
22245   int ret;
22246
22247   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22248     {
22249       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22250         is_ip6 = 1;
22251       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22252         is_ip6 = 0;
22253       else
22254         break;
22255     }
22256
22257   if (is_ip6 == -1)
22258     {
22259       errmsg ("missing address");
22260       return -99;
22261     }
22262
22263   /* Construct the API message */
22264   M (DNS_RESOLVE_IP, mp);
22265   mp->is_ip6 = is_ip6;
22266   if (is_ip6)
22267     memcpy (mp->address, &addr6, sizeof (addr6));
22268   else
22269     memcpy (mp->address, &addr4, sizeof (addr4));
22270
22271   /* send it... */
22272   S (mp);
22273   /* Wait for the reply */
22274   W (ret);
22275   return ret;
22276 }
22277
22278 static int
22279 api_dns_name_server_add_del (vat_main_t * vam)
22280 {
22281   unformat_input_t *i = vam->input;
22282   vl_api_dns_name_server_add_del_t *mp;
22283   u8 is_add = 1;
22284   ip6_address_t ip6_server;
22285   ip4_address_t ip4_server;
22286   int ip6_set = 0;
22287   int ip4_set = 0;
22288   int ret = 0;
22289
22290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22291     {
22292       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22293         ip6_set = 1;
22294       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22295         ip4_set = 1;
22296       else if (unformat (i, "del"))
22297         is_add = 0;
22298       else
22299         {
22300           clib_warning ("parse error '%U'", format_unformat_error, i);
22301           return -99;
22302         }
22303     }
22304
22305   if (ip4_set && ip6_set)
22306     {
22307       errmsg ("Only one server address allowed per message");
22308       return -99;
22309     }
22310   if ((ip4_set + ip6_set) == 0)
22311     {
22312       errmsg ("Server address required");
22313       return -99;
22314     }
22315
22316   /* Construct the API message */
22317   M (DNS_NAME_SERVER_ADD_DEL, mp);
22318
22319   if (ip6_set)
22320     {
22321       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22322       mp->is_ip6 = 1;
22323     }
22324   else
22325     {
22326       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22327       mp->is_ip6 = 0;
22328     }
22329
22330   mp->is_add = is_add;
22331
22332   /* send it... */
22333   S (mp);
22334
22335   /* Wait for a reply, return good/bad news  */
22336   W (ret);
22337   return ret;
22338 }
22339
22340 static void
22341 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22342 {
22343   vat_main_t *vam = &vat_main;
22344
22345   if (mp->is_ip4)
22346     {
22347       print (vam->ofp,
22348              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22349              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22350              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22351              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22352              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22353              clib_net_to_host_u32 (mp->action_index), mp->tag);
22354     }
22355   else
22356     {
22357       print (vam->ofp,
22358              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22359              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22360              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22361              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22362              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22363              clib_net_to_host_u32 (mp->action_index), mp->tag);
22364     }
22365 }
22366
22367 static void
22368 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22369                                              mp)
22370 {
22371   vat_main_t *vam = &vat_main;
22372   vat_json_node_t *node = NULL;
22373   struct in6_addr ip6;
22374   struct in_addr ip4;
22375
22376   if (VAT_JSON_ARRAY != vam->json_tree.type)
22377     {
22378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22379       vat_json_init_array (&vam->json_tree);
22380     }
22381   node = vat_json_array_add (&vam->json_tree);
22382   vat_json_init_object (node);
22383
22384   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22385   vat_json_object_add_uint (node, "appns_index",
22386                             clib_net_to_host_u32 (mp->appns_index));
22387   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22388   vat_json_object_add_uint (node, "scope", mp->scope);
22389   vat_json_object_add_uint (node, "action_index",
22390                             clib_net_to_host_u32 (mp->action_index));
22391   vat_json_object_add_uint (node, "lcl_port",
22392                             clib_net_to_host_u16 (mp->lcl_port));
22393   vat_json_object_add_uint (node, "rmt_port",
22394                             clib_net_to_host_u16 (mp->rmt_port));
22395   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22396   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22397   vat_json_object_add_string_copy (node, "tag", mp->tag);
22398   if (mp->is_ip4)
22399     {
22400       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22401       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22402       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22403       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22404     }
22405   else
22406     {
22407       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22408       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22409       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22410       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22411     }
22412 }
22413
22414 static int
22415 api_session_rule_add_del (vat_main_t * vam)
22416 {
22417   vl_api_session_rule_add_del_t *mp;
22418   unformat_input_t *i = vam->input;
22419   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22420   u32 appns_index = 0, scope = 0;
22421   ip4_address_t lcl_ip4, rmt_ip4;
22422   ip6_address_t lcl_ip6, rmt_ip6;
22423   u8 is_ip4 = 1, conn_set = 0;
22424   u8 is_add = 1, *tag = 0;
22425   int ret;
22426
22427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22428     {
22429       if (unformat (i, "del"))
22430         is_add = 0;
22431       else if (unformat (i, "add"))
22432         ;
22433       else if (unformat (i, "proto tcp"))
22434         proto = 0;
22435       else if (unformat (i, "proto udp"))
22436         proto = 1;
22437       else if (unformat (i, "appns %d", &appns_index))
22438         ;
22439       else if (unformat (i, "scope %d", &scope))
22440         ;
22441       else if (unformat (i, "tag %_%v%_", &tag))
22442         ;
22443       else
22444         if (unformat
22445             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22446              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22447              &rmt_port))
22448         {
22449           is_ip4 = 1;
22450           conn_set = 1;
22451         }
22452       else
22453         if (unformat
22454             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22455              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22456              &rmt_port))
22457         {
22458           is_ip4 = 0;
22459           conn_set = 1;
22460         }
22461       else if (unformat (i, "action %d", &action))
22462         ;
22463       else
22464         break;
22465     }
22466   if (proto == ~0 || !conn_set || action == ~0)
22467     {
22468       errmsg ("transport proto, connection and action must be set");
22469       return -99;
22470     }
22471
22472   if (scope > 3)
22473     {
22474       errmsg ("scope should be 0-3");
22475       return -99;
22476     }
22477
22478   M (SESSION_RULE_ADD_DEL, mp);
22479
22480   mp->is_ip4 = is_ip4;
22481   mp->transport_proto = proto;
22482   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22483   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22484   mp->lcl_plen = lcl_plen;
22485   mp->rmt_plen = rmt_plen;
22486   mp->action_index = clib_host_to_net_u32 (action);
22487   mp->appns_index = clib_host_to_net_u32 (appns_index);
22488   mp->scope = scope;
22489   mp->is_add = is_add;
22490   if (is_ip4)
22491     {
22492       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22493       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22494     }
22495   else
22496     {
22497       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22498       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22499     }
22500   if (tag)
22501     {
22502       clib_memcpy (mp->tag, tag, vec_len (tag));
22503       vec_free (tag);
22504     }
22505
22506   S (mp);
22507   W (ret);
22508   return ret;
22509 }
22510
22511 static int
22512 api_session_rules_dump (vat_main_t * vam)
22513 {
22514   vl_api_session_rules_dump_t *mp;
22515   vl_api_control_ping_t *mp_ping;
22516   int ret;
22517
22518   if (!vam->json_output)
22519     {
22520       print (vam->ofp, "%=20s", "Session Rules");
22521     }
22522
22523   M (SESSION_RULES_DUMP, mp);
22524   /* send it... */
22525   S (mp);
22526
22527   /* Use a control ping for synchronization */
22528   MPING (CONTROL_PING, mp_ping);
22529   S (mp_ping);
22530
22531   /* Wait for a reply... */
22532   W (ret);
22533   return ret;
22534 }
22535
22536 static int
22537 api_ip_container_proxy_add_del (vat_main_t * vam)
22538 {
22539   vl_api_ip_container_proxy_add_del_t *mp;
22540   unformat_input_t *i = vam->input;
22541   u32 plen = ~0, sw_if_index = ~0;
22542   ip4_address_t ip4;
22543   ip6_address_t ip6;
22544   u8 is_ip4 = 1;
22545   u8 is_add = 1;
22546   int ret;
22547
22548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22549     {
22550       if (unformat (i, "del"))
22551         is_add = 0;
22552       else if (unformat (i, "add"))
22553         ;
22554       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22555         {
22556           is_ip4 = 1;
22557           plen = 32;
22558         }
22559       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22560         {
22561           is_ip4 = 0;
22562           plen = 128;
22563         }
22564       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22565         ;
22566       else
22567         break;
22568     }
22569   if (sw_if_index == ~0 || plen == ~0)
22570     {
22571       errmsg ("address and sw_if_index must be set");
22572       return -99;
22573     }
22574
22575   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22576
22577   mp->is_ip4 = is_ip4;
22578   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22579   mp->plen = plen;
22580   mp->is_add = is_add;
22581   if (is_ip4)
22582     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22583   else
22584     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22585
22586   S (mp);
22587   W (ret);
22588   return ret;
22589 }
22590
22591 static int
22592 api_qos_record_enable_disable (vat_main_t * vam)
22593 {
22594   unformat_input_t *i = vam->input;
22595   vl_api_qos_record_enable_disable_t *mp;
22596   u32 sw_if_index, qs = 0xff;
22597   u8 sw_if_index_set = 0;
22598   u8 enable = 1;
22599   int ret;
22600
22601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22602     {
22603       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22604         sw_if_index_set = 1;
22605       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22606         sw_if_index_set = 1;
22607       else if (unformat (i, "%U", unformat_qos_source, &qs))
22608         ;
22609       else if (unformat (i, "disable"))
22610         enable = 0;
22611       else
22612         {
22613           clib_warning ("parse error '%U'", format_unformat_error, i);
22614           return -99;
22615         }
22616     }
22617
22618   if (sw_if_index_set == 0)
22619     {
22620       errmsg ("missing interface name or sw_if_index");
22621       return -99;
22622     }
22623   if (qs == 0xff)
22624     {
22625       errmsg ("input location must be specified");
22626       return -99;
22627     }
22628
22629   M (QOS_RECORD_ENABLE_DISABLE, mp);
22630
22631   mp->sw_if_index = ntohl (sw_if_index);
22632   mp->input_source = qs;
22633   mp->enable = enable;
22634
22635   S (mp);
22636   W (ret);
22637   return ret;
22638 }
22639
22640
22641 static int
22642 q_or_quit (vat_main_t * vam)
22643 {
22644 #if VPP_API_TEST_BUILTIN == 0
22645   longjmp (vam->jump_buf, 1);
22646 #endif
22647   return 0;                     /* not so much */
22648 }
22649
22650 static int
22651 q (vat_main_t * vam)
22652 {
22653   return q_or_quit (vam);
22654 }
22655
22656 static int
22657 quit (vat_main_t * vam)
22658 {
22659   return q_or_quit (vam);
22660 }
22661
22662 static int
22663 comment (vat_main_t * vam)
22664 {
22665   return 0;
22666 }
22667
22668 static int
22669 statseg (vat_main_t * vam)
22670 {
22671   ssvm_private_t *ssvmp = &vam->stat_segment;
22672   ssvm_shared_header_t *shared_header = ssvmp->sh;
22673   vlib_counter_t **counters;
22674   u64 thread0_index1_packets;
22675   u64 thread0_index1_bytes;
22676   f64 vector_rate, input_rate;
22677   uword *p;
22678
22679   uword *counter_vector_by_name;
22680   if (vam->stat_segment_lockp == 0)
22681     {
22682       errmsg ("Stat segment not mapped...");
22683       return -99;
22684     }
22685
22686   /* look up "/if/rx for sw_if_index 1 as a test */
22687
22688   clib_spinlock_lock (vam->stat_segment_lockp);
22689
22690   counter_vector_by_name = (uword *) shared_header->opaque[1];
22691
22692   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22693   if (p == 0)
22694     {
22695       clib_spinlock_unlock (vam->stat_segment_lockp);
22696       errmsg ("/if/tx not found?");
22697       return -99;
22698     }
22699
22700   /* Fish per-thread vector of combined counters from shared memory */
22701   counters = (vlib_counter_t **) p[0];
22702
22703   if (vec_len (counters[0]) < 2)
22704     {
22705       clib_spinlock_unlock (vam->stat_segment_lockp);
22706       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22707       return -99;
22708     }
22709
22710   /* Read thread 0 sw_if_index 1 counter */
22711   thread0_index1_packets = counters[0][1].packets;
22712   thread0_index1_bytes = counters[0][1].bytes;
22713
22714   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22715   if (p == 0)
22716     {
22717       clib_spinlock_unlock (vam->stat_segment_lockp);
22718       errmsg ("vector_rate not found?");
22719       return -99;
22720     }
22721
22722   vector_rate = *(f64 *) (p[0]);
22723   p = hash_get_mem (counter_vector_by_name, "input_rate");
22724   if (p == 0)
22725     {
22726       clib_spinlock_unlock (vam->stat_segment_lockp);
22727       errmsg ("input_rate not found?");
22728       return -99;
22729     }
22730   input_rate = *(f64 *) (p[0]);
22731
22732   clib_spinlock_unlock (vam->stat_segment_lockp);
22733
22734   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22735          vector_rate, input_rate);
22736   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22737          thread0_index1_packets, thread0_index1_bytes);
22738
22739   return 0;
22740 }
22741
22742 static int
22743 cmd_cmp (void *a1, void *a2)
22744 {
22745   u8 **c1 = a1;
22746   u8 **c2 = a2;
22747
22748   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22749 }
22750
22751 static int
22752 help (vat_main_t * vam)
22753 {
22754   u8 **cmds = 0;
22755   u8 *name = 0;
22756   hash_pair_t *p;
22757   unformat_input_t *i = vam->input;
22758   int j;
22759
22760   if (unformat (i, "%s", &name))
22761     {
22762       uword *hs;
22763
22764       vec_add1 (name, 0);
22765
22766       hs = hash_get_mem (vam->help_by_name, name);
22767       if (hs)
22768         print (vam->ofp, "usage: %s %s", name, hs[0]);
22769       else
22770         print (vam->ofp, "No such msg / command '%s'", name);
22771       vec_free (name);
22772       return 0;
22773     }
22774
22775   print (vam->ofp, "Help is available for the following:");
22776
22777     /* *INDENT-OFF* */
22778     hash_foreach_pair (p, vam->function_by_name,
22779     ({
22780       vec_add1 (cmds, (u8 *)(p->key));
22781     }));
22782     /* *INDENT-ON* */
22783
22784   vec_sort_with_function (cmds, cmd_cmp);
22785
22786   for (j = 0; j < vec_len (cmds); j++)
22787     print (vam->ofp, "%s", cmds[j]);
22788
22789   vec_free (cmds);
22790   return 0;
22791 }
22792
22793 static int
22794 set (vat_main_t * vam)
22795 {
22796   u8 *name = 0, *value = 0;
22797   unformat_input_t *i = vam->input;
22798
22799   if (unformat (i, "%s", &name))
22800     {
22801       /* The input buffer is a vector, not a string. */
22802       value = vec_dup (i->buffer);
22803       vec_delete (value, i->index, 0);
22804       /* Almost certainly has a trailing newline */
22805       if (value[vec_len (value) - 1] == '\n')
22806         value[vec_len (value) - 1] = 0;
22807       /* Make sure it's a proper string, one way or the other */
22808       vec_add1 (value, 0);
22809       (void) clib_macro_set_value (&vam->macro_main,
22810                                    (char *) name, (char *) value);
22811     }
22812   else
22813     errmsg ("usage: set <name> <value>");
22814
22815   vec_free (name);
22816   vec_free (value);
22817   return 0;
22818 }
22819
22820 static int
22821 unset (vat_main_t * vam)
22822 {
22823   u8 *name = 0;
22824
22825   if (unformat (vam->input, "%s", &name))
22826     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22827       errmsg ("unset: %s wasn't set", name);
22828   vec_free (name);
22829   return 0;
22830 }
22831
22832 typedef struct
22833 {
22834   u8 *name;
22835   u8 *value;
22836 } macro_sort_t;
22837
22838
22839 static int
22840 macro_sort_cmp (void *a1, void *a2)
22841 {
22842   macro_sort_t *s1 = a1;
22843   macro_sort_t *s2 = a2;
22844
22845   return strcmp ((char *) (s1->name), (char *) (s2->name));
22846 }
22847
22848 static int
22849 dump_macro_table (vat_main_t * vam)
22850 {
22851   macro_sort_t *sort_me = 0, *sm;
22852   int i;
22853   hash_pair_t *p;
22854
22855     /* *INDENT-OFF* */
22856     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22857     ({
22858       vec_add2 (sort_me, sm, 1);
22859       sm->name = (u8 *)(p->key);
22860       sm->value = (u8 *) (p->value[0]);
22861     }));
22862     /* *INDENT-ON* */
22863
22864   vec_sort_with_function (sort_me, macro_sort_cmp);
22865
22866   if (vec_len (sort_me))
22867     print (vam->ofp, "%-15s%s", "Name", "Value");
22868   else
22869     print (vam->ofp, "The macro table is empty...");
22870
22871   for (i = 0; i < vec_len (sort_me); i++)
22872     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22873   return 0;
22874 }
22875
22876 static int
22877 dump_node_table (vat_main_t * vam)
22878 {
22879   int i, j;
22880   vlib_node_t *node, *next_node;
22881
22882   if (vec_len (vam->graph_nodes) == 0)
22883     {
22884       print (vam->ofp, "Node table empty, issue get_node_graph...");
22885       return 0;
22886     }
22887
22888   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
22889     {
22890       node = vam->graph_nodes[0][i];
22891       print (vam->ofp, "[%d] %s", i, node->name);
22892       for (j = 0; j < vec_len (node->next_nodes); j++)
22893         {
22894           if (node->next_nodes[j] != ~0)
22895             {
22896               next_node = vam->graph_nodes[0][node->next_nodes[j]];
22897               print (vam->ofp, "  [%d] %s", j, next_node->name);
22898             }
22899         }
22900     }
22901   return 0;
22902 }
22903
22904 static int
22905 value_sort_cmp (void *a1, void *a2)
22906 {
22907   name_sort_t *n1 = a1;
22908   name_sort_t *n2 = a2;
22909
22910   if (n1->value < n2->value)
22911     return -1;
22912   if (n1->value > n2->value)
22913     return 1;
22914   return 0;
22915 }
22916
22917
22918 static int
22919 dump_msg_api_table (vat_main_t * vam)
22920 {
22921   api_main_t *am = &api_main;
22922   name_sort_t *nses = 0, *ns;
22923   hash_pair_t *hp;
22924   int i;
22925
22926   /* *INDENT-OFF* */
22927   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22928   ({
22929     vec_add2 (nses, ns, 1);
22930     ns->name = (u8 *)(hp->key);
22931     ns->value = (u32) hp->value[0];
22932   }));
22933   /* *INDENT-ON* */
22934
22935   vec_sort_with_function (nses, value_sort_cmp);
22936
22937   for (i = 0; i < vec_len (nses); i++)
22938     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22939   vec_free (nses);
22940   return 0;
22941 }
22942
22943 static int
22944 get_msg_id (vat_main_t * vam)
22945 {
22946   u8 *name_and_crc;
22947   u32 message_index;
22948
22949   if (unformat (vam->input, "%s", &name_and_crc))
22950     {
22951       message_index = vl_msg_api_get_msg_index (name_and_crc);
22952       if (message_index == ~0)
22953         {
22954           print (vam->ofp, " '%s' not found", name_and_crc);
22955           return 0;
22956         }
22957       print (vam->ofp, " '%s' has message index %d",
22958              name_and_crc, message_index);
22959       return 0;
22960     }
22961   errmsg ("name_and_crc required...");
22962   return 0;
22963 }
22964
22965 static int
22966 search_node_table (vat_main_t * vam)
22967 {
22968   unformat_input_t *line_input = vam->input;
22969   u8 *node_to_find;
22970   int j;
22971   vlib_node_t *node, *next_node;
22972   uword *p;
22973
22974   if (vam->graph_node_index_by_name == 0)
22975     {
22976       print (vam->ofp, "Node table empty, issue get_node_graph...");
22977       return 0;
22978     }
22979
22980   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22981     {
22982       if (unformat (line_input, "%s", &node_to_find))
22983         {
22984           vec_add1 (node_to_find, 0);
22985           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22986           if (p == 0)
22987             {
22988               print (vam->ofp, "%s not found...", node_to_find);
22989               goto out;
22990             }
22991           node = vam->graph_nodes[0][p[0]];
22992           print (vam->ofp, "[%d] %s", p[0], node->name);
22993           for (j = 0; j < vec_len (node->next_nodes); j++)
22994             {
22995               if (node->next_nodes[j] != ~0)
22996                 {
22997                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
22998                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22999                 }
23000             }
23001         }
23002
23003       else
23004         {
23005           clib_warning ("parse error '%U'", format_unformat_error,
23006                         line_input);
23007           return -99;
23008         }
23009
23010     out:
23011       vec_free (node_to_find);
23012
23013     }
23014
23015   return 0;
23016 }
23017
23018
23019 static int
23020 script (vat_main_t * vam)
23021 {
23022 #if (VPP_API_TEST_BUILTIN==0)
23023   u8 *s = 0;
23024   char *save_current_file;
23025   unformat_input_t save_input;
23026   jmp_buf save_jump_buf;
23027   u32 save_line_number;
23028
23029   FILE *new_fp, *save_ifp;
23030
23031   if (unformat (vam->input, "%s", &s))
23032     {
23033       new_fp = fopen ((char *) s, "r");
23034       if (new_fp == 0)
23035         {
23036           errmsg ("Couldn't open script file %s", s);
23037           vec_free (s);
23038           return -99;
23039         }
23040     }
23041   else
23042     {
23043       errmsg ("Missing script name");
23044       return -99;
23045     }
23046
23047   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23048   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23049   save_ifp = vam->ifp;
23050   save_line_number = vam->input_line_number;
23051   save_current_file = (char *) vam->current_file;
23052
23053   vam->input_line_number = 0;
23054   vam->ifp = new_fp;
23055   vam->current_file = s;
23056   do_one_file (vam);
23057
23058   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23059   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23060   vam->ifp = save_ifp;
23061   vam->input_line_number = save_line_number;
23062   vam->current_file = (u8 *) save_current_file;
23063   vec_free (s);
23064
23065   return 0;
23066 #else
23067   clib_warning ("use the exec command...");
23068   return -99;
23069 #endif
23070 }
23071
23072 static int
23073 echo (vat_main_t * vam)
23074 {
23075   print (vam->ofp, "%v", vam->input->buffer);
23076   return 0;
23077 }
23078
23079 /* List of API message constructors, CLI names map to api_xxx */
23080 #define foreach_vpe_api_msg                                             \
23081 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23082 _(sw_interface_dump,"")                                                 \
23083 _(sw_interface_set_flags,                                               \
23084   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23085 _(sw_interface_add_del_address,                                         \
23086   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23087 _(sw_interface_set_rx_mode,                                             \
23088   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23089 _(sw_interface_set_rx_placement,                                        \
23090   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23091 _(sw_interface_rx_placement_dump,                                       \
23092   "[<intfc> | sw_if_index <id>]")                                         \
23093 _(sw_interface_set_table,                                               \
23094   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23095 _(sw_interface_set_mpls_enable,                                         \
23096   "<intfc> | sw_if_index [disable | dis]")                              \
23097 _(sw_interface_set_vpath,                                               \
23098   "<intfc> | sw_if_index <id> enable | disable")                        \
23099 _(sw_interface_set_vxlan_bypass,                                        \
23100   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23101 _(sw_interface_set_geneve_bypass,                                       \
23102   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23103 _(sw_interface_set_l2_xconnect,                                         \
23104   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23105   "enable | disable")                                                   \
23106 _(sw_interface_set_l2_bridge,                                           \
23107   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23108   "[shg <split-horizon-group>] [bvi]\n"                                 \
23109   "enable | disable")                                                   \
23110 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23111 _(bridge_domain_add_del,                                                \
23112   "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") \
23113 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23114 _(l2fib_add_del,                                                        \
23115   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23116 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23117 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23118 _(l2_flags,                                                             \
23119   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23120 _(bridge_flags,                                                         \
23121   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23122 _(tap_connect,                                                          \
23123   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23124 _(tap_modify,                                                           \
23125   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23126 _(tap_delete,                                                           \
23127   "<vpp-if-name> | sw_if_index <id>")                                   \
23128 _(sw_interface_tap_dump, "")                                            \
23129 _(tap_create_v2,                                                        \
23130   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23131 _(tap_delete_v2,                                                        \
23132   "<vpp-if-name> | sw_if_index <id>")                                   \
23133 _(sw_interface_tap_v2_dump, "")                                         \
23134 _(bond_create,                                                          \
23135   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23136   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23137 _(bond_delete,                                                          \
23138   "<vpp-if-name> | sw_if_index <id>")                                   \
23139 _(bond_enslave,                                                         \
23140   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23141 _(bond_detach_slave,                                                    \
23142   "sw_if_index <n>")                                                    \
23143 _(sw_interface_bond_dump, "")                                           \
23144 _(sw_interface_slave_dump,                                              \
23145   "<vpp-if-name> | sw_if_index <id>")                                   \
23146 _(ip_table_add_del,                                                     \
23147   "table <n> [ipv6] [add | del]\n")                                     \
23148 _(ip_add_del_route,                                                     \
23149   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23150   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23151   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
23152   "[multipath] [count <n>] [del]")                                      \
23153 _(ip_mroute_add_del,                                                    \
23154   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23155   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23156 _(mpls_table_add_del,                                                   \
23157   "table <n> [add | del]\n")                                            \
23158 _(mpls_route_add_del,                                                   \
23159   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23160   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23161   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23162   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23163   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
23164   "[count <n>] [del]")                                                  \
23165 _(mpls_ip_bind_unbind,                                                  \
23166   "<label> <addr/len>")                                                 \
23167 _(mpls_tunnel_add_del,                                                  \
23168   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
23169   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
23170   "[l2-only]  [out-label <n>]")                                         \
23171 _(sr_mpls_policy_add,                                                   \
23172   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23173 _(sr_mpls_policy_del,                                                   \
23174   "bsid <id>")                                                          \
23175 _(bier_table_add_del,                                                   \
23176   "<label> <sub-domain> <set> <bsl> [del]")                             \
23177 _(bier_route_add_del,                                                   \
23178   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23179   "[<intfc> | sw_if_index <id>]"                                        \
23180   "[weight <n>] [del] [multipath]")                                     \
23181 _(proxy_arp_add_del,                                                    \
23182   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23183 _(proxy_arp_intfc_enable_disable,                                       \
23184   "<intfc> | sw_if_index <id> enable | disable")                        \
23185 _(sw_interface_set_unnumbered,                                          \
23186   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23187 _(ip_neighbor_add_del,                                                  \
23188   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23189   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23190 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23191 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23192   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23193   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23194   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23195 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23196 _(reset_fib, "vrf <n> [ipv6]")                                          \
23197 _(dhcp_proxy_config,                                                    \
23198   "svr <v46-address> src <v46-address>\n"                               \
23199    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23200 _(dhcp_proxy_set_vss,                                                   \
23201   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23202 _(dhcp_proxy_dump, "ip6")                                               \
23203 _(dhcp_client_config,                                                   \
23204   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23205 _(set_ip_flow_hash,                                                     \
23206   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23207 _(sw_interface_ip6_enable_disable,                                      \
23208   "<intfc> | sw_if_index <id> enable | disable")                        \
23209 _(ip6nd_proxy_add_del,                                                  \
23210   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23211 _(ip6nd_proxy_dump, "")                                                 \
23212 _(sw_interface_ip6nd_ra_prefix,                                         \
23213   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23214   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23215   "[nolink] [isno]")                                                    \
23216 _(sw_interface_ip6nd_ra_config,                                         \
23217   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23218   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23219   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23220 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23221 _(l2_patch_add_del,                                                     \
23222   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23223   "enable | disable")                                                   \
23224 _(sr_localsid_add_del,                                                  \
23225   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23226   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23227 _(classify_add_del_table,                                               \
23228   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23229   " [del] [del-chain] mask <mask-value>\n"                              \
23230   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23231   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23232 _(classify_add_del_session,                                             \
23233   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23234   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23235   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23236   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23237 _(classify_set_interface_ip_table,                                      \
23238   "<intfc> | sw_if_index <nn> table <nn>")                              \
23239 _(classify_set_interface_l2_tables,                                     \
23240   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23241   "  [other-table <nn>]")                                               \
23242 _(get_node_index, "node <node-name")                                    \
23243 _(add_node_next, "node <node-name> next <next-node-name>")              \
23244 _(l2tpv3_create_tunnel,                                                 \
23245   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23246   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23247   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23248 _(l2tpv3_set_tunnel_cookies,                                            \
23249   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23250   "[new_remote_cookie <nn>]\n")                                         \
23251 _(l2tpv3_interface_enable_disable,                                      \
23252   "<intfc> | sw_if_index <nn> enable | disable")                        \
23253 _(l2tpv3_set_lookup_key,                                                \
23254   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23255 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23256 _(vxlan_offload_rx,                                                     \
23257   "hw { <interface name> | hw_if_index <nn>} "                          \
23258   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23259 _(vxlan_add_del_tunnel,                                                 \
23260   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23261   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23262   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23263 _(geneve_add_del_tunnel,                                                \
23264   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23265   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23266   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23267 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23268 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23269 _(gre_add_del_tunnel,                                                   \
23270   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23271   "[teb | erspan <session-id>] [del]")                                  \
23272 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23273 _(l2_fib_clear_table, "")                                               \
23274 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23275 _(l2_interface_vlan_tag_rewrite,                                        \
23276   "<intfc> | sw_if_index <nn> \n"                                       \
23277   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23278   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23279 _(create_vhost_user_if,                                                 \
23280         "socket <filename> [server] [renumber <dev_instance>] "         \
23281         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23282         "[mac <mac_address>]")                                          \
23283 _(modify_vhost_user_if,                                                 \
23284         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23285         "[server] [renumber <dev_instance>]")                           \
23286 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23287 _(sw_interface_vhost_user_dump, "")                                     \
23288 _(show_version, "")                                                     \
23289 _(show_threads, "")                                                     \
23290 _(vxlan_gpe_add_del_tunnel,                                             \
23291   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23292   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23293   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23294   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23295 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23296 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23297 _(interface_name_renumber,                                              \
23298   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23299 _(input_acl_set_interface,                                              \
23300   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23301   "  [l2-table <nn>] [del]")                                            \
23302 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23303 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23304   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23305 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23306 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23307 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23308 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23309 _(ip_dump, "ipv4 | ipv6")                                               \
23310 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23311 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23312   "  spid_id <n> ")                                                     \
23313 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23314   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23315   "  integ_alg <alg> integ_key <hex>")                                  \
23316 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23317   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23318   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23319   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23320 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23321 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23322   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23323   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23324   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23325   "  [instance <n>]")     \
23326 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23327 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23328   "  <alg> <hex>\n")                                                    \
23329 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23330 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23331 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23332   "(auth_data 0x<data> | auth_data <data>)")                            \
23333 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23334   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23335 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23336   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23337   "(local|remote)")                                                     \
23338 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23339 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23340 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23341 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23342 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23343 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23344 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23345 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23346 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23347 _(delete_loopback,"sw_if_index <nn>")                                   \
23348 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23349 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23350 _(want_interface_events,  "enable|disable")                             \
23351 _(get_first_msg_id, "client <name>")                                    \
23352 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23353 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23354   "fib-id <nn> [ip4][ip6][default]")                                    \
23355 _(get_node_graph, " ")                                                  \
23356 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23357 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23358 _(ioam_disable, "")                                                     \
23359 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23360                             " sw_if_index <sw_if_index> p <priority> "  \
23361                             "w <weight>] [del]")                        \
23362 _(one_add_del_locator, "locator-set <locator_name> "                    \
23363                         "iface <intf> | sw_if_index <sw_if_index> "     \
23364                         "p <priority> w <weight> [del]")                \
23365 _(one_add_del_local_eid,"vni <vni> eid "                                \
23366                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23367                          "locator-set <locator_name> [del]"             \
23368                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23369 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23370 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23371 _(one_enable_disable, "enable|disable")                                 \
23372 _(one_map_register_enable_disable, "enable|disable")                    \
23373 _(one_map_register_fallback_threshold, "<value>")                       \
23374 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23375 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23376                                "[seid <seid>] "                         \
23377                                "rloc <locator> p <prio> "               \
23378                                "w <weight> [rloc <loc> ... ] "          \
23379                                "action <action> [del-all]")             \
23380 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23381                           "<local-eid>")                                \
23382 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23383 _(one_use_petr, "ip-address> | disable")                                \
23384 _(one_map_request_mode, "src-dst|dst-only")                             \
23385 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23386 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23387 _(one_locator_set_dump, "[local | remote]")                             \
23388 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23389 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23390                        "[local] | [remote]")                            \
23391 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23392 _(one_ndp_bd_get, "")                                                   \
23393 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23394 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23395 _(one_l2_arp_bd_get, "")                                                \
23396 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23397 _(one_stats_enable_disable, "enable|disable")                           \
23398 _(show_one_stats_enable_disable, "")                                    \
23399 _(one_eid_table_vni_dump, "")                                           \
23400 _(one_eid_table_map_dump, "l2|l3")                                      \
23401 _(one_map_resolver_dump, "")                                            \
23402 _(one_map_server_dump, "")                                              \
23403 _(one_adjacencies_get, "vni <vni>")                                     \
23404 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23405 _(show_one_rloc_probe_state, "")                                        \
23406 _(show_one_map_register_state, "")                                      \
23407 _(show_one_status, "")                                                  \
23408 _(one_stats_dump, "")                                                   \
23409 _(one_stats_flush, "")                                                  \
23410 _(one_get_map_request_itr_rlocs, "")                                    \
23411 _(one_map_register_set_ttl, "<ttl>")                                    \
23412 _(one_set_transport_protocol, "udp|api")                                \
23413 _(one_get_transport_protocol, "")                                       \
23414 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23415 _(one_show_xtr_mode, "")                                                \
23416 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23417 _(one_show_pitr_mode, "")                                               \
23418 _(one_enable_disable_petr_mode, "enable|disable")                       \
23419 _(one_show_petr_mode, "")                                               \
23420 _(show_one_nsh_mapping, "")                                             \
23421 _(show_one_pitr, "")                                                    \
23422 _(show_one_use_petr, "")                                                \
23423 _(show_one_map_request_mode, "")                                        \
23424 _(show_one_map_register_ttl, "")                                        \
23425 _(show_one_map_register_fallback_threshold, "")                         \
23426 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23427                             " sw_if_index <sw_if_index> p <priority> "  \
23428                             "w <weight>] [del]")                        \
23429 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23430                         "iface <intf> | sw_if_index <sw_if_index> "     \
23431                         "p <priority> w <weight> [del]")                \
23432 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23433                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23434                          "locator-set <locator_name> [del]"             \
23435                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23436 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23437 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23438 _(lisp_enable_disable, "enable|disable")                                \
23439 _(lisp_map_register_enable_disable, "enable|disable")                   \
23440 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23441 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23442                                "[seid <seid>] "                         \
23443                                "rloc <locator> p <prio> "               \
23444                                "w <weight> [rloc <loc> ... ] "          \
23445                                "action <action> [del-all]")             \
23446 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23447                           "<local-eid>")                                \
23448 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23449 _(lisp_use_petr, "<ip-address> | disable")                              \
23450 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23451 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23452 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23453 _(lisp_locator_set_dump, "[local | remote]")                            \
23454 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23455 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23456                        "[local] | [remote]")                            \
23457 _(lisp_eid_table_vni_dump, "")                                          \
23458 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23459 _(lisp_map_resolver_dump, "")                                           \
23460 _(lisp_map_server_dump, "")                                             \
23461 _(lisp_adjacencies_get, "vni <vni>")                                    \
23462 _(gpe_fwd_entry_vnis_get, "")                                           \
23463 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23464 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23465                                 "[table <table-id>]")                   \
23466 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23467 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23468 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23469 _(gpe_get_encap_mode, "")                                               \
23470 _(lisp_gpe_add_del_iface, "up|down")                                    \
23471 _(lisp_gpe_enable_disable, "enable|disable")                            \
23472 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23473   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23474 _(show_lisp_rloc_probe_state, "")                                       \
23475 _(show_lisp_map_register_state, "")                                     \
23476 _(show_lisp_status, "")                                                 \
23477 _(lisp_get_map_request_itr_rlocs, "")                                   \
23478 _(show_lisp_pitr, "")                                                   \
23479 _(show_lisp_use_petr, "")                                               \
23480 _(show_lisp_map_request_mode, "")                                       \
23481 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23482 _(af_packet_delete, "name <host interface name>")                       \
23483 _(af_packet_dump, "")                                                   \
23484 _(policer_add_del, "name <policer name> <params> [del]")                \
23485 _(policer_dump, "[name <policer name>]")                                \
23486 _(policer_classify_set_interface,                                       \
23487   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23488   "  [l2-table <nn>] [del]")                                            \
23489 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23490 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23491     "[master|slave]")                                                   \
23492 _(netmap_delete, "name <interface name>")                               \
23493 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23494 _(mpls_fib_dump, "")                                                    \
23495 _(classify_table_ids, "")                                               \
23496 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23497 _(classify_table_info, "table_id <nn>")                                 \
23498 _(classify_session_dump, "table_id <nn>")                               \
23499 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23500     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23501     "[template_interval <nn>] [udp_checksum]")                          \
23502 _(ipfix_exporter_dump, "")                                              \
23503 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23504 _(ipfix_classify_stream_dump, "")                                       \
23505 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23506 _(ipfix_classify_table_dump, "")                                        \
23507 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23508 _(sw_interface_span_dump, "[l2]")                                           \
23509 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23510 _(pg_create_interface, "if_id <nn>")                                    \
23511 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23512 _(pg_enable_disable, "[stream <id>] disable")                           \
23513 _(ip_source_and_port_range_check_add_del,                               \
23514   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23515 _(ip_source_and_port_range_check_interface_add_del,                     \
23516   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23517   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23518 _(ipsec_gre_add_del_tunnel,                                             \
23519   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23520 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23521 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23522 _(l2_interface_pbb_tag_rewrite,                                         \
23523   "<intfc> | sw_if_index <nn> \n"                                       \
23524   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23525   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23526 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23527 _(flow_classify_set_interface,                                          \
23528   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23529 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23530 _(ip_fib_dump, "")                                                      \
23531 _(ip_mfib_dump, "")                                                     \
23532 _(ip6_fib_dump, "")                                                     \
23533 _(ip6_mfib_dump, "")                                                    \
23534 _(feature_enable_disable, "arc_name <arc_name> "                        \
23535   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23536 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23537 "[disable]")                                                            \
23538 _(l2_xconnect_dump, "")                                                 \
23539 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23540 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23541 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23542 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23543 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23544 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23545 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23546   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23547 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23548 _(sock_init_shm, "size <nnn>")                                          \
23549 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23550 _(dns_enable_disable, "[enable][disable]")                              \
23551 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23552 _(dns_resolve_name, "<hostname>")                                       \
23553 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23554 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23555 _(dns_resolve_name, "<hostname>")                                       \
23556 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23557   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23558 _(session_rules_dump, "")                                               \
23559 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23560 _(output_acl_set_interface,                                             \
23561   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23562   "  [l2-table <nn>] [del]")                                            \
23563 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23564
23565 /* List of command functions, CLI names map directly to functions */
23566 #define foreach_cli_function                                    \
23567 _(comment, "usage: comment <ignore-rest-of-line>")              \
23568 _(dump_interface_table, "usage: dump_interface_table")          \
23569 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23570 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23571 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23572 _(dump_macro_table, "usage: dump_macro_table ")                 \
23573 _(dump_node_table, "usage: dump_node_table")                    \
23574 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23575 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23576 _(echo, "usage: echo <message>")                                \
23577 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23578 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23579 _(help, "usage: help")                                          \
23580 _(q, "usage: quit")                                             \
23581 _(quit, "usage: quit")                                          \
23582 _(search_node_table, "usage: search_node_table <name>...")      \
23583 _(set, "usage: set <variable-name> <value>")                    \
23584 _(script, "usage: script <file-name>")                          \
23585 _(statseg, "usage: statseg");                                   \
23586 _(unset, "usage: unset <variable-name>")
23587
23588 #define _(N,n)                                  \
23589     static void vl_api_##n##_t_handler_uni      \
23590     (vl_api_##n##_t * mp)                       \
23591     {                                           \
23592         vat_main_t * vam = &vat_main;           \
23593         if (vam->json_output) {                 \
23594             vl_api_##n##_t_handler_json(mp);    \
23595         } else {                                \
23596             vl_api_##n##_t_handler(mp);         \
23597         }                                       \
23598     }
23599 foreach_vpe_api_reply_msg;
23600 #if VPP_API_TEST_BUILTIN == 0
23601 foreach_standalone_reply_msg;
23602 #endif
23603 #undef _
23604
23605 void
23606 vat_api_hookup (vat_main_t * vam)
23607 {
23608 #define _(N,n)                                                  \
23609     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23610                            vl_api_##n##_t_handler_uni,          \
23611                            vl_noop_handler,                     \
23612                            vl_api_##n##_t_endian,               \
23613                            vl_api_##n##_t_print,                \
23614                            sizeof(vl_api_##n##_t), 1);
23615   foreach_vpe_api_reply_msg;
23616 #if VPP_API_TEST_BUILTIN == 0
23617   foreach_standalone_reply_msg;
23618 #endif
23619 #undef _
23620
23621 #if (VPP_API_TEST_BUILTIN==0)
23622   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23623
23624   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23625
23626   vam->function_by_name = hash_create_string (0, sizeof (uword));
23627
23628   vam->help_by_name = hash_create_string (0, sizeof (uword));
23629 #endif
23630
23631   /* API messages we can send */
23632 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23633   foreach_vpe_api_msg;
23634 #undef _
23635
23636   /* Help strings */
23637 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23638   foreach_vpe_api_msg;
23639 #undef _
23640
23641   /* CLI functions */
23642 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23643   foreach_cli_function;
23644 #undef _
23645
23646   /* Help strings */
23647 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23648   foreach_cli_function;
23649 #undef _
23650 }
23651
23652 #if VPP_API_TEST_BUILTIN
23653 static clib_error_t *
23654 vat_api_hookup_shim (vlib_main_t * vm)
23655 {
23656   vat_api_hookup (&vat_main);
23657   return 0;
23658 }
23659
23660 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23661 #endif
23662
23663 /*
23664  * fd.io coding-style-patch-verification: ON
23665  *
23666  * Local Variables:
23667  * eval: (c-set-style "gnu")
23668  * End:
23669  */