vom: Fix the l2 port type in bridge domain
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 static uword
180 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
181 {
182   return 0;
183 }
184
185 /* Parse an IP4 address %d.%d.%d.%d. */
186 uword
187 unformat_ip4_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   unsigned a[4];
191
192   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
193     return 0;
194
195   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
196     return 0;
197
198   result[0] = a[0];
199   result[1] = a[1];
200   result[2] = a[2];
201   result[3] = a[3];
202
203   return 1;
204 }
205
206 uword
207 unformat_ethernet_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   u32 i, a[6];
211
212   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
213                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
214     return 0;
215
216   /* Check range. */
217   for (i = 0; i < 6; i++)
218     if (a[i] >= (1 << 8))
219       return 0;
220
221   for (i = 0; i < 6; i++)
222     result[i] = a[i];
223
224   return 1;
225 }
226
227 /* Returns ethernet type as an int in host byte order. */
228 uword
229 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
230                                         va_list * args)
231 {
232   u16 *result = va_arg (*args, u16 *);
233   int type;
234
235   /* Numeric type. */
236   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
237     {
238       if (type >= (1 << 16))
239         return 0;
240       *result = type;
241       return 1;
242     }
243   return 0;
244 }
245
246 /* Parse an IP6 address. */
247 uword
248 unformat_ip6_address (unformat_input_t * input, va_list * args)
249 {
250   ip6_address_t *result = va_arg (*args, ip6_address_t *);
251   u16 hex_quads[8];
252   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
253   uword c, n_colon, double_colon_index;
254
255   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
256   double_colon_index = ARRAY_LEN (hex_quads);
257   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
258     {
259       hex_digit = 16;
260       if (c >= '0' && c <= '9')
261         hex_digit = c - '0';
262       else if (c >= 'a' && c <= 'f')
263         hex_digit = c + 10 - 'a';
264       else if (c >= 'A' && c <= 'F')
265         hex_digit = c + 10 - 'A';
266       else if (c == ':' && n_colon < 2)
267         n_colon++;
268       else
269         {
270           unformat_put_input (input);
271           break;
272         }
273
274       /* Too many hex quads. */
275       if (n_hex_quads >= ARRAY_LEN (hex_quads))
276         return 0;
277
278       if (hex_digit < 16)
279         {
280           hex_quad = (hex_quad << 4) | hex_digit;
281
282           /* Hex quad must fit in 16 bits. */
283           if (n_hex_digits >= 4)
284             return 0;
285
286           n_colon = 0;
287           n_hex_digits++;
288         }
289
290       /* Save position of :: */
291       if (n_colon == 2)
292         {
293           /* More than one :: ? */
294           if (double_colon_index < ARRAY_LEN (hex_quads))
295             return 0;
296           double_colon_index = n_hex_quads;
297         }
298
299       if (n_colon > 0 && n_hex_digits > 0)
300         {
301           hex_quads[n_hex_quads++] = hex_quad;
302           hex_quad = 0;
303           n_hex_digits = 0;
304         }
305     }
306
307   if (n_hex_digits > 0)
308     hex_quads[n_hex_quads++] = hex_quad;
309
310   {
311     word i;
312
313     /* Expand :: to appropriate number of zero hex quads. */
314     if (double_colon_index < ARRAY_LEN (hex_quads))
315       {
316         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
317
318         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
319           hex_quads[n_zero + i] = hex_quads[i];
320
321         for (i = 0; i < n_zero; i++)
322           hex_quads[double_colon_index + i] = 0;
323
324         n_hex_quads = ARRAY_LEN (hex_quads);
325       }
326
327     /* Too few hex quads given. */
328     if (n_hex_quads < ARRAY_LEN (hex_quads))
329       return 0;
330
331     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
332       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
333
334     return 1;
335   }
336 }
337
338 uword
339 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
340 {
341   u32 *r = va_arg (*args, u32 *);
342
343   if (0);
344 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
345   foreach_ipsec_policy_action
346 #undef _
347     else
348     return 0;
349   return 1;
350 }
351
352 uword
353 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
354 {
355   u32 *r = va_arg (*args, u32 *);
356
357   if (0);
358 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
359   foreach_ipsec_crypto_alg
360 #undef _
361     else
362     return 0;
363   return 1;
364 }
365
366 u8 *
367 format_ipsec_crypto_alg (u8 * s, va_list * args)
368 {
369   u32 i = va_arg (*args, u32);
370   u8 *t = 0;
371
372   switch (i)
373     {
374 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
375       foreach_ipsec_crypto_alg
376 #undef _
377     default:
378       return format (s, "unknown");
379     }
380   return format (s, "%s", t);
381 }
382
383 uword
384 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
385 {
386   u32 *r = va_arg (*args, u32 *);
387
388   if (0);
389 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
390   foreach_ipsec_integ_alg
391 #undef _
392     else
393     return 0;
394   return 1;
395 }
396
397 u8 *
398 format_ipsec_integ_alg (u8 * s, va_list * args)
399 {
400   u32 i = va_arg (*args, u32);
401   u8 *t = 0;
402
403   switch (i)
404     {
405 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
406       foreach_ipsec_integ_alg
407 #undef _
408     default:
409       return format (s, "unknown");
410     }
411   return format (s, "%s", t);
412 }
413
414 uword
415 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
416 {
417   u32 *r = va_arg (*args, u32 *);
418
419   if (0);
420 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
421   foreach_ikev2_auth_method
422 #undef _
423     else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
435   foreach_ikev2_id_type
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441 #else /* VPP_API_TEST_BUILTIN == 1 */
442 static uword
443 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
444 {
445   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
446   vnet_main_t *vnm = vnet_get_main ();
447   u32 *result = va_arg (*args, u32 *);
448
449   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
450 }
451
452 static uword
453 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
454 {
455   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
456   vnet_main_t *vnm = vnet_get_main ();
457   u32 *result = va_arg (*args, u32 *);
458
459   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
460 }
461
462 #endif /* VPP_API_TEST_BUILTIN */
463
464 static uword
465 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
466 {
467   u8 *r = va_arg (*args, u8 *);
468
469   if (unformat (input, "kbps"))
470     *r = SSE2_QOS_RATE_KBPS;
471   else if (unformat (input, "pps"))
472     *r = SSE2_QOS_RATE_PPS;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_round_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "closest"))
484     *r = SSE2_QOS_ROUND_TO_CLOSEST;
485   else if (unformat (input, "up"))
486     *r = SSE2_QOS_ROUND_TO_UP;
487   else if (unformat (input, "down"))
488     *r = SSE2_QOS_ROUND_TO_DOWN;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "1r2c"))
500     *r = SSE2_QOS_POLICER_TYPE_1R2C;
501   else if (unformat (input, "1r3c"))
502     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
503   else if (unformat (input, "2r3c-2698"))
504     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
505   else if (unformat (input, "2r3c-4115"))
506     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
507   else if (unformat (input, "2r3c-mef5cf1"))
508     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
509   else
510     return 0;
511   return 1;
512 }
513
514 static uword
515 unformat_dscp (unformat_input_t * input, va_list * va)
516 {
517   u8 *r = va_arg (*va, u8 *);
518
519   if (0);
520 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
521   foreach_vnet_dscp
522 #undef _
523     else
524     return 0;
525   return 1;
526 }
527
528 static uword
529 unformat_policer_action_type (unformat_input_t * input, va_list * va)
530 {
531   sse2_qos_pol_action_params_st *a
532     = va_arg (*va, sse2_qos_pol_action_params_st *);
533
534   if (unformat (input, "drop"))
535     a->action_type = SSE2_QOS_ACTION_DROP;
536   else if (unformat (input, "transmit"))
537     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
538   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
539     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
540   else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
547 {
548   u32 *r = va_arg (*va, u32 *);
549   u32 tid;
550
551   if (unformat (input, "ip4"))
552     tid = POLICER_CLASSIFY_TABLE_IP4;
553   else if (unformat (input, "ip6"))
554     tid = POLICER_CLASSIFY_TABLE_IP6;
555   else if (unformat (input, "l2"))
556     tid = POLICER_CLASSIFY_TABLE_L2;
557   else
558     return 0;
559
560   *r = tid;
561   return 1;
562 }
563
564 static uword
565 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
566 {
567   u32 *r = va_arg (*va, u32 *);
568   u32 tid;
569
570   if (unformat (input, "ip4"))
571     tid = FLOW_CLASSIFY_TABLE_IP4;
572   else if (unformat (input, "ip6"))
573     tid = FLOW_CLASSIFY_TABLE_IP6;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
582 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
583 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
584 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
585
586 #if (VPP_API_TEST_BUILTIN==0)
587 uword
588 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
589 {
590   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
591   mfib_itf_attribute_t attr;
592
593   old = *iflags;
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_long_names[attr]))
597       *iflags |= (1 << attr);
598   }
599   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_itf_flag_names[attr]))
602       *iflags |= (1 << attr);
603   }
604
605   return (old == *iflags ? 0 : 1);
606 }
607
608 uword
609 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
610 {
611   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
612   mfib_entry_attribute_t attr;
613
614   old = *eflags;
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_long_names[attr]))
618       *eflags |= (1 << attr);
619   }
620   FOR_EACH_MFIB_ATTRIBUTE (attr)
621   {
622     if (unformat (input, mfib_flag_names[attr]))
623       *eflags |= (1 << attr);
624   }
625
626   return (old == *eflags ? 0 : 1);
627 }
628
629 u8 *
630 format_ip4_address (u8 * s, va_list * args)
631 {
632   u8 *a = va_arg (*args, u8 *);
633   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
634 }
635
636 u8 *
637 format_ip6_address (u8 * s, va_list * args)
638 {
639   ip6_address_t *a = va_arg (*args, ip6_address_t *);
640   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
641
642   i_max_n_zero = ARRAY_LEN (a->as_u16);
643   max_n_zeros = 0;
644   i_first_zero = i_max_n_zero;
645   n_zeros = 0;
646   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
647     {
648       u32 is_zero = a->as_u16[i] == 0;
649       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
650         {
651           i_first_zero = i;
652           n_zeros = 0;
653         }
654       n_zeros += is_zero;
655       if ((!is_zero && n_zeros > max_n_zeros)
656           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
657         {
658           i_max_n_zero = i_first_zero;
659           max_n_zeros = n_zeros;
660           i_first_zero = ARRAY_LEN (a->as_u16);
661           n_zeros = 0;
662         }
663     }
664
665   last_double_colon = 0;
666   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
667     {
668       if (i == i_max_n_zero && max_n_zeros > 1)
669         {
670           s = format (s, "::");
671           i += max_n_zeros - 1;
672           last_double_colon = 1;
673         }
674       else
675         {
676           s = format (s, "%s%x",
677                       (last_double_colon || i == 0) ? "" : ":",
678                       clib_net_to_host_u16 (a->as_u16[i]));
679           last_double_colon = 0;
680         }
681     }
682
683   return s;
684 }
685
686 /* Format an IP46 address. */
687 u8 *
688 format_ip46_address (u8 * s, va_list * args)
689 {
690   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
691   ip46_type_t type = va_arg (*args, ip46_type_t);
692   int is_ip4 = 1;
693
694   switch (type)
695     {
696     case IP46_TYPE_ANY:
697       is_ip4 = ip46_address_is_ip4 (ip46);
698       break;
699     case IP46_TYPE_IP4:
700       is_ip4 = 1;
701       break;
702     case IP46_TYPE_IP6:
703       is_ip4 = 0;
704       break;
705     }
706
707   return is_ip4 ?
708     format (s, "%U", format_ip4_address, &ip46->ip4) :
709     format (s, "%U", format_ip6_address, &ip46->ip6);
710 }
711
712 u8 *
713 format_ethernet_address (u8 * s, va_list * args)
714 {
715   u8 *a = va_arg (*args, u8 *);
716
717   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
718                  a[0], a[1], a[2], a[3], a[4], a[5]);
719 }
720 #endif
721
722 static void
723 increment_v4_address (ip4_address_t * a)
724 {
725   u32 v;
726
727   v = ntohl (a->as_u32) + 1;
728   a->as_u32 = ntohl (v);
729 }
730
731 static void
732 increment_v6_address (ip6_address_t * a)
733 {
734   u64 v0, v1;
735
736   v0 = clib_net_to_host_u64 (a->as_u64[0]);
737   v1 = clib_net_to_host_u64 (a->as_u64[1]);
738
739   v1 += 1;
740   if (v1 == 0)
741     v0 += 1;
742   a->as_u64[0] = clib_net_to_host_u64 (v0);
743   a->as_u64[1] = clib_net_to_host_u64 (v1);
744 }
745
746 static void
747 increment_mac_address (u8 * mac)
748 {
749   u64 tmp = *((u64 *) mac);
750   tmp = clib_net_to_host_u64 (tmp);
751   tmp += 1 << 16;               /* skip unused (least significant) octets */
752   tmp = clib_host_to_net_u64 (tmp);
753
754   clib_memcpy (mac, &tmp, 6);
755 }
756
757 static void vl_api_create_loopback_reply_t_handler
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_loopback_reply_t_handler_json
770   (vl_api_create_loopback_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781   vam->retval = ntohl (mp->retval);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   i32 retval = ntohl (mp->retval);
790
791   vam->retval = retval;
792   vam->regenerate_interface_table = 1;
793   vam->sw_if_index = ntohl (mp->sw_if_index);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_loopback_instance_reply_t_handler_json
798   (vl_api_create_loopback_instance_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   vat_json_node_t node;
802
803   vat_json_init_object (&node);
804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
806
807   vat_json_print (vam->ofp, &node);
808   vat_json_free (&node);
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_af_packet_create_reply_t_handler_json
826   (vl_api_af_packet_create_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->sw_if_index = ntohl (mp->sw_if_index);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_vlan_subif_reply_t_handler_json
855   (vl_api_create_vlan_subif_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   vat_json_node_t node;
859
860   vat_json_init_object (&node);
861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
863
864   vat_json_print (vam->ofp, &node);
865   vat_json_free (&node);
866
867   vam->retval = ntohl (mp->retval);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   i32 retval = ntohl (mp->retval);
876
877   vam->retval = retval;
878   vam->regenerate_interface_table = 1;
879   vam->sw_if_index = ntohl (mp->sw_if_index);
880   vam->result_ready = 1;
881 }
882
883 static void vl_api_create_subif_reply_t_handler_json
884   (vl_api_create_subif_reply_t * mp)
885 {
886   vat_main_t *vam = &vat_main;
887   vat_json_node_t node;
888
889   vat_json_init_object (&node);
890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
892
893   vat_json_print (vam->ofp, &node);
894   vat_json_free (&node);
895
896   vam->retval = ntohl (mp->retval);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   i32 retval = ntohl (mp->retval);
905
906   vam->retval = retval;
907   vam->regenerate_interface_table = 1;
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler_json
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   vat_json_node_t node;
916
917   vat_json_init_object (&node);
918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
919
920   vat_json_print (vam->ofp, &node);
921   vat_json_free (&node);
922
923   vam->retval = ntohl (mp->retval);
924   vam->result_ready = 1;
925 }
926
927 /*
928  * Special-case: build the interface table, maintain
929  * the next loopback sw_if_index vbl.
930  */
931 static void vl_api_sw_interface_details_t_handler
932   (vl_api_sw_interface_details_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   u8 *s = format (0, "%s%c", mp->interface_name, 0);
936
937   hash_set_mem (vam->sw_if_index_by_interface_name, s,
938                 ntohl (mp->sw_if_index));
939
940   /* In sub interface case, fill the sub interface table entry */
941   if (mp->sw_if_index != mp->sup_sw_if_index)
942     {
943       sw_interface_subif_t *sub = NULL;
944
945       vec_add2 (vam->sw_if_subif_table, sub, 1);
946
947       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
948       strncpy ((char *) sub->interface_name, (char *) s,
949                vec_len (sub->interface_name));
950       sub->sw_if_index = ntohl (mp->sw_if_index);
951       sub->sub_id = ntohl (mp->sub_id);
952
953       sub->sub_dot1ad = mp->sub_dot1ad;
954       sub->sub_number_of_tags = mp->sub_number_of_tags;
955       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
956       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
957       sub->sub_exact_match = mp->sub_exact_match;
958       sub->sub_default = mp->sub_default;
959       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
960       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
961
962       /* vlan tag rewrite */
963       sub->vtr_op = ntohl (mp->vtr_op);
964       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
965       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
966       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
967     }
968 }
969
970 static void vl_api_sw_interface_details_t_handler_json
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t *node = NULL;
975
976   if (VAT_JSON_ARRAY != vam->json_tree.type)
977     {
978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
979       vat_json_init_array (&vam->json_tree);
980     }
981   node = vat_json_array_add (&vam->json_tree);
982
983   vat_json_init_object (node);
984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
985   vat_json_object_add_uint (node, "sup_sw_if_index",
986                             ntohl (mp->sup_sw_if_index));
987   vat_json_object_add_uint (node, "l2_address_length",
988                             ntohl (mp->l2_address_length));
989   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
990                              sizeof (mp->l2_address));
991   vat_json_object_add_string_copy (node, "interface_name",
992                                    mp->interface_name);
993   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
994   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
995   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
996   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
997   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
998   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
999   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1000   vat_json_object_add_uint (node, "sub_number_of_tags",
1001                             mp->sub_number_of_tags);
1002   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1003                             ntohs (mp->sub_outer_vlan_id));
1004   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1005                             ntohs (mp->sub_inner_vlan_id));
1006   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1007   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1008   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1009                             mp->sub_outer_vlan_id_any);
1010   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1011                             mp->sub_inner_vlan_id_any);
1012   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1013   vat_json_object_add_uint (node, "vtr_push_dot1q",
1014                             ntohl (mp->vtr_push_dot1q));
1015   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1016   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1017   if (mp->sub_dot1ah)
1018     {
1019       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1020                                        format (0, "%U",
1021                                                format_ethernet_address,
1022                                                &mp->b_dmac));
1023       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1024                                        format (0, "%U",
1025                                                format_ethernet_address,
1026                                                &mp->b_smac));
1027       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1028       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1029     }
1030 }
1031
1032 #if VPP_API_TEST_BUILTIN == 0
1033 static void vl_api_sw_interface_event_t_handler
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   if (vam->interface_event_display)
1038     errmsg ("interface flags: sw_if_index %d %s %s",
1039             ntohl (mp->sw_if_index),
1040             mp->admin_up_down ? "admin-up" : "admin-down",
1041             mp->link_up_down ? "link-up" : "link-down");
1042 }
1043 #endif
1044
1045 static void vl_api_sw_interface_event_t_handler_json
1046   (vl_api_sw_interface_event_t * mp)
1047 {
1048   /* JSON output not supported */
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   i32 retval = ntohl (mp->retval);
1056
1057   vam->retval = retval;
1058   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   vat_json_node_t node;
1067   api_main_t *am = &api_main;
1068   void *oldheap;
1069   u8 *reply;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "reply_in_shmem",
1074                             ntohl (mp->reply_in_shmem));
1075   /* Toss the shared-memory original... */
1076   pthread_mutex_lock (&am->vlib_rp->mutex);
1077   oldheap = svm_push_data_heap (am->vlib_rp);
1078
1079   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1080   vec_free (reply);
1081
1082   svm_pop_heap (oldheap);
1083   pthread_mutex_unlock (&am->vlib_rp->mutex);
1084
1085   vat_json_print (vam->ofp, &node);
1086   vat_json_free (&node);
1087
1088   vam->retval = ntohl (mp->retval);
1089   vam->result_ready = 1;
1090 }
1091
1092 static void
1093 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1094 {
1095   vat_main_t *vam = &vat_main;
1096   i32 retval = ntohl (mp->retval);
1097   u32 length = ntohl (mp->length);
1098
1099   vec_reset_length (vam->cmd_reply);
1100
1101   vam->retval = retval;
1102   if (retval == 0)
1103     {
1104       vec_validate (vam->cmd_reply, length);
1105       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1106       vam->cmd_reply[length] = 0;
1107     }
1108   vam->result_ready = 1;
1109 }
1110
1111 static void
1112 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vec_reset_length (vam->cmd_reply);
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1122
1123   vat_json_print (vam->ofp, &node);
1124   vat_json_free (&node);
1125
1126   vam->retval = ntohl (mp->retval);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void vl_api_classify_add_del_table_reply_t_handler
1131   (vl_api_classify_add_del_table_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135   if (vam->async_mode)
1136     {
1137       vam->async_errors += (retval < 0);
1138     }
1139   else
1140     {
1141       vam->retval = retval;
1142       if (retval == 0 &&
1143           ((mp->new_table_index != 0xFFFFFFFF) ||
1144            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1145            (mp->match_n_vectors != 0xFFFFFFFF)))
1146         /*
1147          * Note: this is just barely thread-safe, depends on
1148          * the main thread spinning waiting for an answer...
1149          */
1150         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1151                 ntohl (mp->new_table_index),
1152                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1153       vam->result_ready = 1;
1154     }
1155 }
1156
1157 static void vl_api_classify_add_del_table_reply_t_handler_json
1158   (vl_api_classify_add_del_table_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   vat_json_node_t node;
1162
1163   vat_json_init_object (&node);
1164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1165   vat_json_object_add_uint (&node, "new_table_index",
1166                             ntohl (mp->new_table_index));
1167   vat_json_object_add_uint (&node, "skip_n_vectors",
1168                             ntohl (mp->skip_n_vectors));
1169   vat_json_object_add_uint (&node, "match_n_vectors",
1170                             ntohl (mp->match_n_vectors));
1171
1172   vat_json_print (vam->ofp, &node);
1173   vat_json_free (&node);
1174
1175   vam->retval = ntohl (mp->retval);
1176   vam->result_ready = 1;
1177 }
1178
1179 static void vl_api_get_node_index_reply_t_handler
1180   (vl_api_get_node_index_reply_t * mp)
1181 {
1182   vat_main_t *vam = &vat_main;
1183   i32 retval = ntohl (mp->retval);
1184   if (vam->async_mode)
1185     {
1186       vam->async_errors += (retval < 0);
1187     }
1188   else
1189     {
1190       vam->retval = retval;
1191       if (retval == 0)
1192         errmsg ("node index %d", ntohl (mp->node_index));
1193       vam->result_ready = 1;
1194     }
1195 }
1196
1197 static void vl_api_get_node_index_reply_t_handler_json
1198   (vl_api_get_node_index_reply_t * mp)
1199 {
1200   vat_main_t *vam = &vat_main;
1201   vat_json_node_t node;
1202
1203   vat_json_init_object (&node);
1204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1205   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_next_index_reply_t_handler
1215   (vl_api_get_next_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("next node index %d", ntohl (mp->next_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_next_index_reply_t_handler_json
1233   (vl_api_get_next_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_add_node_next_reply_t_handler
1250   (vl_api_add_node_next_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_add_node_next_reply_t_handler_json
1268   (vl_api_add_node_next_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_show_version_reply_t_handler
1285   (vl_api_show_version_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289
1290   if (retval >= 0)
1291     {
1292       errmsg ("        program: %s", mp->program);
1293       errmsg ("        version: %s", mp->version);
1294       errmsg ("     build date: %s", mp->build_date);
1295       errmsg ("build directory: %s", mp->build_directory);
1296     }
1297   vam->retval = retval;
1298   vam->result_ready = 1;
1299 }
1300
1301 static void vl_api_show_version_reply_t_handler_json
1302   (vl_api_show_version_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_string_copy (&node, "program", mp->program);
1310   vat_json_object_add_string_copy (&node, "version", mp->version);
1311   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1312   vat_json_object_add_string_copy (&node, "build_directory",
1313                                    mp->build_directory);
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void
1323 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1324 {
1325   u32 sw_if_index = ntohl (mp->sw_if_index);
1326   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1327           mp->mac_ip ? "mac/ip binding" : "address resolution",
1328           ntohl (mp->pid), format_ip4_address, &mp->address,
1329           format_ethernet_address, mp->new_mac, sw_if_index);
1330 }
1331
1332 static void
1333 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1334 {
1335   /* JSON output not supported */
1336 }
1337
1338 static void
1339 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1340 {
1341   u32 sw_if_index = ntohl (mp->sw_if_index);
1342   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1343           mp->mac_ip ? "mac/ip binding" : "address resolution",
1344           ntohl (mp->pid), format_ip6_address, mp->address,
1345           format_ethernet_address, mp->new_mac, sw_if_index);
1346 }
1347
1348 static void
1349 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1350 {
1351   /* JSON output not supported */
1352 }
1353
1354 static void
1355 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1356 {
1357   u32 n_macs = ntohl (mp->n_macs);
1358   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1359           ntohl (mp->pid), mp->client_index, n_macs);
1360   int i;
1361   for (i = 0; i < n_macs; i++)
1362     {
1363       vl_api_mac_entry_t *mac = &mp->mac[i];
1364       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1365               i + 1, ntohl (mac->sw_if_index),
1366               format_ethernet_address, mac->mac_addr, mac->action);
1367       if (i == 1000)
1368         break;
1369     }
1370 }
1371
1372 static void
1373 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1374 {
1375   /* JSON output not supported */
1376 }
1377
1378 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1379 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1380
1381 /*
1382  * Special-case: build the bridge domain table, maintain
1383  * the next bd id vbl.
1384  */
1385 static void vl_api_bridge_domain_details_t_handler
1386   (vl_api_bridge_domain_details_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1390   int i;
1391
1392   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index),
1398          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1399
1400   if (n_sw_ifs)
1401     {
1402       vl_api_bridge_domain_sw_if_t *sw_ifs;
1403       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1404              "Interface Name");
1405
1406       sw_ifs = mp->sw_if_details;
1407       for (i = 0; i < n_sw_ifs; i++)
1408         {
1409           u8 *sw_if_name = 0;
1410           u32 sw_if_index;
1411           hash_pair_t *p;
1412
1413           sw_if_index = ntohl (sw_ifs->sw_if_index);
1414
1415           /* *INDENT-OFF* */
1416           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1417                              ({
1418                                if ((u32) p->value[0] == sw_if_index)
1419                                  {
1420                                    sw_if_name = (u8 *)(p->key);
1421                                    break;
1422                                  }
1423                              }));
1424           /* *INDENT-ON* */
1425           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1426                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1427                  "sw_if_index not found!");
1428
1429           sw_ifs++;
1430         }
1431     }
1432 }
1433
1434 static void vl_api_bridge_domain_details_t_handler_json
1435   (vl_api_bridge_domain_details_t * mp)
1436 {
1437   vat_main_t *vam = &vat_main;
1438   vat_json_node_t *node, *array = NULL;
1439   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1440
1441   if (VAT_JSON_ARRAY != vam->json_tree.type)
1442     {
1443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1444       vat_json_init_array (&vam->json_tree);
1445     }
1446   node = vat_json_array_add (&vam->json_tree);
1447
1448   vat_json_init_object (node);
1449   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1450   vat_json_object_add_uint (node, "flood", mp->flood);
1451   vat_json_object_add_uint (node, "forward", mp->forward);
1452   vat_json_object_add_uint (node, "learn", mp->learn);
1453   vat_json_object_add_uint (node, "bvi_sw_if_index",
1454                             ntohl (mp->bvi_sw_if_index));
1455   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1456   array = vat_json_object_add (node, "sw_if");
1457   vat_json_init_array (array);
1458
1459
1460
1461   if (n_sw_ifs)
1462     {
1463       vl_api_bridge_domain_sw_if_t *sw_ifs;
1464       int i;
1465
1466       sw_ifs = mp->sw_if_details;
1467       for (i = 0; i < n_sw_ifs; i++)
1468         {
1469           node = vat_json_array_add (array);
1470           vat_json_init_object (node);
1471           vat_json_object_add_uint (node, "sw_if_index",
1472                                     ntohl (sw_ifs->sw_if_index));
1473           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1474           sw_ifs++;
1475         }
1476     }
1477 }
1478
1479 static void vl_api_control_ping_reply_t_handler
1480   (vl_api_control_ping_reply_t * mp)
1481 {
1482   vat_main_t *vam = &vat_main;
1483   i32 retval = ntohl (mp->retval);
1484   if (vam->async_mode)
1485     {
1486       vam->async_errors += (retval < 0);
1487     }
1488   else
1489     {
1490       vam->retval = retval;
1491       vam->result_ready = 1;
1492     }
1493   if (vam->socket_client_main)
1494     vam->socket_client_main->control_pings_outstanding--;
1495 }
1496
1497 static void vl_api_control_ping_reply_t_handler_json
1498   (vl_api_control_ping_reply_t * mp)
1499 {
1500   vat_main_t *vam = &vat_main;
1501   i32 retval = ntohl (mp->retval);
1502
1503   if (VAT_JSON_NONE != vam->json_tree.type)
1504     {
1505       vat_json_print (vam->ofp, &vam->json_tree);
1506       vat_json_free (&vam->json_tree);
1507       vam->json_tree.type = VAT_JSON_NONE;
1508     }
1509   else
1510     {
1511       /* just print [] */
1512       vat_json_init_array (&vam->json_tree);
1513       vat_json_print (vam->ofp, &vam->json_tree);
1514       vam->json_tree.type = VAT_JSON_NONE;
1515     }
1516
1517   vam->retval = retval;
1518   vam->result_ready = 1;
1519 }
1520
1521 static void
1522   vl_api_bridge_domain_set_mac_age_reply_t_handler
1523   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->result_ready = 1;
1535     }
1536 }
1537
1538 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1539   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1540 {
1541   vat_main_t *vam = &vat_main;
1542   vat_json_node_t node;
1543
1544   vat_json_init_object (&node);
1545   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1546
1547   vat_json_print (vam->ofp, &node);
1548   vat_json_free (&node);
1549
1550   vam->retval = ntohl (mp->retval);
1551   vam->result_ready = 1;
1552 }
1553
1554 static void
1555 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1556 {
1557   vat_main_t *vam = &vat_main;
1558   i32 retval = ntohl (mp->retval);
1559   if (vam->async_mode)
1560     {
1561       vam->async_errors += (retval < 0);
1562     }
1563   else
1564     {
1565       vam->retval = retval;
1566       vam->result_ready = 1;
1567     }
1568 }
1569
1570 static void vl_api_l2_flags_reply_t_handler_json
1571   (vl_api_l2_flags_reply_t * mp)
1572 {
1573   vat_main_t *vam = &vat_main;
1574   vat_json_node_t node;
1575
1576   vat_json_init_object (&node);
1577   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1578   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1579                             ntohl (mp->resulting_feature_bitmap));
1580
1581   vat_json_print (vam->ofp, &node);
1582   vat_json_free (&node);
1583
1584   vam->retval = ntohl (mp->retval);
1585   vam->result_ready = 1;
1586 }
1587
1588 static void vl_api_bridge_flags_reply_t_handler
1589   (vl_api_bridge_flags_reply_t * mp)
1590 {
1591   vat_main_t *vam = &vat_main;
1592   i32 retval = ntohl (mp->retval);
1593   if (vam->async_mode)
1594     {
1595       vam->async_errors += (retval < 0);
1596     }
1597   else
1598     {
1599       vam->retval = retval;
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_bridge_flags_reply_t_handler_json
1605   (vl_api_bridge_flags_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1613                             ntohl (mp->resulting_feature_bitmap));
1614
1615   vat_json_print (vam->ofp, &node);
1616   vat_json_free (&node);
1617
1618   vam->retval = ntohl (mp->retval);
1619   vam->result_ready = 1;
1620 }
1621
1622 static void vl_api_tap_connect_reply_t_handler
1623   (vl_api_tap_connect_reply_t * mp)
1624 {
1625   vat_main_t *vam = &vat_main;
1626   i32 retval = ntohl (mp->retval);
1627   if (vam->async_mode)
1628     {
1629       vam->async_errors += (retval < 0);
1630     }
1631   else
1632     {
1633       vam->retval = retval;
1634       vam->sw_if_index = ntohl (mp->sw_if_index);
1635       vam->result_ready = 1;
1636     }
1637
1638 }
1639
1640 static void vl_api_tap_connect_reply_t_handler_json
1641   (vl_api_tap_connect_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   vat_json_node_t node;
1645
1646   vat_json_init_object (&node);
1647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1649
1650   vat_json_print (vam->ofp, &node);
1651   vat_json_free (&node);
1652
1653   vam->retval = ntohl (mp->retval);
1654   vam->result_ready = 1;
1655
1656 }
1657
1658 static void
1659 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_tap_modify_reply_t_handler_json
1676   (vl_api_tap_modify_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void
1693 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   i32 retval = ntohl (mp->retval);
1697   if (vam->async_mode)
1698     {
1699       vam->async_errors += (retval < 0);
1700     }
1701   else
1702     {
1703       vam->retval = retval;
1704       vam->result_ready = 1;
1705     }
1706 }
1707
1708 static void vl_api_tap_delete_reply_t_handler_json
1709   (vl_api_tap_delete_reply_t * mp)
1710 {
1711   vat_main_t *vam = &vat_main;
1712   vat_json_node_t node;
1713
1714   vat_json_init_object (&node);
1715   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1716
1717   vat_json_print (vam->ofp, &node);
1718   vat_json_free (&node);
1719
1720   vam->retval = ntohl (mp->retval);
1721   vam->result_ready = 1;
1722 }
1723
1724 static void
1725 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1726 {
1727   vat_main_t *vam = &vat_main;
1728   i32 retval = ntohl (mp->retval);
1729   if (vam->async_mode)
1730     {
1731       vam->async_errors += (retval < 0);
1732     }
1733   else
1734     {
1735       vam->retval = retval;
1736       vam->sw_if_index = ntohl (mp->sw_if_index);
1737       vam->result_ready = 1;
1738     }
1739
1740 }
1741
1742 static void vl_api_tap_create_v2_reply_t_handler_json
1743   (vl_api_tap_create_v2_reply_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t node;
1747
1748   vat_json_init_object (&node);
1749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1750   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1751
1752   vat_json_print (vam->ofp, &node);
1753   vat_json_free (&node);
1754
1755   vam->retval = ntohl (mp->retval);
1756   vam->result_ready = 1;
1757
1758 }
1759
1760 static void
1761 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   i32 retval = ntohl (mp->retval);
1765   if (vam->async_mode)
1766     {
1767       vam->async_errors += (retval < 0);
1768     }
1769   else
1770     {
1771       vam->retval = retval;
1772       vam->result_ready = 1;
1773     }
1774 }
1775
1776 static void vl_api_tap_delete_v2_reply_t_handler_json
1777   (vl_api_tap_delete_v2_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   vat_json_node_t node;
1781
1782   vat_json_init_object (&node);
1783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1784
1785   vat_json_print (vam->ofp, &node);
1786   vat_json_free (&node);
1787
1788   vam->retval = ntohl (mp->retval);
1789   vam->result_ready = 1;
1790 }
1791
1792 static void
1793 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1794 {
1795   vat_main_t *vam = &vat_main;
1796   i32 retval = ntohl (mp->retval);
1797
1798   if (vam->async_mode)
1799     {
1800       vam->async_errors += (retval < 0);
1801     }
1802   else
1803     {
1804       vam->retval = retval;
1805       vam->sw_if_index = ntohl (mp->sw_if_index);
1806       vam->result_ready = 1;
1807     }
1808 }
1809
1810 static void vl_api_bond_create_reply_t_handler_json
1811   (vl_api_bond_create_reply_t * mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   vat_json_node_t node;
1815
1816   vat_json_init_object (&node);
1817   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1818   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1819
1820   vat_json_print (vam->ofp, &node);
1821   vat_json_free (&node);
1822
1823   vam->retval = ntohl (mp->retval);
1824   vam->result_ready = 1;
1825 }
1826
1827 static void
1828 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   i32 retval = ntohl (mp->retval);
1832
1833   if (vam->async_mode)
1834     {
1835       vam->async_errors += (retval < 0);
1836     }
1837   else
1838     {
1839       vam->retval = retval;
1840       vam->result_ready = 1;
1841     }
1842 }
1843
1844 static void vl_api_bond_delete_reply_t_handler_json
1845   (vl_api_bond_delete_reply_t * mp)
1846 {
1847   vat_main_t *vam = &vat_main;
1848   vat_json_node_t node;
1849
1850   vat_json_init_object (&node);
1851   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1852
1853   vat_json_print (vam->ofp, &node);
1854   vat_json_free (&node);
1855
1856   vam->retval = ntohl (mp->retval);
1857   vam->result_ready = 1;
1858 }
1859
1860 static void
1861 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1862 {
1863   vat_main_t *vam = &vat_main;
1864   i32 retval = ntohl (mp->retval);
1865
1866   if (vam->async_mode)
1867     {
1868       vam->async_errors += (retval < 0);
1869     }
1870   else
1871     {
1872       vam->retval = retval;
1873       vam->result_ready = 1;
1874     }
1875 }
1876
1877 static void vl_api_bond_enslave_reply_t_handler_json
1878   (vl_api_bond_enslave_reply_t * mp)
1879 {
1880   vat_main_t *vam = &vat_main;
1881   vat_json_node_t node;
1882
1883   vat_json_init_object (&node);
1884   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1885
1886   vat_json_print (vam->ofp, &node);
1887   vat_json_free (&node);
1888
1889   vam->retval = ntohl (mp->retval);
1890   vam->result_ready = 1;
1891 }
1892
1893 static void
1894 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1895                                           mp)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   i32 retval = ntohl (mp->retval);
1899
1900   if (vam->async_mode)
1901     {
1902       vam->async_errors += (retval < 0);
1903     }
1904   else
1905     {
1906       vam->retval = retval;
1907       vam->result_ready = 1;
1908     }
1909 }
1910
1911 static void vl_api_bond_detach_slave_reply_t_handler_json
1912   (vl_api_bond_detach_slave_reply_t * mp)
1913 {
1914   vat_main_t *vam = &vat_main;
1915   vat_json_node_t node;
1916
1917   vat_json_init_object (&node);
1918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1919
1920   vat_json_print (vam->ofp, &node);
1921   vat_json_free (&node);
1922
1923   vam->retval = ntohl (mp->retval);
1924   vam->result_ready = 1;
1925 }
1926
1927 static void vl_api_sw_interface_bond_details_t_handler
1928   (vl_api_sw_interface_bond_details_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931
1932   print (vam->ofp,
1933          "%-16s %-12d %-12U %-13U %-14u %-14u",
1934          mp->interface_name, ntohl (mp->sw_if_index),
1935          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1936          ntohl (mp->active_slaves), ntohl (mp->slaves));
1937 }
1938
1939 static void vl_api_sw_interface_bond_details_t_handler_json
1940   (vl_api_sw_interface_bond_details_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   vat_json_node_t *node = NULL;
1944
1945   if (VAT_JSON_ARRAY != vam->json_tree.type)
1946     {
1947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1948       vat_json_init_array (&vam->json_tree);
1949     }
1950   node = vat_json_array_add (&vam->json_tree);
1951
1952   vat_json_init_object (node);
1953   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1954   vat_json_object_add_string_copy (node, "interface_name",
1955                                    mp->interface_name);
1956   vat_json_object_add_uint (node, "mode", mp->mode);
1957   vat_json_object_add_uint (node, "load_balance", mp->lb);
1958   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1959   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1960 }
1961
1962 static int
1963 api_sw_interface_bond_dump (vat_main_t * vam)
1964 {
1965   vl_api_sw_interface_bond_dump_t *mp;
1966   vl_api_control_ping_t *mp_ping;
1967   int ret;
1968
1969   print (vam->ofp,
1970          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1971          "interface name", "sw_if_index", "mode", "load balance",
1972          "active slaves", "slaves");
1973
1974   /* Get list of bond interfaces */
1975   M (SW_INTERFACE_BOND_DUMP, mp);
1976   S (mp);
1977
1978   /* Use a control ping for synchronization */
1979   MPING (CONTROL_PING, mp_ping);
1980   S (mp_ping);
1981
1982   W (ret);
1983   return ret;
1984 }
1985
1986 static void vl_api_sw_interface_slave_details_t_handler
1987   (vl_api_sw_interface_slave_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990
1991   print (vam->ofp,
1992          "%-25s %-12d %-12d %d", mp->interface_name,
1993          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1994 }
1995
1996 static void vl_api_sw_interface_slave_details_t_handler_json
1997   (vl_api_sw_interface_slave_details_t * mp)
1998 {
1999   vat_main_t *vam = &vat_main;
2000   vat_json_node_t *node = NULL;
2001
2002   if (VAT_JSON_ARRAY != vam->json_tree.type)
2003     {
2004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2005       vat_json_init_array (&vam->json_tree);
2006     }
2007   node = vat_json_array_add (&vam->json_tree);
2008
2009   vat_json_init_object (node);
2010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2011   vat_json_object_add_string_copy (node, "interface_name",
2012                                    mp->interface_name);
2013   vat_json_object_add_uint (node, "passive", mp->is_passive);
2014   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2015 }
2016
2017 static int
2018 api_sw_interface_slave_dump (vat_main_t * vam)
2019 {
2020   unformat_input_t *i = vam->input;
2021   vl_api_sw_interface_slave_dump_t *mp;
2022   vl_api_control_ping_t *mp_ping;
2023   u32 sw_if_index = ~0;
2024   u8 sw_if_index_set = 0;
2025   int ret;
2026
2027   /* Parse args required to build the message */
2028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2029     {
2030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2031         sw_if_index_set = 1;
2032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2033         sw_if_index_set = 1;
2034       else
2035         break;
2036     }
2037
2038   if (sw_if_index_set == 0)
2039     {
2040       errmsg ("missing vpp interface name. ");
2041       return -99;
2042     }
2043
2044   print (vam->ofp,
2045          "\n%-25s %-12s %-12s %s",
2046          "slave interface name", "sw_if_index", "passive", "long_timeout");
2047
2048   /* Get list of bond interfaces */
2049   M (SW_INTERFACE_SLAVE_DUMP, mp);
2050   mp->sw_if_index = ntohl (sw_if_index);
2051   S (mp);
2052
2053   /* Use a control ping for synchronization */
2054   MPING (CONTROL_PING, mp_ping);
2055   S (mp_ping);
2056
2057   W (ret);
2058   return ret;
2059 }
2060
2061 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2062   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   i32 retval = ntohl (mp->retval);
2066   if (vam->async_mode)
2067     {
2068       vam->async_errors += (retval < 0);
2069     }
2070   else
2071     {
2072       vam->retval = retval;
2073       vam->result_ready = 1;
2074     }
2075 }
2076
2077 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2078   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2079 {
2080   vat_main_t *vam = &vat_main;
2081   vat_json_node_t node;
2082
2083   vat_json_init_object (&node);
2084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2085   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2086                             ntohl (mp->sw_if_index));
2087
2088   vat_json_print (vam->ofp, &node);
2089   vat_json_free (&node);
2090
2091   vam->retval = ntohl (mp->retval);
2092   vam->result_ready = 1;
2093 }
2094
2095 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2096   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2097 {
2098   vat_main_t *vam = &vat_main;
2099   i32 retval = ntohl (mp->retval);
2100   if (vam->async_mode)
2101     {
2102       vam->async_errors += (retval < 0);
2103     }
2104   else
2105     {
2106       vam->retval = retval;
2107       vam->sw_if_index = ntohl (mp->sw_if_index);
2108       vam->result_ready = 1;
2109     }
2110 }
2111
2112 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2113   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2114 {
2115   vat_main_t *vam = &vat_main;
2116   vat_json_node_t node;
2117
2118   vat_json_init_object (&node);
2119   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2120   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2121
2122   vat_json_print (vam->ofp, &node);
2123   vat_json_free (&node);
2124
2125   vam->retval = ntohl (mp->retval);
2126   vam->result_ready = 1;
2127 }
2128
2129 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2130   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2131 {
2132   vat_main_t *vam = &vat_main;
2133   i32 retval = ntohl (mp->retval);
2134   if (vam->async_mode)
2135     {
2136       vam->async_errors += (retval < 0);
2137     }
2138   else
2139     {
2140       vam->retval = retval;
2141       vam->result_ready = 1;
2142     }
2143 }
2144
2145 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2146   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2147 {
2148   vat_main_t *vam = &vat_main;
2149   vat_json_node_t node;
2150
2151   vat_json_init_object (&node);
2152   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2153   vat_json_object_add_uint (&node, "fwd_entry_index",
2154                             clib_net_to_host_u32 (mp->fwd_entry_index));
2155
2156   vat_json_print (vam->ofp, &node);
2157   vat_json_free (&node);
2158
2159   vam->retval = ntohl (mp->retval);
2160   vam->result_ready = 1;
2161 }
2162
2163 u8 *
2164 format_lisp_transport_protocol (u8 * s, va_list * args)
2165 {
2166   u32 proto = va_arg (*args, u32);
2167
2168   switch (proto)
2169     {
2170     case 1:
2171       return format (s, "udp");
2172     case 2:
2173       return format (s, "api");
2174     default:
2175       return 0;
2176     }
2177   return 0;
2178 }
2179
2180 static void vl_api_one_get_transport_protocol_reply_t_handler
2181   (vl_api_one_get_transport_protocol_reply_t * mp)
2182 {
2183   vat_main_t *vam = &vat_main;
2184   i32 retval = ntohl (mp->retval);
2185   if (vam->async_mode)
2186     {
2187       vam->async_errors += (retval < 0);
2188     }
2189   else
2190     {
2191       u32 proto = mp->protocol;
2192       print (vam->ofp, "Transport protocol: %U",
2193              format_lisp_transport_protocol, proto);
2194       vam->retval = retval;
2195       vam->result_ready = 1;
2196     }
2197 }
2198
2199 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2200   (vl_api_one_get_transport_protocol_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   vat_json_node_t node;
2204   u8 *s;
2205
2206   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2207   vec_add1 (s, 0);
2208
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2212
2213   vec_free (s);
2214   vat_json_print (vam->ofp, &node);
2215   vat_json_free (&node);
2216
2217   vam->retval = ntohl (mp->retval);
2218   vam->result_ready = 1;
2219 }
2220
2221 static void vl_api_one_add_del_locator_set_reply_t_handler
2222   (vl_api_one_add_del_locator_set_reply_t * mp)
2223 {
2224   vat_main_t *vam = &vat_main;
2225   i32 retval = ntohl (mp->retval);
2226   if (vam->async_mode)
2227     {
2228       vam->async_errors += (retval < 0);
2229     }
2230   else
2231     {
2232       vam->retval = retval;
2233       vam->result_ready = 1;
2234     }
2235 }
2236
2237 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2238   (vl_api_one_add_del_locator_set_reply_t * mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t node;
2242
2243   vat_json_init_object (&node);
2244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2245   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2246
2247   vat_json_print (vam->ofp, &node);
2248   vat_json_free (&node);
2249
2250   vam->retval = ntohl (mp->retval);
2251   vam->result_ready = 1;
2252 }
2253
2254 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2255   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   i32 retval = ntohl (mp->retval);
2259   if (vam->async_mode)
2260     {
2261       vam->async_errors += (retval < 0);
2262     }
2263   else
2264     {
2265       vam->retval = retval;
2266       vam->sw_if_index = ntohl (mp->sw_if_index);
2267       vam->result_ready = 1;
2268     }
2269   vam->regenerate_interface_table = 1;
2270 }
2271
2272 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2273   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2274 {
2275   vat_main_t *vam = &vat_main;
2276   vat_json_node_t node;
2277
2278   vat_json_init_object (&node);
2279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2281
2282   vat_json_print (vam->ofp, &node);
2283   vat_json_free (&node);
2284
2285   vam->retval = ntohl (mp->retval);
2286   vam->result_ready = 1;
2287 }
2288
2289 static void vl_api_vxlan_offload_rx_reply_t_handler
2290   (vl_api_vxlan_offload_rx_reply_t * mp)
2291 {
2292   vat_main_t *vam = &vat_main;
2293   i32 retval = ntohl (mp->retval);
2294   if (vam->async_mode)
2295     {
2296       vam->async_errors += (retval < 0);
2297     }
2298   else
2299     {
2300       vam->retval = retval;
2301       vam->result_ready = 1;
2302     }
2303 }
2304
2305 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2306   (vl_api_vxlan_offload_rx_reply_t * mp)
2307 {
2308   vat_main_t *vam = &vat_main;
2309   vat_json_node_t node;
2310
2311   vat_json_init_object (&node);
2312   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2313
2314   vat_json_print (vam->ofp, &node);
2315   vat_json_free (&node);
2316
2317   vam->retval = ntohl (mp->retval);
2318   vam->result_ready = 1;
2319 }
2320
2321 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2322   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   i32 retval = ntohl (mp->retval);
2326   if (vam->async_mode)
2327     {
2328       vam->async_errors += (retval < 0);
2329     }
2330   else
2331     {
2332       vam->retval = retval;
2333       vam->sw_if_index = ntohl (mp->sw_if_index);
2334       vam->result_ready = 1;
2335     }
2336 }
2337
2338 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2339   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2340 {
2341   vat_main_t *vam = &vat_main;
2342   vat_json_node_t node;
2343
2344   vat_json_init_object (&node);
2345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2346   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2347
2348   vat_json_print (vam->ofp, &node);
2349   vat_json_free (&node);
2350
2351   vam->retval = ntohl (mp->retval);
2352   vam->result_ready = 1;
2353 }
2354
2355 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2356   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   i32 retval = ntohl (mp->retval);
2360   if (vam->async_mode)
2361     {
2362       vam->async_errors += (retval < 0);
2363     }
2364   else
2365     {
2366       vam->retval = retval;
2367       vam->sw_if_index = ntohl (mp->sw_if_index);
2368       vam->result_ready = 1;
2369     }
2370   vam->regenerate_interface_table = 1;
2371 }
2372
2373 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2374   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   vat_json_node_t node;
2378
2379   vat_json_init_object (&node);
2380   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2381   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2382
2383   vat_json_print (vam->ofp, &node);
2384   vat_json_free (&node);
2385
2386   vam->retval = ntohl (mp->retval);
2387   vam->result_ready = 1;
2388 }
2389
2390 static void vl_api_gre_add_del_tunnel_reply_t_handler
2391   (vl_api_gre_add_del_tunnel_reply_t * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   i32 retval = ntohl (mp->retval);
2395   if (vam->async_mode)
2396     {
2397       vam->async_errors += (retval < 0);
2398     }
2399   else
2400     {
2401       vam->retval = retval;
2402       vam->sw_if_index = ntohl (mp->sw_if_index);
2403       vam->result_ready = 1;
2404     }
2405 }
2406
2407 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2408   (vl_api_gre_add_del_tunnel_reply_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   vat_json_node_t node;
2412
2413   vat_json_init_object (&node);
2414   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2415   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2416
2417   vat_json_print (vam->ofp, &node);
2418   vat_json_free (&node);
2419
2420   vam->retval = ntohl (mp->retval);
2421   vam->result_ready = 1;
2422 }
2423
2424 static void vl_api_create_vhost_user_if_reply_t_handler
2425   (vl_api_create_vhost_user_if_reply_t * mp)
2426 {
2427   vat_main_t *vam = &vat_main;
2428   i32 retval = ntohl (mp->retval);
2429   if (vam->async_mode)
2430     {
2431       vam->async_errors += (retval < 0);
2432     }
2433   else
2434     {
2435       vam->retval = retval;
2436       vam->sw_if_index = ntohl (mp->sw_if_index);
2437       vam->result_ready = 1;
2438     }
2439   vam->regenerate_interface_table = 1;
2440 }
2441
2442 static void vl_api_create_vhost_user_if_reply_t_handler_json
2443   (vl_api_create_vhost_user_if_reply_t * mp)
2444 {
2445   vat_main_t *vam = &vat_main;
2446   vat_json_node_t node;
2447
2448   vat_json_init_object (&node);
2449   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2450   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2451
2452   vat_json_print (vam->ofp, &node);
2453   vat_json_free (&node);
2454
2455   vam->retval = ntohl (mp->retval);
2456   vam->result_ready = 1;
2457 }
2458
2459 static void vl_api_dns_resolve_name_reply_t_handler
2460   (vl_api_dns_resolve_name_reply_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   i32 retval = ntohl (mp->retval);
2464   if (vam->async_mode)
2465     {
2466       vam->async_errors += (retval < 0);
2467     }
2468   else
2469     {
2470       vam->retval = retval;
2471       vam->result_ready = 1;
2472
2473       if (retval == 0)
2474         {
2475           if (mp->ip4_set)
2476             clib_warning ("ip4 address %U", format_ip4_address,
2477                           (ip4_address_t *) mp->ip4_address);
2478           if (mp->ip6_set)
2479             clib_warning ("ip6 address %U", format_ip6_address,
2480                           (ip6_address_t *) mp->ip6_address);
2481         }
2482       else
2483         clib_warning ("retval %d", retval);
2484     }
2485 }
2486
2487 static void vl_api_dns_resolve_name_reply_t_handler_json
2488   (vl_api_dns_resolve_name_reply_t * mp)
2489 {
2490   clib_warning ("not implemented");
2491 }
2492
2493 static void vl_api_dns_resolve_ip_reply_t_handler
2494   (vl_api_dns_resolve_ip_reply_t * mp)
2495 {
2496   vat_main_t *vam = &vat_main;
2497   i32 retval = ntohl (mp->retval);
2498   if (vam->async_mode)
2499     {
2500       vam->async_errors += (retval < 0);
2501     }
2502   else
2503     {
2504       vam->retval = retval;
2505       vam->result_ready = 1;
2506
2507       if (retval == 0)
2508         {
2509           clib_warning ("canonical name %s", mp->name);
2510         }
2511       else
2512         clib_warning ("retval %d", retval);
2513     }
2514 }
2515
2516 static void vl_api_dns_resolve_ip_reply_t_handler_json
2517   (vl_api_dns_resolve_ip_reply_t * mp)
2518 {
2519   clib_warning ("not implemented");
2520 }
2521
2522
2523 static void vl_api_ip_address_details_t_handler
2524   (vl_api_ip_address_details_t * mp)
2525 {
2526   vat_main_t *vam = &vat_main;
2527   static ip_address_details_t empty_ip_address_details = { {0} };
2528   ip_address_details_t *address = NULL;
2529   ip_details_t *current_ip_details = NULL;
2530   ip_details_t *details = NULL;
2531
2532   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2533
2534   if (!details || vam->current_sw_if_index >= vec_len (details)
2535       || !details[vam->current_sw_if_index].present)
2536     {
2537       errmsg ("ip address details arrived but not stored");
2538       errmsg ("ip_dump should be called first");
2539       return;
2540     }
2541
2542   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2543
2544 #define addresses (current_ip_details->addr)
2545
2546   vec_validate_init_empty (addresses, vec_len (addresses),
2547                            empty_ip_address_details);
2548
2549   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2550
2551   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2552   address->prefix_length = mp->prefix_length;
2553 #undef addresses
2554 }
2555
2556 static void vl_api_ip_address_details_t_handler_json
2557   (vl_api_ip_address_details_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560   vat_json_node_t *node = NULL;
2561   struct in6_addr ip6;
2562   struct in_addr ip4;
2563
2564   if (VAT_JSON_ARRAY != vam->json_tree.type)
2565     {
2566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2567       vat_json_init_array (&vam->json_tree);
2568     }
2569   node = vat_json_array_add (&vam->json_tree);
2570
2571   vat_json_init_object (node);
2572   if (vam->is_ipv6)
2573     {
2574       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "ip", ip6);
2576     }
2577   else
2578     {
2579       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2580       vat_json_object_add_ip4 (node, "ip", ip4);
2581     }
2582   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2583 }
2584
2585 static void
2586 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   static ip_details_t empty_ip_details = { 0 };
2590   ip_details_t *ip = NULL;
2591   u32 sw_if_index = ~0;
2592
2593   sw_if_index = ntohl (mp->sw_if_index);
2594
2595   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2596                            sw_if_index, empty_ip_details);
2597
2598   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2599                          sw_if_index);
2600
2601   ip->present = 1;
2602 }
2603
2604 static void
2605 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2606 {
2607   vat_main_t *vam = &vat_main;
2608
2609   if (VAT_JSON_ARRAY != vam->json_tree.type)
2610     {
2611       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2612       vat_json_init_array (&vam->json_tree);
2613     }
2614   vat_json_array_add_uint (&vam->json_tree,
2615                            clib_net_to_host_u32 (mp->sw_if_index));
2616 }
2617
2618 static void
2619 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2620 {
2621   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2622           "router_addr %U host_mac %U",
2623           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2624           mp->lease.hostname,
2625           format_ip4_address, &mp->lease.host_address,
2626           format_ip4_address, &mp->lease.router_address,
2627           format_ethernet_address, mp->lease.host_mac);
2628 }
2629
2630 static void vl_api_dhcp_compl_event_t_handler_json
2631   (vl_api_dhcp_compl_event_t * mp)
2632 {
2633   /* JSON output not supported */
2634 }
2635
2636 static void
2637 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2638                               u32 counter)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   static u64 default_counter = 0;
2642
2643   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2644                            NULL);
2645   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2646                            sw_if_index, default_counter);
2647   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2648 }
2649
2650 static void
2651 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2652                                 interface_counter_t counter)
2653 {
2654   vat_main_t *vam = &vat_main;
2655   static interface_counter_t default_counter = { 0, };
2656
2657   vec_validate_init_empty (vam->combined_interface_counters,
2658                            vnet_counter_type, NULL);
2659   vec_validate_init_empty (vam->combined_interface_counters
2660                            [vnet_counter_type], sw_if_index, default_counter);
2661   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2662 }
2663
2664 static void vl_api_vnet_interface_simple_counters_t_handler
2665   (vl_api_vnet_interface_simple_counters_t * mp)
2666 {
2667   /* not supported */
2668 }
2669
2670 static void vl_api_vnet_interface_combined_counters_t_handler
2671   (vl_api_vnet_interface_combined_counters_t * mp)
2672 {
2673   /* not supported */
2674 }
2675
2676 static void vl_api_vnet_interface_simple_counters_t_handler_json
2677   (vl_api_vnet_interface_simple_counters_t * mp)
2678 {
2679   u64 *v_packets;
2680   u64 packets;
2681   u32 count;
2682   u32 first_sw_if_index;
2683   int i;
2684
2685   count = ntohl (mp->count);
2686   first_sw_if_index = ntohl (mp->first_sw_if_index);
2687
2688   v_packets = (u64 *) & mp->data;
2689   for (i = 0; i < count; i++)
2690     {
2691       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2692       set_simple_interface_counter (mp->vnet_counter_type,
2693                                     first_sw_if_index + i, packets);
2694       v_packets++;
2695     }
2696 }
2697
2698 static void vl_api_vnet_interface_combined_counters_t_handler_json
2699   (vl_api_vnet_interface_combined_counters_t * mp)
2700 {
2701   interface_counter_t counter;
2702   vlib_counter_t *v;
2703   u32 first_sw_if_index;
2704   int i;
2705   u32 count;
2706
2707   count = ntohl (mp->count);
2708   first_sw_if_index = ntohl (mp->first_sw_if_index);
2709
2710   v = (vlib_counter_t *) & mp->data;
2711   for (i = 0; i < count; i++)
2712     {
2713       counter.packets =
2714         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2715       counter.bytes =
2716         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2717       set_combined_interface_counter (mp->vnet_counter_type,
2718                                       first_sw_if_index + i, counter);
2719       v++;
2720     }
2721 }
2722
2723 static u32
2724 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2725 {
2726   vat_main_t *vam = &vat_main;
2727   u32 i;
2728
2729   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2730     {
2731       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2732         {
2733           return i;
2734         }
2735     }
2736   return ~0;
2737 }
2738
2739 static u32
2740 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2741 {
2742   vat_main_t *vam = &vat_main;
2743   u32 i;
2744
2745   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2746     {
2747       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2748         {
2749           return i;
2750         }
2751     }
2752   return ~0;
2753 }
2754
2755 static void vl_api_vnet_ip4_fib_counters_t_handler
2756   (vl_api_vnet_ip4_fib_counters_t * mp)
2757 {
2758   /* not supported */
2759 }
2760
2761 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2762   (vl_api_vnet_ip4_fib_counters_t * mp)
2763 {
2764   vat_main_t *vam = &vat_main;
2765   vl_api_ip4_fib_counter_t *v;
2766   ip4_fib_counter_t *counter;
2767   struct in_addr ip4;
2768   u32 vrf_id;
2769   u32 vrf_index;
2770   u32 count;
2771   int i;
2772
2773   vrf_id = ntohl (mp->vrf_id);
2774   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2775   if (~0 == vrf_index)
2776     {
2777       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2778       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2779       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2780       vec_validate (vam->ip4_fib_counters, vrf_index);
2781       vam->ip4_fib_counters[vrf_index] = NULL;
2782     }
2783
2784   vec_free (vam->ip4_fib_counters[vrf_index]);
2785   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2786   count = ntohl (mp->count);
2787   for (i = 0; i < count; i++)
2788     {
2789       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2790       counter = &vam->ip4_fib_counters[vrf_index][i];
2791       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2792       counter->address = ip4;
2793       counter->address_length = v->address_length;
2794       counter->packets = clib_net_to_host_u64 (v->packets);
2795       counter->bytes = clib_net_to_host_u64 (v->bytes);
2796       v++;
2797     }
2798 }
2799
2800 static void vl_api_vnet_ip4_nbr_counters_t_handler
2801   (vl_api_vnet_ip4_nbr_counters_t * mp)
2802 {
2803   /* not supported */
2804 }
2805
2806 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2807   (vl_api_vnet_ip4_nbr_counters_t * mp)
2808 {
2809   vat_main_t *vam = &vat_main;
2810   vl_api_ip4_nbr_counter_t *v;
2811   ip4_nbr_counter_t *counter;
2812   u32 sw_if_index;
2813   u32 count;
2814   int i;
2815
2816   sw_if_index = ntohl (mp->sw_if_index);
2817   count = ntohl (mp->count);
2818   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2819
2820   if (mp->begin)
2821     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2822
2823   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2824   for (i = 0; i < count; i++)
2825     {
2826       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2827       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2828       counter->address.s_addr = v->address;
2829       counter->packets = clib_net_to_host_u64 (v->packets);
2830       counter->bytes = clib_net_to_host_u64 (v->bytes);
2831       counter->linkt = v->link_type;
2832       v++;
2833     }
2834 }
2835
2836 static void vl_api_vnet_ip6_fib_counters_t_handler
2837   (vl_api_vnet_ip6_fib_counters_t * mp)
2838 {
2839   /* not supported */
2840 }
2841
2842 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2843   (vl_api_vnet_ip6_fib_counters_t * mp)
2844 {
2845   vat_main_t *vam = &vat_main;
2846   vl_api_ip6_fib_counter_t *v;
2847   ip6_fib_counter_t *counter;
2848   struct in6_addr ip6;
2849   u32 vrf_id;
2850   u32 vrf_index;
2851   u32 count;
2852   int i;
2853
2854   vrf_id = ntohl (mp->vrf_id);
2855   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2856   if (~0 == vrf_index)
2857     {
2858       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2859       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2860       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2861       vec_validate (vam->ip6_fib_counters, vrf_index);
2862       vam->ip6_fib_counters[vrf_index] = NULL;
2863     }
2864
2865   vec_free (vam->ip6_fib_counters[vrf_index]);
2866   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2867   count = ntohl (mp->count);
2868   for (i = 0; i < count; i++)
2869     {
2870       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2871       counter = &vam->ip6_fib_counters[vrf_index][i];
2872       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2873       counter->address = ip6;
2874       counter->address_length = v->address_length;
2875       counter->packets = clib_net_to_host_u64 (v->packets);
2876       counter->bytes = clib_net_to_host_u64 (v->bytes);
2877       v++;
2878     }
2879 }
2880
2881 static void vl_api_vnet_ip6_nbr_counters_t_handler
2882   (vl_api_vnet_ip6_nbr_counters_t * mp)
2883 {
2884   /* not supported */
2885 }
2886
2887 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2888   (vl_api_vnet_ip6_nbr_counters_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vl_api_ip6_nbr_counter_t *v;
2892   ip6_nbr_counter_t *counter;
2893   struct in6_addr ip6;
2894   u32 sw_if_index;
2895   u32 count;
2896   int i;
2897
2898   sw_if_index = ntohl (mp->sw_if_index);
2899   count = ntohl (mp->count);
2900   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2901
2902   if (mp->begin)
2903     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2904
2905   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2906   for (i = 0; i < count; i++)
2907     {
2908       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2909       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2910       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2911       counter->address = ip6;
2912       counter->packets = clib_net_to_host_u64 (v->packets);
2913       counter->bytes = clib_net_to_host_u64 (v->bytes);
2914       v++;
2915     }
2916 }
2917
2918 static void vl_api_get_first_msg_id_reply_t_handler
2919   (vl_api_get_first_msg_id_reply_t * mp)
2920 {
2921   vat_main_t *vam = &vat_main;
2922   i32 retval = ntohl (mp->retval);
2923
2924   if (vam->async_mode)
2925     {
2926       vam->async_errors += (retval < 0);
2927     }
2928   else
2929     {
2930       vam->retval = retval;
2931       vam->result_ready = 1;
2932     }
2933   if (retval >= 0)
2934     {
2935       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2936     }
2937 }
2938
2939 static void vl_api_get_first_msg_id_reply_t_handler_json
2940   (vl_api_get_first_msg_id_reply_t * mp)
2941 {
2942   vat_main_t *vam = &vat_main;
2943   vat_json_node_t node;
2944
2945   vat_json_init_object (&node);
2946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2947   vat_json_object_add_uint (&node, "first_msg_id",
2948                             (uint) ntohs (mp->first_msg_id));
2949
2950   vat_json_print (vam->ofp, &node);
2951   vat_json_free (&node);
2952
2953   vam->retval = ntohl (mp->retval);
2954   vam->result_ready = 1;
2955 }
2956
2957 static void vl_api_get_node_graph_reply_t_handler
2958   (vl_api_get_node_graph_reply_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   api_main_t *am = &api_main;
2962   i32 retval = ntohl (mp->retval);
2963   u8 *pvt_copy, *reply;
2964   void *oldheap;
2965   vlib_node_t *node;
2966   int i;
2967
2968   if (vam->async_mode)
2969     {
2970       vam->async_errors += (retval < 0);
2971     }
2972   else
2973     {
2974       vam->retval = retval;
2975       vam->result_ready = 1;
2976     }
2977
2978   /* "Should never happen..." */
2979   if (retval != 0)
2980     return;
2981
2982   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2983   pvt_copy = vec_dup (reply);
2984
2985   /* Toss the shared-memory original... */
2986   pthread_mutex_lock (&am->vlib_rp->mutex);
2987   oldheap = svm_push_data_heap (am->vlib_rp);
2988
2989   vec_free (reply);
2990
2991   svm_pop_heap (oldheap);
2992   pthread_mutex_unlock (&am->vlib_rp->mutex);
2993
2994   if (vam->graph_nodes)
2995     {
2996       hash_free (vam->graph_node_index_by_name);
2997
2998       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2999         {
3000           node = vam->graph_nodes[0][i];
3001           vec_free (node->name);
3002           vec_free (node->next_nodes);
3003           vec_free (node);
3004         }
3005       vec_free (vam->graph_nodes[0]);
3006       vec_free (vam->graph_nodes);
3007     }
3008
3009   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3010   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3011   vec_free (pvt_copy);
3012
3013   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3014     {
3015       node = vam->graph_nodes[0][i];
3016       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3017     }
3018 }
3019
3020 static void vl_api_get_node_graph_reply_t_handler_json
3021   (vl_api_get_node_graph_reply_t * mp)
3022 {
3023   vat_main_t *vam = &vat_main;
3024   api_main_t *am = &api_main;
3025   void *oldheap;
3026   vat_json_node_t node;
3027   u8 *reply;
3028
3029   /* $$$$ make this real? */
3030   vat_json_init_object (&node);
3031   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3032   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3033
3034   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3035
3036   /* Toss the shared-memory original... */
3037   pthread_mutex_lock (&am->vlib_rp->mutex);
3038   oldheap = svm_push_data_heap (am->vlib_rp);
3039
3040   vec_free (reply);
3041
3042   svm_pop_heap (oldheap);
3043   pthread_mutex_unlock (&am->vlib_rp->mutex);
3044
3045   vat_json_print (vam->ofp, &node);
3046   vat_json_free (&node);
3047
3048   vam->retval = ntohl (mp->retval);
3049   vam->result_ready = 1;
3050 }
3051
3052 static void
3053 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3054 {
3055   vat_main_t *vam = &vat_main;
3056   u8 *s = 0;
3057
3058   if (mp->local)
3059     {
3060       s = format (s, "%=16d%=16d%=16d",
3061                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3062     }
3063   else
3064     {
3065       s = format (s, "%=16U%=16d%=16d",
3066                   mp->is_ipv6 ? format_ip6_address :
3067                   format_ip4_address,
3068                   mp->ip_address, mp->priority, mp->weight);
3069     }
3070
3071   print (vam->ofp, "%v", s);
3072   vec_free (s);
3073 }
3074
3075 static void
3076 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3077 {
3078   vat_main_t *vam = &vat_main;
3079   vat_json_node_t *node = NULL;
3080   struct in6_addr ip6;
3081   struct in_addr ip4;
3082
3083   if (VAT_JSON_ARRAY != vam->json_tree.type)
3084     {
3085       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3086       vat_json_init_array (&vam->json_tree);
3087     }
3088   node = vat_json_array_add (&vam->json_tree);
3089   vat_json_init_object (node);
3090
3091   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3092   vat_json_object_add_uint (node, "priority", mp->priority);
3093   vat_json_object_add_uint (node, "weight", mp->weight);
3094
3095   if (mp->local)
3096     vat_json_object_add_uint (node, "sw_if_index",
3097                               clib_net_to_host_u32 (mp->sw_if_index));
3098   else
3099     {
3100       if (mp->is_ipv6)
3101         {
3102           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3103           vat_json_object_add_ip6 (node, "address", ip6);
3104         }
3105       else
3106         {
3107           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3108           vat_json_object_add_ip4 (node, "address", ip4);
3109         }
3110     }
3111 }
3112
3113 static void
3114 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3115                                           mp)
3116 {
3117   vat_main_t *vam = &vat_main;
3118   u8 *ls_name = 0;
3119
3120   ls_name = format (0, "%s", mp->ls_name);
3121
3122   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3123          ls_name);
3124   vec_free (ls_name);
3125 }
3126
3127 static void
3128   vl_api_one_locator_set_details_t_handler_json
3129   (vl_api_one_locator_set_details_t * mp)
3130 {
3131   vat_main_t *vam = &vat_main;
3132   vat_json_node_t *node = 0;
3133   u8 *ls_name = 0;
3134
3135   ls_name = format (0, "%s", mp->ls_name);
3136   vec_add1 (ls_name, 0);
3137
3138   if (VAT_JSON_ARRAY != vam->json_tree.type)
3139     {
3140       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3141       vat_json_init_array (&vam->json_tree);
3142     }
3143   node = vat_json_array_add (&vam->json_tree);
3144
3145   vat_json_init_object (node);
3146   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3147   vat_json_object_add_uint (node, "ls_index",
3148                             clib_net_to_host_u32 (mp->ls_index));
3149   vec_free (ls_name);
3150 }
3151
3152 typedef struct
3153 {
3154   u32 spi;
3155   u8 si;
3156 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3157
3158 uword
3159 unformat_nsh_address (unformat_input_t * input, va_list * args)
3160 {
3161   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3162   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3163 }
3164
3165 u8 *
3166 format_nsh_address_vat (u8 * s, va_list * args)
3167 {
3168   nsh_t *a = va_arg (*args, nsh_t *);
3169   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3170 }
3171
3172 static u8 *
3173 format_lisp_flat_eid (u8 * s, va_list * args)
3174 {
3175   u32 type = va_arg (*args, u32);
3176   u8 *eid = va_arg (*args, u8 *);
3177   u32 eid_len = va_arg (*args, u32);
3178
3179   switch (type)
3180     {
3181     case 0:
3182       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3183     case 1:
3184       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3185     case 2:
3186       return format (s, "%U", format_ethernet_address, eid);
3187     case 3:
3188       return format (s, "%U", format_nsh_address_vat, eid);
3189     }
3190   return 0;
3191 }
3192
3193 static u8 *
3194 format_lisp_eid_vat (u8 * s, va_list * args)
3195 {
3196   u32 type = va_arg (*args, u32);
3197   u8 *eid = va_arg (*args, u8 *);
3198   u32 eid_len = va_arg (*args, u32);
3199   u8 *seid = va_arg (*args, u8 *);
3200   u32 seid_len = va_arg (*args, u32);
3201   u32 is_src_dst = va_arg (*args, u32);
3202
3203   if (is_src_dst)
3204     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3205
3206   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3207
3208   return s;
3209 }
3210
3211 static void
3212 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215   u8 *s = 0, *eid = 0;
3216
3217   if (~0 == mp->locator_set_index)
3218     s = format (0, "action: %d", mp->action);
3219   else
3220     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3221
3222   eid = format (0, "%U", format_lisp_eid_vat,
3223                 mp->eid_type,
3224                 mp->eid,
3225                 mp->eid_prefix_len,
3226                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3227   vec_add1 (eid, 0);
3228
3229   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3230          clib_net_to_host_u32 (mp->vni),
3231          eid,
3232          mp->is_local ? "local" : "remote",
3233          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3234          clib_net_to_host_u16 (mp->key_id), mp->key);
3235
3236   vec_free (s);
3237   vec_free (eid);
3238 }
3239
3240 static void
3241 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3242                                              * mp)
3243 {
3244   vat_main_t *vam = &vat_main;
3245   vat_json_node_t *node = 0;
3246   u8 *eid = 0;
3247
3248   if (VAT_JSON_ARRAY != vam->json_tree.type)
3249     {
3250       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3251       vat_json_init_array (&vam->json_tree);
3252     }
3253   node = vat_json_array_add (&vam->json_tree);
3254
3255   vat_json_init_object (node);
3256   if (~0 == mp->locator_set_index)
3257     vat_json_object_add_uint (node, "action", mp->action);
3258   else
3259     vat_json_object_add_uint (node, "locator_set_index",
3260                               clib_net_to_host_u32 (mp->locator_set_index));
3261
3262   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3263   if (mp->eid_type == 3)
3264     {
3265       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3266       vat_json_init_object (nsh_json);
3267       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3268       vat_json_object_add_uint (nsh_json, "spi",
3269                                 clib_net_to_host_u32 (nsh->spi));
3270       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3271     }
3272   else
3273     {
3274       eid = format (0, "%U", format_lisp_eid_vat,
3275                     mp->eid_type,
3276                     mp->eid,
3277                     mp->eid_prefix_len,
3278                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3279       vec_add1 (eid, 0);
3280       vat_json_object_add_string_copy (node, "eid", eid);
3281       vec_free (eid);
3282     }
3283   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3284   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3285   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3286
3287   if (mp->key_id)
3288     {
3289       vat_json_object_add_uint (node, "key_id",
3290                                 clib_net_to_host_u16 (mp->key_id));
3291       vat_json_object_add_string_copy (node, "key", mp->key);
3292     }
3293 }
3294
3295 static void
3296 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   u8 *seid = 0, *deid = 0;
3300   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3301
3302   deid = format (0, "%U", format_lisp_eid_vat,
3303                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3304
3305   seid = format (0, "%U", format_lisp_eid_vat,
3306                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3307
3308   vec_add1 (deid, 0);
3309   vec_add1 (seid, 0);
3310
3311   if (mp->is_ip4)
3312     format_ip_address_fcn = format_ip4_address;
3313   else
3314     format_ip_address_fcn = format_ip6_address;
3315
3316
3317   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3318          clib_net_to_host_u32 (mp->vni),
3319          seid, deid,
3320          format_ip_address_fcn, mp->lloc,
3321          format_ip_address_fcn, mp->rloc,
3322          clib_net_to_host_u32 (mp->pkt_count),
3323          clib_net_to_host_u32 (mp->bytes));
3324
3325   vec_free (deid);
3326   vec_free (seid);
3327 }
3328
3329 static void
3330 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3331 {
3332   struct in6_addr ip6;
3333   struct in_addr ip4;
3334   vat_main_t *vam = &vat_main;
3335   vat_json_node_t *node = 0;
3336   u8 *deid = 0, *seid = 0;
3337
3338   if (VAT_JSON_ARRAY != vam->json_tree.type)
3339     {
3340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3341       vat_json_init_array (&vam->json_tree);
3342     }
3343   node = vat_json_array_add (&vam->json_tree);
3344
3345   vat_json_init_object (node);
3346   deid = format (0, "%U", format_lisp_eid_vat,
3347                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3348
3349   seid = format (0, "%U", format_lisp_eid_vat,
3350                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3351
3352   vec_add1 (deid, 0);
3353   vec_add1 (seid, 0);
3354
3355   vat_json_object_add_string_copy (node, "seid", seid);
3356   vat_json_object_add_string_copy (node, "deid", deid);
3357   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3358
3359   if (mp->is_ip4)
3360     {
3361       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3362       vat_json_object_add_ip4 (node, "lloc", ip4);
3363       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3364       vat_json_object_add_ip4 (node, "rloc", ip4);
3365     }
3366   else
3367     {
3368       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3369       vat_json_object_add_ip6 (node, "lloc", ip6);
3370       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3371       vat_json_object_add_ip6 (node, "rloc", ip6);
3372     }
3373   vat_json_object_add_uint (node, "pkt_count",
3374                             clib_net_to_host_u32 (mp->pkt_count));
3375   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3376
3377   vec_free (deid);
3378   vec_free (seid);
3379 }
3380
3381 static void
3382   vl_api_one_eid_table_map_details_t_handler
3383   (vl_api_one_eid_table_map_details_t * mp)
3384 {
3385   vat_main_t *vam = &vat_main;
3386
3387   u8 *line = format (0, "%=10d%=10d",
3388                      clib_net_to_host_u32 (mp->vni),
3389                      clib_net_to_host_u32 (mp->dp_table));
3390   print (vam->ofp, "%v", line);
3391   vec_free (line);
3392 }
3393
3394 static void
3395   vl_api_one_eid_table_map_details_t_handler_json
3396   (vl_api_one_eid_table_map_details_t * mp)
3397 {
3398   vat_main_t *vam = &vat_main;
3399   vat_json_node_t *node = NULL;
3400
3401   if (VAT_JSON_ARRAY != vam->json_tree.type)
3402     {
3403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3404       vat_json_init_array (&vam->json_tree);
3405     }
3406   node = vat_json_array_add (&vam->json_tree);
3407   vat_json_init_object (node);
3408   vat_json_object_add_uint (node, "dp_table",
3409                             clib_net_to_host_u32 (mp->dp_table));
3410   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3411 }
3412
3413 static void
3414   vl_api_one_eid_table_vni_details_t_handler
3415   (vl_api_one_eid_table_vni_details_t * mp)
3416 {
3417   vat_main_t *vam = &vat_main;
3418
3419   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3420   print (vam->ofp, "%v", line);
3421   vec_free (line);
3422 }
3423
3424 static void
3425   vl_api_one_eid_table_vni_details_t_handler_json
3426   (vl_api_one_eid_table_vni_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   vat_json_node_t *node = NULL;
3430
3431   if (VAT_JSON_ARRAY != vam->json_tree.type)
3432     {
3433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3434       vat_json_init_array (&vam->json_tree);
3435     }
3436   node = vat_json_array_add (&vam->json_tree);
3437   vat_json_init_object (node);
3438   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3439 }
3440
3441 static void
3442   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3443   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3444 {
3445   vat_main_t *vam = &vat_main;
3446   int retval = clib_net_to_host_u32 (mp->retval);
3447
3448   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3449   print (vam->ofp, "fallback threshold value: %d", mp->value);
3450
3451   vam->retval = retval;
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3457   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   vat_json_node_t _node, *node = &_node;
3461   int retval = clib_net_to_host_u32 (mp->retval);
3462
3463   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3464   vat_json_init_object (node);
3465   vat_json_object_add_uint (node, "value", mp->value);
3466
3467   vat_json_print (vam->ofp, node);
3468   vat_json_free (node);
3469
3470   vam->retval = retval;
3471   vam->result_ready = 1;
3472 }
3473
3474 static void
3475   vl_api_show_one_map_register_state_reply_t_handler
3476   (vl_api_show_one_map_register_state_reply_t * mp)
3477 {
3478   vat_main_t *vam = &vat_main;
3479   int retval = clib_net_to_host_u32 (mp->retval);
3480
3481   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3482
3483   vam->retval = retval;
3484   vam->result_ready = 1;
3485 }
3486
3487 static void
3488   vl_api_show_one_map_register_state_reply_t_handler_json
3489   (vl_api_show_one_map_register_state_reply_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492   vat_json_node_t _node, *node = &_node;
3493   int retval = clib_net_to_host_u32 (mp->retval);
3494
3495   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3496
3497   vat_json_init_object (node);
3498   vat_json_object_add_string_copy (node, "state", s);
3499
3500   vat_json_print (vam->ofp, node);
3501   vat_json_free (node);
3502
3503   vam->retval = retval;
3504   vam->result_ready = 1;
3505   vec_free (s);
3506 }
3507
3508 static void
3509   vl_api_show_one_rloc_probe_state_reply_t_handler
3510   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3511 {
3512   vat_main_t *vam = &vat_main;
3513   int retval = clib_net_to_host_u32 (mp->retval);
3514
3515   if (retval)
3516     goto end;
3517
3518   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3519 end:
3520   vam->retval = retval;
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3526   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t _node, *node = &_node;
3530   int retval = clib_net_to_host_u32 (mp->retval);
3531
3532   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3533   vat_json_init_object (node);
3534   vat_json_object_add_string_copy (node, "state", s);
3535
3536   vat_json_print (vam->ofp, node);
3537   vat_json_free (node);
3538
3539   vam->retval = retval;
3540   vam->result_ready = 1;
3541   vec_free (s);
3542 }
3543
3544 static void
3545   vl_api_show_one_stats_enable_disable_reply_t_handler
3546   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3547 {
3548   vat_main_t *vam = &vat_main;
3549   int retval = clib_net_to_host_u32 (mp->retval);
3550
3551   if (retval)
3552     goto end;
3553
3554   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3555 end:
3556   vam->retval = retval;
3557   vam->result_ready = 1;
3558 }
3559
3560 static void
3561   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3562   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3563 {
3564   vat_main_t *vam = &vat_main;
3565   vat_json_node_t _node, *node = &_node;
3566   int retval = clib_net_to_host_u32 (mp->retval);
3567
3568   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3569   vat_json_init_object (node);
3570   vat_json_object_add_string_copy (node, "state", s);
3571
3572   vat_json_print (vam->ofp, node);
3573   vat_json_free (node);
3574
3575   vam->retval = retval;
3576   vam->result_ready = 1;
3577   vec_free (s);
3578 }
3579
3580 static void
3581 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3582 {
3583   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3584   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3585   e->vni = clib_net_to_host_u32 (e->vni);
3586 }
3587
3588 static void
3589   gpe_fwd_entries_get_reply_t_net_to_host
3590   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3591 {
3592   u32 i;
3593
3594   mp->count = clib_net_to_host_u32 (mp->count);
3595   for (i = 0; i < mp->count; i++)
3596     {
3597       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3598     }
3599 }
3600
3601 static u8 *
3602 format_gpe_encap_mode (u8 * s, va_list * args)
3603 {
3604   u32 mode = va_arg (*args, u32);
3605
3606   switch (mode)
3607     {
3608     case 0:
3609       return format (s, "lisp");
3610     case 1:
3611       return format (s, "vxlan");
3612     }
3613   return 0;
3614 }
3615
3616 static void
3617   vl_api_gpe_get_encap_mode_reply_t_handler
3618   (vl_api_gpe_get_encap_mode_reply_t * mp)
3619 {
3620   vat_main_t *vam = &vat_main;
3621
3622   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3623   vam->retval = ntohl (mp->retval);
3624   vam->result_ready = 1;
3625 }
3626
3627 static void
3628   vl_api_gpe_get_encap_mode_reply_t_handler_json
3629   (vl_api_gpe_get_encap_mode_reply_t * mp)
3630 {
3631   vat_main_t *vam = &vat_main;
3632   vat_json_node_t node;
3633
3634   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3635   vec_add1 (encap_mode, 0);
3636
3637   vat_json_init_object (&node);
3638   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3639
3640   vec_free (encap_mode);
3641   vat_json_print (vam->ofp, &node);
3642   vat_json_free (&node);
3643
3644   vam->retval = ntohl (mp->retval);
3645   vam->result_ready = 1;
3646 }
3647
3648 static void
3649   vl_api_gpe_fwd_entry_path_details_t_handler
3650   (vl_api_gpe_fwd_entry_path_details_t * mp)
3651 {
3652   vat_main_t *vam = &vat_main;
3653   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3654
3655   if (mp->lcl_loc.is_ip4)
3656     format_ip_address_fcn = format_ip4_address;
3657   else
3658     format_ip_address_fcn = format_ip6_address;
3659
3660   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3661          format_ip_address_fcn, &mp->lcl_loc,
3662          format_ip_address_fcn, &mp->rmt_loc);
3663 }
3664
3665 static void
3666 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3667 {
3668   struct in6_addr ip6;
3669   struct in_addr ip4;
3670
3671   if (loc->is_ip4)
3672     {
3673       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3674       vat_json_object_add_ip4 (n, "address", ip4);
3675     }
3676   else
3677     {
3678       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3679       vat_json_object_add_ip6 (n, "address", ip6);
3680     }
3681   vat_json_object_add_uint (n, "weight", loc->weight);
3682 }
3683
3684 static void
3685   vl_api_gpe_fwd_entry_path_details_t_handler_json
3686   (vl_api_gpe_fwd_entry_path_details_t * mp)
3687 {
3688   vat_main_t *vam = &vat_main;
3689   vat_json_node_t *node = NULL;
3690   vat_json_node_t *loc_node;
3691
3692   if (VAT_JSON_ARRAY != vam->json_tree.type)
3693     {
3694       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3695       vat_json_init_array (&vam->json_tree);
3696     }
3697   node = vat_json_array_add (&vam->json_tree);
3698   vat_json_init_object (node);
3699
3700   loc_node = vat_json_object_add (node, "local_locator");
3701   vat_json_init_object (loc_node);
3702   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3703
3704   loc_node = vat_json_object_add (node, "remote_locator");
3705   vat_json_init_object (loc_node);
3706   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3707 }
3708
3709 static void
3710   vl_api_gpe_fwd_entries_get_reply_t_handler
3711   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3712 {
3713   vat_main_t *vam = &vat_main;
3714   u32 i;
3715   int retval = clib_net_to_host_u32 (mp->retval);
3716   vl_api_gpe_fwd_entry_t *e;
3717
3718   if (retval)
3719     goto end;
3720
3721   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3722
3723   for (i = 0; i < mp->count; i++)
3724     {
3725       e = &mp->entries[i];
3726       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3727              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3728              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3729     }
3730
3731 end:
3732   vam->retval = retval;
3733   vam->result_ready = 1;
3734 }
3735
3736 static void
3737   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3738   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3739 {
3740   u8 *s = 0;
3741   vat_main_t *vam = &vat_main;
3742   vat_json_node_t *e = 0, root;
3743   u32 i;
3744   int retval = clib_net_to_host_u32 (mp->retval);
3745   vl_api_gpe_fwd_entry_t *fwd;
3746
3747   if (retval)
3748     goto end;
3749
3750   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3751   vat_json_init_array (&root);
3752
3753   for (i = 0; i < mp->count; i++)
3754     {
3755       e = vat_json_array_add (&root);
3756       fwd = &mp->entries[i];
3757
3758       vat_json_init_object (e);
3759       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3760       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3761       vat_json_object_add_int (e, "vni", fwd->vni);
3762       vat_json_object_add_int (e, "action", fwd->action);
3763
3764       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3765                   fwd->leid_prefix_len);
3766       vec_add1 (s, 0);
3767       vat_json_object_add_string_copy (e, "leid", s);
3768       vec_free (s);
3769
3770       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3771                   fwd->reid_prefix_len);
3772       vec_add1 (s, 0);
3773       vat_json_object_add_string_copy (e, "reid", s);
3774       vec_free (s);
3775     }
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3787   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   u32 i, n;
3791   int retval = clib_net_to_host_u32 (mp->retval);
3792   vl_api_gpe_native_fwd_rpath_t *r;
3793
3794   if (retval)
3795     goto end;
3796
3797   n = clib_net_to_host_u32 (mp->count);
3798
3799   for (i = 0; i < n; i++)
3800     {
3801       r = &mp->entries[i];
3802       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3803              clib_net_to_host_u32 (r->fib_index),
3804              clib_net_to_host_u32 (r->nh_sw_if_index),
3805              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3806     }
3807
3808 end:
3809   vam->retval = retval;
3810   vam->result_ready = 1;
3811 }
3812
3813 static void
3814   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3815   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3816 {
3817   vat_main_t *vam = &vat_main;
3818   vat_json_node_t root, *e;
3819   u32 i, n;
3820   int retval = clib_net_to_host_u32 (mp->retval);
3821   vl_api_gpe_native_fwd_rpath_t *r;
3822   u8 *s;
3823
3824   if (retval)
3825     goto end;
3826
3827   n = clib_net_to_host_u32 (mp->count);
3828   vat_json_init_array (&root);
3829
3830   for (i = 0; i < n; i++)
3831     {
3832       e = vat_json_array_add (&root);
3833       vat_json_init_object (e);
3834       r = &mp->entries[i];
3835       s =
3836         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3837                 r->nh_addr);
3838       vec_add1 (s, 0);
3839       vat_json_object_add_string_copy (e, "ip4", s);
3840       vec_free (s);
3841
3842       vat_json_object_add_uint (e, "fib_index",
3843                                 clib_net_to_host_u32 (r->fib_index));
3844       vat_json_object_add_uint (e, "nh_sw_if_index",
3845                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3846     }
3847
3848   vat_json_print (vam->ofp, &root);
3849   vat_json_free (&root);
3850
3851 end:
3852   vam->retval = retval;
3853   vam->result_ready = 1;
3854 }
3855
3856 static void
3857   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3858   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3859 {
3860   vat_main_t *vam = &vat_main;
3861   u32 i, n;
3862   int retval = clib_net_to_host_u32 (mp->retval);
3863
3864   if (retval)
3865     goto end;
3866
3867   n = clib_net_to_host_u32 (mp->count);
3868
3869   for (i = 0; i < n; i++)
3870     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3871
3872 end:
3873   vam->retval = retval;
3874   vam->result_ready = 1;
3875 }
3876
3877 static void
3878   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3879   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3880 {
3881   vat_main_t *vam = &vat_main;
3882   vat_json_node_t root;
3883   u32 i, n;
3884   int retval = clib_net_to_host_u32 (mp->retval);
3885
3886   if (retval)
3887     goto end;
3888
3889   n = clib_net_to_host_u32 (mp->count);
3890   vat_json_init_array (&root);
3891
3892   for (i = 0; i < n; i++)
3893     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3894
3895   vat_json_print (vam->ofp, &root);
3896   vat_json_free (&root);
3897
3898 end:
3899   vam->retval = retval;
3900   vam->result_ready = 1;
3901 }
3902
3903 static void
3904   vl_api_one_ndp_entries_get_reply_t_handler
3905   (vl_api_one_ndp_entries_get_reply_t * mp)
3906 {
3907   vat_main_t *vam = &vat_main;
3908   u32 i, n;
3909   int retval = clib_net_to_host_u32 (mp->retval);
3910
3911   if (retval)
3912     goto end;
3913
3914   n = clib_net_to_host_u32 (mp->count);
3915
3916   for (i = 0; i < n; i++)
3917     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3918            format_ethernet_address, mp->entries[i].mac);
3919
3920 end:
3921   vam->retval = retval;
3922   vam->result_ready = 1;
3923 }
3924
3925 static void
3926   vl_api_one_ndp_entries_get_reply_t_handler_json
3927   (vl_api_one_ndp_entries_get_reply_t * mp)
3928 {
3929   u8 *s = 0;
3930   vat_main_t *vam = &vat_main;
3931   vat_json_node_t *e = 0, root;
3932   u32 i, n;
3933   int retval = clib_net_to_host_u32 (mp->retval);
3934   vl_api_one_ndp_entry_t *arp_entry;
3935
3936   if (retval)
3937     goto end;
3938
3939   n = clib_net_to_host_u32 (mp->count);
3940   vat_json_init_array (&root);
3941
3942   for (i = 0; i < n; i++)
3943     {
3944       e = vat_json_array_add (&root);
3945       arp_entry = &mp->entries[i];
3946
3947       vat_json_init_object (e);
3948       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3949       vec_add1 (s, 0);
3950
3951       vat_json_object_add_string_copy (e, "mac", s);
3952       vec_free (s);
3953
3954       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3955       vec_add1 (s, 0);
3956       vat_json_object_add_string_copy (e, "ip6", s);
3957       vec_free (s);
3958     }
3959
3960   vat_json_print (vam->ofp, &root);
3961   vat_json_free (&root);
3962
3963 end:
3964   vam->retval = retval;
3965   vam->result_ready = 1;
3966 }
3967
3968 static void
3969   vl_api_one_l2_arp_entries_get_reply_t_handler
3970   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   u32 i, n;
3974   int retval = clib_net_to_host_u32 (mp->retval);
3975
3976   if (retval)
3977     goto end;
3978
3979   n = clib_net_to_host_u32 (mp->count);
3980
3981   for (i = 0; i < n; i++)
3982     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3983            format_ethernet_address, mp->entries[i].mac);
3984
3985 end:
3986   vam->retval = retval;
3987   vam->result_ready = 1;
3988 }
3989
3990 static void
3991   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3992   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3993 {
3994   u8 *s = 0;
3995   vat_main_t *vam = &vat_main;
3996   vat_json_node_t *e = 0, root;
3997   u32 i, n;
3998   int retval = clib_net_to_host_u32 (mp->retval);
3999   vl_api_one_l2_arp_entry_t *arp_entry;
4000
4001   if (retval)
4002     goto end;
4003
4004   n = clib_net_to_host_u32 (mp->count);
4005   vat_json_init_array (&root);
4006
4007   for (i = 0; i < n; i++)
4008     {
4009       e = vat_json_array_add (&root);
4010       arp_entry = &mp->entries[i];
4011
4012       vat_json_init_object (e);
4013       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4014       vec_add1 (s, 0);
4015
4016       vat_json_object_add_string_copy (e, "mac", s);
4017       vec_free (s);
4018
4019       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4020       vec_add1 (s, 0);
4021       vat_json_object_add_string_copy (e, "ip4", s);
4022       vec_free (s);
4023     }
4024
4025   vat_json_print (vam->ofp, &root);
4026   vat_json_free (&root);
4027
4028 end:
4029   vam->retval = retval;
4030   vam->result_ready = 1;
4031 }
4032
4033 static void
4034 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4035 {
4036   vat_main_t *vam = &vat_main;
4037   u32 i, n;
4038   int retval = clib_net_to_host_u32 (mp->retval);
4039
4040   if (retval)
4041     goto end;
4042
4043   n = clib_net_to_host_u32 (mp->count);
4044
4045   for (i = 0; i < n; i++)
4046     {
4047       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4048     }
4049
4050 end:
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_one_ndp_bd_get_reply_t_handler_json
4057   (vl_api_one_ndp_bd_get_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   vat_json_node_t root;
4061   u32 i, n;
4062   int retval = clib_net_to_host_u32 (mp->retval);
4063
4064   if (retval)
4065     goto end;
4066
4067   n = clib_net_to_host_u32 (mp->count);
4068   vat_json_init_array (&root);
4069
4070   for (i = 0; i < n; i++)
4071     {
4072       vat_json_array_add_uint (&root,
4073                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4074     }
4075
4076   vat_json_print (vam->ofp, &root);
4077   vat_json_free (&root);
4078
4079 end:
4080   vam->retval = retval;
4081   vam->result_ready = 1;
4082 }
4083
4084 static void
4085   vl_api_one_l2_arp_bd_get_reply_t_handler
4086   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4087 {
4088   vat_main_t *vam = &vat_main;
4089   u32 i, n;
4090   int retval = clib_net_to_host_u32 (mp->retval);
4091
4092   if (retval)
4093     goto end;
4094
4095   n = clib_net_to_host_u32 (mp->count);
4096
4097   for (i = 0; i < n; i++)
4098     {
4099       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4100     }
4101
4102 end:
4103   vam->retval = retval;
4104   vam->result_ready = 1;
4105 }
4106
4107 static void
4108   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4109   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4110 {
4111   vat_main_t *vam = &vat_main;
4112   vat_json_node_t root;
4113   u32 i, n;
4114   int retval = clib_net_to_host_u32 (mp->retval);
4115
4116   if (retval)
4117     goto end;
4118
4119   n = clib_net_to_host_u32 (mp->count);
4120   vat_json_init_array (&root);
4121
4122   for (i = 0; i < n; i++)
4123     {
4124       vat_json_array_add_uint (&root,
4125                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4126     }
4127
4128   vat_json_print (vam->ofp, &root);
4129   vat_json_free (&root);
4130
4131 end:
4132   vam->retval = retval;
4133   vam->result_ready = 1;
4134 }
4135
4136 static void
4137   vl_api_one_adjacencies_get_reply_t_handler
4138   (vl_api_one_adjacencies_get_reply_t * mp)
4139 {
4140   vat_main_t *vam = &vat_main;
4141   u32 i, n;
4142   int retval = clib_net_to_host_u32 (mp->retval);
4143   vl_api_one_adjacency_t *a;
4144
4145   if (retval)
4146     goto end;
4147
4148   n = clib_net_to_host_u32 (mp->count);
4149
4150   for (i = 0; i < n; i++)
4151     {
4152       a = &mp->adjacencies[i];
4153       print (vam->ofp, "%U %40U",
4154              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4155              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4156     }
4157
4158 end:
4159   vam->retval = retval;
4160   vam->result_ready = 1;
4161 }
4162
4163 static void
4164   vl_api_one_adjacencies_get_reply_t_handler_json
4165   (vl_api_one_adjacencies_get_reply_t * mp)
4166 {
4167   u8 *s = 0;
4168   vat_main_t *vam = &vat_main;
4169   vat_json_node_t *e = 0, root;
4170   u32 i, n;
4171   int retval = clib_net_to_host_u32 (mp->retval);
4172   vl_api_one_adjacency_t *a;
4173
4174   if (retval)
4175     goto end;
4176
4177   n = clib_net_to_host_u32 (mp->count);
4178   vat_json_init_array (&root);
4179
4180   for (i = 0; i < n; i++)
4181     {
4182       e = vat_json_array_add (&root);
4183       a = &mp->adjacencies[i];
4184
4185       vat_json_init_object (e);
4186       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4187                   a->leid_prefix_len);
4188       vec_add1 (s, 0);
4189       vat_json_object_add_string_copy (e, "leid", s);
4190       vec_free (s);
4191
4192       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4193                   a->reid_prefix_len);
4194       vec_add1 (s, 0);
4195       vat_json_object_add_string_copy (e, "reid", s);
4196       vec_free (s);
4197     }
4198
4199   vat_json_print (vam->ofp, &root);
4200   vat_json_free (&root);
4201
4202 end:
4203   vam->retval = retval;
4204   vam->result_ready = 1;
4205 }
4206
4207 static void
4208 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4209 {
4210   vat_main_t *vam = &vat_main;
4211
4212   print (vam->ofp, "%=20U",
4213          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4214          mp->ip_address);
4215 }
4216
4217 static void
4218   vl_api_one_map_server_details_t_handler_json
4219   (vl_api_one_map_server_details_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   vat_json_node_t *node = NULL;
4223   struct in6_addr ip6;
4224   struct in_addr ip4;
4225
4226   if (VAT_JSON_ARRAY != vam->json_tree.type)
4227     {
4228       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4229       vat_json_init_array (&vam->json_tree);
4230     }
4231   node = vat_json_array_add (&vam->json_tree);
4232
4233   vat_json_init_object (node);
4234   if (mp->is_ipv6)
4235     {
4236       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4237       vat_json_object_add_ip6 (node, "map-server", ip6);
4238     }
4239   else
4240     {
4241       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4242       vat_json_object_add_ip4 (node, "map-server", ip4);
4243     }
4244 }
4245
4246 static void
4247 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4248                                            * mp)
4249 {
4250   vat_main_t *vam = &vat_main;
4251
4252   print (vam->ofp, "%=20U",
4253          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4254          mp->ip_address);
4255 }
4256
4257 static void
4258   vl_api_one_map_resolver_details_t_handler_json
4259   (vl_api_one_map_resolver_details_t * mp)
4260 {
4261   vat_main_t *vam = &vat_main;
4262   vat_json_node_t *node = NULL;
4263   struct in6_addr ip6;
4264   struct in_addr ip4;
4265
4266   if (VAT_JSON_ARRAY != vam->json_tree.type)
4267     {
4268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4269       vat_json_init_array (&vam->json_tree);
4270     }
4271   node = vat_json_array_add (&vam->json_tree);
4272
4273   vat_json_init_object (node);
4274   if (mp->is_ipv6)
4275     {
4276       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4277       vat_json_object_add_ip6 (node, "map resolver", ip6);
4278     }
4279   else
4280     {
4281       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4282       vat_json_object_add_ip4 (node, "map resolver", ip4);
4283     }
4284 }
4285
4286 static void
4287 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   if (0 <= retval)
4293     {
4294       print (vam->ofp, "feature: %s\ngpe: %s",
4295              mp->feature_status ? "enabled" : "disabled",
4296              mp->gpe_status ? "enabled" : "disabled");
4297     }
4298
4299   vam->retval = retval;
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_show_one_status_reply_t_handler_json
4305   (vl_api_show_one_status_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   vat_json_node_t node;
4309   u8 *gpe_status = NULL;
4310   u8 *feature_status = NULL;
4311
4312   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4313   feature_status = format (0, "%s",
4314                            mp->feature_status ? "enabled" : "disabled");
4315   vec_add1 (gpe_status, 0);
4316   vec_add1 (feature_status, 0);
4317
4318   vat_json_init_object (&node);
4319   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4320   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4321
4322   vec_free (gpe_status);
4323   vec_free (feature_status);
4324
4325   vat_json_print (vam->ofp, &node);
4326   vat_json_free (&node);
4327
4328   vam->retval = ntohl (mp->retval);
4329   vam->result_ready = 1;
4330 }
4331
4332 static void
4333   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4334   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4335 {
4336   vat_main_t *vam = &vat_main;
4337   i32 retval = ntohl (mp->retval);
4338
4339   if (retval >= 0)
4340     {
4341       print (vam->ofp, "%=20s", mp->locator_set_name);
4342     }
4343
4344   vam->retval = retval;
4345   vam->result_ready = 1;
4346 }
4347
4348 static void
4349   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4350   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4351 {
4352   vat_main_t *vam = &vat_main;
4353   vat_json_node_t *node = NULL;
4354
4355   if (VAT_JSON_ARRAY != vam->json_tree.type)
4356     {
4357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4358       vat_json_init_array (&vam->json_tree);
4359     }
4360   node = vat_json_array_add (&vam->json_tree);
4361
4362   vat_json_init_object (node);
4363   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4364
4365   vat_json_print (vam->ofp, node);
4366   vat_json_free (node);
4367
4368   vam->retval = ntohl (mp->retval);
4369   vam->result_ready = 1;
4370 }
4371
4372 static u8 *
4373 format_lisp_map_request_mode (u8 * s, va_list * args)
4374 {
4375   u32 mode = va_arg (*args, u32);
4376
4377   switch (mode)
4378     {
4379     case 0:
4380       return format (0, "dst-only");
4381     case 1:
4382       return format (0, "src-dst");
4383     }
4384   return 0;
4385 }
4386
4387 static void
4388   vl_api_show_one_map_request_mode_reply_t_handler
4389   (vl_api_show_one_map_request_mode_reply_t * mp)
4390 {
4391   vat_main_t *vam = &vat_main;
4392   i32 retval = ntohl (mp->retval);
4393
4394   if (0 <= retval)
4395     {
4396       u32 mode = mp->mode;
4397       print (vam->ofp, "map_request_mode: %U",
4398              format_lisp_map_request_mode, mode);
4399     }
4400
4401   vam->retval = retval;
4402   vam->result_ready = 1;
4403 }
4404
4405 static void
4406   vl_api_show_one_map_request_mode_reply_t_handler_json
4407   (vl_api_show_one_map_request_mode_reply_t * mp)
4408 {
4409   vat_main_t *vam = &vat_main;
4410   vat_json_node_t node;
4411   u8 *s = 0;
4412   u32 mode;
4413
4414   mode = mp->mode;
4415   s = format (0, "%U", format_lisp_map_request_mode, mode);
4416   vec_add1 (s, 0);
4417
4418   vat_json_init_object (&node);
4419   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vec_free (s);
4424   vam->retval = ntohl (mp->retval);
4425   vam->result_ready = 1;
4426 }
4427
4428 static void
4429   vl_api_one_show_xtr_mode_reply_t_handler
4430   (vl_api_one_show_xtr_mode_reply_t * mp)
4431 {
4432   vat_main_t *vam = &vat_main;
4433   i32 retval = ntohl (mp->retval);
4434
4435   if (0 <= retval)
4436     {
4437       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4438     }
4439
4440   vam->retval = retval;
4441   vam->result_ready = 1;
4442 }
4443
4444 static void
4445   vl_api_one_show_xtr_mode_reply_t_handler_json
4446   (vl_api_one_show_xtr_mode_reply_t * mp)
4447 {
4448   vat_main_t *vam = &vat_main;
4449   vat_json_node_t node;
4450   u8 *status = 0;
4451
4452   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4453   vec_add1 (status, 0);
4454
4455   vat_json_init_object (&node);
4456   vat_json_object_add_string_copy (&node, "status", status);
4457
4458   vec_free (status);
4459
4460   vat_json_print (vam->ofp, &node);
4461   vat_json_free (&node);
4462
4463   vam->retval = ntohl (mp->retval);
4464   vam->result_ready = 1;
4465 }
4466
4467 static void
4468   vl_api_one_show_pitr_mode_reply_t_handler
4469   (vl_api_one_show_pitr_mode_reply_t * mp)
4470 {
4471   vat_main_t *vam = &vat_main;
4472   i32 retval = ntohl (mp->retval);
4473
4474   if (0 <= retval)
4475     {
4476       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4477     }
4478
4479   vam->retval = retval;
4480   vam->result_ready = 1;
4481 }
4482
4483 static void
4484   vl_api_one_show_pitr_mode_reply_t_handler_json
4485   (vl_api_one_show_pitr_mode_reply_t * mp)
4486 {
4487   vat_main_t *vam = &vat_main;
4488   vat_json_node_t node;
4489   u8 *status = 0;
4490
4491   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4492   vec_add1 (status, 0);
4493
4494   vat_json_init_object (&node);
4495   vat_json_object_add_string_copy (&node, "status", status);
4496
4497   vec_free (status);
4498
4499   vat_json_print (vam->ofp, &node);
4500   vat_json_free (&node);
4501
4502   vam->retval = ntohl (mp->retval);
4503   vam->result_ready = 1;
4504 }
4505
4506 static void
4507   vl_api_one_show_petr_mode_reply_t_handler
4508   (vl_api_one_show_petr_mode_reply_t * mp)
4509 {
4510   vat_main_t *vam = &vat_main;
4511   i32 retval = ntohl (mp->retval);
4512
4513   if (0 <= retval)
4514     {
4515       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4516     }
4517
4518   vam->retval = retval;
4519   vam->result_ready = 1;
4520 }
4521
4522 static void
4523   vl_api_one_show_petr_mode_reply_t_handler_json
4524   (vl_api_one_show_petr_mode_reply_t * mp)
4525 {
4526   vat_main_t *vam = &vat_main;
4527   vat_json_node_t node;
4528   u8 *status = 0;
4529
4530   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4531   vec_add1 (status, 0);
4532
4533   vat_json_init_object (&node);
4534   vat_json_object_add_string_copy (&node, "status", status);
4535
4536   vec_free (status);
4537
4538   vat_json_print (vam->ofp, &node);
4539   vat_json_free (&node);
4540
4541   vam->retval = ntohl (mp->retval);
4542   vam->result_ready = 1;
4543 }
4544
4545 static void
4546   vl_api_show_one_use_petr_reply_t_handler
4547   (vl_api_show_one_use_petr_reply_t * mp)
4548 {
4549   vat_main_t *vam = &vat_main;
4550   i32 retval = ntohl (mp->retval);
4551
4552   if (0 <= retval)
4553     {
4554       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4555       if (mp->status)
4556         {
4557           print (vam->ofp, "Proxy-ETR address; %U",
4558                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4559                  mp->address);
4560         }
4561     }
4562
4563   vam->retval = retval;
4564   vam->result_ready = 1;
4565 }
4566
4567 static void
4568   vl_api_show_one_use_petr_reply_t_handler_json
4569   (vl_api_show_one_use_petr_reply_t * mp)
4570 {
4571   vat_main_t *vam = &vat_main;
4572   vat_json_node_t node;
4573   u8 *status = 0;
4574   struct in_addr ip4;
4575   struct in6_addr ip6;
4576
4577   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4578   vec_add1 (status, 0);
4579
4580   vat_json_init_object (&node);
4581   vat_json_object_add_string_copy (&node, "status", status);
4582   if (mp->status)
4583     {
4584       if (mp->is_ip4)
4585         {
4586           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4587           vat_json_object_add_ip6 (&node, "address", ip6);
4588         }
4589       else
4590         {
4591           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4592           vat_json_object_add_ip4 (&node, "address", ip4);
4593         }
4594     }
4595
4596   vec_free (status);
4597
4598   vat_json_print (vam->ofp, &node);
4599   vat_json_free (&node);
4600
4601   vam->retval = ntohl (mp->retval);
4602   vam->result_ready = 1;
4603 }
4604
4605 static void
4606   vl_api_show_one_nsh_mapping_reply_t_handler
4607   (vl_api_show_one_nsh_mapping_reply_t * mp)
4608 {
4609   vat_main_t *vam = &vat_main;
4610   i32 retval = ntohl (mp->retval);
4611
4612   if (0 <= retval)
4613     {
4614       print (vam->ofp, "%-20s%-16s",
4615              mp->is_set ? "set" : "not-set",
4616              mp->is_set ? (char *) mp->locator_set_name : "");
4617     }
4618
4619   vam->retval = retval;
4620   vam->result_ready = 1;
4621 }
4622
4623 static void
4624   vl_api_show_one_nsh_mapping_reply_t_handler_json
4625   (vl_api_show_one_nsh_mapping_reply_t * mp)
4626 {
4627   vat_main_t *vam = &vat_main;
4628   vat_json_node_t node;
4629   u8 *status = 0;
4630
4631   status = format (0, "%s", mp->is_set ? "yes" : "no");
4632   vec_add1 (status, 0);
4633
4634   vat_json_init_object (&node);
4635   vat_json_object_add_string_copy (&node, "is_set", status);
4636   if (mp->is_set)
4637     {
4638       vat_json_object_add_string_copy (&node, "locator_set",
4639                                        mp->locator_set_name);
4640     }
4641
4642   vec_free (status);
4643
4644   vat_json_print (vam->ofp, &node);
4645   vat_json_free (&node);
4646
4647   vam->retval = ntohl (mp->retval);
4648   vam->result_ready = 1;
4649 }
4650
4651 static void
4652   vl_api_show_one_map_register_ttl_reply_t_handler
4653   (vl_api_show_one_map_register_ttl_reply_t * mp)
4654 {
4655   vat_main_t *vam = &vat_main;
4656   i32 retval = ntohl (mp->retval);
4657
4658   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4659
4660   if (0 <= retval)
4661     {
4662       print (vam->ofp, "ttl: %u", mp->ttl);
4663     }
4664
4665   vam->retval = retval;
4666   vam->result_ready = 1;
4667 }
4668
4669 static void
4670   vl_api_show_one_map_register_ttl_reply_t_handler_json
4671   (vl_api_show_one_map_register_ttl_reply_t * mp)
4672 {
4673   vat_main_t *vam = &vat_main;
4674   vat_json_node_t node;
4675
4676   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4677   vat_json_init_object (&node);
4678   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4679
4680   vat_json_print (vam->ofp, &node);
4681   vat_json_free (&node);
4682
4683   vam->retval = ntohl (mp->retval);
4684   vam->result_ready = 1;
4685 }
4686
4687 static void
4688 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4689 {
4690   vat_main_t *vam = &vat_main;
4691   i32 retval = ntohl (mp->retval);
4692
4693   if (0 <= retval)
4694     {
4695       print (vam->ofp, "%-20s%-16s",
4696              mp->status ? "enabled" : "disabled",
4697              mp->status ? (char *) mp->locator_set_name : "");
4698     }
4699
4700   vam->retval = retval;
4701   vam->result_ready = 1;
4702 }
4703
4704 static void
4705 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4706 {
4707   vat_main_t *vam = &vat_main;
4708   vat_json_node_t node;
4709   u8 *status = 0;
4710
4711   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4712   vec_add1 (status, 0);
4713
4714   vat_json_init_object (&node);
4715   vat_json_object_add_string_copy (&node, "status", status);
4716   if (mp->status)
4717     {
4718       vat_json_object_add_string_copy (&node, "locator_set",
4719                                        mp->locator_set_name);
4720     }
4721
4722   vec_free (status);
4723
4724   vat_json_print (vam->ofp, &node);
4725   vat_json_free (&node);
4726
4727   vam->retval = ntohl (mp->retval);
4728   vam->result_ready = 1;
4729 }
4730
4731 static u8 *
4732 format_policer_type (u8 * s, va_list * va)
4733 {
4734   u32 i = va_arg (*va, u32);
4735
4736   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4737     s = format (s, "1r2c");
4738   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4739     s = format (s, "1r3c");
4740   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4741     s = format (s, "2r3c-2698");
4742   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4743     s = format (s, "2r3c-4115");
4744   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4745     s = format (s, "2r3c-mef5cf1");
4746   else
4747     s = format (s, "ILLEGAL");
4748   return s;
4749 }
4750
4751 static u8 *
4752 format_policer_rate_type (u8 * s, va_list * va)
4753 {
4754   u32 i = va_arg (*va, u32);
4755
4756   if (i == SSE2_QOS_RATE_KBPS)
4757     s = format (s, "kbps");
4758   else if (i == SSE2_QOS_RATE_PPS)
4759     s = format (s, "pps");
4760   else
4761     s = format (s, "ILLEGAL");
4762   return s;
4763 }
4764
4765 static u8 *
4766 format_policer_round_type (u8 * s, va_list * va)
4767 {
4768   u32 i = va_arg (*va, u32);
4769
4770   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4771     s = format (s, "closest");
4772   else if (i == SSE2_QOS_ROUND_TO_UP)
4773     s = format (s, "up");
4774   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4775     s = format (s, "down");
4776   else
4777     s = format (s, "ILLEGAL");
4778   return s;
4779 }
4780
4781 static u8 *
4782 format_policer_action_type (u8 * s, va_list * va)
4783 {
4784   u32 i = va_arg (*va, u32);
4785
4786   if (i == SSE2_QOS_ACTION_DROP)
4787     s = format (s, "drop");
4788   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4789     s = format (s, "transmit");
4790   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4791     s = format (s, "mark-and-transmit");
4792   else
4793     s = format (s, "ILLEGAL");
4794   return s;
4795 }
4796
4797 static u8 *
4798 format_dscp (u8 * s, va_list * va)
4799 {
4800   u32 i = va_arg (*va, u32);
4801   char *t = 0;
4802
4803   switch (i)
4804     {
4805 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4806       foreach_vnet_dscp
4807 #undef _
4808     default:
4809       return format (s, "ILLEGAL");
4810     }
4811   s = format (s, "%s", t);
4812   return s;
4813 }
4814
4815 static void
4816 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4817 {
4818   vat_main_t *vam = &vat_main;
4819   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4820
4821   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4822     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4823   else
4824     conform_dscp_str = format (0, "");
4825
4826   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4827     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4828   else
4829     exceed_dscp_str = format (0, "");
4830
4831   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4832     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4833   else
4834     violate_dscp_str = format (0, "");
4835
4836   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4837          "rate type %U, round type %U, %s rate, %s color-aware, "
4838          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4839          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4840          "conform action %U%s, exceed action %U%s, violate action %U%s",
4841          mp->name,
4842          format_policer_type, mp->type,
4843          ntohl (mp->cir),
4844          ntohl (mp->eir),
4845          clib_net_to_host_u64 (mp->cb),
4846          clib_net_to_host_u64 (mp->eb),
4847          format_policer_rate_type, mp->rate_type,
4848          format_policer_round_type, mp->round_type,
4849          mp->single_rate ? "single" : "dual",
4850          mp->color_aware ? "is" : "not",
4851          ntohl (mp->cir_tokens_per_period),
4852          ntohl (mp->pir_tokens_per_period),
4853          ntohl (mp->scale),
4854          ntohl (mp->current_limit),
4855          ntohl (mp->current_bucket),
4856          ntohl (mp->extended_limit),
4857          ntohl (mp->extended_bucket),
4858          clib_net_to_host_u64 (mp->last_update_time),
4859          format_policer_action_type, mp->conform_action_type,
4860          conform_dscp_str,
4861          format_policer_action_type, mp->exceed_action_type,
4862          exceed_dscp_str,
4863          format_policer_action_type, mp->violate_action_type,
4864          violate_dscp_str);
4865
4866   vec_free (conform_dscp_str);
4867   vec_free (exceed_dscp_str);
4868   vec_free (violate_dscp_str);
4869 }
4870
4871 static void vl_api_policer_details_t_handler_json
4872   (vl_api_policer_details_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t *node;
4876   u8 *rate_type_str, *round_type_str, *type_str;
4877   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4878
4879   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4880   round_type_str =
4881     format (0, "%U", format_policer_round_type, mp->round_type);
4882   type_str = format (0, "%U", format_policer_type, mp->type);
4883   conform_action_str = format (0, "%U", format_policer_action_type,
4884                                mp->conform_action_type);
4885   exceed_action_str = format (0, "%U", format_policer_action_type,
4886                               mp->exceed_action_type);
4887   violate_action_str = format (0, "%U", format_policer_action_type,
4888                                mp->violate_action_type);
4889
4890   if (VAT_JSON_ARRAY != vam->json_tree.type)
4891     {
4892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4893       vat_json_init_array (&vam->json_tree);
4894     }
4895   node = vat_json_array_add (&vam->json_tree);
4896
4897   vat_json_init_object (node);
4898   vat_json_object_add_string_copy (node, "name", mp->name);
4899   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4900   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4901   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4902   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4903   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4904   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4905   vat_json_object_add_string_copy (node, "type", type_str);
4906   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4907   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4908   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4909   vat_json_object_add_uint (node, "cir_tokens_per_period",
4910                             ntohl (mp->cir_tokens_per_period));
4911   vat_json_object_add_uint (node, "eir_tokens_per_period",
4912                             ntohl (mp->pir_tokens_per_period));
4913   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4914   vat_json_object_add_uint (node, "current_bucket",
4915                             ntohl (mp->current_bucket));
4916   vat_json_object_add_uint (node, "extended_limit",
4917                             ntohl (mp->extended_limit));
4918   vat_json_object_add_uint (node, "extended_bucket",
4919                             ntohl (mp->extended_bucket));
4920   vat_json_object_add_uint (node, "last_update_time",
4921                             ntohl (mp->last_update_time));
4922   vat_json_object_add_string_copy (node, "conform_action",
4923                                    conform_action_str);
4924   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4925     {
4926       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4927       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4928       vec_free (dscp_str);
4929     }
4930   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4931   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4932     {
4933       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4934       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4935       vec_free (dscp_str);
4936     }
4937   vat_json_object_add_string_copy (node, "violate_action",
4938                                    violate_action_str);
4939   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4940     {
4941       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4942       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4943       vec_free (dscp_str);
4944     }
4945
4946   vec_free (rate_type_str);
4947   vec_free (round_type_str);
4948   vec_free (type_str);
4949   vec_free (conform_action_str);
4950   vec_free (exceed_action_str);
4951   vec_free (violate_action_str);
4952 }
4953
4954 static void
4955 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4956                                            mp)
4957 {
4958   vat_main_t *vam = &vat_main;
4959   int i, count = ntohl (mp->count);
4960
4961   if (count > 0)
4962     print (vam->ofp, "classify table ids (%d) : ", count);
4963   for (i = 0; i < count; i++)
4964     {
4965       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4966       print (vam->ofp, (i < count - 1) ? "," : "");
4967     }
4968   vam->retval = ntohl (mp->retval);
4969   vam->result_ready = 1;
4970 }
4971
4972 static void
4973   vl_api_classify_table_ids_reply_t_handler_json
4974   (vl_api_classify_table_ids_reply_t * mp)
4975 {
4976   vat_main_t *vam = &vat_main;
4977   int i, count = ntohl (mp->count);
4978
4979   if (count > 0)
4980     {
4981       vat_json_node_t node;
4982
4983       vat_json_init_object (&node);
4984       for (i = 0; i < count; i++)
4985         {
4986           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4987         }
4988       vat_json_print (vam->ofp, &node);
4989       vat_json_free (&node);
4990     }
4991   vam->retval = ntohl (mp->retval);
4992   vam->result_ready = 1;
4993 }
4994
4995 static void
4996   vl_api_classify_table_by_interface_reply_t_handler
4997   (vl_api_classify_table_by_interface_reply_t * mp)
4998 {
4999   vat_main_t *vam = &vat_main;
5000   u32 table_id;
5001
5002   table_id = ntohl (mp->l2_table_id);
5003   if (table_id != ~0)
5004     print (vam->ofp, "l2 table id : %d", table_id);
5005   else
5006     print (vam->ofp, "l2 table id : No input ACL tables configured");
5007   table_id = ntohl (mp->ip4_table_id);
5008   if (table_id != ~0)
5009     print (vam->ofp, "ip4 table id : %d", table_id);
5010   else
5011     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5012   table_id = ntohl (mp->ip6_table_id);
5013   if (table_id != ~0)
5014     print (vam->ofp, "ip6 table id : %d", table_id);
5015   else
5016     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5017   vam->retval = ntohl (mp->retval);
5018   vam->result_ready = 1;
5019 }
5020
5021 static void
5022   vl_api_classify_table_by_interface_reply_t_handler_json
5023   (vl_api_classify_table_by_interface_reply_t * mp)
5024 {
5025   vat_main_t *vam = &vat_main;
5026   vat_json_node_t node;
5027
5028   vat_json_init_object (&node);
5029
5030   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5031   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5032   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5033
5034   vat_json_print (vam->ofp, &node);
5035   vat_json_free (&node);
5036
5037   vam->retval = ntohl (mp->retval);
5038   vam->result_ready = 1;
5039 }
5040
5041 static void vl_api_policer_add_del_reply_t_handler
5042   (vl_api_policer_add_del_reply_t * mp)
5043 {
5044   vat_main_t *vam = &vat_main;
5045   i32 retval = ntohl (mp->retval);
5046   if (vam->async_mode)
5047     {
5048       vam->async_errors += (retval < 0);
5049     }
5050   else
5051     {
5052       vam->retval = retval;
5053       vam->result_ready = 1;
5054       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5055         /*
5056          * Note: this is just barely thread-safe, depends on
5057          * the main thread spinning waiting for an answer...
5058          */
5059         errmsg ("policer index %d", ntohl (mp->policer_index));
5060     }
5061 }
5062
5063 static void vl_api_policer_add_del_reply_t_handler_json
5064   (vl_api_policer_add_del_reply_t * mp)
5065 {
5066   vat_main_t *vam = &vat_main;
5067   vat_json_node_t node;
5068
5069   vat_json_init_object (&node);
5070   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5071   vat_json_object_add_uint (&node, "policer_index",
5072                             ntohl (mp->policer_index));
5073
5074   vat_json_print (vam->ofp, &node);
5075   vat_json_free (&node);
5076
5077   vam->retval = ntohl (mp->retval);
5078   vam->result_ready = 1;
5079 }
5080
5081 /* Format hex dump. */
5082 u8 *
5083 format_hex_bytes (u8 * s, va_list * va)
5084 {
5085   u8 *bytes = va_arg (*va, u8 *);
5086   int n_bytes = va_arg (*va, int);
5087   uword i;
5088
5089   /* Print short or long form depending on byte count. */
5090   uword short_form = n_bytes <= 32;
5091   u32 indent = format_get_indent (s);
5092
5093   if (n_bytes == 0)
5094     return s;
5095
5096   for (i = 0; i < n_bytes; i++)
5097     {
5098       if (!short_form && (i % 32) == 0)
5099         s = format (s, "%08x: ", i);
5100       s = format (s, "%02x", bytes[i]);
5101       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5102         s = format (s, "\n%U", format_white_space, indent);
5103     }
5104
5105   return s;
5106 }
5107
5108 static void
5109 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5110                                             * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113   i32 retval = ntohl (mp->retval);
5114   if (retval == 0)
5115     {
5116       print (vam->ofp, "classify table info :");
5117       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5118              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5119              ntohl (mp->miss_next_index));
5120       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5121              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5122              ntohl (mp->match_n_vectors));
5123       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5124              ntohl (mp->mask_length));
5125     }
5126   vam->retval = retval;
5127   vam->result_ready = 1;
5128 }
5129
5130 static void
5131   vl_api_classify_table_info_reply_t_handler_json
5132   (vl_api_classify_table_info_reply_t * mp)
5133 {
5134   vat_main_t *vam = &vat_main;
5135   vat_json_node_t node;
5136
5137   i32 retval = ntohl (mp->retval);
5138   if (retval == 0)
5139     {
5140       vat_json_init_object (&node);
5141
5142       vat_json_object_add_int (&node, "sessions",
5143                                ntohl (mp->active_sessions));
5144       vat_json_object_add_int (&node, "nexttbl",
5145                                ntohl (mp->next_table_index));
5146       vat_json_object_add_int (&node, "nextnode",
5147                                ntohl (mp->miss_next_index));
5148       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5149       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5150       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5151       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5152                       ntohl (mp->mask_length), 0);
5153       vat_json_object_add_string_copy (&node, "mask", s);
5154
5155       vat_json_print (vam->ofp, &node);
5156       vat_json_free (&node);
5157     }
5158   vam->retval = ntohl (mp->retval);
5159   vam->result_ready = 1;
5160 }
5161
5162 static void
5163 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5164                                            mp)
5165 {
5166   vat_main_t *vam = &vat_main;
5167
5168   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5169          ntohl (mp->hit_next_index), ntohl (mp->advance),
5170          ntohl (mp->opaque_index));
5171   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5172          ntohl (mp->match_length));
5173 }
5174
5175 static void
5176   vl_api_classify_session_details_t_handler_json
5177   (vl_api_classify_session_details_t * mp)
5178 {
5179   vat_main_t *vam = &vat_main;
5180   vat_json_node_t *node = NULL;
5181
5182   if (VAT_JSON_ARRAY != vam->json_tree.type)
5183     {
5184       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5185       vat_json_init_array (&vam->json_tree);
5186     }
5187   node = vat_json_array_add (&vam->json_tree);
5188
5189   vat_json_init_object (node);
5190   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5191   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5192   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5193   u8 *s =
5194     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5195             0);
5196   vat_json_object_add_string_copy (node, "match", s);
5197 }
5198
5199 static void vl_api_pg_create_interface_reply_t_handler
5200   (vl_api_pg_create_interface_reply_t * mp)
5201 {
5202   vat_main_t *vam = &vat_main;
5203
5204   vam->retval = ntohl (mp->retval);
5205   vam->result_ready = 1;
5206 }
5207
5208 static void vl_api_pg_create_interface_reply_t_handler_json
5209   (vl_api_pg_create_interface_reply_t * mp)
5210 {
5211   vat_main_t *vam = &vat_main;
5212   vat_json_node_t node;
5213
5214   i32 retval = ntohl (mp->retval);
5215   if (retval == 0)
5216     {
5217       vat_json_init_object (&node);
5218
5219       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5220
5221       vat_json_print (vam->ofp, &node);
5222       vat_json_free (&node);
5223     }
5224   vam->retval = ntohl (mp->retval);
5225   vam->result_ready = 1;
5226 }
5227
5228 static void vl_api_policer_classify_details_t_handler
5229   (vl_api_policer_classify_details_t * mp)
5230 {
5231   vat_main_t *vam = &vat_main;
5232
5233   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5234          ntohl (mp->table_index));
5235 }
5236
5237 static void vl_api_policer_classify_details_t_handler_json
5238   (vl_api_policer_classify_details_t * mp)
5239 {
5240   vat_main_t *vam = &vat_main;
5241   vat_json_node_t *node;
5242
5243   if (VAT_JSON_ARRAY != vam->json_tree.type)
5244     {
5245       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5246       vat_json_init_array (&vam->json_tree);
5247     }
5248   node = vat_json_array_add (&vam->json_tree);
5249
5250   vat_json_init_object (node);
5251   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5252   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5253 }
5254
5255 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5256   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5257 {
5258   vat_main_t *vam = &vat_main;
5259   i32 retval = ntohl (mp->retval);
5260   if (vam->async_mode)
5261     {
5262       vam->async_errors += (retval < 0);
5263     }
5264   else
5265     {
5266       vam->retval = retval;
5267       vam->sw_if_index = ntohl (mp->sw_if_index);
5268       vam->result_ready = 1;
5269     }
5270   vam->regenerate_interface_table = 1;
5271 }
5272
5273 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5274   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5275 {
5276   vat_main_t *vam = &vat_main;
5277   vat_json_node_t node;
5278
5279   vat_json_init_object (&node);
5280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5281   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5282
5283   vat_json_print (vam->ofp, &node);
5284   vat_json_free (&node);
5285
5286   vam->retval = ntohl (mp->retval);
5287   vam->result_ready = 1;
5288 }
5289
5290 static void vl_api_flow_classify_details_t_handler
5291   (vl_api_flow_classify_details_t * mp)
5292 {
5293   vat_main_t *vam = &vat_main;
5294
5295   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5296          ntohl (mp->table_index));
5297 }
5298
5299 static void vl_api_flow_classify_details_t_handler_json
5300   (vl_api_flow_classify_details_t * mp)
5301 {
5302   vat_main_t *vam = &vat_main;
5303   vat_json_node_t *node;
5304
5305   if (VAT_JSON_ARRAY != vam->json_tree.type)
5306     {
5307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5308       vat_json_init_array (&vam->json_tree);
5309     }
5310   node = vat_json_array_add (&vam->json_tree);
5311
5312   vat_json_init_object (node);
5313   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5314   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5315 }
5316
5317 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5318 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5320 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5322 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5324 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5326 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5328 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5330 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5333 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5334 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5336 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5338 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5339
5340 /*
5341  * Generate boilerplate reply handlers, which
5342  * dig the return value out of the xxx_reply_t API message,
5343  * stick it into vam->retval, and set vam->result_ready
5344  *
5345  * Could also do this by pointing N message decode slots at
5346  * a single function, but that could break in subtle ways.
5347  */
5348
5349 #define foreach_standard_reply_retval_handler           \
5350 _(sw_interface_set_flags_reply)                         \
5351 _(sw_interface_add_del_address_reply)                   \
5352 _(sw_interface_set_rx_mode_reply)                       \
5353 _(sw_interface_set_rx_placement_reply)                  \
5354 _(sw_interface_set_table_reply)                         \
5355 _(sw_interface_set_mpls_enable_reply)                   \
5356 _(sw_interface_set_vpath_reply)                         \
5357 _(sw_interface_set_vxlan_bypass_reply)                  \
5358 _(sw_interface_set_geneve_bypass_reply)                 \
5359 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5360 _(sw_interface_set_l2_bridge_reply)                     \
5361 _(bridge_domain_add_del_reply)                          \
5362 _(sw_interface_set_l2_xconnect_reply)                   \
5363 _(l2fib_add_del_reply)                                  \
5364 _(l2fib_flush_int_reply)                                \
5365 _(l2fib_flush_bd_reply)                                 \
5366 _(ip_add_del_route_reply)                               \
5367 _(ip_table_add_del_reply)                               \
5368 _(ip_mroute_add_del_reply)                              \
5369 _(mpls_route_add_del_reply)                             \
5370 _(mpls_table_add_del_reply)                             \
5371 _(mpls_ip_bind_unbind_reply)                            \
5372 _(bier_route_add_del_reply)                             \
5373 _(bier_table_add_del_reply)                             \
5374 _(proxy_arp_add_del_reply)                              \
5375 _(proxy_arp_intfc_enable_disable_reply)                 \
5376 _(sw_interface_set_unnumbered_reply)                    \
5377 _(ip_neighbor_add_del_reply)                            \
5378 _(oam_add_del_reply)                                    \
5379 _(reset_fib_reply)                                      \
5380 _(dhcp_proxy_config_reply)                              \
5381 _(dhcp_proxy_set_vss_reply)                             \
5382 _(dhcp_client_config_reply)                             \
5383 _(set_ip_flow_hash_reply)                               \
5384 _(sw_interface_ip6_enable_disable_reply)                \
5385 _(sw_interface_ip6_set_link_local_address_reply)        \
5386 _(ip6nd_proxy_add_del_reply)                            \
5387 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5388 _(sw_interface_ip6nd_ra_config_reply)                   \
5389 _(set_arp_neighbor_limit_reply)                         \
5390 _(l2_patch_add_del_reply)                               \
5391 _(sr_mpls_policy_add_reply)                             \
5392 _(sr_mpls_policy_mod_reply)                             \
5393 _(sr_mpls_policy_del_reply)                             \
5394 _(sr_policy_add_reply)                                  \
5395 _(sr_policy_mod_reply)                                  \
5396 _(sr_policy_del_reply)                                  \
5397 _(sr_localsid_add_del_reply)                            \
5398 _(sr_steering_add_del_reply)                            \
5399 _(classify_add_del_session_reply)                       \
5400 _(classify_set_interface_ip_table_reply)                \
5401 _(classify_set_interface_l2_tables_reply)               \
5402 _(l2tpv3_set_tunnel_cookies_reply)                      \
5403 _(l2tpv3_interface_enable_disable_reply)                \
5404 _(l2tpv3_set_lookup_key_reply)                          \
5405 _(l2_fib_clear_table_reply)                             \
5406 _(l2_interface_efp_filter_reply)                        \
5407 _(l2_interface_vlan_tag_rewrite_reply)                  \
5408 _(modify_vhost_user_if_reply)                           \
5409 _(delete_vhost_user_if_reply)                           \
5410 _(ip_probe_neighbor_reply)                              \
5411 _(ip_scan_neighbor_enable_disable_reply)                \
5412 _(want_ip4_arp_events_reply)                            \
5413 _(want_ip6_nd_events_reply)                             \
5414 _(want_l2_macs_events_reply)                            \
5415 _(input_acl_set_interface_reply)                        \
5416 _(ipsec_spd_add_del_reply)                              \
5417 _(ipsec_interface_add_del_spd_reply)                    \
5418 _(ipsec_spd_add_del_entry_reply)                        \
5419 _(ipsec_sad_add_del_entry_reply)                        \
5420 _(ipsec_sa_set_key_reply)                               \
5421 _(ipsec_tunnel_if_add_del_reply)                        \
5422 _(ipsec_tunnel_if_set_key_reply)                        \
5423 _(ipsec_tunnel_if_set_sa_reply)                         \
5424 _(ikev2_profile_add_del_reply)                          \
5425 _(ikev2_profile_set_auth_reply)                         \
5426 _(ikev2_profile_set_id_reply)                           \
5427 _(ikev2_profile_set_ts_reply)                           \
5428 _(ikev2_set_local_key_reply)                            \
5429 _(ikev2_set_responder_reply)                            \
5430 _(ikev2_set_ike_transforms_reply)                       \
5431 _(ikev2_set_esp_transforms_reply)                       \
5432 _(ikev2_set_sa_lifetime_reply)                          \
5433 _(ikev2_initiate_sa_init_reply)                         \
5434 _(ikev2_initiate_del_ike_sa_reply)                      \
5435 _(ikev2_initiate_del_child_sa_reply)                    \
5436 _(ikev2_initiate_rekey_child_sa_reply)                  \
5437 _(delete_loopback_reply)                                \
5438 _(bd_ip_mac_add_del_reply)                              \
5439 _(want_interface_events_reply)                          \
5440 _(want_stats_reply)                                     \
5441 _(cop_interface_enable_disable_reply)                   \
5442 _(cop_whitelist_enable_disable_reply)                   \
5443 _(sw_interface_clear_stats_reply)                       \
5444 _(ioam_enable_reply)                                    \
5445 _(ioam_disable_reply)                                   \
5446 _(one_add_del_locator_reply)                            \
5447 _(one_add_del_local_eid_reply)                          \
5448 _(one_add_del_remote_mapping_reply)                     \
5449 _(one_add_del_adjacency_reply)                          \
5450 _(one_add_del_map_resolver_reply)                       \
5451 _(one_add_del_map_server_reply)                         \
5452 _(one_enable_disable_reply)                             \
5453 _(one_rloc_probe_enable_disable_reply)                  \
5454 _(one_map_register_enable_disable_reply)                \
5455 _(one_map_register_set_ttl_reply)                       \
5456 _(one_set_transport_protocol_reply)                     \
5457 _(one_map_register_fallback_threshold_reply)            \
5458 _(one_pitr_set_locator_set_reply)                       \
5459 _(one_map_request_mode_reply)                           \
5460 _(one_add_del_map_request_itr_rlocs_reply)              \
5461 _(one_eid_table_add_del_map_reply)                      \
5462 _(one_use_petr_reply)                                   \
5463 _(one_stats_enable_disable_reply)                       \
5464 _(one_add_del_l2_arp_entry_reply)                       \
5465 _(one_add_del_ndp_entry_reply)                          \
5466 _(one_stats_flush_reply)                                \
5467 _(one_enable_disable_xtr_mode_reply)                    \
5468 _(one_enable_disable_pitr_mode_reply)                   \
5469 _(one_enable_disable_petr_mode_reply)                   \
5470 _(gpe_enable_disable_reply)                             \
5471 _(gpe_set_encap_mode_reply)                             \
5472 _(gpe_add_del_iface_reply)                              \
5473 _(gpe_add_del_native_fwd_rpath_reply)                   \
5474 _(af_packet_delete_reply)                               \
5475 _(policer_classify_set_interface_reply)                 \
5476 _(netmap_create_reply)                                  \
5477 _(netmap_delete_reply)                                  \
5478 _(set_ipfix_exporter_reply)                             \
5479 _(set_ipfix_classify_stream_reply)                      \
5480 _(ipfix_classify_table_add_del_reply)                   \
5481 _(flow_classify_set_interface_reply)                    \
5482 _(sw_interface_span_enable_disable_reply)               \
5483 _(pg_capture_reply)                                     \
5484 _(pg_enable_disable_reply)                              \
5485 _(ip_source_and_port_range_check_add_del_reply)         \
5486 _(ip_source_and_port_range_check_interface_add_del_reply)\
5487 _(delete_subif_reply)                                   \
5488 _(l2_interface_pbb_tag_rewrite_reply)                   \
5489 _(punt_reply)                                           \
5490 _(feature_enable_disable_reply)                         \
5491 _(sw_interface_tag_add_del_reply)                       \
5492 _(hw_interface_set_mtu_reply)                           \
5493 _(p2p_ethernet_add_reply)                               \
5494 _(p2p_ethernet_del_reply)                               \
5495 _(lldp_config_reply)                                    \
5496 _(sw_interface_set_lldp_reply)                          \
5497 _(tcp_configure_src_addresses_reply)                    \
5498 _(dns_enable_disable_reply)                             \
5499 _(dns_name_server_add_del_reply)                        \
5500 _(session_rule_add_del_reply)                           \
5501 _(ip_container_proxy_add_del_reply)                     \
5502 _(output_acl_set_interface_reply)                       \
5503 _(qos_record_enable_disable_reply)
5504
5505 #define _(n)                                    \
5506     static void vl_api_##n##_t_handler          \
5507     (vl_api_##n##_t * mp)                       \
5508     {                                           \
5509         vat_main_t * vam = &vat_main;           \
5510         i32 retval = ntohl(mp->retval);         \
5511         if (vam->async_mode) {                  \
5512             vam->async_errors += (retval < 0);  \
5513         } else {                                \
5514             vam->retval = retval;               \
5515             vam->result_ready = 1;              \
5516         }                                       \
5517     }
5518 foreach_standard_reply_retval_handler;
5519 #undef _
5520
5521 #define _(n)                                    \
5522     static void vl_api_##n##_t_handler_json     \
5523     (vl_api_##n##_t * mp)                       \
5524     {                                           \
5525         vat_main_t * vam = &vat_main;           \
5526         vat_json_node_t node;                   \
5527         vat_json_init_object(&node);            \
5528         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5529         vat_json_print(vam->ofp, &node);        \
5530         vam->retval = ntohl(mp->retval);        \
5531         vam->result_ready = 1;                  \
5532     }
5533 foreach_standard_reply_retval_handler;
5534 #undef _
5535
5536 /*
5537  * Table of message reply handlers, must include boilerplate handlers
5538  * we just generated
5539  */
5540
5541 #define foreach_vpe_api_reply_msg                                       \
5542 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5543 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5544 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5545 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5546 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5547 _(CLI_REPLY, cli_reply)                                                 \
5548 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5549 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5550   sw_interface_add_del_address_reply)                                   \
5551 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5552 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5553 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5554 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5555 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5556 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5557 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5558 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5559 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5560 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5561   sw_interface_set_l2_xconnect_reply)                                   \
5562 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5563   sw_interface_set_l2_bridge_reply)                                     \
5564 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5565 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5566 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5567 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5568 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5569 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5570 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5571 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5572 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5573 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5574 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5575 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5576 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5577 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5578 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5579 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5580 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5581 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5582 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5583 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5584 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5585 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5586 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5587 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5588 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5589 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5590 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5591 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5592 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5593 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5594 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5595   proxy_arp_intfc_enable_disable_reply)                                 \
5596 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5597 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5598   sw_interface_set_unnumbered_reply)                                    \
5599 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5600 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5601 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5602 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5603 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5604 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5605 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5606 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5607 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5608 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5609 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5610   sw_interface_ip6_enable_disable_reply)                                \
5611 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5612   sw_interface_ip6_set_link_local_address_reply)                        \
5613 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5614 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5615 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5616   sw_interface_ip6nd_ra_prefix_reply)                                   \
5617 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5618   sw_interface_ip6nd_ra_config_reply)                                   \
5619 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5620 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5621 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5622 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5623 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5624 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5625 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5626 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5627 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5628 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5629 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5630 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5631 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5632 classify_set_interface_ip_table_reply)                                  \
5633 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5634   classify_set_interface_l2_tables_reply)                               \
5635 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5636 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5637 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5638 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5639 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5640   l2tpv3_interface_enable_disable_reply)                                \
5641 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5642 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5643 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5644 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5645 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5646 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5647 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5648 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5649 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5650 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5651 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5652 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5653 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5654 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5655 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5656 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5657 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5658 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5659 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5660 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5661 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5662 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5663 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5664 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5665 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5666 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5667 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5668 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5669 _(L2_MACS_EVENT, l2_macs_event)                                         \
5670 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5671 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5672 _(IP_DETAILS, ip_details)                                               \
5673 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5674 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5675 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5676 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5677 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5678 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5679 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5680 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5681 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5682 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5683 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5684 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5685 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5686 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5687 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5688 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5689 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5690 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5691 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5692 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5693 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5694 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5695 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5696 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5697 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5698 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5699 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5700 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5701 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5702 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5703 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5704 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5705 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5706 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5707 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5708 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5709 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5710 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5711 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5712 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5713 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5714 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5715 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5716 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5717   one_map_register_enable_disable_reply)                                \
5718 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5719 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5720 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5721 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5722   one_map_register_fallback_threshold_reply)                            \
5723 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5724   one_rloc_probe_enable_disable_reply)                                  \
5725 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5726 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5727 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5728 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5729 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5730 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5731 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5732 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5733 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5734 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5735 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5736 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5737 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5738 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5739 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5740 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5741   show_one_stats_enable_disable_reply)                                  \
5742 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5743 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5744 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5745 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5746 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5747 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5748 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5749 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5750   one_enable_disable_pitr_mode_reply)                                   \
5751 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5752   one_enable_disable_petr_mode_reply)                                   \
5753 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5754 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5755 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5756 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5757 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5758 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5759 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5760 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5761 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5762 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5763 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5764 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5765   gpe_add_del_native_fwd_rpath_reply)                                   \
5766 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5767   gpe_fwd_entry_path_details)                                           \
5768 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5769 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5770   one_add_del_map_request_itr_rlocs_reply)                              \
5771 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5772   one_get_map_request_itr_rlocs_reply)                                  \
5773 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5774 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5775 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5776 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5777 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5778 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5779   show_one_map_register_state_reply)                                    \
5780 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5781 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5782   show_one_map_register_fallback_threshold_reply)                       \
5783 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5784 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5785 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5786 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5787 _(POLICER_DETAILS, policer_details)                                     \
5788 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5789 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5790 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5791 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5792 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5793 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5794 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5795 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5796 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5797 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5798 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5799 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5800 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5801 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5802 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5803 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5804 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5805 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5806 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5807 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5808 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5809 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5810 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5811 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5812 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5813  ip_source_and_port_range_check_add_del_reply)                          \
5814 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5815  ip_source_and_port_range_check_interface_add_del_reply)                \
5816 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5817 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5818 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5819 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5820 _(PUNT_REPLY, punt_reply)                                               \
5821 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5822 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5823 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5824 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5825 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5826 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5827 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5828 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5829 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5830 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5831 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5832 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5833 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5834 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5835 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5836 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5837 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5838 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5839 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5840 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5841 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5842 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5843 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5844
5845 #define foreach_standalone_reply_msg                                    \
5846 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5847 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5848 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5849 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5850 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5851 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5852 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5853
5854 typedef struct
5855 {
5856   u8 *name;
5857   u32 value;
5858 } name_sort_t;
5859
5860 #define STR_VTR_OP_CASE(op)     \
5861     case L2_VTR_ ## op:         \
5862         return "" # op;
5863
5864 static const char *
5865 str_vtr_op (u32 vtr_op)
5866 {
5867   switch (vtr_op)
5868     {
5869       STR_VTR_OP_CASE (DISABLED);
5870       STR_VTR_OP_CASE (PUSH_1);
5871       STR_VTR_OP_CASE (PUSH_2);
5872       STR_VTR_OP_CASE (POP_1);
5873       STR_VTR_OP_CASE (POP_2);
5874       STR_VTR_OP_CASE (TRANSLATE_1_1);
5875       STR_VTR_OP_CASE (TRANSLATE_1_2);
5876       STR_VTR_OP_CASE (TRANSLATE_2_1);
5877       STR_VTR_OP_CASE (TRANSLATE_2_2);
5878     }
5879
5880   return "UNKNOWN";
5881 }
5882
5883 static int
5884 dump_sub_interface_table (vat_main_t * vam)
5885 {
5886   const sw_interface_subif_t *sub = NULL;
5887
5888   if (vam->json_output)
5889     {
5890       clib_warning
5891         ("JSON output supported only for VPE API calls and dump_stats_table");
5892       return -99;
5893     }
5894
5895   print (vam->ofp,
5896          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5897          "Interface", "sw_if_index",
5898          "sub id", "dot1ad", "tags", "outer id",
5899          "inner id", "exact", "default", "outer any", "inner any");
5900
5901   vec_foreach (sub, vam->sw_if_subif_table)
5902   {
5903     print (vam->ofp,
5904            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5905            sub->interface_name,
5906            sub->sw_if_index,
5907            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5908            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5909            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5910            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5911     if (sub->vtr_op != L2_VTR_DISABLED)
5912       {
5913         print (vam->ofp,
5914                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5915                "tag1: %d tag2: %d ]",
5916                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5917                sub->vtr_tag1, sub->vtr_tag2);
5918       }
5919   }
5920
5921   return 0;
5922 }
5923
5924 static int
5925 name_sort_cmp (void *a1, void *a2)
5926 {
5927   name_sort_t *n1 = a1;
5928   name_sort_t *n2 = a2;
5929
5930   return strcmp ((char *) n1->name, (char *) n2->name);
5931 }
5932
5933 static int
5934 dump_interface_table (vat_main_t * vam)
5935 {
5936   hash_pair_t *p;
5937   name_sort_t *nses = 0, *ns;
5938
5939   if (vam->json_output)
5940     {
5941       clib_warning
5942         ("JSON output supported only for VPE API calls and dump_stats_table");
5943       return -99;
5944     }
5945
5946   /* *INDENT-OFF* */
5947   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5948   ({
5949     vec_add2 (nses, ns, 1);
5950     ns->name = (u8 *)(p->key);
5951     ns->value = (u32) p->value[0];
5952   }));
5953   /* *INDENT-ON* */
5954
5955   vec_sort_with_function (nses, name_sort_cmp);
5956
5957   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5958   vec_foreach (ns, nses)
5959   {
5960     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5961   }
5962   vec_free (nses);
5963   return 0;
5964 }
5965
5966 static int
5967 dump_ip_table (vat_main_t * vam, int is_ipv6)
5968 {
5969   const ip_details_t *det = NULL;
5970   const ip_address_details_t *address = NULL;
5971   u32 i = ~0;
5972
5973   print (vam->ofp, "%-12s", "sw_if_index");
5974
5975   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5976   {
5977     i++;
5978     if (!det->present)
5979       {
5980         continue;
5981       }
5982     print (vam->ofp, "%-12d", i);
5983     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5984     if (!det->addr)
5985       {
5986         continue;
5987       }
5988     vec_foreach (address, det->addr)
5989     {
5990       print (vam->ofp,
5991              "            %-30U%-13d",
5992              is_ipv6 ? format_ip6_address : format_ip4_address,
5993              address->ip, address->prefix_length);
5994     }
5995   }
5996
5997   return 0;
5998 }
5999
6000 static int
6001 dump_ipv4_table (vat_main_t * vam)
6002 {
6003   if (vam->json_output)
6004     {
6005       clib_warning
6006         ("JSON output supported only for VPE API calls and dump_stats_table");
6007       return -99;
6008     }
6009
6010   return dump_ip_table (vam, 0);
6011 }
6012
6013 static int
6014 dump_ipv6_table (vat_main_t * vam)
6015 {
6016   if (vam->json_output)
6017     {
6018       clib_warning
6019         ("JSON output supported only for VPE API calls and dump_stats_table");
6020       return -99;
6021     }
6022
6023   return dump_ip_table (vam, 1);
6024 }
6025
6026 static char *
6027 counter_type_to_str (u8 counter_type, u8 is_combined)
6028 {
6029   if (!is_combined)
6030     {
6031       switch (counter_type)
6032         {
6033         case VNET_INTERFACE_COUNTER_DROP:
6034           return "drop";
6035         case VNET_INTERFACE_COUNTER_PUNT:
6036           return "punt";
6037         case VNET_INTERFACE_COUNTER_IP4:
6038           return "ip4";
6039         case VNET_INTERFACE_COUNTER_IP6:
6040           return "ip6";
6041         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6042           return "rx-no-buf";
6043         case VNET_INTERFACE_COUNTER_RX_MISS:
6044           return "rx-miss";
6045         case VNET_INTERFACE_COUNTER_RX_ERROR:
6046           return "rx-error";
6047         case VNET_INTERFACE_COUNTER_TX_ERROR:
6048           return "tx-error";
6049         default:
6050           return "INVALID-COUNTER-TYPE";
6051         }
6052     }
6053   else
6054     {
6055       switch (counter_type)
6056         {
6057         case VNET_INTERFACE_COUNTER_RX:
6058           return "rx";
6059         case VNET_INTERFACE_COUNTER_TX:
6060           return "tx";
6061         default:
6062           return "INVALID-COUNTER-TYPE";
6063         }
6064     }
6065 }
6066
6067 static int
6068 dump_stats_table (vat_main_t * vam)
6069 {
6070   vat_json_node_t node;
6071   vat_json_node_t *msg_array;
6072   vat_json_node_t *msg;
6073   vat_json_node_t *counter_array;
6074   vat_json_node_t *counter;
6075   interface_counter_t c;
6076   u64 packets;
6077   ip4_fib_counter_t *c4;
6078   ip6_fib_counter_t *c6;
6079   ip4_nbr_counter_t *n4;
6080   ip6_nbr_counter_t *n6;
6081   int i, j;
6082
6083   if (!vam->json_output)
6084     {
6085       clib_warning ("dump_stats_table supported only in JSON format");
6086       return -99;
6087     }
6088
6089   vat_json_init_object (&node);
6090
6091   /* interface counters */
6092   msg_array = vat_json_object_add (&node, "interface_counters");
6093   vat_json_init_array (msg_array);
6094   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6095     {
6096       msg = vat_json_array_add (msg_array);
6097       vat_json_init_object (msg);
6098       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6099                                        (u8 *) counter_type_to_str (i, 0));
6100       vat_json_object_add_int (msg, "is_combined", 0);
6101       counter_array = vat_json_object_add (msg, "data");
6102       vat_json_init_array (counter_array);
6103       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6104         {
6105           packets = vam->simple_interface_counters[i][j];
6106           vat_json_array_add_uint (counter_array, packets);
6107         }
6108     }
6109   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6110     {
6111       msg = vat_json_array_add (msg_array);
6112       vat_json_init_object (msg);
6113       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6114                                        (u8 *) counter_type_to_str (i, 1));
6115       vat_json_object_add_int (msg, "is_combined", 1);
6116       counter_array = vat_json_object_add (msg, "data");
6117       vat_json_init_array (counter_array);
6118       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6119         {
6120           c = vam->combined_interface_counters[i][j];
6121           counter = vat_json_array_add (counter_array);
6122           vat_json_init_object (counter);
6123           vat_json_object_add_uint (counter, "packets", c.packets);
6124           vat_json_object_add_uint (counter, "bytes", c.bytes);
6125         }
6126     }
6127
6128   /* ip4 fib counters */
6129   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6130   vat_json_init_array (msg_array);
6131   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6132     {
6133       msg = vat_json_array_add (msg_array);
6134       vat_json_init_object (msg);
6135       vat_json_object_add_uint (msg, "vrf_id",
6136                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6137       counter_array = vat_json_object_add (msg, "c");
6138       vat_json_init_array (counter_array);
6139       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6140         {
6141           counter = vat_json_array_add (counter_array);
6142           vat_json_init_object (counter);
6143           c4 = &vam->ip4_fib_counters[i][j];
6144           vat_json_object_add_ip4 (counter, "address", c4->address);
6145           vat_json_object_add_uint (counter, "address_length",
6146                                     c4->address_length);
6147           vat_json_object_add_uint (counter, "packets", c4->packets);
6148           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6149         }
6150     }
6151
6152   /* ip6 fib counters */
6153   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6154   vat_json_init_array (msg_array);
6155   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6156     {
6157       msg = vat_json_array_add (msg_array);
6158       vat_json_init_object (msg);
6159       vat_json_object_add_uint (msg, "vrf_id",
6160                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6161       counter_array = vat_json_object_add (msg, "c");
6162       vat_json_init_array (counter_array);
6163       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6164         {
6165           counter = vat_json_array_add (counter_array);
6166           vat_json_init_object (counter);
6167           c6 = &vam->ip6_fib_counters[i][j];
6168           vat_json_object_add_ip6 (counter, "address", c6->address);
6169           vat_json_object_add_uint (counter, "address_length",
6170                                     c6->address_length);
6171           vat_json_object_add_uint (counter, "packets", c6->packets);
6172           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6173         }
6174     }
6175
6176   /* ip4 nbr counters */
6177   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6178   vat_json_init_array (msg_array);
6179   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6180     {
6181       msg = vat_json_array_add (msg_array);
6182       vat_json_init_object (msg);
6183       vat_json_object_add_uint (msg, "sw_if_index", i);
6184       counter_array = vat_json_object_add (msg, "c");
6185       vat_json_init_array (counter_array);
6186       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6187         {
6188           counter = vat_json_array_add (counter_array);
6189           vat_json_init_object (counter);
6190           n4 = &vam->ip4_nbr_counters[i][j];
6191           vat_json_object_add_ip4 (counter, "address", n4->address);
6192           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6193           vat_json_object_add_uint (counter, "packets", n4->packets);
6194           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6195         }
6196     }
6197
6198   /* ip6 nbr counters */
6199   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6200   vat_json_init_array (msg_array);
6201   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6202     {
6203       msg = vat_json_array_add (msg_array);
6204       vat_json_init_object (msg);
6205       vat_json_object_add_uint (msg, "sw_if_index", i);
6206       counter_array = vat_json_object_add (msg, "c");
6207       vat_json_init_array (counter_array);
6208       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6209         {
6210           counter = vat_json_array_add (counter_array);
6211           vat_json_init_object (counter);
6212           n6 = &vam->ip6_nbr_counters[i][j];
6213           vat_json_object_add_ip6 (counter, "address", n6->address);
6214           vat_json_object_add_uint (counter, "packets", n6->packets);
6215           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6216         }
6217     }
6218
6219   vat_json_print (vam->ofp, &node);
6220   vat_json_free (&node);
6221
6222   return 0;
6223 }
6224
6225 /*
6226  * Pass CLI buffers directly in the CLI_INBAND API message,
6227  * instead of an additional shared memory area.
6228  */
6229 static int
6230 exec_inband (vat_main_t * vam)
6231 {
6232   vl_api_cli_inband_t *mp;
6233   unformat_input_t *i = vam->input;
6234   int ret;
6235
6236   if (vec_len (i->buffer) == 0)
6237     return -1;
6238
6239   if (vam->exec_mode == 0 && unformat (i, "mode"))
6240     {
6241       vam->exec_mode = 1;
6242       return 0;
6243     }
6244   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6245     {
6246       vam->exec_mode = 0;
6247       return 0;
6248     }
6249
6250   /*
6251    * In order for the CLI command to work, it
6252    * must be a vector ending in \n, not a C-string ending
6253    * in \n\0.
6254    */
6255   u32 len = vec_len (vam->input->buffer);
6256   M2 (CLI_INBAND, mp, len);
6257   clib_memcpy (mp->cmd, vam->input->buffer, len);
6258   mp->length = htonl (len);
6259
6260   S (mp);
6261   W (ret);
6262   /* json responses may or may not include a useful reply... */
6263   if (vec_len (vam->cmd_reply))
6264     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6265   return ret;
6266 }
6267
6268 int
6269 exec (vat_main_t * vam)
6270 {
6271   return exec_inband (vam);
6272 }
6273
6274 static int
6275 api_create_loopback (vat_main_t * vam)
6276 {
6277   unformat_input_t *i = vam->input;
6278   vl_api_create_loopback_t *mp;
6279   vl_api_create_loopback_instance_t *mp_lbi;
6280   u8 mac_address[6];
6281   u8 mac_set = 0;
6282   u8 is_specified = 0;
6283   u32 user_instance = 0;
6284   int ret;
6285
6286   memset (mac_address, 0, sizeof (mac_address));
6287
6288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6289     {
6290       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6291         mac_set = 1;
6292       if (unformat (i, "instance %d", &user_instance))
6293         is_specified = 1;
6294       else
6295         break;
6296     }
6297
6298   if (is_specified)
6299     {
6300       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6301       mp_lbi->is_specified = is_specified;
6302       if (is_specified)
6303         mp_lbi->user_instance = htonl (user_instance);
6304       if (mac_set)
6305         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6306       S (mp_lbi);
6307     }
6308   else
6309     {
6310       /* Construct the API message */
6311       M (CREATE_LOOPBACK, mp);
6312       if (mac_set)
6313         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6314       S (mp);
6315     }
6316
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_delete_loopback (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_delete_loopback_t *mp;
6326   u32 sw_if_index = ~0;
6327   int ret;
6328
6329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6330     {
6331       if (unformat (i, "sw_if_index %d", &sw_if_index))
6332         ;
6333       else
6334         break;
6335     }
6336
6337   if (sw_if_index == ~0)
6338     {
6339       errmsg ("missing sw_if_index");
6340       return -99;
6341     }
6342
6343   /* Construct the API message */
6344   M (DELETE_LOOPBACK, mp);
6345   mp->sw_if_index = ntohl (sw_if_index);
6346
6347   S (mp);
6348   W (ret);
6349   return ret;
6350 }
6351
6352 static int
6353 api_want_stats (vat_main_t * vam)
6354 {
6355   unformat_input_t *i = vam->input;
6356   vl_api_want_stats_t *mp;
6357   int enable = -1;
6358   int ret;
6359
6360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6361     {
6362       if (unformat (i, "enable"))
6363         enable = 1;
6364       else if (unformat (i, "disable"))
6365         enable = 0;
6366       else
6367         break;
6368     }
6369
6370   if (enable == -1)
6371     {
6372       errmsg ("missing enable|disable");
6373       return -99;
6374     }
6375
6376   M (WANT_STATS, mp);
6377   mp->enable_disable = enable;
6378
6379   S (mp);
6380   W (ret);
6381   return ret;
6382 }
6383
6384 static int
6385 api_want_interface_events (vat_main_t * vam)
6386 {
6387   unformat_input_t *i = vam->input;
6388   vl_api_want_interface_events_t *mp;
6389   int enable = -1;
6390   int ret;
6391
6392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6393     {
6394       if (unformat (i, "enable"))
6395         enable = 1;
6396       else if (unformat (i, "disable"))
6397         enable = 0;
6398       else
6399         break;
6400     }
6401
6402   if (enable == -1)
6403     {
6404       errmsg ("missing enable|disable");
6405       return -99;
6406     }
6407
6408   M (WANT_INTERFACE_EVENTS, mp);
6409   mp->enable_disable = enable;
6410
6411   vam->interface_event_display = enable;
6412
6413   S (mp);
6414   W (ret);
6415   return ret;
6416 }
6417
6418
6419 /* Note: non-static, called once to set up the initial intfc table */
6420 int
6421 api_sw_interface_dump (vat_main_t * vam)
6422 {
6423   vl_api_sw_interface_dump_t *mp;
6424   vl_api_control_ping_t *mp_ping;
6425   hash_pair_t *p;
6426   name_sort_t *nses = 0, *ns;
6427   sw_interface_subif_t *sub = NULL;
6428   int ret;
6429
6430   /* Toss the old name table */
6431   /* *INDENT-OFF* */
6432   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6433   ({
6434     vec_add2 (nses, ns, 1);
6435     ns->name = (u8 *)(p->key);
6436     ns->value = (u32) p->value[0];
6437   }));
6438   /* *INDENT-ON* */
6439
6440   hash_free (vam->sw_if_index_by_interface_name);
6441
6442   vec_foreach (ns, nses) vec_free (ns->name);
6443
6444   vec_free (nses);
6445
6446   vec_foreach (sub, vam->sw_if_subif_table)
6447   {
6448     vec_free (sub->interface_name);
6449   }
6450   vec_free (vam->sw_if_subif_table);
6451
6452   /* recreate the interface name hash table */
6453   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6454
6455   /*
6456    * Ask for all interface names. Otherwise, the epic catalog of
6457    * name filters becomes ridiculously long, and vat ends up needing
6458    * to be taught about new interface types.
6459    */
6460   M (SW_INTERFACE_DUMP, mp);
6461   S (mp);
6462
6463   /* Use a control ping for synchronization */
6464   MPING (CONTROL_PING, mp_ping);
6465   S (mp_ping);
6466
6467   W (ret);
6468   return ret;
6469 }
6470
6471 static int
6472 api_sw_interface_set_flags (vat_main_t * vam)
6473 {
6474   unformat_input_t *i = vam->input;
6475   vl_api_sw_interface_set_flags_t *mp;
6476   u32 sw_if_index;
6477   u8 sw_if_index_set = 0;
6478   u8 admin_up = 0;
6479   int ret;
6480
6481   /* Parse args required to build the message */
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "admin-up"))
6485         admin_up = 1;
6486       else if (unformat (i, "admin-down"))
6487         admin_up = 0;
6488       else
6489         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6490         sw_if_index_set = 1;
6491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6492         sw_if_index_set = 1;
6493       else
6494         break;
6495     }
6496
6497   if (sw_if_index_set == 0)
6498     {
6499       errmsg ("missing interface name or sw_if_index");
6500       return -99;
6501     }
6502
6503   /* Construct the API message */
6504   M (SW_INTERFACE_SET_FLAGS, mp);
6505   mp->sw_if_index = ntohl (sw_if_index);
6506   mp->admin_up_down = admin_up;
6507
6508   /* send it... */
6509   S (mp);
6510
6511   /* Wait for a reply, return the good/bad news... */
6512   W (ret);
6513   return ret;
6514 }
6515
6516 static int
6517 api_sw_interface_set_rx_mode (vat_main_t * vam)
6518 {
6519   unformat_input_t *i = vam->input;
6520   vl_api_sw_interface_set_rx_mode_t *mp;
6521   u32 sw_if_index;
6522   u8 sw_if_index_set = 0;
6523   int ret;
6524   u8 queue_id_valid = 0;
6525   u32 queue_id;
6526   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6527
6528   /* Parse args required to build the message */
6529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6530     {
6531       if (unformat (i, "queue %d", &queue_id))
6532         queue_id_valid = 1;
6533       else if (unformat (i, "polling"))
6534         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6535       else if (unformat (i, "interrupt"))
6536         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6537       else if (unformat (i, "adaptive"))
6538         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6539       else
6540         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6541         sw_if_index_set = 1;
6542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6543         sw_if_index_set = 1;
6544       else
6545         break;
6546     }
6547
6548   if (sw_if_index_set == 0)
6549     {
6550       errmsg ("missing interface name or sw_if_index");
6551       return -99;
6552     }
6553   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6554     {
6555       errmsg ("missing rx-mode");
6556       return -99;
6557     }
6558
6559   /* Construct the API message */
6560   M (SW_INTERFACE_SET_RX_MODE, mp);
6561   mp->sw_if_index = ntohl (sw_if_index);
6562   mp->mode = mode;
6563   mp->queue_id_valid = queue_id_valid;
6564   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6565
6566   /* send it... */
6567   S (mp);
6568
6569   /* Wait for a reply, return the good/bad news... */
6570   W (ret);
6571   return ret;
6572 }
6573
6574 static int
6575 api_sw_interface_set_rx_placement (vat_main_t * vam)
6576 {
6577   unformat_input_t *i = vam->input;
6578   vl_api_sw_interface_set_rx_placement_t *mp;
6579   u32 sw_if_index;
6580   u8 sw_if_index_set = 0;
6581   int ret;
6582   u8 is_main = 0;
6583   u32 queue_id, thread_index;
6584
6585   /* Parse args required to build the message */
6586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6587     {
6588       if (unformat (i, "queue %d", &queue_id))
6589         ;
6590       else if (unformat (i, "main"))
6591         is_main = 1;
6592       else if (unformat (i, "worker %d", &thread_index))
6593         ;
6594       else
6595         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6598         sw_if_index_set = 1;
6599       else
6600         break;
6601     }
6602
6603   if (sw_if_index_set == 0)
6604     {
6605       errmsg ("missing interface name or sw_if_index");
6606       return -99;
6607     }
6608
6609   if (is_main)
6610     thread_index = 0;
6611   /* Construct the API message */
6612   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6613   mp->sw_if_index = ntohl (sw_if_index);
6614   mp->worker_id = ntohl (thread_index);
6615   mp->queue_id = ntohl (queue_id);
6616   mp->is_main = is_main;
6617
6618   /* send it... */
6619   S (mp);
6620   /* Wait for a reply, return the good/bad news... */
6621   W (ret);
6622   return ret;
6623 }
6624
6625 static void vl_api_sw_interface_rx_placement_details_t_handler
6626   (vl_api_sw_interface_rx_placement_details_t * mp)
6627 {
6628   vat_main_t *vam = &vat_main;
6629   u32 worker_id = ntohl (mp->worker_id);
6630
6631   print (vam->ofp,
6632          "\n%-11d %-11s %-6d %-5d %-9s",
6633          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6634          worker_id, ntohl (mp->queue_id),
6635          (mp->mode ==
6636           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6637 }
6638
6639 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6640   (vl_api_sw_interface_rx_placement_details_t * mp)
6641 {
6642   vat_main_t *vam = &vat_main;
6643   vat_json_node_t *node = NULL;
6644
6645   if (VAT_JSON_ARRAY != vam->json_tree.type)
6646     {
6647       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6648       vat_json_init_array (&vam->json_tree);
6649     }
6650   node = vat_json_array_add (&vam->json_tree);
6651
6652   vat_json_init_object (node);
6653   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6654   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6655   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6656   vat_json_object_add_uint (node, "mode", mp->mode);
6657 }
6658
6659 static int
6660 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6661 {
6662   unformat_input_t *i = vam->input;
6663   vl_api_sw_interface_rx_placement_dump_t *mp;
6664   vl_api_control_ping_t *mp_ping;
6665   int ret;
6666   u32 sw_if_index;
6667   u8 sw_if_index_set = 0;
6668
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6672         sw_if_index_set++;
6673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6674         sw_if_index_set++;
6675       else
6676         break;
6677     }
6678
6679   print (vam->ofp,
6680          "\n%-11s %-11s %-6s %-5s %-4s",
6681          "sw_if_index", "main/worker", "thread", "queue", "mode");
6682
6683   /* Dump Interface rx placement */
6684   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6685
6686   if (sw_if_index_set)
6687     mp->sw_if_index = htonl (sw_if_index);
6688   else
6689     mp->sw_if_index = ~0;
6690
6691   S (mp);
6692
6693   /* Use a control ping for synchronization */
6694   MPING (CONTROL_PING, mp_ping);
6695   S (mp_ping);
6696
6697   W (ret);
6698   return ret;
6699 }
6700
6701 static int
6702 api_sw_interface_clear_stats (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_sw_interface_clear_stats_t *mp;
6706   u32 sw_if_index;
6707   u8 sw_if_index_set = 0;
6708   int ret;
6709
6710   /* Parse args required to build the message */
6711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6712     {
6713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6714         sw_if_index_set = 1;
6715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6716         sw_if_index_set = 1;
6717       else
6718         break;
6719     }
6720
6721   /* Construct the API message */
6722   M (SW_INTERFACE_CLEAR_STATS, mp);
6723
6724   if (sw_if_index_set == 1)
6725     mp->sw_if_index = ntohl (sw_if_index);
6726   else
6727     mp->sw_if_index = ~0;
6728
6729   /* send it... */
6730   S (mp);
6731
6732   /* Wait for a reply, return the good/bad news... */
6733   W (ret);
6734   return ret;
6735 }
6736
6737 static int
6738 api_sw_interface_add_del_address (vat_main_t * vam)
6739 {
6740   unformat_input_t *i = vam->input;
6741   vl_api_sw_interface_add_del_address_t *mp;
6742   u32 sw_if_index;
6743   u8 sw_if_index_set = 0;
6744   u8 is_add = 1, del_all = 0;
6745   u32 address_length = 0;
6746   u8 v4_address_set = 0;
6747   u8 v6_address_set = 0;
6748   ip4_address_t v4address;
6749   ip6_address_t v6address;
6750   int ret;
6751
6752   /* Parse args required to build the message */
6753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6754     {
6755       if (unformat (i, "del-all"))
6756         del_all = 1;
6757       else if (unformat (i, "del"))
6758         is_add = 0;
6759       else
6760         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6761         sw_if_index_set = 1;
6762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6763         sw_if_index_set = 1;
6764       else if (unformat (i, "%U/%d",
6765                          unformat_ip4_address, &v4address, &address_length))
6766         v4_address_set = 1;
6767       else if (unformat (i, "%U/%d",
6768                          unformat_ip6_address, &v6address, &address_length))
6769         v6_address_set = 1;
6770       else
6771         break;
6772     }
6773
6774   if (sw_if_index_set == 0)
6775     {
6776       errmsg ("missing interface name or sw_if_index");
6777       return -99;
6778     }
6779   if (v4_address_set && v6_address_set)
6780     {
6781       errmsg ("both v4 and v6 addresses set");
6782       return -99;
6783     }
6784   if (!v4_address_set && !v6_address_set && !del_all)
6785     {
6786       errmsg ("no addresses set");
6787       return -99;
6788     }
6789
6790   /* Construct the API message */
6791   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6792
6793   mp->sw_if_index = ntohl (sw_if_index);
6794   mp->is_add = is_add;
6795   mp->del_all = del_all;
6796   if (v6_address_set)
6797     {
6798       mp->is_ipv6 = 1;
6799       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6800     }
6801   else
6802     {
6803       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6804     }
6805   mp->address_length = address_length;
6806
6807   /* send it... */
6808   S (mp);
6809
6810   /* Wait for a reply, return good/bad news  */
6811   W (ret);
6812   return ret;
6813 }
6814
6815 static int
6816 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6817 {
6818   unformat_input_t *i = vam->input;
6819   vl_api_sw_interface_set_mpls_enable_t *mp;
6820   u32 sw_if_index;
6821   u8 sw_if_index_set = 0;
6822   u8 enable = 1;
6823   int ret;
6824
6825   /* Parse args required to build the message */
6826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6827     {
6828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6829         sw_if_index_set = 1;
6830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6831         sw_if_index_set = 1;
6832       else if (unformat (i, "disable"))
6833         enable = 0;
6834       else if (unformat (i, "dis"))
6835         enable = 0;
6836       else
6837         break;
6838     }
6839
6840   if (sw_if_index_set == 0)
6841     {
6842       errmsg ("missing interface name or sw_if_index");
6843       return -99;
6844     }
6845
6846   /* Construct the API message */
6847   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6848
6849   mp->sw_if_index = ntohl (sw_if_index);
6850   mp->enable = enable;
6851
6852   /* send it... */
6853   S (mp);
6854
6855   /* Wait for a reply... */
6856   W (ret);
6857   return ret;
6858 }
6859
6860 static int
6861 api_sw_interface_set_table (vat_main_t * vam)
6862 {
6863   unformat_input_t *i = vam->input;
6864   vl_api_sw_interface_set_table_t *mp;
6865   u32 sw_if_index, vrf_id = 0;
6866   u8 sw_if_index_set = 0;
6867   u8 is_ipv6 = 0;
6868   int ret;
6869
6870   /* Parse args required to build the message */
6871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6872     {
6873       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6874         sw_if_index_set = 1;
6875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6876         sw_if_index_set = 1;
6877       else if (unformat (i, "vrf %d", &vrf_id))
6878         ;
6879       else if (unformat (i, "ipv6"))
6880         is_ipv6 = 1;
6881       else
6882         break;
6883     }
6884
6885   if (sw_if_index_set == 0)
6886     {
6887       errmsg ("missing interface name or sw_if_index");
6888       return -99;
6889     }
6890
6891   /* Construct the API message */
6892   M (SW_INTERFACE_SET_TABLE, mp);
6893
6894   mp->sw_if_index = ntohl (sw_if_index);
6895   mp->is_ipv6 = is_ipv6;
6896   mp->vrf_id = ntohl (vrf_id);
6897
6898   /* send it... */
6899   S (mp);
6900
6901   /* Wait for a reply... */
6902   W (ret);
6903   return ret;
6904 }
6905
6906 static void vl_api_sw_interface_get_table_reply_t_handler
6907   (vl_api_sw_interface_get_table_reply_t * mp)
6908 {
6909   vat_main_t *vam = &vat_main;
6910
6911   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6912
6913   vam->retval = ntohl (mp->retval);
6914   vam->result_ready = 1;
6915
6916 }
6917
6918 static void vl_api_sw_interface_get_table_reply_t_handler_json
6919   (vl_api_sw_interface_get_table_reply_t * mp)
6920 {
6921   vat_main_t *vam = &vat_main;
6922   vat_json_node_t node;
6923
6924   vat_json_init_object (&node);
6925   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6926   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6927
6928   vat_json_print (vam->ofp, &node);
6929   vat_json_free (&node);
6930
6931   vam->retval = ntohl (mp->retval);
6932   vam->result_ready = 1;
6933 }
6934
6935 static int
6936 api_sw_interface_get_table (vat_main_t * vam)
6937 {
6938   unformat_input_t *i = vam->input;
6939   vl_api_sw_interface_get_table_t *mp;
6940   u32 sw_if_index;
6941   u8 sw_if_index_set = 0;
6942   u8 is_ipv6 = 0;
6943   int ret;
6944
6945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6946     {
6947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6948         sw_if_index_set = 1;
6949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6950         sw_if_index_set = 1;
6951       else if (unformat (i, "ipv6"))
6952         is_ipv6 = 1;
6953       else
6954         break;
6955     }
6956
6957   if (sw_if_index_set == 0)
6958     {
6959       errmsg ("missing interface name or sw_if_index");
6960       return -99;
6961     }
6962
6963   M (SW_INTERFACE_GET_TABLE, mp);
6964   mp->sw_if_index = htonl (sw_if_index);
6965   mp->is_ipv6 = is_ipv6;
6966
6967   S (mp);
6968   W (ret);
6969   return ret;
6970 }
6971
6972 static int
6973 api_sw_interface_set_vpath (vat_main_t * vam)
6974 {
6975   unformat_input_t *i = vam->input;
6976   vl_api_sw_interface_set_vpath_t *mp;
6977   u32 sw_if_index = 0;
6978   u8 sw_if_index_set = 0;
6979   u8 is_enable = 0;
6980   int ret;
6981
6982   /* Parse args required to build the message */
6983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984     {
6985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6986         sw_if_index_set = 1;
6987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6988         sw_if_index_set = 1;
6989       else if (unformat (i, "enable"))
6990         is_enable = 1;
6991       else if (unformat (i, "disable"))
6992         is_enable = 0;
6993       else
6994         break;
6995     }
6996
6997   if (sw_if_index_set == 0)
6998     {
6999       errmsg ("missing interface name or sw_if_index");
7000       return -99;
7001     }
7002
7003   /* Construct the API message */
7004   M (SW_INTERFACE_SET_VPATH, mp);
7005
7006   mp->sw_if_index = ntohl (sw_if_index);
7007   mp->enable = is_enable;
7008
7009   /* send it... */
7010   S (mp);
7011
7012   /* Wait for a reply... */
7013   W (ret);
7014   return ret;
7015 }
7016
7017 static int
7018 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7019 {
7020   unformat_input_t *i = vam->input;
7021   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7022   u32 sw_if_index = 0;
7023   u8 sw_if_index_set = 0;
7024   u8 is_enable = 1;
7025   u8 is_ipv6 = 0;
7026   int ret;
7027
7028   /* Parse args required to build the message */
7029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7030     {
7031       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7032         sw_if_index_set = 1;
7033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7034         sw_if_index_set = 1;
7035       else if (unformat (i, "enable"))
7036         is_enable = 1;
7037       else if (unformat (i, "disable"))
7038         is_enable = 0;
7039       else if (unformat (i, "ip4"))
7040         is_ipv6 = 0;
7041       else if (unformat (i, "ip6"))
7042         is_ipv6 = 1;
7043       else
7044         break;
7045     }
7046
7047   if (sw_if_index_set == 0)
7048     {
7049       errmsg ("missing interface name or sw_if_index");
7050       return -99;
7051     }
7052
7053   /* Construct the API message */
7054   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7055
7056   mp->sw_if_index = ntohl (sw_if_index);
7057   mp->enable = is_enable;
7058   mp->is_ipv6 = is_ipv6;
7059
7060   /* send it... */
7061   S (mp);
7062
7063   /* Wait for a reply... */
7064   W (ret);
7065   return ret;
7066 }
7067
7068 static int
7069 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7070 {
7071   unformat_input_t *i = vam->input;
7072   vl_api_sw_interface_set_geneve_bypass_t *mp;
7073   u32 sw_if_index = 0;
7074   u8 sw_if_index_set = 0;
7075   u8 is_enable = 1;
7076   u8 is_ipv6 = 0;
7077   int ret;
7078
7079   /* Parse args required to build the message */
7080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7081     {
7082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7083         sw_if_index_set = 1;
7084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7085         sw_if_index_set = 1;
7086       else if (unformat (i, "enable"))
7087         is_enable = 1;
7088       else if (unformat (i, "disable"))
7089         is_enable = 0;
7090       else if (unformat (i, "ip4"))
7091         is_ipv6 = 0;
7092       else if (unformat (i, "ip6"))
7093         is_ipv6 = 1;
7094       else
7095         break;
7096     }
7097
7098   if (sw_if_index_set == 0)
7099     {
7100       errmsg ("missing interface name or sw_if_index");
7101       return -99;
7102     }
7103
7104   /* Construct the API message */
7105   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7106
7107   mp->sw_if_index = ntohl (sw_if_index);
7108   mp->enable = is_enable;
7109   mp->is_ipv6 = is_ipv6;
7110
7111   /* send it... */
7112   S (mp);
7113
7114   /* Wait for a reply... */
7115   W (ret);
7116   return ret;
7117 }
7118
7119 static int
7120 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7121 {
7122   unformat_input_t *i = vam->input;
7123   vl_api_sw_interface_set_l2_xconnect_t *mp;
7124   u32 rx_sw_if_index;
7125   u8 rx_sw_if_index_set = 0;
7126   u32 tx_sw_if_index;
7127   u8 tx_sw_if_index_set = 0;
7128   u8 enable = 1;
7129   int ret;
7130
7131   /* Parse args required to build the message */
7132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7133     {
7134       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7135         rx_sw_if_index_set = 1;
7136       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7137         tx_sw_if_index_set = 1;
7138       else if (unformat (i, "rx"))
7139         {
7140           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7141             {
7142               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7143                             &rx_sw_if_index))
7144                 rx_sw_if_index_set = 1;
7145             }
7146           else
7147             break;
7148         }
7149       else if (unformat (i, "tx"))
7150         {
7151           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152             {
7153               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7154                             &tx_sw_if_index))
7155                 tx_sw_if_index_set = 1;
7156             }
7157           else
7158             break;
7159         }
7160       else if (unformat (i, "enable"))
7161         enable = 1;
7162       else if (unformat (i, "disable"))
7163         enable = 0;
7164       else
7165         break;
7166     }
7167
7168   if (rx_sw_if_index_set == 0)
7169     {
7170       errmsg ("missing rx interface name or rx_sw_if_index");
7171       return -99;
7172     }
7173
7174   if (enable && (tx_sw_if_index_set == 0))
7175     {
7176       errmsg ("missing tx interface name or tx_sw_if_index");
7177       return -99;
7178     }
7179
7180   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7181
7182   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7183   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7184   mp->enable = enable;
7185
7186   S (mp);
7187   W (ret);
7188   return ret;
7189 }
7190
7191 static int
7192 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7193 {
7194   unformat_input_t *i = vam->input;
7195   vl_api_sw_interface_set_l2_bridge_t *mp;
7196   vl_api_l2_port_type_t port_type;
7197   u32 rx_sw_if_index;
7198   u8 rx_sw_if_index_set = 0;
7199   u32 bd_id;
7200   u8 bd_id_set = 0;
7201   u32 shg = 0;
7202   u8 enable = 1;
7203   int ret;
7204
7205   port_type = L2_API_PORT_TYPE_NORMAL;
7206
7207   /* Parse args required to build the message */
7208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7209     {
7210       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7211         rx_sw_if_index_set = 1;
7212       else if (unformat (i, "bd_id %d", &bd_id))
7213         bd_id_set = 1;
7214       else
7215         if (unformat
7216             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7217         rx_sw_if_index_set = 1;
7218       else if (unformat (i, "shg %d", &shg))
7219         ;
7220       else if (unformat (i, "bvi"))
7221         port_type = L2_API_PORT_TYPE_BVI;
7222       else if (unformat (i, "uu-fwd"))
7223         port_type = L2_API_PORT_TYPE_UU_FWD;
7224       else if (unformat (i, "enable"))
7225         enable = 1;
7226       else if (unformat (i, "disable"))
7227         enable = 0;
7228       else
7229         break;
7230     }
7231
7232   if (rx_sw_if_index_set == 0)
7233     {
7234       errmsg ("missing rx interface name or sw_if_index");
7235       return -99;
7236     }
7237
7238   if (enable && (bd_id_set == 0))
7239     {
7240       errmsg ("missing bridge domain");
7241       return -99;
7242     }
7243
7244   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7245
7246   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7247   mp->bd_id = ntohl (bd_id);
7248   mp->shg = (u8) shg;
7249   mp->port_type = ntohl (port_type);
7250   mp->enable = enable;
7251
7252   S (mp);
7253   W (ret);
7254   return ret;
7255 }
7256
7257 static int
7258 api_bridge_domain_dump (vat_main_t * vam)
7259 {
7260   unformat_input_t *i = vam->input;
7261   vl_api_bridge_domain_dump_t *mp;
7262   vl_api_control_ping_t *mp_ping;
7263   u32 bd_id = ~0;
7264   int ret;
7265
7266   /* Parse args required to build the message */
7267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7268     {
7269       if (unformat (i, "bd_id %d", &bd_id))
7270         ;
7271       else
7272         break;
7273     }
7274
7275   M (BRIDGE_DOMAIN_DUMP, mp);
7276   mp->bd_id = ntohl (bd_id);
7277   S (mp);
7278
7279   /* Use a control ping for synchronization */
7280   MPING (CONTROL_PING, mp_ping);
7281   S (mp_ping);
7282
7283   W (ret);
7284   return ret;
7285 }
7286
7287 static int
7288 api_bridge_domain_add_del (vat_main_t * vam)
7289 {
7290   unformat_input_t *i = vam->input;
7291   vl_api_bridge_domain_add_del_t *mp;
7292   u32 bd_id = ~0;
7293   u8 is_add = 1;
7294   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7295   u8 *bd_tag = NULL;
7296   u32 mac_age = 0;
7297   int ret;
7298
7299   /* Parse args required to build the message */
7300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7301     {
7302       if (unformat (i, "bd_id %d", &bd_id))
7303         ;
7304       else if (unformat (i, "flood %d", &flood))
7305         ;
7306       else if (unformat (i, "uu-flood %d", &uu_flood))
7307         ;
7308       else if (unformat (i, "forward %d", &forward))
7309         ;
7310       else if (unformat (i, "learn %d", &learn))
7311         ;
7312       else if (unformat (i, "arp-term %d", &arp_term))
7313         ;
7314       else if (unformat (i, "mac-age %d", &mac_age))
7315         ;
7316       else if (unformat (i, "bd-tag %s", &bd_tag))
7317         ;
7318       else if (unformat (i, "del"))
7319         {
7320           is_add = 0;
7321           flood = uu_flood = forward = learn = 0;
7322         }
7323       else
7324         break;
7325     }
7326
7327   if (bd_id == ~0)
7328     {
7329       errmsg ("missing bridge domain");
7330       ret = -99;
7331       goto done;
7332     }
7333
7334   if (mac_age > 255)
7335     {
7336       errmsg ("mac age must be less than 256 ");
7337       ret = -99;
7338       goto done;
7339     }
7340
7341   if ((bd_tag) && (vec_len (bd_tag) > 63))
7342     {
7343       errmsg ("bd-tag cannot be longer than 63");
7344       ret = -99;
7345       goto done;
7346     }
7347
7348   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7349
7350   mp->bd_id = ntohl (bd_id);
7351   mp->flood = flood;
7352   mp->uu_flood = uu_flood;
7353   mp->forward = forward;
7354   mp->learn = learn;
7355   mp->arp_term = arp_term;
7356   mp->is_add = is_add;
7357   mp->mac_age = (u8) mac_age;
7358   if (bd_tag)
7359     {
7360       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7361       mp->bd_tag[vec_len (bd_tag)] = 0;
7362     }
7363   S (mp);
7364   W (ret);
7365
7366 done:
7367   vec_free (bd_tag);
7368   return ret;
7369 }
7370
7371 static int
7372 api_l2fib_flush_bd (vat_main_t * vam)
7373 {
7374   unformat_input_t *i = vam->input;
7375   vl_api_l2fib_flush_bd_t *mp;
7376   u32 bd_id = ~0;
7377   int ret;
7378
7379   /* Parse args required to build the message */
7380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7381     {
7382       if (unformat (i, "bd_id %d", &bd_id));
7383       else
7384         break;
7385     }
7386
7387   if (bd_id == ~0)
7388     {
7389       errmsg ("missing bridge domain");
7390       return -99;
7391     }
7392
7393   M (L2FIB_FLUSH_BD, mp);
7394
7395   mp->bd_id = htonl (bd_id);
7396
7397   S (mp);
7398   W (ret);
7399   return ret;
7400 }
7401
7402 static int
7403 api_l2fib_flush_int (vat_main_t * vam)
7404 {
7405   unformat_input_t *i = vam->input;
7406   vl_api_l2fib_flush_int_t *mp;
7407   u32 sw_if_index = ~0;
7408   int ret;
7409
7410   /* Parse args required to build the message */
7411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7412     {
7413       if (unformat (i, "sw_if_index %d", &sw_if_index));
7414       else
7415         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7416       else
7417         break;
7418     }
7419
7420   if (sw_if_index == ~0)
7421     {
7422       errmsg ("missing interface name or sw_if_index");
7423       return -99;
7424     }
7425
7426   M (L2FIB_FLUSH_INT, mp);
7427
7428   mp->sw_if_index = ntohl (sw_if_index);
7429
7430   S (mp);
7431   W (ret);
7432   return ret;
7433 }
7434
7435 static int
7436 api_l2fib_add_del (vat_main_t * vam)
7437 {
7438   unformat_input_t *i = vam->input;
7439   vl_api_l2fib_add_del_t *mp;
7440   f64 timeout;
7441   u8 mac[6] = { 0 };
7442   u8 mac_set = 0;
7443   u32 bd_id;
7444   u8 bd_id_set = 0;
7445   u32 sw_if_index = 0;
7446   u8 sw_if_index_set = 0;
7447   u8 is_add = 1;
7448   u8 static_mac = 0;
7449   u8 filter_mac = 0;
7450   u8 bvi_mac = 0;
7451   int count = 1;
7452   f64 before = 0;
7453   int j;
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7459         mac_set = 1;
7460       else if (unformat (i, "bd_id %d", &bd_id))
7461         bd_id_set = 1;
7462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7463         sw_if_index_set = 1;
7464       else if (unformat (i, "sw_if"))
7465         {
7466           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467             {
7468               if (unformat
7469                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7470                 sw_if_index_set = 1;
7471             }
7472           else
7473             break;
7474         }
7475       else if (unformat (i, "static"))
7476         static_mac = 1;
7477       else if (unformat (i, "filter"))
7478         {
7479           filter_mac = 1;
7480           static_mac = 1;
7481         }
7482       else if (unformat (i, "bvi"))
7483         {
7484           bvi_mac = 1;
7485           static_mac = 1;
7486         }
7487       else if (unformat (i, "del"))
7488         is_add = 0;
7489       else if (unformat (i, "count %d", &count))
7490         ;
7491       else
7492         break;
7493     }
7494
7495   if (mac_set == 0)
7496     {
7497       errmsg ("missing mac address");
7498       return -99;
7499     }
7500
7501   if (bd_id_set == 0)
7502     {
7503       errmsg ("missing bridge domain");
7504       return -99;
7505     }
7506
7507   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7508     {
7509       errmsg ("missing interface name or sw_if_index");
7510       return -99;
7511     }
7512
7513   if (count > 1)
7514     {
7515       /* Turn on async mode */
7516       vam->async_mode = 1;
7517       vam->async_errors = 0;
7518       before = vat_time_now (vam);
7519     }
7520
7521   for (j = 0; j < count; j++)
7522     {
7523       M (L2FIB_ADD_DEL, mp);
7524
7525       clib_memcpy (mp->mac, mac, 6);
7526       mp->bd_id = ntohl (bd_id);
7527       mp->is_add = is_add;
7528       mp->sw_if_index = ntohl (sw_if_index);
7529
7530       if (is_add)
7531         {
7532           mp->static_mac = static_mac;
7533           mp->filter_mac = filter_mac;
7534           mp->bvi_mac = bvi_mac;
7535         }
7536       increment_mac_address (mac);
7537       /* send it... */
7538       S (mp);
7539     }
7540
7541   if (count > 1)
7542     {
7543       vl_api_control_ping_t *mp_ping;
7544       f64 after;
7545
7546       /* Shut off async mode */
7547       vam->async_mode = 0;
7548
7549       MPING (CONTROL_PING, mp_ping);
7550       S (mp_ping);
7551
7552       timeout = vat_time_now (vam) + 1.0;
7553       while (vat_time_now (vam) < timeout)
7554         if (vam->result_ready == 1)
7555           goto out;
7556       vam->retval = -99;
7557
7558     out:
7559       if (vam->retval == -99)
7560         errmsg ("timeout");
7561
7562       if (vam->async_errors > 0)
7563         {
7564           errmsg ("%d asynchronous errors", vam->async_errors);
7565           vam->retval = -98;
7566         }
7567       vam->async_errors = 0;
7568       after = vat_time_now (vam);
7569
7570       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7571              count, after - before, count / (after - before));
7572     }
7573   else
7574     {
7575       int ret;
7576
7577       /* Wait for a reply... */
7578       W (ret);
7579       return ret;
7580     }
7581   /* Return the good/bad news */
7582   return (vam->retval);
7583 }
7584
7585 static int
7586 api_bridge_domain_set_mac_age (vat_main_t * vam)
7587 {
7588   unformat_input_t *i = vam->input;
7589   vl_api_bridge_domain_set_mac_age_t *mp;
7590   u32 bd_id = ~0;
7591   u32 mac_age = 0;
7592   int ret;
7593
7594   /* Parse args required to build the message */
7595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7596     {
7597       if (unformat (i, "bd_id %d", &bd_id));
7598       else if (unformat (i, "mac-age %d", &mac_age));
7599       else
7600         break;
7601     }
7602
7603   if (bd_id == ~0)
7604     {
7605       errmsg ("missing bridge domain");
7606       return -99;
7607     }
7608
7609   if (mac_age > 255)
7610     {
7611       errmsg ("mac age must be less than 256 ");
7612       return -99;
7613     }
7614
7615   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7616
7617   mp->bd_id = htonl (bd_id);
7618   mp->mac_age = (u8) mac_age;
7619
7620   S (mp);
7621   W (ret);
7622   return ret;
7623 }
7624
7625 static int
7626 api_l2_flags (vat_main_t * vam)
7627 {
7628   unformat_input_t *i = vam->input;
7629   vl_api_l2_flags_t *mp;
7630   u32 sw_if_index;
7631   u32 flags = 0;
7632   u8 sw_if_index_set = 0;
7633   u8 is_set = 0;
7634   int ret;
7635
7636   /* Parse args required to build the message */
7637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7638     {
7639       if (unformat (i, "sw_if_index %d", &sw_if_index))
7640         sw_if_index_set = 1;
7641       else if (unformat (i, "sw_if"))
7642         {
7643           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7644             {
7645               if (unformat
7646                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7647                 sw_if_index_set = 1;
7648             }
7649           else
7650             break;
7651         }
7652       else if (unformat (i, "learn"))
7653         flags |= L2_LEARN;
7654       else if (unformat (i, "forward"))
7655         flags |= L2_FWD;
7656       else if (unformat (i, "flood"))
7657         flags |= L2_FLOOD;
7658       else if (unformat (i, "uu-flood"))
7659         flags |= L2_UU_FLOOD;
7660       else if (unformat (i, "arp-term"))
7661         flags |= L2_ARP_TERM;
7662       else if (unformat (i, "off"))
7663         is_set = 0;
7664       else if (unformat (i, "disable"))
7665         is_set = 0;
7666       else
7667         break;
7668     }
7669
7670   if (sw_if_index_set == 0)
7671     {
7672       errmsg ("missing interface name or sw_if_index");
7673       return -99;
7674     }
7675
7676   M (L2_FLAGS, mp);
7677
7678   mp->sw_if_index = ntohl (sw_if_index);
7679   mp->feature_bitmap = ntohl (flags);
7680   mp->is_set = is_set;
7681
7682   S (mp);
7683   W (ret);
7684   return ret;
7685 }
7686
7687 static int
7688 api_bridge_flags (vat_main_t * vam)
7689 {
7690   unformat_input_t *i = vam->input;
7691   vl_api_bridge_flags_t *mp;
7692   u32 bd_id;
7693   u8 bd_id_set = 0;
7694   u8 is_set = 1;
7695   bd_flags_t flags = 0;
7696   int ret;
7697
7698   /* Parse args required to build the message */
7699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7700     {
7701       if (unformat (i, "bd_id %d", &bd_id))
7702         bd_id_set = 1;
7703       else if (unformat (i, "learn"))
7704         flags |= BRIDGE_API_FLAG_LEARN;
7705       else if (unformat (i, "forward"))
7706         flags |= BRIDGE_API_FLAG_FWD;
7707       else if (unformat (i, "flood"))
7708         flags |= BRIDGE_API_FLAG_FLOOD;
7709       else if (unformat (i, "uu-flood"))
7710         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7711       else if (unformat (i, "arp-term"))
7712         flags |= BRIDGE_API_FLAG_ARP_TERM;
7713       else if (unformat (i, "off"))
7714         is_set = 0;
7715       else if (unformat (i, "disable"))
7716         is_set = 0;
7717       else
7718         break;
7719     }
7720
7721   if (bd_id_set == 0)
7722     {
7723       errmsg ("missing bridge domain");
7724       return -99;
7725     }
7726
7727   M (BRIDGE_FLAGS, mp);
7728
7729   mp->bd_id = ntohl (bd_id);
7730   mp->flags = ntohl (flags);
7731   mp->is_set = is_set;
7732
7733   S (mp);
7734   W (ret);
7735   return ret;
7736 }
7737
7738 static int
7739 api_bd_ip_mac_add_del (vat_main_t * vam)
7740 {
7741   unformat_input_t *i = vam->input;
7742   vl_api_bd_ip_mac_add_del_t *mp;
7743   u32 bd_id;
7744   u8 is_ipv6 = 0;
7745   u8 is_add = 1;
7746   u8 bd_id_set = 0;
7747   u8 ip_set = 0;
7748   u8 mac_set = 0;
7749   ip4_address_t v4addr;
7750   ip6_address_t v6addr;
7751   u8 macaddr[6];
7752   int ret;
7753
7754
7755   /* Parse args required to build the message */
7756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7757     {
7758       if (unformat (i, "bd_id %d", &bd_id))
7759         {
7760           bd_id_set++;
7761         }
7762       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7763         {
7764           ip_set++;
7765         }
7766       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7767         {
7768           ip_set++;
7769           is_ipv6++;
7770         }
7771       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7772         {
7773           mac_set++;
7774         }
7775       else if (unformat (i, "del"))
7776         is_add = 0;
7777       else
7778         break;
7779     }
7780
7781   if (bd_id_set == 0)
7782     {
7783       errmsg ("missing bridge domain");
7784       return -99;
7785     }
7786   else if (ip_set == 0)
7787     {
7788       errmsg ("missing IP address");
7789       return -99;
7790     }
7791   else if (mac_set == 0)
7792     {
7793       errmsg ("missing MAC address");
7794       return -99;
7795     }
7796
7797   M (BD_IP_MAC_ADD_DEL, mp);
7798
7799   mp->bd_id = ntohl (bd_id);
7800   mp->is_ipv6 = is_ipv6;
7801   mp->is_add = is_add;
7802   if (is_ipv6)
7803     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7804   else
7805     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7806   clib_memcpy (mp->mac_address, macaddr, 6);
7807   S (mp);
7808   W (ret);
7809   return ret;
7810 }
7811
7812 static void vl_api_bd_ip_mac_details_t_handler
7813   (vl_api_bd_ip_mac_details_t * mp)
7814 {
7815   vat_main_t *vam = &vat_main;
7816   u8 *ip = 0;
7817
7818   if (!mp->is_ipv6)
7819     ip =
7820       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7821   else
7822     ip =
7823       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7824
7825   print (vam->ofp,
7826          "\n%-5d %-7s %-20U %-30s",
7827          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7828          format_ethernet_address, mp->mac_address, ip);
7829
7830   vec_free (ip);
7831 }
7832
7833 static void vl_api_bd_ip_mac_details_t_handler_json
7834   (vl_api_bd_ip_mac_details_t * mp)
7835 {
7836   vat_main_t *vam = &vat_main;
7837   vat_json_node_t *node = NULL;
7838
7839   if (VAT_JSON_ARRAY != vam->json_tree.type)
7840     {
7841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7842       vat_json_init_array (&vam->json_tree);
7843     }
7844   node = vat_json_array_add (&vam->json_tree);
7845
7846   vat_json_init_object (node);
7847   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7848   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7849   vat_json_object_add_string_copy (node, "mac_address",
7850                                    format (0, "%U", format_ethernet_address,
7851                                            &mp->mac_address));
7852   u8 *ip = 0;
7853
7854   if (!mp->is_ipv6)
7855     ip =
7856       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7857   else
7858     ip =
7859       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7860   vat_json_object_add_string_copy (node, "ip_address", ip);
7861   vec_free (ip);
7862 }
7863
7864 static int
7865 api_bd_ip_mac_dump (vat_main_t * vam)
7866 {
7867   unformat_input_t *i = vam->input;
7868   vl_api_bd_ip_mac_dump_t *mp;
7869   vl_api_control_ping_t *mp_ping;
7870   int ret;
7871   u32 bd_id;
7872   u8 bd_id_set = 0;
7873
7874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7875     {
7876       if (unformat (i, "bd_id %d", &bd_id))
7877         {
7878           bd_id_set++;
7879         }
7880       else
7881         break;
7882     }
7883
7884   print (vam->ofp,
7885          "\n%-5s %-7s %-20s %-30s",
7886          "bd_id", "is_ipv6", "mac_address", "ip_address");
7887
7888   /* Dump Bridge Domain Ip to Mac entries */
7889   M (BD_IP_MAC_DUMP, mp);
7890
7891   if (bd_id_set)
7892     mp->bd_id = htonl (bd_id);
7893   else
7894     mp->bd_id = ~0;
7895
7896   S (mp);
7897
7898   /* Use a control ping for synchronization */
7899   MPING (CONTROL_PING, mp_ping);
7900   S (mp_ping);
7901
7902   W (ret);
7903   return ret;
7904 }
7905
7906 static int
7907 api_tap_connect (vat_main_t * vam)
7908 {
7909   unformat_input_t *i = vam->input;
7910   vl_api_tap_connect_t *mp;
7911   u8 mac_address[6];
7912   u8 random_mac = 1;
7913   u8 name_set = 0;
7914   u8 *tap_name;
7915   u8 *tag = 0;
7916   ip4_address_t ip4_address;
7917   u32 ip4_mask_width;
7918   int ip4_address_set = 0;
7919   ip6_address_t ip6_address;
7920   u32 ip6_mask_width;
7921   int ip6_address_set = 0;
7922   int ret;
7923
7924   memset (mac_address, 0, sizeof (mac_address));
7925
7926   /* Parse args required to build the message */
7927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7928     {
7929       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7930         {
7931           random_mac = 0;
7932         }
7933       else if (unformat (i, "random-mac"))
7934         random_mac = 1;
7935       else if (unformat (i, "tapname %s", &tap_name))
7936         name_set = 1;
7937       else if (unformat (i, "tag %s", &tag))
7938         ;
7939       else if (unformat (i, "address %U/%d",
7940                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7941         ip4_address_set = 1;
7942       else if (unformat (i, "address %U/%d",
7943                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7944         ip6_address_set = 1;
7945       else
7946         break;
7947     }
7948
7949   if (name_set == 0)
7950     {
7951       errmsg ("missing tap name");
7952       return -99;
7953     }
7954   if (vec_len (tap_name) > 63)
7955     {
7956       errmsg ("tap name too long");
7957       return -99;
7958     }
7959   vec_add1 (tap_name, 0);
7960
7961   if (vec_len (tag) > 63)
7962     {
7963       errmsg ("tag too long");
7964       return -99;
7965     }
7966
7967   /* Construct the API message */
7968   M (TAP_CONNECT, mp);
7969
7970   mp->use_random_mac = random_mac;
7971   clib_memcpy (mp->mac_address, mac_address, 6);
7972   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7973   if (tag)
7974     clib_memcpy (mp->tag, tag, vec_len (tag));
7975
7976   if (ip4_address_set)
7977     {
7978       mp->ip4_address_set = 1;
7979       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7980       mp->ip4_mask_width = ip4_mask_width;
7981     }
7982   if (ip6_address_set)
7983     {
7984       mp->ip6_address_set = 1;
7985       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7986       mp->ip6_mask_width = ip6_mask_width;
7987     }
7988
7989   vec_free (tap_name);
7990   vec_free (tag);
7991
7992   /* send it... */
7993   S (mp);
7994
7995   /* Wait for a reply... */
7996   W (ret);
7997   return ret;
7998 }
7999
8000 static int
8001 api_tap_modify (vat_main_t * vam)
8002 {
8003   unformat_input_t *i = vam->input;
8004   vl_api_tap_modify_t *mp;
8005   u8 mac_address[6];
8006   u8 random_mac = 1;
8007   u8 name_set = 0;
8008   u8 *tap_name;
8009   u32 sw_if_index = ~0;
8010   u8 sw_if_index_set = 0;
8011   int ret;
8012
8013   memset (mac_address, 0, sizeof (mac_address));
8014
8015   /* Parse args required to build the message */
8016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8017     {
8018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8019         sw_if_index_set = 1;
8020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8021         sw_if_index_set = 1;
8022       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8023         {
8024           random_mac = 0;
8025         }
8026       else if (unformat (i, "random-mac"))
8027         random_mac = 1;
8028       else if (unformat (i, "tapname %s", &tap_name))
8029         name_set = 1;
8030       else
8031         break;
8032     }
8033
8034   if (sw_if_index_set == 0)
8035     {
8036       errmsg ("missing vpp interface name");
8037       return -99;
8038     }
8039   if (name_set == 0)
8040     {
8041       errmsg ("missing tap name");
8042       return -99;
8043     }
8044   if (vec_len (tap_name) > 63)
8045     {
8046       errmsg ("tap name too long");
8047     }
8048   vec_add1 (tap_name, 0);
8049
8050   /* Construct the API message */
8051   M (TAP_MODIFY, mp);
8052
8053   mp->use_random_mac = random_mac;
8054   mp->sw_if_index = ntohl (sw_if_index);
8055   clib_memcpy (mp->mac_address, mac_address, 6);
8056   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8057   vec_free (tap_name);
8058
8059   /* send it... */
8060   S (mp);
8061
8062   /* Wait for a reply... */
8063   W (ret);
8064   return ret;
8065 }
8066
8067 static int
8068 api_tap_delete (vat_main_t * vam)
8069 {
8070   unformat_input_t *i = vam->input;
8071   vl_api_tap_delete_t *mp;
8072   u32 sw_if_index = ~0;
8073   u8 sw_if_index_set = 0;
8074   int ret;
8075
8076   /* Parse args required to build the message */
8077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8078     {
8079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8080         sw_if_index_set = 1;
8081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8082         sw_if_index_set = 1;
8083       else
8084         break;
8085     }
8086
8087   if (sw_if_index_set == 0)
8088     {
8089       errmsg ("missing vpp interface name");
8090       return -99;
8091     }
8092
8093   /* Construct the API message */
8094   M (TAP_DELETE, mp);
8095
8096   mp->sw_if_index = ntohl (sw_if_index);
8097
8098   /* send it... */
8099   S (mp);
8100
8101   /* Wait for a reply... */
8102   W (ret);
8103   return ret;
8104 }
8105
8106 static int
8107 api_tap_create_v2 (vat_main_t * vam)
8108 {
8109   unformat_input_t *i = vam->input;
8110   vl_api_tap_create_v2_t *mp;
8111   u8 mac_address[6];
8112   u8 random_mac = 1;
8113   u32 id = ~0;
8114   u8 *host_if_name = 0;
8115   u8 *host_ns = 0;
8116   u8 host_mac_addr[6];
8117   u8 host_mac_addr_set = 0;
8118   u8 *host_bridge = 0;
8119   ip4_address_t host_ip4_addr;
8120   ip4_address_t host_ip4_gw;
8121   u8 host_ip4_gw_set = 0;
8122   u32 host_ip4_prefix_len = 0;
8123   ip6_address_t host_ip6_addr;
8124   ip6_address_t host_ip6_gw;
8125   u8 host_ip6_gw_set = 0;
8126   u32 host_ip6_prefix_len = 0;
8127   int ret;
8128   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8129
8130   memset (mac_address, 0, sizeof (mac_address));
8131
8132   /* Parse args required to build the message */
8133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8134     {
8135       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8136         {
8137           random_mac = 0;
8138         }
8139       else if (unformat (i, "id %u", &id))
8140         ;
8141       else if (unformat (i, "host-if-name %s", &host_if_name))
8142         ;
8143       else if (unformat (i, "host-ns %s", &host_ns))
8144         ;
8145       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8146                          host_mac_addr))
8147         host_mac_addr_set = 1;
8148       else if (unformat (i, "host-bridge %s", &host_bridge))
8149         ;
8150       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8151                          &host_ip4_addr, &host_ip4_prefix_len))
8152         ;
8153       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8154                          &host_ip6_addr, &host_ip6_prefix_len))
8155         ;
8156       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8157                          &host_ip4_gw))
8158         host_ip4_gw_set = 1;
8159       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8160                          &host_ip6_gw))
8161         host_ip6_gw_set = 1;
8162       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8163         ;
8164       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8165         ;
8166       else
8167         break;
8168     }
8169
8170   if (vec_len (host_if_name) > 63)
8171     {
8172       errmsg ("tap name too long. ");
8173       return -99;
8174     }
8175   if (vec_len (host_ns) > 63)
8176     {
8177       errmsg ("host name space too long. ");
8178       return -99;
8179     }
8180   if (vec_len (host_bridge) > 63)
8181     {
8182       errmsg ("host bridge name too long. ");
8183       return -99;
8184     }
8185   if (host_ip4_prefix_len > 32)
8186     {
8187       errmsg ("host ip4 prefix length not valid. ");
8188       return -99;
8189     }
8190   if (host_ip6_prefix_len > 128)
8191     {
8192       errmsg ("host ip6 prefix length not valid. ");
8193       return -99;
8194     }
8195   if (!is_pow2 (rx_ring_sz))
8196     {
8197       errmsg ("rx ring size must be power of 2. ");
8198       return -99;
8199     }
8200   if (rx_ring_sz > 32768)
8201     {
8202       errmsg ("rx ring size must be 32768 or lower. ");
8203       return -99;
8204     }
8205   if (!is_pow2 (tx_ring_sz))
8206     {
8207       errmsg ("tx ring size must be power of 2. ");
8208       return -99;
8209     }
8210   if (tx_ring_sz > 32768)
8211     {
8212       errmsg ("tx ring size must be 32768 or lower. ");
8213       return -99;
8214     }
8215
8216   /* Construct the API message */
8217   M (TAP_CREATE_V2, mp);
8218
8219   mp->use_random_mac = random_mac;
8220
8221   mp->id = ntohl (id);
8222   mp->host_namespace_set = host_ns != 0;
8223   mp->host_bridge_set = host_bridge != 0;
8224   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8225   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8226   mp->rx_ring_sz = ntohs (rx_ring_sz);
8227   mp->tx_ring_sz = ntohs (tx_ring_sz);
8228
8229   if (random_mac == 0)
8230     clib_memcpy (mp->mac_address, mac_address, 6);
8231   if (host_mac_addr_set)
8232     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8233   if (host_if_name)
8234     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8235   if (host_ns)
8236     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8237   if (host_bridge)
8238     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8239   if (host_ip4_prefix_len)
8240     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8241   if (host_ip4_prefix_len)
8242     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8243   if (host_ip4_gw_set)
8244     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8245   if (host_ip6_gw_set)
8246     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8247
8248   vec_free (host_ns);
8249   vec_free (host_if_name);
8250   vec_free (host_bridge);
8251
8252   /* send it... */
8253   S (mp);
8254
8255   /* Wait for a reply... */
8256   W (ret);
8257   return ret;
8258 }
8259
8260 static int
8261 api_tap_delete_v2 (vat_main_t * vam)
8262 {
8263   unformat_input_t *i = vam->input;
8264   vl_api_tap_delete_v2_t *mp;
8265   u32 sw_if_index = ~0;
8266   u8 sw_if_index_set = 0;
8267   int ret;
8268
8269   /* Parse args required to build the message */
8270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8273         sw_if_index_set = 1;
8274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8275         sw_if_index_set = 1;
8276       else
8277         break;
8278     }
8279
8280   if (sw_if_index_set == 0)
8281     {
8282       errmsg ("missing vpp interface name. ");
8283       return -99;
8284     }
8285
8286   /* Construct the API message */
8287   M (TAP_DELETE_V2, mp);
8288
8289   mp->sw_if_index = ntohl (sw_if_index);
8290
8291   /* send it... */
8292   S (mp);
8293
8294   /* Wait for a reply... */
8295   W (ret);
8296   return ret;
8297 }
8298
8299 static int
8300 api_bond_create (vat_main_t * vam)
8301 {
8302   unformat_input_t *i = vam->input;
8303   vl_api_bond_create_t *mp;
8304   u8 mac_address[6];
8305   u8 custom_mac = 0;
8306   int ret;
8307   u8 mode;
8308   u8 lb;
8309   u8 mode_is_set = 0;
8310
8311   memset (mac_address, 0, sizeof (mac_address));
8312   lb = BOND_LB_L2;
8313
8314   /* Parse args required to build the message */
8315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8316     {
8317       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8318         mode_is_set = 1;
8319       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8320                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8321         ;
8322       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8323                          mac_address))
8324         custom_mac = 1;
8325       else
8326         break;
8327     }
8328
8329   if (mode_is_set == 0)
8330     {
8331       errmsg ("Missing bond mode. ");
8332       return -99;
8333     }
8334
8335   /* Construct the API message */
8336   M (BOND_CREATE, mp);
8337
8338   mp->use_custom_mac = custom_mac;
8339
8340   mp->mode = mode;
8341   mp->lb = lb;
8342
8343   if (custom_mac)
8344     clib_memcpy (mp->mac_address, mac_address, 6);
8345
8346   /* send it... */
8347   S (mp);
8348
8349   /* Wait for a reply... */
8350   W (ret);
8351   return ret;
8352 }
8353
8354 static int
8355 api_bond_delete (vat_main_t * vam)
8356 {
8357   unformat_input_t *i = vam->input;
8358   vl_api_bond_delete_t *mp;
8359   u32 sw_if_index = ~0;
8360   u8 sw_if_index_set = 0;
8361   int ret;
8362
8363   /* Parse args required to build the message */
8364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8365     {
8366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8367         sw_if_index_set = 1;
8368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8369         sw_if_index_set = 1;
8370       else
8371         break;
8372     }
8373
8374   if (sw_if_index_set == 0)
8375     {
8376       errmsg ("missing vpp interface name. ");
8377       return -99;
8378     }
8379
8380   /* Construct the API message */
8381   M (BOND_DELETE, mp);
8382
8383   mp->sw_if_index = ntohl (sw_if_index);
8384
8385   /* send it... */
8386   S (mp);
8387
8388   /* Wait for a reply... */
8389   W (ret);
8390   return ret;
8391 }
8392
8393 static int
8394 api_bond_enslave (vat_main_t * vam)
8395 {
8396   unformat_input_t *i = vam->input;
8397   vl_api_bond_enslave_t *mp;
8398   u32 bond_sw_if_index;
8399   int ret;
8400   u8 is_passive;
8401   u8 is_long_timeout;
8402   u32 bond_sw_if_index_is_set = 0;
8403   u32 sw_if_index;
8404   u8 sw_if_index_is_set = 0;
8405
8406   /* Parse args required to build the message */
8407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (unformat (i, "sw_if_index %d", &sw_if_index))
8410         sw_if_index_is_set = 1;
8411       else if (unformat (i, "bond %u", &bond_sw_if_index))
8412         bond_sw_if_index_is_set = 1;
8413       else if (unformat (i, "passive %d", &is_passive))
8414         ;
8415       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8416         ;
8417       else
8418         break;
8419     }
8420
8421   if (bond_sw_if_index_is_set == 0)
8422     {
8423       errmsg ("Missing bond sw_if_index. ");
8424       return -99;
8425     }
8426   if (sw_if_index_is_set == 0)
8427     {
8428       errmsg ("Missing slave sw_if_index. ");
8429       return -99;
8430     }
8431
8432   /* Construct the API message */
8433   M (BOND_ENSLAVE, mp);
8434
8435   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8436   mp->sw_if_index = ntohl (sw_if_index);
8437   mp->is_long_timeout = is_long_timeout;
8438   mp->is_passive = is_passive;
8439
8440   /* send it... */
8441   S (mp);
8442
8443   /* Wait for a reply... */
8444   W (ret);
8445   return ret;
8446 }
8447
8448 static int
8449 api_bond_detach_slave (vat_main_t * vam)
8450 {
8451   unformat_input_t *i = vam->input;
8452   vl_api_bond_detach_slave_t *mp;
8453   u32 sw_if_index = ~0;
8454   u8 sw_if_index_set = 0;
8455   int ret;
8456
8457   /* Parse args required to build the message */
8458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8459     {
8460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8461         sw_if_index_set = 1;
8462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8463         sw_if_index_set = 1;
8464       else
8465         break;
8466     }
8467
8468   if (sw_if_index_set == 0)
8469     {
8470       errmsg ("missing vpp interface name. ");
8471       return -99;
8472     }
8473
8474   /* Construct the API message */
8475   M (BOND_DETACH_SLAVE, mp);
8476
8477   mp->sw_if_index = ntohl (sw_if_index);
8478
8479   /* send it... */
8480   S (mp);
8481
8482   /* Wait for a reply... */
8483   W (ret);
8484   return ret;
8485 }
8486
8487 static int
8488 api_ip_table_add_del (vat_main_t * vam)
8489 {
8490   unformat_input_t *i = vam->input;
8491   vl_api_ip_table_add_del_t *mp;
8492   u32 table_id = ~0;
8493   u8 is_ipv6 = 0;
8494   u8 is_add = 1;
8495   int ret = 0;
8496
8497   /* Parse args required to build the message */
8498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8499     {
8500       if (unformat (i, "ipv6"))
8501         is_ipv6 = 1;
8502       else if (unformat (i, "del"))
8503         is_add = 0;
8504       else if (unformat (i, "add"))
8505         is_add = 1;
8506       else if (unformat (i, "table %d", &table_id))
8507         ;
8508       else
8509         {
8510           clib_warning ("parse error '%U'", format_unformat_error, i);
8511           return -99;
8512         }
8513     }
8514
8515   if (~0 == table_id)
8516     {
8517       errmsg ("missing table-ID");
8518       return -99;
8519     }
8520
8521   /* Construct the API message */
8522   M (IP_TABLE_ADD_DEL, mp);
8523
8524   mp->table_id = ntohl (table_id);
8525   mp->is_ipv6 = is_ipv6;
8526   mp->is_add = is_add;
8527
8528   /* send it... */
8529   S (mp);
8530
8531   /* Wait for a reply... */
8532   W (ret);
8533
8534   return ret;
8535 }
8536
8537 static int
8538 api_ip_add_del_route (vat_main_t * vam)
8539 {
8540   unformat_input_t *i = vam->input;
8541   vl_api_ip_add_del_route_t *mp;
8542   u32 sw_if_index = ~0, vrf_id = 0;
8543   u8 is_ipv6 = 0;
8544   u8 is_local = 0, is_drop = 0;
8545   u8 is_unreach = 0, is_prohibit = 0;
8546   u8 is_add = 1;
8547   u32 next_hop_weight = 1;
8548   u8 is_multipath = 0;
8549   u8 address_set = 0;
8550   u8 address_length_set = 0;
8551   u32 next_hop_table_id = 0;
8552   u32 resolve_attempts = 0;
8553   u32 dst_address_length = 0;
8554   u8 next_hop_set = 0;
8555   ip4_address_t v4_dst_address, v4_next_hop_address;
8556   ip6_address_t v6_dst_address, v6_next_hop_address;
8557   int count = 1;
8558   int j;
8559   f64 before = 0;
8560   u32 random_add_del = 0;
8561   u32 *random_vector = 0;
8562   uword *random_hash;
8563   u32 random_seed = 0xdeaddabe;
8564   u32 classify_table_index = ~0;
8565   u8 is_classify = 0;
8566   u8 resolve_host = 0, resolve_attached = 0;
8567   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8568   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8569   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8570
8571   memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8572   memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8573   /* Parse args required to build the message */
8574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8575     {
8576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8577         ;
8578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8579         ;
8580       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8581         {
8582           address_set = 1;
8583           is_ipv6 = 0;
8584         }
8585       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8586         {
8587           address_set = 1;
8588           is_ipv6 = 1;
8589         }
8590       else if (unformat (i, "/%d", &dst_address_length))
8591         {
8592           address_length_set = 1;
8593         }
8594
8595       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8596                                          &v4_next_hop_address))
8597         {
8598           next_hop_set = 1;
8599         }
8600       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8601                                          &v6_next_hop_address))
8602         {
8603           next_hop_set = 1;
8604         }
8605       else
8606         if (unformat
8607             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8608         {
8609           next_hop_set = 1;
8610         }
8611       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8612         {
8613           next_hop_set = 1;
8614         }
8615       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8616         ;
8617       else if (unformat (i, "weight %d", &next_hop_weight))
8618         ;
8619       else if (unformat (i, "drop"))
8620         {
8621           is_drop = 1;
8622         }
8623       else if (unformat (i, "null-send-unreach"))
8624         {
8625           is_unreach = 1;
8626         }
8627       else if (unformat (i, "null-send-prohibit"))
8628         {
8629           is_prohibit = 1;
8630         }
8631       else if (unformat (i, "local"))
8632         {
8633           is_local = 1;
8634         }
8635       else if (unformat (i, "classify %d", &classify_table_index))
8636         {
8637           is_classify = 1;
8638         }
8639       else if (unformat (i, "del"))
8640         is_add = 0;
8641       else if (unformat (i, "add"))
8642         is_add = 1;
8643       else if (unformat (i, "resolve-via-host"))
8644         resolve_host = 1;
8645       else if (unformat (i, "resolve-via-attached"))
8646         resolve_attached = 1;
8647       else if (unformat (i, "multipath"))
8648         is_multipath = 1;
8649       else if (unformat (i, "vrf %d", &vrf_id))
8650         ;
8651       else if (unformat (i, "count %d", &count))
8652         ;
8653       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8654         ;
8655       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8656         ;
8657       else if (unformat (i, "out-label %d", &next_hop_out_label))
8658         {
8659           vl_api_fib_mpls_label_t fib_label = {
8660             .label = ntohl (next_hop_out_label),
8661             .ttl = 64,
8662             .exp = 0,
8663           };
8664           vec_add1 (next_hop_out_label_stack, fib_label);
8665         }
8666       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8667         ;
8668       else if (unformat (i, "random"))
8669         random_add_del = 1;
8670       else if (unformat (i, "seed %d", &random_seed))
8671         ;
8672       else
8673         {
8674           clib_warning ("parse error '%U'", format_unformat_error, i);
8675           return -99;
8676         }
8677     }
8678
8679   if (!next_hop_set && !is_drop && !is_local &&
8680       !is_classify && !is_unreach && !is_prohibit &&
8681       MPLS_LABEL_INVALID == next_hop_via_label)
8682     {
8683       errmsg
8684         ("next hop / local / drop / unreach / prohibit / classify not set");
8685       return -99;
8686     }
8687
8688   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8689     {
8690       errmsg ("next hop and next-hop via label set");
8691       return -99;
8692     }
8693   if (address_set == 0)
8694     {
8695       errmsg ("missing addresses");
8696       return -99;
8697     }
8698
8699   if (address_length_set == 0)
8700     {
8701       errmsg ("missing address length");
8702       return -99;
8703     }
8704
8705   /* Generate a pile of unique, random routes */
8706   if (random_add_del)
8707     {
8708       u32 this_random_address;
8709       random_hash = hash_create (count, sizeof (uword));
8710
8711       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8712       for (j = 0; j <= count; j++)
8713         {
8714           do
8715             {
8716               this_random_address = random_u32 (&random_seed);
8717               this_random_address =
8718                 clib_host_to_net_u32 (this_random_address);
8719             }
8720           while (hash_get (random_hash, this_random_address));
8721           vec_add1 (random_vector, this_random_address);
8722           hash_set (random_hash, this_random_address, 1);
8723         }
8724       hash_free (random_hash);
8725       v4_dst_address.as_u32 = random_vector[0];
8726     }
8727
8728   if (count > 1)
8729     {
8730       /* Turn on async mode */
8731       vam->async_mode = 1;
8732       vam->async_errors = 0;
8733       before = vat_time_now (vam);
8734     }
8735
8736   for (j = 0; j < count; j++)
8737     {
8738       /* Construct the API message */
8739       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8740           vec_len (next_hop_out_label_stack));
8741
8742       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8743       mp->table_id = ntohl (vrf_id);
8744
8745       mp->is_add = is_add;
8746       mp->is_drop = is_drop;
8747       mp->is_unreach = is_unreach;
8748       mp->is_prohibit = is_prohibit;
8749       mp->is_ipv6 = is_ipv6;
8750       mp->is_local = is_local;
8751       mp->is_classify = is_classify;
8752       mp->is_multipath = is_multipath;
8753       mp->is_resolve_host = resolve_host;
8754       mp->is_resolve_attached = resolve_attached;
8755       mp->next_hop_weight = next_hop_weight;
8756       mp->dst_address_length = dst_address_length;
8757       mp->next_hop_table_id = ntohl (next_hop_table_id);
8758       mp->classify_table_index = ntohl (classify_table_index);
8759       mp->next_hop_via_label = ntohl (next_hop_via_label);
8760       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8761       if (0 != mp->next_hop_n_out_labels)
8762         {
8763           memcpy (mp->next_hop_out_label_stack,
8764                   next_hop_out_label_stack,
8765                   (vec_len (next_hop_out_label_stack) *
8766                    sizeof (vl_api_fib_mpls_label_t)));
8767           vec_free (next_hop_out_label_stack);
8768         }
8769
8770       if (is_ipv6)
8771         {
8772           clib_memcpy (mp->dst_address, &v6_dst_address,
8773                        sizeof (v6_dst_address));
8774           if (next_hop_set)
8775             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8776                          sizeof (v6_next_hop_address));
8777           increment_v6_address (&v6_dst_address);
8778         }
8779       else
8780         {
8781           clib_memcpy (mp->dst_address, &v4_dst_address,
8782                        sizeof (v4_dst_address));
8783           if (next_hop_set)
8784             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8785                          sizeof (v4_next_hop_address));
8786           if (random_add_del)
8787             v4_dst_address.as_u32 = random_vector[j + 1];
8788           else
8789             increment_v4_address (&v4_dst_address);
8790         }
8791       /* send it... */
8792       S (mp);
8793       /* If we receive SIGTERM, stop now... */
8794       if (vam->do_exit)
8795         break;
8796     }
8797
8798   /* When testing multiple add/del ops, use a control-ping to sync */
8799   if (count > 1)
8800     {
8801       vl_api_control_ping_t *mp_ping;
8802       f64 after;
8803       f64 timeout;
8804
8805       /* Shut off async mode */
8806       vam->async_mode = 0;
8807
8808       MPING (CONTROL_PING, mp_ping);
8809       S (mp_ping);
8810
8811       timeout = vat_time_now (vam) + 1.0;
8812       while (vat_time_now (vam) < timeout)
8813         if (vam->result_ready == 1)
8814           goto out;
8815       vam->retval = -99;
8816
8817     out:
8818       if (vam->retval == -99)
8819         errmsg ("timeout");
8820
8821       if (vam->async_errors > 0)
8822         {
8823           errmsg ("%d asynchronous errors", vam->async_errors);
8824           vam->retval = -98;
8825         }
8826       vam->async_errors = 0;
8827       after = vat_time_now (vam);
8828
8829       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8830       if (j > 0)
8831         count = j;
8832
8833       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8834              count, after - before, count / (after - before));
8835     }
8836   else
8837     {
8838       int ret;
8839
8840       /* Wait for a reply... */
8841       W (ret);
8842       return ret;
8843     }
8844
8845   /* Return the good/bad news */
8846   return (vam->retval);
8847 }
8848
8849 static int
8850 api_ip_mroute_add_del (vat_main_t * vam)
8851 {
8852   unformat_input_t *i = vam->input;
8853   vl_api_ip_mroute_add_del_t *mp;
8854   u32 sw_if_index = ~0, vrf_id = 0;
8855   u8 is_ipv6 = 0;
8856   u8 is_local = 0;
8857   u8 is_add = 1;
8858   u8 address_set = 0;
8859   u32 grp_address_length = 0;
8860   ip4_address_t v4_grp_address, v4_src_address;
8861   ip6_address_t v6_grp_address, v6_src_address;
8862   mfib_itf_flags_t iflags = 0;
8863   mfib_entry_flags_t eflags = 0;
8864   int ret;
8865
8866   /* Parse args required to build the message */
8867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8868     {
8869       if (unformat (i, "sw_if_index %d", &sw_if_index))
8870         ;
8871       else if (unformat (i, "%U %U",
8872                          unformat_ip4_address, &v4_src_address,
8873                          unformat_ip4_address, &v4_grp_address))
8874         {
8875           grp_address_length = 64;
8876           address_set = 1;
8877           is_ipv6 = 0;
8878         }
8879       else if (unformat (i, "%U %U",
8880                          unformat_ip6_address, &v6_src_address,
8881                          unformat_ip6_address, &v6_grp_address))
8882         {
8883           grp_address_length = 256;
8884           address_set = 1;
8885           is_ipv6 = 1;
8886         }
8887       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8888         {
8889           memset (&v4_src_address, 0, sizeof (v4_src_address));
8890           grp_address_length = 32;
8891           address_set = 1;
8892           is_ipv6 = 0;
8893         }
8894       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8895         {
8896           memset (&v6_src_address, 0, sizeof (v6_src_address));
8897           grp_address_length = 128;
8898           address_set = 1;
8899           is_ipv6 = 1;
8900         }
8901       else if (unformat (i, "/%d", &grp_address_length))
8902         ;
8903       else if (unformat (i, "local"))
8904         {
8905           is_local = 1;
8906         }
8907       else if (unformat (i, "del"))
8908         is_add = 0;
8909       else if (unformat (i, "add"))
8910         is_add = 1;
8911       else if (unformat (i, "vrf %d", &vrf_id))
8912         ;
8913       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8914         ;
8915       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8916         ;
8917       else
8918         {
8919           clib_warning ("parse error '%U'", format_unformat_error, i);
8920           return -99;
8921         }
8922     }
8923
8924   if (address_set == 0)
8925     {
8926       errmsg ("missing addresses\n");
8927       return -99;
8928     }
8929
8930   /* Construct the API message */
8931   M (IP_MROUTE_ADD_DEL, mp);
8932
8933   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8934   mp->table_id = ntohl (vrf_id);
8935
8936   mp->is_add = is_add;
8937   mp->is_ipv6 = is_ipv6;
8938   mp->is_local = is_local;
8939   mp->itf_flags = ntohl (iflags);
8940   mp->entry_flags = ntohl (eflags);
8941   mp->grp_address_length = grp_address_length;
8942   mp->grp_address_length = ntohs (mp->grp_address_length);
8943
8944   if (is_ipv6)
8945     {
8946       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8947       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8948     }
8949   else
8950     {
8951       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8952       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8953
8954     }
8955
8956   /* send it... */
8957   S (mp);
8958   /* Wait for a reply... */
8959   W (ret);
8960   return ret;
8961 }
8962
8963 static int
8964 api_mpls_table_add_del (vat_main_t * vam)
8965 {
8966   unformat_input_t *i = vam->input;
8967   vl_api_mpls_table_add_del_t *mp;
8968   u32 table_id = ~0;
8969   u8 is_add = 1;
8970   int ret = 0;
8971
8972   /* Parse args required to build the message */
8973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (i, "table %d", &table_id))
8976         ;
8977       else if (unformat (i, "del"))
8978         is_add = 0;
8979       else if (unformat (i, "add"))
8980         is_add = 1;
8981       else
8982         {
8983           clib_warning ("parse error '%U'", format_unformat_error, i);
8984           return -99;
8985         }
8986     }
8987
8988   if (~0 == table_id)
8989     {
8990       errmsg ("missing table-ID");
8991       return -99;
8992     }
8993
8994   /* Construct the API message */
8995   M (MPLS_TABLE_ADD_DEL, mp);
8996
8997   mp->mt_table_id = ntohl (table_id);
8998   mp->mt_is_add = is_add;
8999
9000   /* send it... */
9001   S (mp);
9002
9003   /* Wait for a reply... */
9004   W (ret);
9005
9006   return ret;
9007 }
9008
9009 static int
9010 api_mpls_route_add_del (vat_main_t * vam)
9011 {
9012   unformat_input_t *i = vam->input;
9013   vl_api_mpls_route_add_del_t *mp;
9014   u32 sw_if_index = ~0, table_id = 0;
9015   u8 is_add = 1;
9016   u32 next_hop_weight = 1;
9017   u8 is_multipath = 0;
9018   u32 next_hop_table_id = 0;
9019   u8 next_hop_set = 0;
9020   ip4_address_t v4_next_hop_address = {
9021     .as_u32 = 0,
9022   };
9023   ip6_address_t v6_next_hop_address = { {0} };
9024   int count = 1;
9025   int j;
9026   f64 before = 0;
9027   u32 classify_table_index = ~0;
9028   u8 is_classify = 0;
9029   u8 resolve_host = 0, resolve_attached = 0;
9030   u8 is_interface_rx = 0;
9031   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9032   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9033   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9034   mpls_label_t local_label = MPLS_LABEL_INVALID;
9035   u8 is_eos = 0;
9036   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9037
9038   /* Parse args required to build the message */
9039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9040     {
9041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9042         ;
9043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9044         ;
9045       else if (unformat (i, "%d", &local_label))
9046         ;
9047       else if (unformat (i, "eos"))
9048         is_eos = 1;
9049       else if (unformat (i, "non-eos"))
9050         is_eos = 0;
9051       else if (unformat (i, "via %U", unformat_ip4_address,
9052                          &v4_next_hop_address))
9053         {
9054           next_hop_set = 1;
9055           next_hop_proto = DPO_PROTO_IP4;
9056         }
9057       else if (unformat (i, "via %U", unformat_ip6_address,
9058                          &v6_next_hop_address))
9059         {
9060           next_hop_set = 1;
9061           next_hop_proto = DPO_PROTO_IP6;
9062         }
9063       else if (unformat (i, "weight %d", &next_hop_weight))
9064         ;
9065       else if (unformat (i, "classify %d", &classify_table_index))
9066         {
9067           is_classify = 1;
9068         }
9069       else if (unformat (i, "del"))
9070         is_add = 0;
9071       else if (unformat (i, "add"))
9072         is_add = 1;
9073       else if (unformat (i, "resolve-via-host"))
9074         resolve_host = 1;
9075       else if (unformat (i, "resolve-via-attached"))
9076         resolve_attached = 1;
9077       else if (unformat (i, "multipath"))
9078         is_multipath = 1;
9079       else if (unformat (i, "count %d", &count))
9080         ;
9081       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9082         {
9083           next_hop_set = 1;
9084           next_hop_proto = DPO_PROTO_IP4;
9085         }
9086       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9087         {
9088           next_hop_set = 1;
9089           next_hop_proto = DPO_PROTO_IP6;
9090         }
9091       else
9092         if (unformat
9093             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9094              &sw_if_index))
9095         {
9096           next_hop_set = 1;
9097           next_hop_proto = DPO_PROTO_ETHERNET;
9098           is_interface_rx = 1;
9099         }
9100       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9101         {
9102           next_hop_set = 1;
9103           next_hop_proto = DPO_PROTO_ETHERNET;
9104           is_interface_rx = 1;
9105         }
9106       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9107         next_hop_set = 1;
9108       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9109         next_hop_set = 1;
9110       else if (unformat (i, "out-label %d", &next_hop_out_label))
9111         {
9112           vl_api_fib_mpls_label_t fib_label = {
9113             .label = ntohl (next_hop_out_label),
9114             .ttl = 64,
9115             .exp = 0,
9116           };
9117           vec_add1 (next_hop_out_label_stack, fib_label);
9118         }
9119       else
9120         {
9121           clib_warning ("parse error '%U'", format_unformat_error, i);
9122           return -99;
9123         }
9124     }
9125
9126   if (!next_hop_set && !is_classify)
9127     {
9128       errmsg ("next hop / classify not set");
9129       return -99;
9130     }
9131
9132   if (MPLS_LABEL_INVALID == local_label)
9133     {
9134       errmsg ("missing label");
9135       return -99;
9136     }
9137
9138   if (count > 1)
9139     {
9140       /* Turn on async mode */
9141       vam->async_mode = 1;
9142       vam->async_errors = 0;
9143       before = vat_time_now (vam);
9144     }
9145
9146   for (j = 0; j < count; j++)
9147     {
9148       /* Construct the API message */
9149       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9150           vec_len (next_hop_out_label_stack));
9151
9152       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9153       mp->mr_table_id = ntohl (table_id);
9154
9155       mp->mr_is_add = is_add;
9156       mp->mr_next_hop_proto = next_hop_proto;
9157       mp->mr_is_classify = is_classify;
9158       mp->mr_is_multipath = is_multipath;
9159       mp->mr_is_resolve_host = resolve_host;
9160       mp->mr_is_resolve_attached = resolve_attached;
9161       mp->mr_is_interface_rx = is_interface_rx;
9162       mp->mr_next_hop_weight = next_hop_weight;
9163       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9164       mp->mr_classify_table_index = ntohl (classify_table_index);
9165       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9166       mp->mr_label = ntohl (local_label);
9167       mp->mr_eos = is_eos;
9168
9169       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9170       if (0 != mp->mr_next_hop_n_out_labels)
9171         {
9172           memcpy (mp->mr_next_hop_out_label_stack,
9173                   next_hop_out_label_stack,
9174                   vec_len (next_hop_out_label_stack) *
9175                   sizeof (vl_api_fib_mpls_label_t));
9176           vec_free (next_hop_out_label_stack);
9177         }
9178
9179       if (next_hop_set)
9180         {
9181           if (DPO_PROTO_IP4 == next_hop_proto)
9182             {
9183               clib_memcpy (mp->mr_next_hop,
9184                            &v4_next_hop_address,
9185                            sizeof (v4_next_hop_address));
9186             }
9187           else if (DPO_PROTO_IP6 == next_hop_proto)
9188
9189             {
9190               clib_memcpy (mp->mr_next_hop,
9191                            &v6_next_hop_address,
9192                            sizeof (v6_next_hop_address));
9193             }
9194         }
9195       local_label++;
9196
9197       /* send it... */
9198       S (mp);
9199       /* If we receive SIGTERM, stop now... */
9200       if (vam->do_exit)
9201         break;
9202     }
9203
9204   /* When testing multiple add/del ops, use a control-ping to sync */
9205   if (count > 1)
9206     {
9207       vl_api_control_ping_t *mp_ping;
9208       f64 after;
9209       f64 timeout;
9210
9211       /* Shut off async mode */
9212       vam->async_mode = 0;
9213
9214       MPING (CONTROL_PING, mp_ping);
9215       S (mp_ping);
9216
9217       timeout = vat_time_now (vam) + 1.0;
9218       while (vat_time_now (vam) < timeout)
9219         if (vam->result_ready == 1)
9220           goto out;
9221       vam->retval = -99;
9222
9223     out:
9224       if (vam->retval == -99)
9225         errmsg ("timeout");
9226
9227       if (vam->async_errors > 0)
9228         {
9229           errmsg ("%d asynchronous errors", vam->async_errors);
9230           vam->retval = -98;
9231         }
9232       vam->async_errors = 0;
9233       after = vat_time_now (vam);
9234
9235       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9236       if (j > 0)
9237         count = j;
9238
9239       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9240              count, after - before, count / (after - before));
9241     }
9242   else
9243     {
9244       int ret;
9245
9246       /* Wait for a reply... */
9247       W (ret);
9248       return ret;
9249     }
9250
9251   /* Return the good/bad news */
9252   return (vam->retval);
9253 }
9254
9255 static int
9256 api_mpls_ip_bind_unbind (vat_main_t * vam)
9257 {
9258   unformat_input_t *i = vam->input;
9259   vl_api_mpls_ip_bind_unbind_t *mp;
9260   u32 ip_table_id = 0;
9261   u8 is_bind = 1;
9262   u8 is_ip4 = 1;
9263   ip4_address_t v4_address;
9264   ip6_address_t v6_address;
9265   u32 address_length;
9266   u8 address_set = 0;
9267   mpls_label_t local_label = MPLS_LABEL_INVALID;
9268   int ret;
9269
9270   /* Parse args required to build the message */
9271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9272     {
9273       if (unformat (i, "%U/%d", unformat_ip4_address,
9274                     &v4_address, &address_length))
9275         {
9276           is_ip4 = 1;
9277           address_set = 1;
9278         }
9279       else if (unformat (i, "%U/%d", unformat_ip6_address,
9280                          &v6_address, &address_length))
9281         {
9282           is_ip4 = 0;
9283           address_set = 1;
9284         }
9285       else if (unformat (i, "%d", &local_label))
9286         ;
9287       else if (unformat (i, "table-id %d", &ip_table_id))
9288         ;
9289       else if (unformat (i, "unbind"))
9290         is_bind = 0;
9291       else if (unformat (i, "bind"))
9292         is_bind = 1;
9293       else
9294         {
9295           clib_warning ("parse error '%U'", format_unformat_error, i);
9296           return -99;
9297         }
9298     }
9299
9300   if (!address_set)
9301     {
9302       errmsg ("IP address not set");
9303       return -99;
9304     }
9305
9306   if (MPLS_LABEL_INVALID == local_label)
9307     {
9308       errmsg ("missing label");
9309       return -99;
9310     }
9311
9312   /* Construct the API message */
9313   M (MPLS_IP_BIND_UNBIND, mp);
9314
9315   mp->mb_is_bind = is_bind;
9316   mp->mb_is_ip4 = is_ip4;
9317   mp->mb_ip_table_id = ntohl (ip_table_id);
9318   mp->mb_mpls_table_id = 0;
9319   mp->mb_label = ntohl (local_label);
9320   mp->mb_address_length = address_length;
9321
9322   if (is_ip4)
9323     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9324   else
9325     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9326
9327   /* send it... */
9328   S (mp);
9329
9330   /* Wait for a reply... */
9331   W (ret);
9332   return ret;
9333 }
9334
9335 static int
9336 api_sr_mpls_policy_add (vat_main_t * vam)
9337 {
9338   unformat_input_t *i = vam->input;
9339   vl_api_sr_mpls_policy_add_t *mp;
9340   u32 bsid = 0;
9341   u32 weight = 1;
9342   u8 type = 0;
9343   u8 n_segments = 0;
9344   u32 sid;
9345   u32 *segments = NULL;
9346   int ret;
9347
9348   /* Parse args required to build the message */
9349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9350     {
9351       if (unformat (i, "bsid %d", &bsid))
9352         ;
9353       else if (unformat (i, "weight %d", &weight))
9354         ;
9355       else if (unformat (i, "spray"))
9356         type = 1;
9357       else if (unformat (i, "next %d", &sid))
9358         {
9359           n_segments += 1;
9360           vec_add1 (segments, htonl (sid));
9361         }
9362       else
9363         {
9364           clib_warning ("parse error '%U'", format_unformat_error, i);
9365           return -99;
9366         }
9367     }
9368
9369   if (bsid == 0)
9370     {
9371       errmsg ("bsid not set");
9372       return -99;
9373     }
9374
9375   if (n_segments == 0)
9376     {
9377       errmsg ("no sid in segment stack");
9378       return -99;
9379     }
9380
9381   /* Construct the API message */
9382   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9383
9384   mp->bsid = htonl (bsid);
9385   mp->weight = htonl (weight);
9386   mp->type = type;
9387   mp->n_segments = n_segments;
9388   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9389   vec_free (segments);
9390
9391   /* send it... */
9392   S (mp);
9393
9394   /* Wait for a reply... */
9395   W (ret);
9396   return ret;
9397 }
9398
9399 static int
9400 api_sr_mpls_policy_del (vat_main_t * vam)
9401 {
9402   unformat_input_t *i = vam->input;
9403   vl_api_sr_mpls_policy_del_t *mp;
9404   u32 bsid = 0;
9405   int ret;
9406
9407   /* Parse args required to build the message */
9408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9409     {
9410       if (unformat (i, "bsid %d", &bsid))
9411         ;
9412       else
9413         {
9414           clib_warning ("parse error '%U'", format_unformat_error, i);
9415           return -99;
9416         }
9417     }
9418
9419   if (bsid == 0)
9420     {
9421       errmsg ("bsid not set");
9422       return -99;
9423     }
9424
9425   /* Construct the API message */
9426   M (SR_MPLS_POLICY_DEL, mp);
9427
9428   mp->bsid = htonl (bsid);
9429
9430   /* send it... */
9431   S (mp);
9432
9433   /* Wait for a reply... */
9434   W (ret);
9435   return ret;
9436 }
9437
9438 static int
9439 api_bier_table_add_del (vat_main_t * vam)
9440 {
9441   unformat_input_t *i = vam->input;
9442   vl_api_bier_table_add_del_t *mp;
9443   u8 is_add = 1;
9444   u32 set = 0, sub_domain = 0, hdr_len = 3;
9445   mpls_label_t local_label = MPLS_LABEL_INVALID;
9446   int ret;
9447
9448   /* Parse args required to build the message */
9449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9450     {
9451       if (unformat (i, "sub-domain %d", &sub_domain))
9452         ;
9453       else if (unformat (i, "set %d", &set))
9454         ;
9455       else if (unformat (i, "label %d", &local_label))
9456         ;
9457       else if (unformat (i, "hdr-len %d", &hdr_len))
9458         ;
9459       else if (unformat (i, "add"))
9460         is_add = 1;
9461       else if (unformat (i, "del"))
9462         is_add = 0;
9463       else
9464         {
9465           clib_warning ("parse error '%U'", format_unformat_error, i);
9466           return -99;
9467         }
9468     }
9469
9470   if (MPLS_LABEL_INVALID == local_label)
9471     {
9472       errmsg ("missing label\n");
9473       return -99;
9474     }
9475
9476   /* Construct the API message */
9477   M (BIER_TABLE_ADD_DEL, mp);
9478
9479   mp->bt_is_add = is_add;
9480   mp->bt_label = ntohl (local_label);
9481   mp->bt_tbl_id.bt_set = set;
9482   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9483   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9484
9485   /* send it... */
9486   S (mp);
9487
9488   /* Wait for a reply... */
9489   W (ret);
9490
9491   return (ret);
9492 }
9493
9494 static int
9495 api_bier_route_add_del (vat_main_t * vam)
9496 {
9497   unformat_input_t *i = vam->input;
9498   vl_api_bier_route_add_del_t *mp;
9499   u8 is_add = 1;
9500   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9501   ip4_address_t v4_next_hop_address;
9502   ip6_address_t v6_next_hop_address;
9503   u8 next_hop_set = 0;
9504   u8 next_hop_proto_is_ip4 = 1;
9505   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9506   int ret;
9507
9508   /* Parse args required to build the message */
9509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9510     {
9511       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9512         {
9513           next_hop_proto_is_ip4 = 1;
9514           next_hop_set = 1;
9515         }
9516       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9517         {
9518           next_hop_proto_is_ip4 = 0;
9519           next_hop_set = 1;
9520         }
9521       if (unformat (i, "sub-domain %d", &sub_domain))
9522         ;
9523       else if (unformat (i, "set %d", &set))
9524         ;
9525       else if (unformat (i, "hdr-len %d", &hdr_len))
9526         ;
9527       else if (unformat (i, "bp %d", &bp))
9528         ;
9529       else if (unformat (i, "add"))
9530         is_add = 1;
9531       else if (unformat (i, "del"))
9532         is_add = 0;
9533       else if (unformat (i, "out-label %d", &next_hop_out_label))
9534         ;
9535       else
9536         {
9537           clib_warning ("parse error '%U'", format_unformat_error, i);
9538           return -99;
9539         }
9540     }
9541
9542   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9543     {
9544       errmsg ("next hop / label set\n");
9545       return -99;
9546     }
9547   if (0 == bp)
9548     {
9549       errmsg ("bit=position not set\n");
9550       return -99;
9551     }
9552
9553   /* Construct the API message */
9554   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9555
9556   mp->br_is_add = is_add;
9557   mp->br_tbl_id.bt_set = set;
9558   mp->br_tbl_id.bt_sub_domain = sub_domain;
9559   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9560   mp->br_bp = ntohs (bp);
9561   mp->br_n_paths = 1;
9562   mp->br_paths[0].n_labels = 1;
9563   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9564   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9565
9566   if (next_hop_proto_is_ip4)
9567     {
9568       clib_memcpy (mp->br_paths[0].next_hop,
9569                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9570     }
9571   else
9572     {
9573       clib_memcpy (mp->br_paths[0].next_hop,
9574                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9575     }
9576
9577   /* send it... */
9578   S (mp);
9579
9580   /* Wait for a reply... */
9581   W (ret);
9582
9583   return (ret);
9584 }
9585
9586 static int
9587 api_proxy_arp_add_del (vat_main_t * vam)
9588 {
9589   unformat_input_t *i = vam->input;
9590   vl_api_proxy_arp_add_del_t *mp;
9591   u32 vrf_id = 0;
9592   u8 is_add = 1;
9593   ip4_address_t lo, hi;
9594   u8 range_set = 0;
9595   int ret;
9596
9597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9598     {
9599       if (unformat (i, "vrf %d", &vrf_id))
9600         ;
9601       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9602                          unformat_ip4_address, &hi))
9603         range_set = 1;
9604       else if (unformat (i, "del"))
9605         is_add = 0;
9606       else
9607         {
9608           clib_warning ("parse error '%U'", format_unformat_error, i);
9609           return -99;
9610         }
9611     }
9612
9613   if (range_set == 0)
9614     {
9615       errmsg ("address range not set");
9616       return -99;
9617     }
9618
9619   M (PROXY_ARP_ADD_DEL, mp);
9620
9621   mp->proxy.vrf_id = ntohl (vrf_id);
9622   mp->is_add = is_add;
9623   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9624   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9625
9626   S (mp);
9627   W (ret);
9628   return ret;
9629 }
9630
9631 static int
9632 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9633 {
9634   unformat_input_t *i = vam->input;
9635   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9636   u32 sw_if_index;
9637   u8 enable = 1;
9638   u8 sw_if_index_set = 0;
9639   int ret;
9640
9641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9644         sw_if_index_set = 1;
9645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9646         sw_if_index_set = 1;
9647       else if (unformat (i, "enable"))
9648         enable = 1;
9649       else if (unformat (i, "disable"))
9650         enable = 0;
9651       else
9652         {
9653           clib_warning ("parse error '%U'", format_unformat_error, i);
9654           return -99;
9655         }
9656     }
9657
9658   if (sw_if_index_set == 0)
9659     {
9660       errmsg ("missing interface name or sw_if_index");
9661       return -99;
9662     }
9663
9664   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9665
9666   mp->sw_if_index = ntohl (sw_if_index);
9667   mp->enable_disable = enable;
9668
9669   S (mp);
9670   W (ret);
9671   return ret;
9672 }
9673
9674 static int
9675 api_mpls_tunnel_add_del (vat_main_t * vam)
9676 {
9677   unformat_input_t *i = vam->input;
9678   vl_api_mpls_tunnel_add_del_t *mp;
9679
9680   u8 is_add = 1;
9681   u8 l2_only = 0;
9682   u32 sw_if_index = ~0;
9683   u32 next_hop_sw_if_index = ~0;
9684   u32 next_hop_proto_is_ip4 = 1;
9685
9686   u32 next_hop_table_id = 0;
9687   ip4_address_t v4_next_hop_address = {
9688     .as_u32 = 0,
9689   };
9690   ip6_address_t v6_next_hop_address = { {0} };
9691   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9692   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9693   int ret;
9694
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "add"))
9698         is_add = 1;
9699       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9700         is_add = 0;
9701       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9702         ;
9703       else if (unformat (i, "via %U",
9704                          unformat_ip4_address, &v4_next_hop_address))
9705         {
9706           next_hop_proto_is_ip4 = 1;
9707         }
9708       else if (unformat (i, "via %U",
9709                          unformat_ip6_address, &v6_next_hop_address))
9710         {
9711           next_hop_proto_is_ip4 = 0;
9712         }
9713       else if (unformat (i, "via-label %d", &next_hop_via_label))
9714         ;
9715       else if (unformat (i, "l2-only"))
9716         l2_only = 1;
9717       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9718         ;
9719       else if (unformat (i, "out-label %d", &next_hop_out_label))
9720         vec_add1 (labels, ntohl (next_hop_out_label));
9721       else
9722         {
9723           clib_warning ("parse error '%U'", format_unformat_error, i);
9724           return -99;
9725         }
9726     }
9727
9728   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9729
9730   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9731   mp->mt_sw_if_index = ntohl (sw_if_index);
9732   mp->mt_is_add = is_add;
9733   mp->mt_l2_only = l2_only;
9734   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9735   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9736   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9737
9738   mp->mt_next_hop_n_out_labels = vec_len (labels);
9739
9740   if (0 != mp->mt_next_hop_n_out_labels)
9741     {
9742       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9743                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9744       vec_free (labels);
9745     }
9746
9747   if (next_hop_proto_is_ip4)
9748     {
9749       clib_memcpy (mp->mt_next_hop,
9750                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9751     }
9752   else
9753     {
9754       clib_memcpy (mp->mt_next_hop,
9755                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9756     }
9757
9758   S (mp);
9759   W (ret);
9760   return ret;
9761 }
9762
9763 static int
9764 api_sw_interface_set_unnumbered (vat_main_t * vam)
9765 {
9766   unformat_input_t *i = vam->input;
9767   vl_api_sw_interface_set_unnumbered_t *mp;
9768   u32 sw_if_index;
9769   u32 unnum_sw_index = ~0;
9770   u8 is_add = 1;
9771   u8 sw_if_index_set = 0;
9772   int ret;
9773
9774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9775     {
9776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9777         sw_if_index_set = 1;
9778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9779         sw_if_index_set = 1;
9780       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9781         ;
9782       else if (unformat (i, "del"))
9783         is_add = 0;
9784       else
9785         {
9786           clib_warning ("parse error '%U'", format_unformat_error, i);
9787           return -99;
9788         }
9789     }
9790
9791   if (sw_if_index_set == 0)
9792     {
9793       errmsg ("missing interface name or sw_if_index");
9794       return -99;
9795     }
9796
9797   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9798
9799   mp->sw_if_index = ntohl (sw_if_index);
9800   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9801   mp->is_add = is_add;
9802
9803   S (mp);
9804   W (ret);
9805   return ret;
9806 }
9807
9808 static int
9809 api_ip_neighbor_add_del (vat_main_t * vam)
9810 {
9811   unformat_input_t *i = vam->input;
9812   vl_api_ip_neighbor_add_del_t *mp;
9813   u32 sw_if_index;
9814   u8 sw_if_index_set = 0;
9815   u8 is_add = 1;
9816   u8 is_static = 0;
9817   u8 is_no_fib_entry = 0;
9818   u8 mac_address[6];
9819   u8 mac_set = 0;
9820   u8 v4_address_set = 0;
9821   u8 v6_address_set = 0;
9822   ip4_address_t v4address;
9823   ip6_address_t v6address;
9824   int ret;
9825
9826   memset (mac_address, 0, sizeof (mac_address));
9827
9828   /* Parse args required to build the message */
9829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9830     {
9831       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9832         {
9833           mac_set = 1;
9834         }
9835       else if (unformat (i, "del"))
9836         is_add = 0;
9837       else
9838         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9839         sw_if_index_set = 1;
9840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9841         sw_if_index_set = 1;
9842       else if (unformat (i, "is_static"))
9843         is_static = 1;
9844       else if (unformat (i, "no-fib-entry"))
9845         is_no_fib_entry = 1;
9846       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9847         v4_address_set = 1;
9848       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9849         v6_address_set = 1;
9850       else
9851         {
9852           clib_warning ("parse error '%U'", format_unformat_error, i);
9853           return -99;
9854         }
9855     }
9856
9857   if (sw_if_index_set == 0)
9858     {
9859       errmsg ("missing interface name or sw_if_index");
9860       return -99;
9861     }
9862   if (v4_address_set && v6_address_set)
9863     {
9864       errmsg ("both v4 and v6 addresses set");
9865       return -99;
9866     }
9867   if (!v4_address_set && !v6_address_set)
9868     {
9869       errmsg ("no address set");
9870       return -99;
9871     }
9872
9873   /* Construct the API message */
9874   M (IP_NEIGHBOR_ADD_DEL, mp);
9875
9876   mp->sw_if_index = ntohl (sw_if_index);
9877   mp->is_add = is_add;
9878   mp->is_static = is_static;
9879   mp->is_no_adj_fib = is_no_fib_entry;
9880   if (mac_set)
9881     clib_memcpy (mp->mac_address, mac_address, 6);
9882   if (v6_address_set)
9883     {
9884       mp->is_ipv6 = 1;
9885       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9886     }
9887   else
9888     {
9889       /* mp->is_ipv6 = 0; via memset in M macro above */
9890       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9891     }
9892
9893   /* send it... */
9894   S (mp);
9895
9896   /* Wait for a reply, return good/bad news  */
9897   W (ret);
9898   return ret;
9899 }
9900
9901 static int
9902 api_create_vlan_subif (vat_main_t * vam)
9903 {
9904   unformat_input_t *i = vam->input;
9905   vl_api_create_vlan_subif_t *mp;
9906   u32 sw_if_index;
9907   u8 sw_if_index_set = 0;
9908   u32 vlan_id;
9909   u8 vlan_id_set = 0;
9910   int ret;
9911
9912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9913     {
9914       if (unformat (i, "sw_if_index %d", &sw_if_index))
9915         sw_if_index_set = 1;
9916       else
9917         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9918         sw_if_index_set = 1;
9919       else if (unformat (i, "vlan %d", &vlan_id))
9920         vlan_id_set = 1;
9921       else
9922         {
9923           clib_warning ("parse error '%U'", format_unformat_error, i);
9924           return -99;
9925         }
9926     }
9927
9928   if (sw_if_index_set == 0)
9929     {
9930       errmsg ("missing interface name or sw_if_index");
9931       return -99;
9932     }
9933
9934   if (vlan_id_set == 0)
9935     {
9936       errmsg ("missing vlan_id");
9937       return -99;
9938     }
9939   M (CREATE_VLAN_SUBIF, mp);
9940
9941   mp->sw_if_index = ntohl (sw_if_index);
9942   mp->vlan_id = ntohl (vlan_id);
9943
9944   S (mp);
9945   W (ret);
9946   return ret;
9947 }
9948
9949 #define foreach_create_subif_bit                \
9950 _(no_tags)                                      \
9951 _(one_tag)                                      \
9952 _(two_tags)                                     \
9953 _(dot1ad)                                       \
9954 _(exact_match)                                  \
9955 _(default_sub)                                  \
9956 _(outer_vlan_id_any)                            \
9957 _(inner_vlan_id_any)
9958
9959 static int
9960 api_create_subif (vat_main_t * vam)
9961 {
9962   unformat_input_t *i = vam->input;
9963   vl_api_create_subif_t *mp;
9964   u32 sw_if_index;
9965   u8 sw_if_index_set = 0;
9966   u32 sub_id;
9967   u8 sub_id_set = 0;
9968   u32 no_tags = 0;
9969   u32 one_tag = 0;
9970   u32 two_tags = 0;
9971   u32 dot1ad = 0;
9972   u32 exact_match = 0;
9973   u32 default_sub = 0;
9974   u32 outer_vlan_id_any = 0;
9975   u32 inner_vlan_id_any = 0;
9976   u32 tmp;
9977   u16 outer_vlan_id = 0;
9978   u16 inner_vlan_id = 0;
9979   int ret;
9980
9981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9982     {
9983       if (unformat (i, "sw_if_index %d", &sw_if_index))
9984         sw_if_index_set = 1;
9985       else
9986         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9987         sw_if_index_set = 1;
9988       else if (unformat (i, "sub_id %d", &sub_id))
9989         sub_id_set = 1;
9990       else if (unformat (i, "outer_vlan_id %d", &tmp))
9991         outer_vlan_id = tmp;
9992       else if (unformat (i, "inner_vlan_id %d", &tmp))
9993         inner_vlan_id = tmp;
9994
9995 #define _(a) else if (unformat (i, #a)) a = 1 ;
9996       foreach_create_subif_bit
9997 #undef _
9998         else
9999         {
10000           clib_warning ("parse error '%U'", format_unformat_error, i);
10001           return -99;
10002         }
10003     }
10004
10005   if (sw_if_index_set == 0)
10006     {
10007       errmsg ("missing interface name or sw_if_index");
10008       return -99;
10009     }
10010
10011   if (sub_id_set == 0)
10012     {
10013       errmsg ("missing sub_id");
10014       return -99;
10015     }
10016   M (CREATE_SUBIF, mp);
10017
10018   mp->sw_if_index = ntohl (sw_if_index);
10019   mp->sub_id = ntohl (sub_id);
10020
10021 #define _(a) mp->a = a;
10022   foreach_create_subif_bit;
10023 #undef _
10024
10025   mp->outer_vlan_id = ntohs (outer_vlan_id);
10026   mp->inner_vlan_id = ntohs (inner_vlan_id);
10027
10028   S (mp);
10029   W (ret);
10030   return ret;
10031 }
10032
10033 static int
10034 api_oam_add_del (vat_main_t * vam)
10035 {
10036   unformat_input_t *i = vam->input;
10037   vl_api_oam_add_del_t *mp;
10038   u32 vrf_id = 0;
10039   u8 is_add = 1;
10040   ip4_address_t src, dst;
10041   u8 src_set = 0;
10042   u8 dst_set = 0;
10043   int ret;
10044
10045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10046     {
10047       if (unformat (i, "vrf %d", &vrf_id))
10048         ;
10049       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10050         src_set = 1;
10051       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10052         dst_set = 1;
10053       else if (unformat (i, "del"))
10054         is_add = 0;
10055       else
10056         {
10057           clib_warning ("parse error '%U'", format_unformat_error, i);
10058           return -99;
10059         }
10060     }
10061
10062   if (src_set == 0)
10063     {
10064       errmsg ("missing src addr");
10065       return -99;
10066     }
10067
10068   if (dst_set == 0)
10069     {
10070       errmsg ("missing dst addr");
10071       return -99;
10072     }
10073
10074   M (OAM_ADD_DEL, mp);
10075
10076   mp->vrf_id = ntohl (vrf_id);
10077   mp->is_add = is_add;
10078   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10079   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10080
10081   S (mp);
10082   W (ret);
10083   return ret;
10084 }
10085
10086 static int
10087 api_reset_fib (vat_main_t * vam)
10088 {
10089   unformat_input_t *i = vam->input;
10090   vl_api_reset_fib_t *mp;
10091   u32 vrf_id = 0;
10092   u8 is_ipv6 = 0;
10093   u8 vrf_id_set = 0;
10094
10095   int ret;
10096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10097     {
10098       if (unformat (i, "vrf %d", &vrf_id))
10099         vrf_id_set = 1;
10100       else if (unformat (i, "ipv6"))
10101         is_ipv6 = 1;
10102       else
10103         {
10104           clib_warning ("parse error '%U'", format_unformat_error, i);
10105           return -99;
10106         }
10107     }
10108
10109   if (vrf_id_set == 0)
10110     {
10111       errmsg ("missing vrf id");
10112       return -99;
10113     }
10114
10115   M (RESET_FIB, mp);
10116
10117   mp->vrf_id = ntohl (vrf_id);
10118   mp->is_ipv6 = is_ipv6;
10119
10120   S (mp);
10121   W (ret);
10122   return ret;
10123 }
10124
10125 static int
10126 api_dhcp_proxy_config (vat_main_t * vam)
10127 {
10128   unformat_input_t *i = vam->input;
10129   vl_api_dhcp_proxy_config_t *mp;
10130   u32 rx_vrf_id = 0;
10131   u32 server_vrf_id = 0;
10132   u8 is_add = 1;
10133   u8 v4_address_set = 0;
10134   u8 v6_address_set = 0;
10135   ip4_address_t v4address;
10136   ip6_address_t v6address;
10137   u8 v4_src_address_set = 0;
10138   u8 v6_src_address_set = 0;
10139   ip4_address_t v4srcaddress;
10140   ip6_address_t v6srcaddress;
10141   int ret;
10142
10143   /* Parse args required to build the message */
10144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10145     {
10146       if (unformat (i, "del"))
10147         is_add = 0;
10148       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10149         ;
10150       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10151         ;
10152       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10153         v4_address_set = 1;
10154       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10155         v6_address_set = 1;
10156       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10157         v4_src_address_set = 1;
10158       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10159         v6_src_address_set = 1;
10160       else
10161         break;
10162     }
10163
10164   if (v4_address_set && v6_address_set)
10165     {
10166       errmsg ("both v4 and v6 server addresses set");
10167       return -99;
10168     }
10169   if (!v4_address_set && !v6_address_set)
10170     {
10171       errmsg ("no server addresses set");
10172       return -99;
10173     }
10174
10175   if (v4_src_address_set && v6_src_address_set)
10176     {
10177       errmsg ("both v4 and v6  src addresses set");
10178       return -99;
10179     }
10180   if (!v4_src_address_set && !v6_src_address_set)
10181     {
10182       errmsg ("no src addresses set");
10183       return -99;
10184     }
10185
10186   if (!(v4_src_address_set && v4_address_set) &&
10187       !(v6_src_address_set && v6_address_set))
10188     {
10189       errmsg ("no matching server and src addresses set");
10190       return -99;
10191     }
10192
10193   /* Construct the API message */
10194   M (DHCP_PROXY_CONFIG, mp);
10195
10196   mp->is_add = is_add;
10197   mp->rx_vrf_id = ntohl (rx_vrf_id);
10198   mp->server_vrf_id = ntohl (server_vrf_id);
10199   if (v6_address_set)
10200     {
10201       mp->is_ipv6 = 1;
10202       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10203       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10204     }
10205   else
10206     {
10207       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10208       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10209     }
10210
10211   /* send it... */
10212   S (mp);
10213
10214   /* Wait for a reply, return good/bad news  */
10215   W (ret);
10216   return ret;
10217 }
10218
10219 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10220 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10221
10222 static void
10223 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10224 {
10225   vat_main_t *vam = &vat_main;
10226   u32 i, count = mp->count;
10227   vl_api_dhcp_server_t *s;
10228
10229   if (mp->is_ipv6)
10230     print (vam->ofp,
10231            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10232            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10233            ntohl (mp->rx_vrf_id),
10234            format_ip6_address, mp->dhcp_src_address,
10235            mp->vss_type, mp->vss_vpn_ascii_id,
10236            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10237   else
10238     print (vam->ofp,
10239            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10240            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10241            ntohl (mp->rx_vrf_id),
10242            format_ip4_address, mp->dhcp_src_address,
10243            mp->vss_type, mp->vss_vpn_ascii_id,
10244            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10245
10246   for (i = 0; i < count; i++)
10247     {
10248       s = &mp->servers[i];
10249
10250       if (mp->is_ipv6)
10251         print (vam->ofp,
10252                " Server Table-ID %d, Server Address %U",
10253                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10254       else
10255         print (vam->ofp,
10256                " Server Table-ID %d, Server Address %U",
10257                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10258     }
10259 }
10260
10261 static void vl_api_dhcp_proxy_details_t_handler_json
10262   (vl_api_dhcp_proxy_details_t * mp)
10263 {
10264   vat_main_t *vam = &vat_main;
10265   vat_json_node_t *node = NULL;
10266   u32 i, count = mp->count;
10267   struct in_addr ip4;
10268   struct in6_addr ip6;
10269   vl_api_dhcp_server_t *s;
10270
10271   if (VAT_JSON_ARRAY != vam->json_tree.type)
10272     {
10273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10274       vat_json_init_array (&vam->json_tree);
10275     }
10276   node = vat_json_array_add (&vam->json_tree);
10277
10278   vat_json_init_object (node);
10279   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10280   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10281                              sizeof (mp->vss_type));
10282   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10283                                    mp->vss_vpn_ascii_id);
10284   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10285   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10286
10287   if (mp->is_ipv6)
10288     {
10289       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10290       vat_json_object_add_ip6 (node, "src_address", ip6);
10291     }
10292   else
10293     {
10294       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10295       vat_json_object_add_ip4 (node, "src_address", ip4);
10296     }
10297
10298   for (i = 0; i < count; i++)
10299     {
10300       s = &mp->servers[i];
10301
10302       vat_json_object_add_uint (node, "server-table-id",
10303                                 ntohl (s->server_vrf_id));
10304
10305       if (mp->is_ipv6)
10306         {
10307           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10308           vat_json_object_add_ip4 (node, "src_address", ip4);
10309         }
10310       else
10311         {
10312           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10313           vat_json_object_add_ip6 (node, "server_address", ip6);
10314         }
10315     }
10316 }
10317
10318 static int
10319 api_dhcp_proxy_dump (vat_main_t * vam)
10320 {
10321   unformat_input_t *i = vam->input;
10322   vl_api_control_ping_t *mp_ping;
10323   vl_api_dhcp_proxy_dump_t *mp;
10324   u8 is_ipv6 = 0;
10325   int ret;
10326
10327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10328     {
10329       if (unformat (i, "ipv6"))
10330         is_ipv6 = 1;
10331       else
10332         {
10333           clib_warning ("parse error '%U'", format_unformat_error, i);
10334           return -99;
10335         }
10336     }
10337
10338   M (DHCP_PROXY_DUMP, mp);
10339
10340   mp->is_ip6 = is_ipv6;
10341   S (mp);
10342
10343   /* Use a control ping for synchronization */
10344   MPING (CONTROL_PING, mp_ping);
10345   S (mp_ping);
10346
10347   W (ret);
10348   return ret;
10349 }
10350
10351 static int
10352 api_dhcp_proxy_set_vss (vat_main_t * vam)
10353 {
10354   unformat_input_t *i = vam->input;
10355   vl_api_dhcp_proxy_set_vss_t *mp;
10356   u8 is_ipv6 = 0;
10357   u8 is_add = 1;
10358   u32 tbl_id = ~0;
10359   u8 vss_type = VSS_TYPE_DEFAULT;
10360   u8 *vpn_ascii_id = 0;
10361   u32 oui = 0;
10362   u32 fib_id = 0;
10363   int ret;
10364
10365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10366     {
10367       if (unformat (i, "tbl_id %d", &tbl_id))
10368         ;
10369       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10370         vss_type = VSS_TYPE_ASCII;
10371       else if (unformat (i, "fib_id %d", &fib_id))
10372         vss_type = VSS_TYPE_VPN_ID;
10373       else if (unformat (i, "oui %d", &oui))
10374         vss_type = VSS_TYPE_VPN_ID;
10375       else if (unformat (i, "ipv6"))
10376         is_ipv6 = 1;
10377       else if (unformat (i, "del"))
10378         is_add = 0;
10379       else
10380         break;
10381     }
10382
10383   if (tbl_id == ~0)
10384     {
10385       errmsg ("missing tbl_id ");
10386       vec_free (vpn_ascii_id);
10387       return -99;
10388     }
10389
10390   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10391     {
10392       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10393       vec_free (vpn_ascii_id);
10394       return -99;
10395     }
10396
10397   M (DHCP_PROXY_SET_VSS, mp);
10398   mp->tbl_id = ntohl (tbl_id);
10399   mp->vss_type = vss_type;
10400   if (vpn_ascii_id)
10401     {
10402       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10403       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10404     }
10405   mp->vpn_index = ntohl (fib_id);
10406   mp->oui = ntohl (oui);
10407   mp->is_ipv6 = is_ipv6;
10408   mp->is_add = is_add;
10409
10410   S (mp);
10411   W (ret);
10412
10413   vec_free (vpn_ascii_id);
10414   return ret;
10415 }
10416
10417 static int
10418 api_dhcp_client_config (vat_main_t * vam)
10419 {
10420   unformat_input_t *i = vam->input;
10421   vl_api_dhcp_client_config_t *mp;
10422   u32 sw_if_index;
10423   u8 sw_if_index_set = 0;
10424   u8 is_add = 1;
10425   u8 *hostname = 0;
10426   u8 disable_event = 0;
10427   int ret;
10428
10429   /* Parse args required to build the message */
10430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10431     {
10432       if (unformat (i, "del"))
10433         is_add = 0;
10434       else
10435         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10436         sw_if_index_set = 1;
10437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10438         sw_if_index_set = 1;
10439       else if (unformat (i, "hostname %s", &hostname))
10440         ;
10441       else if (unformat (i, "disable_event"))
10442         disable_event = 1;
10443       else
10444         break;
10445     }
10446
10447   if (sw_if_index_set == 0)
10448     {
10449       errmsg ("missing interface name or sw_if_index");
10450       return -99;
10451     }
10452
10453   if (vec_len (hostname) > 63)
10454     {
10455       errmsg ("hostname too long");
10456     }
10457   vec_add1 (hostname, 0);
10458
10459   /* Construct the API message */
10460   M (DHCP_CLIENT_CONFIG, mp);
10461
10462   mp->is_add = is_add;
10463   mp->client.sw_if_index = htonl (sw_if_index);
10464   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10465   vec_free (hostname);
10466   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10467   mp->client.pid = htonl (getpid ());
10468
10469   /* send it... */
10470   S (mp);
10471
10472   /* Wait for a reply, return good/bad news  */
10473   W (ret);
10474   return ret;
10475 }
10476
10477 static int
10478 api_set_ip_flow_hash (vat_main_t * vam)
10479 {
10480   unformat_input_t *i = vam->input;
10481   vl_api_set_ip_flow_hash_t *mp;
10482   u32 vrf_id = 0;
10483   u8 is_ipv6 = 0;
10484   u8 vrf_id_set = 0;
10485   u8 src = 0;
10486   u8 dst = 0;
10487   u8 sport = 0;
10488   u8 dport = 0;
10489   u8 proto = 0;
10490   u8 reverse = 0;
10491   int ret;
10492
10493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (i, "vrf %d", &vrf_id))
10496         vrf_id_set = 1;
10497       else if (unformat (i, "ipv6"))
10498         is_ipv6 = 1;
10499       else if (unformat (i, "src"))
10500         src = 1;
10501       else if (unformat (i, "dst"))
10502         dst = 1;
10503       else if (unformat (i, "sport"))
10504         sport = 1;
10505       else if (unformat (i, "dport"))
10506         dport = 1;
10507       else if (unformat (i, "proto"))
10508         proto = 1;
10509       else if (unformat (i, "reverse"))
10510         reverse = 1;
10511
10512       else
10513         {
10514           clib_warning ("parse error '%U'", format_unformat_error, i);
10515           return -99;
10516         }
10517     }
10518
10519   if (vrf_id_set == 0)
10520     {
10521       errmsg ("missing vrf id");
10522       return -99;
10523     }
10524
10525   M (SET_IP_FLOW_HASH, mp);
10526   mp->src = src;
10527   mp->dst = dst;
10528   mp->sport = sport;
10529   mp->dport = dport;
10530   mp->proto = proto;
10531   mp->reverse = reverse;
10532   mp->vrf_id = ntohl (vrf_id);
10533   mp->is_ipv6 = is_ipv6;
10534
10535   S (mp);
10536   W (ret);
10537   return ret;
10538 }
10539
10540 static int
10541 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10542 {
10543   unformat_input_t *i = vam->input;
10544   vl_api_sw_interface_ip6_enable_disable_t *mp;
10545   u32 sw_if_index;
10546   u8 sw_if_index_set = 0;
10547   u8 enable = 0;
10548   int ret;
10549
10550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10553         sw_if_index_set = 1;
10554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10555         sw_if_index_set = 1;
10556       else if (unformat (i, "enable"))
10557         enable = 1;
10558       else if (unformat (i, "disable"))
10559         enable = 0;
10560       else
10561         {
10562           clib_warning ("parse error '%U'", format_unformat_error, i);
10563           return -99;
10564         }
10565     }
10566
10567   if (sw_if_index_set == 0)
10568     {
10569       errmsg ("missing interface name or sw_if_index");
10570       return -99;
10571     }
10572
10573   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10574
10575   mp->sw_if_index = ntohl (sw_if_index);
10576   mp->enable = enable;
10577
10578   S (mp);
10579   W (ret);
10580   return ret;
10581 }
10582
10583 static int
10584 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10585 {
10586   unformat_input_t *i = vam->input;
10587   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10588   u32 sw_if_index;
10589   u8 sw_if_index_set = 0;
10590   u8 v6_address_set = 0;
10591   ip6_address_t v6address;
10592   int ret;
10593
10594   /* Parse args required to build the message */
10595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10596     {
10597       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10598         sw_if_index_set = 1;
10599       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10600         sw_if_index_set = 1;
10601       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10602         v6_address_set = 1;
10603       else
10604         break;
10605     }
10606
10607   if (sw_if_index_set == 0)
10608     {
10609       errmsg ("missing interface name or sw_if_index");
10610       return -99;
10611     }
10612   if (!v6_address_set)
10613     {
10614       errmsg ("no address set");
10615       return -99;
10616     }
10617
10618   /* Construct the API message */
10619   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10620
10621   mp->sw_if_index = ntohl (sw_if_index);
10622   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10623
10624   /* send it... */
10625   S (mp);
10626
10627   /* Wait for a reply, return good/bad news  */
10628   W (ret);
10629   return ret;
10630 }
10631
10632 static int
10633 api_ip6nd_proxy_add_del (vat_main_t * vam)
10634 {
10635   unformat_input_t *i = vam->input;
10636   vl_api_ip6nd_proxy_add_del_t *mp;
10637   u32 sw_if_index = ~0;
10638   u8 v6_address_set = 0;
10639   ip6_address_t v6address;
10640   u8 is_del = 0;
10641   int ret;
10642
10643   /* Parse args required to build the message */
10644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10645     {
10646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10647         ;
10648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10649         ;
10650       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10651         v6_address_set = 1;
10652       if (unformat (i, "del"))
10653         is_del = 1;
10654       else
10655         {
10656           clib_warning ("parse error '%U'", format_unformat_error, i);
10657           return -99;
10658         }
10659     }
10660
10661   if (sw_if_index == ~0)
10662     {
10663       errmsg ("missing interface name or sw_if_index");
10664       return -99;
10665     }
10666   if (!v6_address_set)
10667     {
10668       errmsg ("no address set");
10669       return -99;
10670     }
10671
10672   /* Construct the API message */
10673   M (IP6ND_PROXY_ADD_DEL, mp);
10674
10675   mp->is_del = is_del;
10676   mp->sw_if_index = ntohl (sw_if_index);
10677   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10678
10679   /* send it... */
10680   S (mp);
10681
10682   /* Wait for a reply, return good/bad news  */
10683   W (ret);
10684   return ret;
10685 }
10686
10687 static int
10688 api_ip6nd_proxy_dump (vat_main_t * vam)
10689 {
10690   vl_api_ip6nd_proxy_dump_t *mp;
10691   vl_api_control_ping_t *mp_ping;
10692   int ret;
10693
10694   M (IP6ND_PROXY_DUMP, mp);
10695
10696   S (mp);
10697
10698   /* Use a control ping for synchronization */
10699   MPING (CONTROL_PING, mp_ping);
10700   S (mp_ping);
10701
10702   W (ret);
10703   return ret;
10704 }
10705
10706 static void vl_api_ip6nd_proxy_details_t_handler
10707   (vl_api_ip6nd_proxy_details_t * mp)
10708 {
10709   vat_main_t *vam = &vat_main;
10710
10711   print (vam->ofp, "host %U sw_if_index %d",
10712          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10713 }
10714
10715 static void vl_api_ip6nd_proxy_details_t_handler_json
10716   (vl_api_ip6nd_proxy_details_t * mp)
10717 {
10718   vat_main_t *vam = &vat_main;
10719   struct in6_addr ip6;
10720   vat_json_node_t *node = NULL;
10721
10722   if (VAT_JSON_ARRAY != vam->json_tree.type)
10723     {
10724       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10725       vat_json_init_array (&vam->json_tree);
10726     }
10727   node = vat_json_array_add (&vam->json_tree);
10728
10729   vat_json_init_object (node);
10730   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10731
10732   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10733   vat_json_object_add_ip6 (node, "host", ip6);
10734 }
10735
10736 static int
10737 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10738 {
10739   unformat_input_t *i = vam->input;
10740   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10741   u32 sw_if_index;
10742   u8 sw_if_index_set = 0;
10743   u32 address_length = 0;
10744   u8 v6_address_set = 0;
10745   ip6_address_t v6address;
10746   u8 use_default = 0;
10747   u8 no_advertise = 0;
10748   u8 off_link = 0;
10749   u8 no_autoconfig = 0;
10750   u8 no_onlink = 0;
10751   u8 is_no = 0;
10752   u32 val_lifetime = 0;
10753   u32 pref_lifetime = 0;
10754   int ret;
10755
10756   /* Parse args required to build the message */
10757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10758     {
10759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10760         sw_if_index_set = 1;
10761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10762         sw_if_index_set = 1;
10763       else if (unformat (i, "%U/%d",
10764                          unformat_ip6_address, &v6address, &address_length))
10765         v6_address_set = 1;
10766       else if (unformat (i, "val_life %d", &val_lifetime))
10767         ;
10768       else if (unformat (i, "pref_life %d", &pref_lifetime))
10769         ;
10770       else if (unformat (i, "def"))
10771         use_default = 1;
10772       else if (unformat (i, "noadv"))
10773         no_advertise = 1;
10774       else if (unformat (i, "offl"))
10775         off_link = 1;
10776       else if (unformat (i, "noauto"))
10777         no_autoconfig = 1;
10778       else if (unformat (i, "nolink"))
10779         no_onlink = 1;
10780       else if (unformat (i, "isno"))
10781         is_no = 1;
10782       else
10783         {
10784           clib_warning ("parse error '%U'", format_unformat_error, i);
10785           return -99;
10786         }
10787     }
10788
10789   if (sw_if_index_set == 0)
10790     {
10791       errmsg ("missing interface name or sw_if_index");
10792       return -99;
10793     }
10794   if (!v6_address_set)
10795     {
10796       errmsg ("no address set");
10797       return -99;
10798     }
10799
10800   /* Construct the API message */
10801   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10802
10803   mp->sw_if_index = ntohl (sw_if_index);
10804   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10805   mp->address_length = address_length;
10806   mp->use_default = use_default;
10807   mp->no_advertise = no_advertise;
10808   mp->off_link = off_link;
10809   mp->no_autoconfig = no_autoconfig;
10810   mp->no_onlink = no_onlink;
10811   mp->is_no = is_no;
10812   mp->val_lifetime = ntohl (val_lifetime);
10813   mp->pref_lifetime = ntohl (pref_lifetime);
10814
10815   /* send it... */
10816   S (mp);
10817
10818   /* Wait for a reply, return good/bad news  */
10819   W (ret);
10820   return ret;
10821 }
10822
10823 static int
10824 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10825 {
10826   unformat_input_t *i = vam->input;
10827   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10828   u32 sw_if_index;
10829   u8 sw_if_index_set = 0;
10830   u8 suppress = 0;
10831   u8 managed = 0;
10832   u8 other = 0;
10833   u8 ll_option = 0;
10834   u8 send_unicast = 0;
10835   u8 cease = 0;
10836   u8 is_no = 0;
10837   u8 default_router = 0;
10838   u32 max_interval = 0;
10839   u32 min_interval = 0;
10840   u32 lifetime = 0;
10841   u32 initial_count = 0;
10842   u32 initial_interval = 0;
10843   int ret;
10844
10845
10846   /* Parse args required to build the message */
10847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10848     {
10849       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10850         sw_if_index_set = 1;
10851       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10852         sw_if_index_set = 1;
10853       else if (unformat (i, "maxint %d", &max_interval))
10854         ;
10855       else if (unformat (i, "minint %d", &min_interval))
10856         ;
10857       else if (unformat (i, "life %d", &lifetime))
10858         ;
10859       else if (unformat (i, "count %d", &initial_count))
10860         ;
10861       else if (unformat (i, "interval %d", &initial_interval))
10862         ;
10863       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10864         suppress = 1;
10865       else if (unformat (i, "managed"))
10866         managed = 1;
10867       else if (unformat (i, "other"))
10868         other = 1;
10869       else if (unformat (i, "ll"))
10870         ll_option = 1;
10871       else if (unformat (i, "send"))
10872         send_unicast = 1;
10873       else if (unformat (i, "cease"))
10874         cease = 1;
10875       else if (unformat (i, "isno"))
10876         is_no = 1;
10877       else if (unformat (i, "def"))
10878         default_router = 1;
10879       else
10880         {
10881           clib_warning ("parse error '%U'", format_unformat_error, i);
10882           return -99;
10883         }
10884     }
10885
10886   if (sw_if_index_set == 0)
10887     {
10888       errmsg ("missing interface name or sw_if_index");
10889       return -99;
10890     }
10891
10892   /* Construct the API message */
10893   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10894
10895   mp->sw_if_index = ntohl (sw_if_index);
10896   mp->max_interval = ntohl (max_interval);
10897   mp->min_interval = ntohl (min_interval);
10898   mp->lifetime = ntohl (lifetime);
10899   mp->initial_count = ntohl (initial_count);
10900   mp->initial_interval = ntohl (initial_interval);
10901   mp->suppress = suppress;
10902   mp->managed = managed;
10903   mp->other = other;
10904   mp->ll_option = ll_option;
10905   mp->send_unicast = send_unicast;
10906   mp->cease = cease;
10907   mp->is_no = is_no;
10908   mp->default_router = default_router;
10909
10910   /* send it... */
10911   S (mp);
10912
10913   /* Wait for a reply, return good/bad news  */
10914   W (ret);
10915   return ret;
10916 }
10917
10918 static int
10919 api_set_arp_neighbor_limit (vat_main_t * vam)
10920 {
10921   unformat_input_t *i = vam->input;
10922   vl_api_set_arp_neighbor_limit_t *mp;
10923   u32 arp_nbr_limit;
10924   u8 limit_set = 0;
10925   u8 is_ipv6 = 0;
10926   int ret;
10927
10928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10929     {
10930       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10931         limit_set = 1;
10932       else if (unformat (i, "ipv6"))
10933         is_ipv6 = 1;
10934       else
10935         {
10936           clib_warning ("parse error '%U'", format_unformat_error, i);
10937           return -99;
10938         }
10939     }
10940
10941   if (limit_set == 0)
10942     {
10943       errmsg ("missing limit value");
10944       return -99;
10945     }
10946
10947   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10948
10949   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10950   mp->is_ipv6 = is_ipv6;
10951
10952   S (mp);
10953   W (ret);
10954   return ret;
10955 }
10956
10957 static int
10958 api_l2_patch_add_del (vat_main_t * vam)
10959 {
10960   unformat_input_t *i = vam->input;
10961   vl_api_l2_patch_add_del_t *mp;
10962   u32 rx_sw_if_index;
10963   u8 rx_sw_if_index_set = 0;
10964   u32 tx_sw_if_index;
10965   u8 tx_sw_if_index_set = 0;
10966   u8 is_add = 1;
10967   int ret;
10968
10969   /* Parse args required to build the message */
10970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10971     {
10972       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10973         rx_sw_if_index_set = 1;
10974       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10975         tx_sw_if_index_set = 1;
10976       else if (unformat (i, "rx"))
10977         {
10978           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10979             {
10980               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10981                             &rx_sw_if_index))
10982                 rx_sw_if_index_set = 1;
10983             }
10984           else
10985             break;
10986         }
10987       else if (unformat (i, "tx"))
10988         {
10989           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10990             {
10991               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10992                             &tx_sw_if_index))
10993                 tx_sw_if_index_set = 1;
10994             }
10995           else
10996             break;
10997         }
10998       else if (unformat (i, "del"))
10999         is_add = 0;
11000       else
11001         break;
11002     }
11003
11004   if (rx_sw_if_index_set == 0)
11005     {
11006       errmsg ("missing rx interface name or rx_sw_if_index");
11007       return -99;
11008     }
11009
11010   if (tx_sw_if_index_set == 0)
11011     {
11012       errmsg ("missing tx interface name or tx_sw_if_index");
11013       return -99;
11014     }
11015
11016   M (L2_PATCH_ADD_DEL, mp);
11017
11018   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11019   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11020   mp->is_add = is_add;
11021
11022   S (mp);
11023   W (ret);
11024   return ret;
11025 }
11026
11027 u8 is_del;
11028 u8 localsid_addr[16];
11029 u8 end_psp;
11030 u8 behavior;
11031 u32 sw_if_index;
11032 u32 vlan_index;
11033 u32 fib_table;
11034 u8 nh_addr[16];
11035
11036 static int
11037 api_sr_localsid_add_del (vat_main_t * vam)
11038 {
11039   unformat_input_t *i = vam->input;
11040   vl_api_sr_localsid_add_del_t *mp;
11041
11042   u8 is_del;
11043   ip6_address_t localsid;
11044   u8 end_psp = 0;
11045   u8 behavior = ~0;
11046   u32 sw_if_index;
11047   u32 fib_table = ~(u32) 0;
11048   ip6_address_t nh_addr6;
11049   ip4_address_t nh_addr4;
11050   memset (&nh_addr6, 0, sizeof (ip6_address_t));
11051   memset (&nh_addr4, 0, sizeof (ip4_address_t));
11052
11053   bool nexthop_set = 0;
11054
11055   int ret;
11056
11057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11058     {
11059       if (unformat (i, "del"))
11060         is_del = 1;
11061       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11062       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11063         nexthop_set = 1;
11064       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11065         nexthop_set = 1;
11066       else if (unformat (i, "behavior %u", &behavior));
11067       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11068       else if (unformat (i, "fib-table %u", &fib_table));
11069       else if (unformat (i, "end.psp %u", &behavior));
11070       else
11071         break;
11072     }
11073
11074   M (SR_LOCALSID_ADD_DEL, mp);
11075
11076   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11077   if (nexthop_set)
11078     {
11079       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11080       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11081     }
11082   mp->behavior = behavior;
11083   mp->sw_if_index = ntohl (sw_if_index);
11084   mp->fib_table = ntohl (fib_table);
11085   mp->end_psp = end_psp;
11086   mp->is_del = is_del;
11087
11088   S (mp);
11089   W (ret);
11090   return ret;
11091 }
11092
11093 static int
11094 api_ioam_enable (vat_main_t * vam)
11095 {
11096   unformat_input_t *input = vam->input;
11097   vl_api_ioam_enable_t *mp;
11098   u32 id = 0;
11099   int has_trace_option = 0;
11100   int has_pot_option = 0;
11101   int has_seqno_option = 0;
11102   int has_analyse_option = 0;
11103   int ret;
11104
11105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11106     {
11107       if (unformat (input, "trace"))
11108         has_trace_option = 1;
11109       else if (unformat (input, "pot"))
11110         has_pot_option = 1;
11111       else if (unformat (input, "seqno"))
11112         has_seqno_option = 1;
11113       else if (unformat (input, "analyse"))
11114         has_analyse_option = 1;
11115       else
11116         break;
11117     }
11118   M (IOAM_ENABLE, mp);
11119   mp->id = htons (id);
11120   mp->seqno = has_seqno_option;
11121   mp->analyse = has_analyse_option;
11122   mp->pot_enable = has_pot_option;
11123   mp->trace_enable = has_trace_option;
11124
11125   S (mp);
11126   W (ret);
11127   return ret;
11128 }
11129
11130
11131 static int
11132 api_ioam_disable (vat_main_t * vam)
11133 {
11134   vl_api_ioam_disable_t *mp;
11135   int ret;
11136
11137   M (IOAM_DISABLE, mp);
11138   S (mp);
11139   W (ret);
11140   return ret;
11141 }
11142
11143 #define foreach_tcp_proto_field                 \
11144 _(src_port)                                     \
11145 _(dst_port)
11146
11147 #define foreach_udp_proto_field                 \
11148 _(src_port)                                     \
11149 _(dst_port)
11150
11151 #define foreach_ip4_proto_field                 \
11152 _(src_address)                                  \
11153 _(dst_address)                                  \
11154 _(tos)                                          \
11155 _(length)                                       \
11156 _(fragment_id)                                  \
11157 _(ttl)                                          \
11158 _(protocol)                                     \
11159 _(checksum)
11160
11161 typedef struct
11162 {
11163   u16 src_port, dst_port;
11164 } tcpudp_header_t;
11165
11166 #if VPP_API_TEST_BUILTIN == 0
11167 uword
11168 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11169 {
11170   u8 **maskp = va_arg (*args, u8 **);
11171   u8 *mask = 0;
11172   u8 found_something = 0;
11173   tcp_header_t *tcp;
11174
11175 #define _(a) u8 a=0;
11176   foreach_tcp_proto_field;
11177 #undef _
11178
11179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11180     {
11181       if (0);
11182 #define _(a) else if (unformat (input, #a)) a=1;
11183       foreach_tcp_proto_field
11184 #undef _
11185         else
11186         break;
11187     }
11188
11189 #define _(a) found_something += a;
11190   foreach_tcp_proto_field;
11191 #undef _
11192
11193   if (found_something == 0)
11194     return 0;
11195
11196   vec_validate (mask, sizeof (*tcp) - 1);
11197
11198   tcp = (tcp_header_t *) mask;
11199
11200 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11201   foreach_tcp_proto_field;
11202 #undef _
11203
11204   *maskp = mask;
11205   return 1;
11206 }
11207
11208 uword
11209 unformat_udp_mask (unformat_input_t * input, va_list * args)
11210 {
11211   u8 **maskp = va_arg (*args, u8 **);
11212   u8 *mask = 0;
11213   u8 found_something = 0;
11214   udp_header_t *udp;
11215
11216 #define _(a) u8 a=0;
11217   foreach_udp_proto_field;
11218 #undef _
11219
11220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11221     {
11222       if (0);
11223 #define _(a) else if (unformat (input, #a)) a=1;
11224       foreach_udp_proto_field
11225 #undef _
11226         else
11227         break;
11228     }
11229
11230 #define _(a) found_something += a;
11231   foreach_udp_proto_field;
11232 #undef _
11233
11234   if (found_something == 0)
11235     return 0;
11236
11237   vec_validate (mask, sizeof (*udp) - 1);
11238
11239   udp = (udp_header_t *) mask;
11240
11241 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11242   foreach_udp_proto_field;
11243 #undef _
11244
11245   *maskp = mask;
11246   return 1;
11247 }
11248
11249 uword
11250 unformat_l4_mask (unformat_input_t * input, va_list * args)
11251 {
11252   u8 **maskp = va_arg (*args, u8 **);
11253   u16 src_port = 0, dst_port = 0;
11254   tcpudp_header_t *tcpudp;
11255
11256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11257     {
11258       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11259         return 1;
11260       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11261         return 1;
11262       else if (unformat (input, "src_port"))
11263         src_port = 0xFFFF;
11264       else if (unformat (input, "dst_port"))
11265         dst_port = 0xFFFF;
11266       else
11267         return 0;
11268     }
11269
11270   if (!src_port && !dst_port)
11271     return 0;
11272
11273   u8 *mask = 0;
11274   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11275
11276   tcpudp = (tcpudp_header_t *) mask;
11277   tcpudp->src_port = src_port;
11278   tcpudp->dst_port = dst_port;
11279
11280   *maskp = mask;
11281
11282   return 1;
11283 }
11284
11285 uword
11286 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11287 {
11288   u8 **maskp = va_arg (*args, u8 **);
11289   u8 *mask = 0;
11290   u8 found_something = 0;
11291   ip4_header_t *ip;
11292
11293 #define _(a) u8 a=0;
11294   foreach_ip4_proto_field;
11295 #undef _
11296   u8 version = 0;
11297   u8 hdr_length = 0;
11298
11299
11300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11301     {
11302       if (unformat (input, "version"))
11303         version = 1;
11304       else if (unformat (input, "hdr_length"))
11305         hdr_length = 1;
11306       else if (unformat (input, "src"))
11307         src_address = 1;
11308       else if (unformat (input, "dst"))
11309         dst_address = 1;
11310       else if (unformat (input, "proto"))
11311         protocol = 1;
11312
11313 #define _(a) else if (unformat (input, #a)) a=1;
11314       foreach_ip4_proto_field
11315 #undef _
11316         else
11317         break;
11318     }
11319
11320 #define _(a) found_something += a;
11321   foreach_ip4_proto_field;
11322 #undef _
11323
11324   if (found_something == 0)
11325     return 0;
11326
11327   vec_validate (mask, sizeof (*ip) - 1);
11328
11329   ip = (ip4_header_t *) mask;
11330
11331 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11332   foreach_ip4_proto_field;
11333 #undef _
11334
11335   ip->ip_version_and_header_length = 0;
11336
11337   if (version)
11338     ip->ip_version_and_header_length |= 0xF0;
11339
11340   if (hdr_length)
11341     ip->ip_version_and_header_length |= 0x0F;
11342
11343   *maskp = mask;
11344   return 1;
11345 }
11346
11347 #define foreach_ip6_proto_field                 \
11348 _(src_address)                                  \
11349 _(dst_address)                                  \
11350 _(payload_length)                               \
11351 _(hop_limit)                                    \
11352 _(protocol)
11353
11354 uword
11355 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11356 {
11357   u8 **maskp = va_arg (*args, u8 **);
11358   u8 *mask = 0;
11359   u8 found_something = 0;
11360   ip6_header_t *ip;
11361   u32 ip_version_traffic_class_and_flow_label;
11362
11363 #define _(a) u8 a=0;
11364   foreach_ip6_proto_field;
11365 #undef _
11366   u8 version = 0;
11367   u8 traffic_class = 0;
11368   u8 flow_label = 0;
11369
11370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (input, "version"))
11373         version = 1;
11374       else if (unformat (input, "traffic-class"))
11375         traffic_class = 1;
11376       else if (unformat (input, "flow-label"))
11377         flow_label = 1;
11378       else if (unformat (input, "src"))
11379         src_address = 1;
11380       else if (unformat (input, "dst"))
11381         dst_address = 1;
11382       else if (unformat (input, "proto"))
11383         protocol = 1;
11384
11385 #define _(a) else if (unformat (input, #a)) a=1;
11386       foreach_ip6_proto_field
11387 #undef _
11388         else
11389         break;
11390     }
11391
11392 #define _(a) found_something += a;
11393   foreach_ip6_proto_field;
11394 #undef _
11395
11396   if (found_something == 0)
11397     return 0;
11398
11399   vec_validate (mask, sizeof (*ip) - 1);
11400
11401   ip = (ip6_header_t *) mask;
11402
11403 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11404   foreach_ip6_proto_field;
11405 #undef _
11406
11407   ip_version_traffic_class_and_flow_label = 0;
11408
11409   if (version)
11410     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11411
11412   if (traffic_class)
11413     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11414
11415   if (flow_label)
11416     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11417
11418   ip->ip_version_traffic_class_and_flow_label =
11419     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11420
11421   *maskp = mask;
11422   return 1;
11423 }
11424
11425 uword
11426 unformat_l3_mask (unformat_input_t * input, va_list * args)
11427 {
11428   u8 **maskp = va_arg (*args, u8 **);
11429
11430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11431     {
11432       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11433         return 1;
11434       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11435         return 1;
11436       else
11437         break;
11438     }
11439   return 0;
11440 }
11441
11442 uword
11443 unformat_l2_mask (unformat_input_t * input, va_list * args)
11444 {
11445   u8 **maskp = va_arg (*args, u8 **);
11446   u8 *mask = 0;
11447   u8 src = 0;
11448   u8 dst = 0;
11449   u8 proto = 0;
11450   u8 tag1 = 0;
11451   u8 tag2 = 0;
11452   u8 ignore_tag1 = 0;
11453   u8 ignore_tag2 = 0;
11454   u8 cos1 = 0;
11455   u8 cos2 = 0;
11456   u8 dot1q = 0;
11457   u8 dot1ad = 0;
11458   int len = 14;
11459
11460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11461     {
11462       if (unformat (input, "src"))
11463         src = 1;
11464       else if (unformat (input, "dst"))
11465         dst = 1;
11466       else if (unformat (input, "proto"))
11467         proto = 1;
11468       else if (unformat (input, "tag1"))
11469         tag1 = 1;
11470       else if (unformat (input, "tag2"))
11471         tag2 = 1;
11472       else if (unformat (input, "ignore-tag1"))
11473         ignore_tag1 = 1;
11474       else if (unformat (input, "ignore-tag2"))
11475         ignore_tag2 = 1;
11476       else if (unformat (input, "cos1"))
11477         cos1 = 1;
11478       else if (unformat (input, "cos2"))
11479         cos2 = 1;
11480       else if (unformat (input, "dot1q"))
11481         dot1q = 1;
11482       else if (unformat (input, "dot1ad"))
11483         dot1ad = 1;
11484       else
11485         break;
11486     }
11487   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11488        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11489     return 0;
11490
11491   if (tag1 || ignore_tag1 || cos1 || dot1q)
11492     len = 18;
11493   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11494     len = 22;
11495
11496   vec_validate (mask, len - 1);
11497
11498   if (dst)
11499     memset (mask, 0xff, 6);
11500
11501   if (src)
11502     memset (mask + 6, 0xff, 6);
11503
11504   if (tag2 || dot1ad)
11505     {
11506       /* inner vlan tag */
11507       if (tag2)
11508         {
11509           mask[19] = 0xff;
11510           mask[18] = 0x0f;
11511         }
11512       if (cos2)
11513         mask[18] |= 0xe0;
11514       if (proto)
11515         mask[21] = mask[20] = 0xff;
11516       if (tag1)
11517         {
11518           mask[15] = 0xff;
11519           mask[14] = 0x0f;
11520         }
11521       if (cos1)
11522         mask[14] |= 0xe0;
11523       *maskp = mask;
11524       return 1;
11525     }
11526   if (tag1 | dot1q)
11527     {
11528       if (tag1)
11529         {
11530           mask[15] = 0xff;
11531           mask[14] = 0x0f;
11532         }
11533       if (cos1)
11534         mask[14] |= 0xe0;
11535       if (proto)
11536         mask[16] = mask[17] = 0xff;
11537
11538       *maskp = mask;
11539       return 1;
11540     }
11541   if (cos2)
11542     mask[18] |= 0xe0;
11543   if (cos1)
11544     mask[14] |= 0xe0;
11545   if (proto)
11546     mask[12] = mask[13] = 0xff;
11547
11548   *maskp = mask;
11549   return 1;
11550 }
11551
11552 uword
11553 unformat_classify_mask (unformat_input_t * input, va_list * args)
11554 {
11555   u8 **maskp = va_arg (*args, u8 **);
11556   u32 *skipp = va_arg (*args, u32 *);
11557   u32 *matchp = va_arg (*args, u32 *);
11558   u32 match;
11559   u8 *mask = 0;
11560   u8 *l2 = 0;
11561   u8 *l3 = 0;
11562   u8 *l4 = 0;
11563   int i;
11564
11565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11566     {
11567       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11568         ;
11569       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11570         ;
11571       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11572         ;
11573       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11574         ;
11575       else
11576         break;
11577     }
11578
11579   if (l4 && !l3)
11580     {
11581       vec_free (mask);
11582       vec_free (l2);
11583       vec_free (l4);
11584       return 0;
11585     }
11586
11587   if (mask || l2 || l3 || l4)
11588     {
11589       if (l2 || l3 || l4)
11590         {
11591           /* "With a free Ethernet header in every package" */
11592           if (l2 == 0)
11593             vec_validate (l2, 13);
11594           mask = l2;
11595           if (vec_len (l3))
11596             {
11597               vec_append (mask, l3);
11598               vec_free (l3);
11599             }
11600           if (vec_len (l4))
11601             {
11602               vec_append (mask, l4);
11603               vec_free (l4);
11604             }
11605         }
11606
11607       /* Scan forward looking for the first significant mask octet */
11608       for (i = 0; i < vec_len (mask); i++)
11609         if (mask[i])
11610           break;
11611
11612       /* compute (skip, match) params */
11613       *skipp = i / sizeof (u32x4);
11614       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11615
11616       /* Pad mask to an even multiple of the vector size */
11617       while (vec_len (mask) % sizeof (u32x4))
11618         vec_add1 (mask, 0);
11619
11620       match = vec_len (mask) / sizeof (u32x4);
11621
11622       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11623         {
11624           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11625           if (*tmp || *(tmp + 1))
11626             break;
11627           match--;
11628         }
11629       if (match == 0)
11630         clib_warning ("BUG: match 0");
11631
11632       _vec_len (mask) = match * sizeof (u32x4);
11633
11634       *matchp = match;
11635       *maskp = mask;
11636
11637       return 1;
11638     }
11639
11640   return 0;
11641 }
11642 #endif /* VPP_API_TEST_BUILTIN */
11643
11644 #define foreach_l2_next                         \
11645 _(drop, DROP)                                   \
11646 _(ethernet, ETHERNET_INPUT)                     \
11647 _(ip4, IP4_INPUT)                               \
11648 _(ip6, IP6_INPUT)
11649
11650 uword
11651 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11652 {
11653   u32 *miss_next_indexp = va_arg (*args, u32 *);
11654   u32 next_index = 0;
11655   u32 tmp;
11656
11657 #define _(n,N) \
11658   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11659   foreach_l2_next;
11660 #undef _
11661
11662   if (unformat (input, "%d", &tmp))
11663     {
11664       next_index = tmp;
11665       goto out;
11666     }
11667
11668   return 0;
11669
11670 out:
11671   *miss_next_indexp = next_index;
11672   return 1;
11673 }
11674
11675 #define foreach_ip_next                         \
11676 _(drop, DROP)                                   \
11677 _(local, LOCAL)                                 \
11678 _(rewrite, REWRITE)
11679
11680 uword
11681 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11682 {
11683   u32 *miss_next_indexp = va_arg (*args, u32 *);
11684   u32 next_index = 0;
11685   u32 tmp;
11686
11687 #define _(n,N) \
11688   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11689   foreach_ip_next;
11690 #undef _
11691
11692   if (unformat (input, "%d", &tmp))
11693     {
11694       next_index = tmp;
11695       goto out;
11696     }
11697
11698   return 0;
11699
11700 out:
11701   *miss_next_indexp = next_index;
11702   return 1;
11703 }
11704
11705 #define foreach_acl_next                        \
11706 _(deny, DENY)
11707
11708 uword
11709 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11710 {
11711   u32 *miss_next_indexp = va_arg (*args, u32 *);
11712   u32 next_index = 0;
11713   u32 tmp;
11714
11715 #define _(n,N) \
11716   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11717   foreach_acl_next;
11718 #undef _
11719
11720   if (unformat (input, "permit"))
11721     {
11722       next_index = ~0;
11723       goto out;
11724     }
11725   else if (unformat (input, "%d", &tmp))
11726     {
11727       next_index = tmp;
11728       goto out;
11729     }
11730
11731   return 0;
11732
11733 out:
11734   *miss_next_indexp = next_index;
11735   return 1;
11736 }
11737
11738 uword
11739 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11740 {
11741   u32 *r = va_arg (*args, u32 *);
11742
11743   if (unformat (input, "conform-color"))
11744     *r = POLICE_CONFORM;
11745   else if (unformat (input, "exceed-color"))
11746     *r = POLICE_EXCEED;
11747   else
11748     return 0;
11749
11750   return 1;
11751 }
11752
11753 static int
11754 api_classify_add_del_table (vat_main_t * vam)
11755 {
11756   unformat_input_t *i = vam->input;
11757   vl_api_classify_add_del_table_t *mp;
11758
11759   u32 nbuckets = 2;
11760   u32 skip = ~0;
11761   u32 match = ~0;
11762   int is_add = 1;
11763   int del_chain = 0;
11764   u32 table_index = ~0;
11765   u32 next_table_index = ~0;
11766   u32 miss_next_index = ~0;
11767   u32 memory_size = 32 << 20;
11768   u8 *mask = 0;
11769   u32 current_data_flag = 0;
11770   int current_data_offset = 0;
11771   int ret;
11772
11773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11774     {
11775       if (unformat (i, "del"))
11776         is_add = 0;
11777       else if (unformat (i, "del-chain"))
11778         {
11779           is_add = 0;
11780           del_chain = 1;
11781         }
11782       else if (unformat (i, "buckets %d", &nbuckets))
11783         ;
11784       else if (unformat (i, "memory_size %d", &memory_size))
11785         ;
11786       else if (unformat (i, "skip %d", &skip))
11787         ;
11788       else if (unformat (i, "match %d", &match))
11789         ;
11790       else if (unformat (i, "table %d", &table_index))
11791         ;
11792       else if (unformat (i, "mask %U", unformat_classify_mask,
11793                          &mask, &skip, &match))
11794         ;
11795       else if (unformat (i, "next-table %d", &next_table_index))
11796         ;
11797       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11798                          &miss_next_index))
11799         ;
11800       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11801                          &miss_next_index))
11802         ;
11803       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11804                          &miss_next_index))
11805         ;
11806       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11807         ;
11808       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11809         ;
11810       else
11811         break;
11812     }
11813
11814   if (is_add && mask == 0)
11815     {
11816       errmsg ("Mask required");
11817       return -99;
11818     }
11819
11820   if (is_add && skip == ~0)
11821     {
11822       errmsg ("skip count required");
11823       return -99;
11824     }
11825
11826   if (is_add && match == ~0)
11827     {
11828       errmsg ("match count required");
11829       return -99;
11830     }
11831
11832   if (!is_add && table_index == ~0)
11833     {
11834       errmsg ("table index required for delete");
11835       return -99;
11836     }
11837
11838   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11839
11840   mp->is_add = is_add;
11841   mp->del_chain = del_chain;
11842   mp->table_index = ntohl (table_index);
11843   mp->nbuckets = ntohl (nbuckets);
11844   mp->memory_size = ntohl (memory_size);
11845   mp->skip_n_vectors = ntohl (skip);
11846   mp->match_n_vectors = ntohl (match);
11847   mp->next_table_index = ntohl (next_table_index);
11848   mp->miss_next_index = ntohl (miss_next_index);
11849   mp->current_data_flag = ntohl (current_data_flag);
11850   mp->current_data_offset = ntohl (current_data_offset);
11851   mp->mask_len = ntohl (vec_len (mask));
11852   clib_memcpy (mp->mask, mask, vec_len (mask));
11853
11854   vec_free (mask);
11855
11856   S (mp);
11857   W (ret);
11858   return ret;
11859 }
11860
11861 #if VPP_API_TEST_BUILTIN == 0
11862 uword
11863 unformat_l4_match (unformat_input_t * input, va_list * args)
11864 {
11865   u8 **matchp = va_arg (*args, u8 **);
11866
11867   u8 *proto_header = 0;
11868   int src_port = 0;
11869   int dst_port = 0;
11870
11871   tcpudp_header_t h;
11872
11873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (input, "src_port %d", &src_port))
11876         ;
11877       else if (unformat (input, "dst_port %d", &dst_port))
11878         ;
11879       else
11880         return 0;
11881     }
11882
11883   h.src_port = clib_host_to_net_u16 (src_port);
11884   h.dst_port = clib_host_to_net_u16 (dst_port);
11885   vec_validate (proto_header, sizeof (h) - 1);
11886   memcpy (proto_header, &h, sizeof (h));
11887
11888   *matchp = proto_header;
11889
11890   return 1;
11891 }
11892
11893 uword
11894 unformat_ip4_match (unformat_input_t * input, va_list * args)
11895 {
11896   u8 **matchp = va_arg (*args, u8 **);
11897   u8 *match = 0;
11898   ip4_header_t *ip;
11899   int version = 0;
11900   u32 version_val;
11901   int hdr_length = 0;
11902   u32 hdr_length_val;
11903   int src = 0, dst = 0;
11904   ip4_address_t src_val, dst_val;
11905   int proto = 0;
11906   u32 proto_val;
11907   int tos = 0;
11908   u32 tos_val;
11909   int length = 0;
11910   u32 length_val;
11911   int fragment_id = 0;
11912   u32 fragment_id_val;
11913   int ttl = 0;
11914   int ttl_val;
11915   int checksum = 0;
11916   u32 checksum_val;
11917
11918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11919     {
11920       if (unformat (input, "version %d", &version_val))
11921         version = 1;
11922       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11923         hdr_length = 1;
11924       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11925         src = 1;
11926       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11927         dst = 1;
11928       else if (unformat (input, "proto %d", &proto_val))
11929         proto = 1;
11930       else if (unformat (input, "tos %d", &tos_val))
11931         tos = 1;
11932       else if (unformat (input, "length %d", &length_val))
11933         length = 1;
11934       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11935         fragment_id = 1;
11936       else if (unformat (input, "ttl %d", &ttl_val))
11937         ttl = 1;
11938       else if (unformat (input, "checksum %d", &checksum_val))
11939         checksum = 1;
11940       else
11941         break;
11942     }
11943
11944   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11945       + ttl + checksum == 0)
11946     return 0;
11947
11948   /*
11949    * Aligned because we use the real comparison functions
11950    */
11951   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11952
11953   ip = (ip4_header_t *) match;
11954
11955   /* These are realistically matched in practice */
11956   if (src)
11957     ip->src_address.as_u32 = src_val.as_u32;
11958
11959   if (dst)
11960     ip->dst_address.as_u32 = dst_val.as_u32;
11961
11962   if (proto)
11963     ip->protocol = proto_val;
11964
11965
11966   /* These are not, but they're included for completeness */
11967   if (version)
11968     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11969
11970   if (hdr_length)
11971     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11972
11973   if (tos)
11974     ip->tos = tos_val;
11975
11976   if (length)
11977     ip->length = clib_host_to_net_u16 (length_val);
11978
11979   if (ttl)
11980     ip->ttl = ttl_val;
11981
11982   if (checksum)
11983     ip->checksum = clib_host_to_net_u16 (checksum_val);
11984
11985   *matchp = match;
11986   return 1;
11987 }
11988
11989 uword
11990 unformat_ip6_match (unformat_input_t * input, va_list * args)
11991 {
11992   u8 **matchp = va_arg (*args, u8 **);
11993   u8 *match = 0;
11994   ip6_header_t *ip;
11995   int version = 0;
11996   u32 version_val;
11997   u8 traffic_class = 0;
11998   u32 traffic_class_val = 0;
11999   u8 flow_label = 0;
12000   u8 flow_label_val;
12001   int src = 0, dst = 0;
12002   ip6_address_t src_val, dst_val;
12003   int proto = 0;
12004   u32 proto_val;
12005   int payload_length = 0;
12006   u32 payload_length_val;
12007   int hop_limit = 0;
12008   int hop_limit_val;
12009   u32 ip_version_traffic_class_and_flow_label;
12010
12011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12012     {
12013       if (unformat (input, "version %d", &version_val))
12014         version = 1;
12015       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12016         traffic_class = 1;
12017       else if (unformat (input, "flow_label %d", &flow_label_val))
12018         flow_label = 1;
12019       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12020         src = 1;
12021       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12022         dst = 1;
12023       else if (unformat (input, "proto %d", &proto_val))
12024         proto = 1;
12025       else if (unformat (input, "payload_length %d", &payload_length_val))
12026         payload_length = 1;
12027       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12028         hop_limit = 1;
12029       else
12030         break;
12031     }
12032
12033   if (version + traffic_class + flow_label + src + dst + proto +
12034       payload_length + hop_limit == 0)
12035     return 0;
12036
12037   /*
12038    * Aligned because we use the real comparison functions
12039    */
12040   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12041
12042   ip = (ip6_header_t *) match;
12043
12044   if (src)
12045     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12046
12047   if (dst)
12048     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12049
12050   if (proto)
12051     ip->protocol = proto_val;
12052
12053   ip_version_traffic_class_and_flow_label = 0;
12054
12055   if (version)
12056     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12057
12058   if (traffic_class)
12059     ip_version_traffic_class_and_flow_label |=
12060       (traffic_class_val & 0xFF) << 20;
12061
12062   if (flow_label)
12063     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12064
12065   ip->ip_version_traffic_class_and_flow_label =
12066     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12067
12068   if (payload_length)
12069     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12070
12071   if (hop_limit)
12072     ip->hop_limit = hop_limit_val;
12073
12074   *matchp = match;
12075   return 1;
12076 }
12077
12078 uword
12079 unformat_l3_match (unformat_input_t * input, va_list * args)
12080 {
12081   u8 **matchp = va_arg (*args, u8 **);
12082
12083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12084     {
12085       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12086         return 1;
12087       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12088         return 1;
12089       else
12090         break;
12091     }
12092   return 0;
12093 }
12094
12095 uword
12096 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12097 {
12098   u8 *tagp = va_arg (*args, u8 *);
12099   u32 tag;
12100
12101   if (unformat (input, "%d", &tag))
12102     {
12103       tagp[0] = (tag >> 8) & 0x0F;
12104       tagp[1] = tag & 0xFF;
12105       return 1;
12106     }
12107
12108   return 0;
12109 }
12110
12111 uword
12112 unformat_l2_match (unformat_input_t * input, va_list * args)
12113 {
12114   u8 **matchp = va_arg (*args, u8 **);
12115   u8 *match = 0;
12116   u8 src = 0;
12117   u8 src_val[6];
12118   u8 dst = 0;
12119   u8 dst_val[6];
12120   u8 proto = 0;
12121   u16 proto_val;
12122   u8 tag1 = 0;
12123   u8 tag1_val[2];
12124   u8 tag2 = 0;
12125   u8 tag2_val[2];
12126   int len = 14;
12127   u8 ignore_tag1 = 0;
12128   u8 ignore_tag2 = 0;
12129   u8 cos1 = 0;
12130   u8 cos2 = 0;
12131   u32 cos1_val = 0;
12132   u32 cos2_val = 0;
12133
12134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12135     {
12136       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12137         src = 1;
12138       else
12139         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12140         dst = 1;
12141       else if (unformat (input, "proto %U",
12142                          unformat_ethernet_type_host_byte_order, &proto_val))
12143         proto = 1;
12144       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12145         tag1 = 1;
12146       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12147         tag2 = 1;
12148       else if (unformat (input, "ignore-tag1"))
12149         ignore_tag1 = 1;
12150       else if (unformat (input, "ignore-tag2"))
12151         ignore_tag2 = 1;
12152       else if (unformat (input, "cos1 %d", &cos1_val))
12153         cos1 = 1;
12154       else if (unformat (input, "cos2 %d", &cos2_val))
12155         cos2 = 1;
12156       else
12157         break;
12158     }
12159   if ((src + dst + proto + tag1 + tag2 +
12160        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12161     return 0;
12162
12163   if (tag1 || ignore_tag1 || cos1)
12164     len = 18;
12165   if (tag2 || ignore_tag2 || cos2)
12166     len = 22;
12167
12168   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12169
12170   if (dst)
12171     clib_memcpy (match, dst_val, 6);
12172
12173   if (src)
12174     clib_memcpy (match + 6, src_val, 6);
12175
12176   if (tag2)
12177     {
12178       /* inner vlan tag */
12179       match[19] = tag2_val[1];
12180       match[18] = tag2_val[0];
12181       if (cos2)
12182         match[18] |= (cos2_val & 0x7) << 5;
12183       if (proto)
12184         {
12185           match[21] = proto_val & 0xff;
12186           match[20] = proto_val >> 8;
12187         }
12188       if (tag1)
12189         {
12190           match[15] = tag1_val[1];
12191           match[14] = tag1_val[0];
12192         }
12193       if (cos1)
12194         match[14] |= (cos1_val & 0x7) << 5;
12195       *matchp = match;
12196       return 1;
12197     }
12198   if (tag1)
12199     {
12200       match[15] = tag1_val[1];
12201       match[14] = tag1_val[0];
12202       if (proto)
12203         {
12204           match[17] = proto_val & 0xff;
12205           match[16] = proto_val >> 8;
12206         }
12207       if (cos1)
12208         match[14] |= (cos1_val & 0x7) << 5;
12209
12210       *matchp = match;
12211       return 1;
12212     }
12213   if (cos2)
12214     match[18] |= (cos2_val & 0x7) << 5;
12215   if (cos1)
12216     match[14] |= (cos1_val & 0x7) << 5;
12217   if (proto)
12218     {
12219       match[13] = proto_val & 0xff;
12220       match[12] = proto_val >> 8;
12221     }
12222
12223   *matchp = match;
12224   return 1;
12225 }
12226
12227 uword
12228 unformat_qos_source (unformat_input_t * input, va_list * args)
12229 {
12230   int *qs = va_arg (*args, int *);
12231
12232   if (unformat (input, "ip"))
12233     *qs = QOS_SOURCE_IP;
12234   else if (unformat (input, "mpls"))
12235     *qs = QOS_SOURCE_MPLS;
12236   else if (unformat (input, "ext"))
12237     *qs = QOS_SOURCE_EXT;
12238   else if (unformat (input, "vlan"))
12239     *qs = QOS_SOURCE_VLAN;
12240   else
12241     return 0;
12242
12243   return 1;
12244 }
12245 #endif
12246
12247 uword
12248 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12249 {
12250   u8 **matchp = va_arg (*args, u8 **);
12251   u32 skip_n_vectors = va_arg (*args, u32);
12252   u32 match_n_vectors = va_arg (*args, u32);
12253
12254   u8 *match = 0;
12255   u8 *l2 = 0;
12256   u8 *l3 = 0;
12257   u8 *l4 = 0;
12258
12259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12260     {
12261       if (unformat (input, "hex %U", unformat_hex_string, &match))
12262         ;
12263       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12264         ;
12265       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12266         ;
12267       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12268         ;
12269       else
12270         break;
12271     }
12272
12273   if (l4 && !l3)
12274     {
12275       vec_free (match);
12276       vec_free (l2);
12277       vec_free (l4);
12278       return 0;
12279     }
12280
12281   if (match || l2 || l3 || l4)
12282     {
12283       if (l2 || l3 || l4)
12284         {
12285           /* "Win a free Ethernet header in every packet" */
12286           if (l2 == 0)
12287             vec_validate_aligned (l2, 13, sizeof (u32x4));
12288           match = l2;
12289           if (vec_len (l3))
12290             {
12291               vec_append_aligned (match, l3, sizeof (u32x4));
12292               vec_free (l3);
12293             }
12294           if (vec_len (l4))
12295             {
12296               vec_append_aligned (match, l4, sizeof (u32x4));
12297               vec_free (l4);
12298             }
12299         }
12300
12301       /* Make sure the vector is big enough even if key is all 0's */
12302       vec_validate_aligned
12303         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12304          sizeof (u32x4));
12305
12306       /* Set size, include skipped vectors */
12307       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12308
12309       *matchp = match;
12310
12311       return 1;
12312     }
12313
12314   return 0;
12315 }
12316
12317 static int
12318 api_classify_add_del_session (vat_main_t * vam)
12319 {
12320   unformat_input_t *i = vam->input;
12321   vl_api_classify_add_del_session_t *mp;
12322   int is_add = 1;
12323   u32 table_index = ~0;
12324   u32 hit_next_index = ~0;
12325   u32 opaque_index = ~0;
12326   u8 *match = 0;
12327   i32 advance = 0;
12328   u32 skip_n_vectors = 0;
12329   u32 match_n_vectors = 0;
12330   u32 action = 0;
12331   u32 metadata = 0;
12332   int ret;
12333
12334   /*
12335    * Warning: you have to supply skip_n and match_n
12336    * because the API client cant simply look at the classify
12337    * table object.
12338    */
12339
12340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12341     {
12342       if (unformat (i, "del"))
12343         is_add = 0;
12344       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12345                          &hit_next_index))
12346         ;
12347       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12348                          &hit_next_index))
12349         ;
12350       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12351                          &hit_next_index))
12352         ;
12353       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12354         ;
12355       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12356         ;
12357       else if (unformat (i, "opaque-index %d", &opaque_index))
12358         ;
12359       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12360         ;
12361       else if (unformat (i, "match_n %d", &match_n_vectors))
12362         ;
12363       else if (unformat (i, "match %U", api_unformat_classify_match,
12364                          &match, skip_n_vectors, match_n_vectors))
12365         ;
12366       else if (unformat (i, "advance %d", &advance))
12367         ;
12368       else if (unformat (i, "table-index %d", &table_index))
12369         ;
12370       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12371         action = 1;
12372       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12373         action = 2;
12374       else if (unformat (i, "action %d", &action))
12375         ;
12376       else if (unformat (i, "metadata %d", &metadata))
12377         ;
12378       else
12379         break;
12380     }
12381
12382   if (table_index == ~0)
12383     {
12384       errmsg ("Table index required");
12385       return -99;
12386     }
12387
12388   if (is_add && match == 0)
12389     {
12390       errmsg ("Match value required");
12391       return -99;
12392     }
12393
12394   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12395
12396   mp->is_add = is_add;
12397   mp->table_index = ntohl (table_index);
12398   mp->hit_next_index = ntohl (hit_next_index);
12399   mp->opaque_index = ntohl (opaque_index);
12400   mp->advance = ntohl (advance);
12401   mp->action = action;
12402   mp->metadata = ntohl (metadata);
12403   mp->match_len = ntohl (vec_len (match));
12404   clib_memcpy (mp->match, match, vec_len (match));
12405   vec_free (match);
12406
12407   S (mp);
12408   W (ret);
12409   return ret;
12410 }
12411
12412 static int
12413 api_classify_set_interface_ip_table (vat_main_t * vam)
12414 {
12415   unformat_input_t *i = vam->input;
12416   vl_api_classify_set_interface_ip_table_t *mp;
12417   u32 sw_if_index;
12418   int sw_if_index_set;
12419   u32 table_index = ~0;
12420   u8 is_ipv6 = 0;
12421   int ret;
12422
12423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12424     {
12425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12426         sw_if_index_set = 1;
12427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12428         sw_if_index_set = 1;
12429       else if (unformat (i, "table %d", &table_index))
12430         ;
12431       else
12432         {
12433           clib_warning ("parse error '%U'", format_unformat_error, i);
12434           return -99;
12435         }
12436     }
12437
12438   if (sw_if_index_set == 0)
12439     {
12440       errmsg ("missing interface name or sw_if_index");
12441       return -99;
12442     }
12443
12444
12445   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12446
12447   mp->sw_if_index = ntohl (sw_if_index);
12448   mp->table_index = ntohl (table_index);
12449   mp->is_ipv6 = is_ipv6;
12450
12451   S (mp);
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static int
12457 api_classify_set_interface_l2_tables (vat_main_t * vam)
12458 {
12459   unformat_input_t *i = vam->input;
12460   vl_api_classify_set_interface_l2_tables_t *mp;
12461   u32 sw_if_index;
12462   int sw_if_index_set;
12463   u32 ip4_table_index = ~0;
12464   u32 ip6_table_index = ~0;
12465   u32 other_table_index = ~0;
12466   u32 is_input = 1;
12467   int ret;
12468
12469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12470     {
12471       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12472         sw_if_index_set = 1;
12473       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12474         sw_if_index_set = 1;
12475       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12476         ;
12477       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12478         ;
12479       else if (unformat (i, "other-table %d", &other_table_index))
12480         ;
12481       else if (unformat (i, "is-input %d", &is_input))
12482         ;
12483       else
12484         {
12485           clib_warning ("parse error '%U'", format_unformat_error, i);
12486           return -99;
12487         }
12488     }
12489
12490   if (sw_if_index_set == 0)
12491     {
12492       errmsg ("missing interface name or sw_if_index");
12493       return -99;
12494     }
12495
12496
12497   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12498
12499   mp->sw_if_index = ntohl (sw_if_index);
12500   mp->ip4_table_index = ntohl (ip4_table_index);
12501   mp->ip6_table_index = ntohl (ip6_table_index);
12502   mp->other_table_index = ntohl (other_table_index);
12503   mp->is_input = (u8) is_input;
12504
12505   S (mp);
12506   W (ret);
12507   return ret;
12508 }
12509
12510 static int
12511 api_set_ipfix_exporter (vat_main_t * vam)
12512 {
12513   unformat_input_t *i = vam->input;
12514   vl_api_set_ipfix_exporter_t *mp;
12515   ip4_address_t collector_address;
12516   u8 collector_address_set = 0;
12517   u32 collector_port = ~0;
12518   ip4_address_t src_address;
12519   u8 src_address_set = 0;
12520   u32 vrf_id = ~0;
12521   u32 path_mtu = ~0;
12522   u32 template_interval = ~0;
12523   u8 udp_checksum = 0;
12524   int ret;
12525
12526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12527     {
12528       if (unformat (i, "collector_address %U", unformat_ip4_address,
12529                     &collector_address))
12530         collector_address_set = 1;
12531       else if (unformat (i, "collector_port %d", &collector_port))
12532         ;
12533       else if (unformat (i, "src_address %U", unformat_ip4_address,
12534                          &src_address))
12535         src_address_set = 1;
12536       else if (unformat (i, "vrf_id %d", &vrf_id))
12537         ;
12538       else if (unformat (i, "path_mtu %d", &path_mtu))
12539         ;
12540       else if (unformat (i, "template_interval %d", &template_interval))
12541         ;
12542       else if (unformat (i, "udp_checksum"))
12543         udp_checksum = 1;
12544       else
12545         break;
12546     }
12547
12548   if (collector_address_set == 0)
12549     {
12550       errmsg ("collector_address required");
12551       return -99;
12552     }
12553
12554   if (src_address_set == 0)
12555     {
12556       errmsg ("src_address required");
12557       return -99;
12558     }
12559
12560   M (SET_IPFIX_EXPORTER, mp);
12561
12562   memcpy (mp->collector_address, collector_address.data,
12563           sizeof (collector_address.data));
12564   mp->collector_port = htons ((u16) collector_port);
12565   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12566   mp->vrf_id = htonl (vrf_id);
12567   mp->path_mtu = htonl (path_mtu);
12568   mp->template_interval = htonl (template_interval);
12569   mp->udp_checksum = udp_checksum;
12570
12571   S (mp);
12572   W (ret);
12573   return ret;
12574 }
12575
12576 static int
12577 api_set_ipfix_classify_stream (vat_main_t * vam)
12578 {
12579   unformat_input_t *i = vam->input;
12580   vl_api_set_ipfix_classify_stream_t *mp;
12581   u32 domain_id = 0;
12582   u32 src_port = UDP_DST_PORT_ipfix;
12583   int ret;
12584
12585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12586     {
12587       if (unformat (i, "domain %d", &domain_id))
12588         ;
12589       else if (unformat (i, "src_port %d", &src_port))
12590         ;
12591       else
12592         {
12593           errmsg ("unknown input `%U'", format_unformat_error, i);
12594           return -99;
12595         }
12596     }
12597
12598   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12599
12600   mp->domain_id = htonl (domain_id);
12601   mp->src_port = htons ((u16) src_port);
12602
12603   S (mp);
12604   W (ret);
12605   return ret;
12606 }
12607
12608 static int
12609 api_ipfix_classify_table_add_del (vat_main_t * vam)
12610 {
12611   unformat_input_t *i = vam->input;
12612   vl_api_ipfix_classify_table_add_del_t *mp;
12613   int is_add = -1;
12614   u32 classify_table_index = ~0;
12615   u8 ip_version = 0;
12616   u8 transport_protocol = 255;
12617   int ret;
12618
12619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12620     {
12621       if (unformat (i, "add"))
12622         is_add = 1;
12623       else if (unformat (i, "del"))
12624         is_add = 0;
12625       else if (unformat (i, "table %d", &classify_table_index))
12626         ;
12627       else if (unformat (i, "ip4"))
12628         ip_version = 4;
12629       else if (unformat (i, "ip6"))
12630         ip_version = 6;
12631       else if (unformat (i, "tcp"))
12632         transport_protocol = 6;
12633       else if (unformat (i, "udp"))
12634         transport_protocol = 17;
12635       else
12636         {
12637           errmsg ("unknown input `%U'", format_unformat_error, i);
12638           return -99;
12639         }
12640     }
12641
12642   if (is_add == -1)
12643     {
12644       errmsg ("expecting: add|del");
12645       return -99;
12646     }
12647   if (classify_table_index == ~0)
12648     {
12649       errmsg ("classifier table not specified");
12650       return -99;
12651     }
12652   if (ip_version == 0)
12653     {
12654       errmsg ("IP version not specified");
12655       return -99;
12656     }
12657
12658   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12659
12660   mp->is_add = is_add;
12661   mp->table_id = htonl (classify_table_index);
12662   mp->ip_version = ip_version;
12663   mp->transport_protocol = transport_protocol;
12664
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_get_node_index (vat_main_t * vam)
12672 {
12673   unformat_input_t *i = vam->input;
12674   vl_api_get_node_index_t *mp;
12675   u8 *name = 0;
12676   int ret;
12677
12678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12679     {
12680       if (unformat (i, "node %s", &name))
12681         ;
12682       else
12683         break;
12684     }
12685   if (name == 0)
12686     {
12687       errmsg ("node name required");
12688       return -99;
12689     }
12690   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12691     {
12692       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12693       return -99;
12694     }
12695
12696   M (GET_NODE_INDEX, mp);
12697   clib_memcpy (mp->node_name, name, vec_len (name));
12698   vec_free (name);
12699
12700   S (mp);
12701   W (ret);
12702   return ret;
12703 }
12704
12705 static int
12706 api_get_next_index (vat_main_t * vam)
12707 {
12708   unformat_input_t *i = vam->input;
12709   vl_api_get_next_index_t *mp;
12710   u8 *node_name = 0, *next_node_name = 0;
12711   int ret;
12712
12713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12714     {
12715       if (unformat (i, "node-name %s", &node_name))
12716         ;
12717       else if (unformat (i, "next-node-name %s", &next_node_name))
12718         break;
12719     }
12720
12721   if (node_name == 0)
12722     {
12723       errmsg ("node name required");
12724       return -99;
12725     }
12726   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12727     {
12728       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12729       return -99;
12730     }
12731
12732   if (next_node_name == 0)
12733     {
12734       errmsg ("next node name required");
12735       return -99;
12736     }
12737   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12738     {
12739       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12740       return -99;
12741     }
12742
12743   M (GET_NEXT_INDEX, mp);
12744   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12745   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12746   vec_free (node_name);
12747   vec_free (next_node_name);
12748
12749   S (mp);
12750   W (ret);
12751   return ret;
12752 }
12753
12754 static int
12755 api_add_node_next (vat_main_t * vam)
12756 {
12757   unformat_input_t *i = vam->input;
12758   vl_api_add_node_next_t *mp;
12759   u8 *name = 0;
12760   u8 *next = 0;
12761   int ret;
12762
12763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12764     {
12765       if (unformat (i, "node %s", &name))
12766         ;
12767       else if (unformat (i, "next %s", &next))
12768         ;
12769       else
12770         break;
12771     }
12772   if (name == 0)
12773     {
12774       errmsg ("node name required");
12775       return -99;
12776     }
12777   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12778     {
12779       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12780       return -99;
12781     }
12782   if (next == 0)
12783     {
12784       errmsg ("next node required");
12785       return -99;
12786     }
12787   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12788     {
12789       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12790       return -99;
12791     }
12792
12793   M (ADD_NODE_NEXT, mp);
12794   clib_memcpy (mp->node_name, name, vec_len (name));
12795   clib_memcpy (mp->next_name, next, vec_len (next));
12796   vec_free (name);
12797   vec_free (next);
12798
12799   S (mp);
12800   W (ret);
12801   return ret;
12802 }
12803
12804 static int
12805 api_l2tpv3_create_tunnel (vat_main_t * vam)
12806 {
12807   unformat_input_t *i = vam->input;
12808   ip6_address_t client_address, our_address;
12809   int client_address_set = 0;
12810   int our_address_set = 0;
12811   u32 local_session_id = 0;
12812   u32 remote_session_id = 0;
12813   u64 local_cookie = 0;
12814   u64 remote_cookie = 0;
12815   u8 l2_sublayer_present = 0;
12816   vl_api_l2tpv3_create_tunnel_t *mp;
12817   int ret;
12818
12819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12820     {
12821       if (unformat (i, "client_address %U", unformat_ip6_address,
12822                     &client_address))
12823         client_address_set = 1;
12824       else if (unformat (i, "our_address %U", unformat_ip6_address,
12825                          &our_address))
12826         our_address_set = 1;
12827       else if (unformat (i, "local_session_id %d", &local_session_id))
12828         ;
12829       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12830         ;
12831       else if (unformat (i, "local_cookie %lld", &local_cookie))
12832         ;
12833       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12834         ;
12835       else if (unformat (i, "l2-sublayer-present"))
12836         l2_sublayer_present = 1;
12837       else
12838         break;
12839     }
12840
12841   if (client_address_set == 0)
12842     {
12843       errmsg ("client_address required");
12844       return -99;
12845     }
12846
12847   if (our_address_set == 0)
12848     {
12849       errmsg ("our_address required");
12850       return -99;
12851     }
12852
12853   M (L2TPV3_CREATE_TUNNEL, mp);
12854
12855   clib_memcpy (mp->client_address, client_address.as_u8,
12856                sizeof (mp->client_address));
12857
12858   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12859
12860   mp->local_session_id = ntohl (local_session_id);
12861   mp->remote_session_id = ntohl (remote_session_id);
12862   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12863   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12864   mp->l2_sublayer_present = l2_sublayer_present;
12865   mp->is_ipv6 = 1;
12866
12867   S (mp);
12868   W (ret);
12869   return ret;
12870 }
12871
12872 static int
12873 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12874 {
12875   unformat_input_t *i = vam->input;
12876   u32 sw_if_index;
12877   u8 sw_if_index_set = 0;
12878   u64 new_local_cookie = 0;
12879   u64 new_remote_cookie = 0;
12880   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12881   int ret;
12882
12883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12884     {
12885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12886         sw_if_index_set = 1;
12887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12888         sw_if_index_set = 1;
12889       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12890         ;
12891       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12892         ;
12893       else
12894         break;
12895     }
12896
12897   if (sw_if_index_set == 0)
12898     {
12899       errmsg ("missing interface name or sw_if_index");
12900       return -99;
12901     }
12902
12903   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12904
12905   mp->sw_if_index = ntohl (sw_if_index);
12906   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12907   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12908
12909   S (mp);
12910   W (ret);
12911   return ret;
12912 }
12913
12914 static int
12915 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12916 {
12917   unformat_input_t *i = vam->input;
12918   vl_api_l2tpv3_interface_enable_disable_t *mp;
12919   u32 sw_if_index;
12920   u8 sw_if_index_set = 0;
12921   u8 enable_disable = 1;
12922   int ret;
12923
12924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12925     {
12926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12927         sw_if_index_set = 1;
12928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12929         sw_if_index_set = 1;
12930       else if (unformat (i, "enable"))
12931         enable_disable = 1;
12932       else if (unformat (i, "disable"))
12933         enable_disable = 0;
12934       else
12935         break;
12936     }
12937
12938   if (sw_if_index_set == 0)
12939     {
12940       errmsg ("missing interface name or sw_if_index");
12941       return -99;
12942     }
12943
12944   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12945
12946   mp->sw_if_index = ntohl (sw_if_index);
12947   mp->enable_disable = enable_disable;
12948
12949   S (mp);
12950   W (ret);
12951   return ret;
12952 }
12953
12954 static int
12955 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12956 {
12957   unformat_input_t *i = vam->input;
12958   vl_api_l2tpv3_set_lookup_key_t *mp;
12959   u8 key = ~0;
12960   int ret;
12961
12962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12963     {
12964       if (unformat (i, "lookup_v6_src"))
12965         key = L2T_LOOKUP_SRC_ADDRESS;
12966       else if (unformat (i, "lookup_v6_dst"))
12967         key = L2T_LOOKUP_DST_ADDRESS;
12968       else if (unformat (i, "lookup_session_id"))
12969         key = L2T_LOOKUP_SESSION_ID;
12970       else
12971         break;
12972     }
12973
12974   if (key == (u8) ~ 0)
12975     {
12976       errmsg ("l2tp session lookup key unset");
12977       return -99;
12978     }
12979
12980   M (L2TPV3_SET_LOOKUP_KEY, mp);
12981
12982   mp->key = key;
12983
12984   S (mp);
12985   W (ret);
12986   return ret;
12987 }
12988
12989 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12990   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12991 {
12992   vat_main_t *vam = &vat_main;
12993
12994   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12995          format_ip6_address, mp->our_address,
12996          format_ip6_address, mp->client_address,
12997          clib_net_to_host_u32 (mp->sw_if_index));
12998
12999   print (vam->ofp,
13000          "   local cookies %016llx %016llx remote cookie %016llx",
13001          clib_net_to_host_u64 (mp->local_cookie[0]),
13002          clib_net_to_host_u64 (mp->local_cookie[1]),
13003          clib_net_to_host_u64 (mp->remote_cookie));
13004
13005   print (vam->ofp, "   local session-id %d remote session-id %d",
13006          clib_net_to_host_u32 (mp->local_session_id),
13007          clib_net_to_host_u32 (mp->remote_session_id));
13008
13009   print (vam->ofp, "   l2 specific sublayer %s\n",
13010          mp->l2_sublayer_present ? "preset" : "absent");
13011
13012 }
13013
13014 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13015   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13016 {
13017   vat_main_t *vam = &vat_main;
13018   vat_json_node_t *node = NULL;
13019   struct in6_addr addr;
13020
13021   if (VAT_JSON_ARRAY != vam->json_tree.type)
13022     {
13023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13024       vat_json_init_array (&vam->json_tree);
13025     }
13026   node = vat_json_array_add (&vam->json_tree);
13027
13028   vat_json_init_object (node);
13029
13030   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13031   vat_json_object_add_ip6 (node, "our_address", addr);
13032   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13033   vat_json_object_add_ip6 (node, "client_address", addr);
13034
13035   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13036   vat_json_init_array (lc);
13037   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13038   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13039   vat_json_object_add_uint (node, "remote_cookie",
13040                             clib_net_to_host_u64 (mp->remote_cookie));
13041
13042   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13043   vat_json_object_add_uint (node, "local_session_id",
13044                             clib_net_to_host_u32 (mp->local_session_id));
13045   vat_json_object_add_uint (node, "remote_session_id",
13046                             clib_net_to_host_u32 (mp->remote_session_id));
13047   vat_json_object_add_string_copy (node, "l2_sublayer",
13048                                    mp->l2_sublayer_present ? (u8 *) "present"
13049                                    : (u8 *) "absent");
13050 }
13051
13052 static int
13053 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13054 {
13055   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13056   vl_api_control_ping_t *mp_ping;
13057   int ret;
13058
13059   /* Get list of l2tpv3-tunnel interfaces */
13060   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13061   S (mp);
13062
13063   /* Use a control ping for synchronization */
13064   MPING (CONTROL_PING, mp_ping);
13065   S (mp_ping);
13066
13067   W (ret);
13068   return ret;
13069 }
13070
13071
13072 static void vl_api_sw_interface_tap_details_t_handler
13073   (vl_api_sw_interface_tap_details_t * mp)
13074 {
13075   vat_main_t *vam = &vat_main;
13076
13077   print (vam->ofp, "%-16s %d",
13078          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13079 }
13080
13081 static void vl_api_sw_interface_tap_details_t_handler_json
13082   (vl_api_sw_interface_tap_details_t * mp)
13083 {
13084   vat_main_t *vam = &vat_main;
13085   vat_json_node_t *node = NULL;
13086
13087   if (VAT_JSON_ARRAY != vam->json_tree.type)
13088     {
13089       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13090       vat_json_init_array (&vam->json_tree);
13091     }
13092   node = vat_json_array_add (&vam->json_tree);
13093
13094   vat_json_init_object (node);
13095   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13096   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13097 }
13098
13099 static int
13100 api_sw_interface_tap_dump (vat_main_t * vam)
13101 {
13102   vl_api_sw_interface_tap_dump_t *mp;
13103   vl_api_control_ping_t *mp_ping;
13104   int ret;
13105
13106   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13107   /* Get list of tap interfaces */
13108   M (SW_INTERFACE_TAP_DUMP, mp);
13109   S (mp);
13110
13111   /* Use a control ping for synchronization */
13112   MPING (CONTROL_PING, mp_ping);
13113   S (mp_ping);
13114
13115   W (ret);
13116   return ret;
13117 }
13118
13119 static void vl_api_sw_interface_tap_v2_details_t_handler
13120   (vl_api_sw_interface_tap_v2_details_t * mp)
13121 {
13122   vat_main_t *vam = &vat_main;
13123
13124   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13125                     mp->host_ip4_prefix_len);
13126   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13127                     mp->host_ip6_prefix_len);
13128
13129   print (vam->ofp,
13130          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13131          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13132          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13133          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13134          mp->host_bridge, ip4, ip6);
13135
13136   vec_free (ip4);
13137   vec_free (ip6);
13138 }
13139
13140 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13141   (vl_api_sw_interface_tap_v2_details_t * mp)
13142 {
13143   vat_main_t *vam = &vat_main;
13144   vat_json_node_t *node = NULL;
13145
13146   if (VAT_JSON_ARRAY != vam->json_tree.type)
13147     {
13148       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13149       vat_json_init_array (&vam->json_tree);
13150     }
13151   node = vat_json_array_add (&vam->json_tree);
13152
13153   vat_json_init_object (node);
13154   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13155   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13156   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13157   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13158   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13159   vat_json_object_add_string_copy (node, "host_mac_addr",
13160                                    format (0, "%U", format_ethernet_address,
13161                                            &mp->host_mac_addr));
13162   vat_json_object_add_string_copy (node, "host_namespace",
13163                                    mp->host_namespace);
13164   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13165   vat_json_object_add_string_copy (node, "host_ip4_addr",
13166                                    format (0, "%U/%d", format_ip4_address,
13167                                            mp->host_ip4_addr,
13168                                            mp->host_ip4_prefix_len));
13169   vat_json_object_add_string_copy (node, "host_ip6_addr",
13170                                    format (0, "%U/%d", format_ip6_address,
13171                                            mp->host_ip6_addr,
13172                                            mp->host_ip6_prefix_len));
13173
13174 }
13175
13176 static int
13177 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13178 {
13179   vl_api_sw_interface_tap_v2_dump_t *mp;
13180   vl_api_control_ping_t *mp_ping;
13181   int ret;
13182
13183   print (vam->ofp,
13184          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13185          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13186          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13187          "host_ip6_addr");
13188
13189   /* Get list of tap interfaces */
13190   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13191   S (mp);
13192
13193   /* Use a control ping for synchronization */
13194   MPING (CONTROL_PING, mp_ping);
13195   S (mp_ping);
13196
13197   W (ret);
13198   return ret;
13199 }
13200
13201 static int
13202 api_vxlan_offload_rx (vat_main_t * vam)
13203 {
13204   unformat_input_t *line_input = vam->input;
13205   vl_api_vxlan_offload_rx_t *mp;
13206   u32 hw_if_index = ~0, rx_if_index = ~0;
13207   u8 is_add = 1;
13208   int ret;
13209
13210   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13211     {
13212       if (unformat (line_input, "del"))
13213         is_add = 0;
13214       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13215                          &hw_if_index))
13216         ;
13217       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13218         ;
13219       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13220                          &rx_if_index))
13221         ;
13222       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13223         ;
13224       else
13225         {
13226           errmsg ("parse error '%U'", format_unformat_error, line_input);
13227           return -99;
13228         }
13229     }
13230
13231   if (hw_if_index == ~0)
13232     {
13233       errmsg ("no hw interface");
13234       return -99;
13235     }
13236
13237   if (rx_if_index == ~0)
13238     {
13239       errmsg ("no rx tunnel");
13240       return -99;
13241     }
13242
13243   M (VXLAN_OFFLOAD_RX, mp);
13244
13245   mp->hw_if_index = ntohl (hw_if_index);
13246   mp->sw_if_index = ntohl (rx_if_index);
13247   mp->enable = is_add;
13248
13249   S (mp);
13250   W (ret);
13251   return ret;
13252 }
13253
13254 static uword unformat_vxlan_decap_next
13255   (unformat_input_t * input, va_list * args)
13256 {
13257   u32 *result = va_arg (*args, u32 *);
13258   u32 tmp;
13259
13260   if (unformat (input, "l2"))
13261     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13262   else if (unformat (input, "%d", &tmp))
13263     *result = tmp;
13264   else
13265     return 0;
13266   return 1;
13267 }
13268
13269 static int
13270 api_vxlan_add_del_tunnel (vat_main_t * vam)
13271 {
13272   unformat_input_t *line_input = vam->input;
13273   vl_api_vxlan_add_del_tunnel_t *mp;
13274   ip46_address_t src, dst;
13275   u8 is_add = 1;
13276   u8 ipv4_set = 0, ipv6_set = 0;
13277   u8 src_set = 0;
13278   u8 dst_set = 0;
13279   u8 grp_set = 0;
13280   u32 instance = ~0;
13281   u32 mcast_sw_if_index = ~0;
13282   u32 encap_vrf_id = 0;
13283   u32 decap_next_index = ~0;
13284   u32 vni = 0;
13285   int ret;
13286
13287   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13288   memset (&src, 0, sizeof src);
13289   memset (&dst, 0, sizeof dst);
13290
13291   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13292     {
13293       if (unformat (line_input, "del"))
13294         is_add = 0;
13295       else if (unformat (line_input, "instance %d", &instance))
13296         ;
13297       else
13298         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13299         {
13300           ipv4_set = 1;
13301           src_set = 1;
13302         }
13303       else
13304         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13305         {
13306           ipv4_set = 1;
13307           dst_set = 1;
13308         }
13309       else
13310         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13311         {
13312           ipv6_set = 1;
13313           src_set = 1;
13314         }
13315       else
13316         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13317         {
13318           ipv6_set = 1;
13319           dst_set = 1;
13320         }
13321       else if (unformat (line_input, "group %U %U",
13322                          unformat_ip4_address, &dst.ip4,
13323                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13324         {
13325           grp_set = dst_set = 1;
13326           ipv4_set = 1;
13327         }
13328       else if (unformat (line_input, "group %U",
13329                          unformat_ip4_address, &dst.ip4))
13330         {
13331           grp_set = dst_set = 1;
13332           ipv4_set = 1;
13333         }
13334       else if (unformat (line_input, "group %U %U",
13335                          unformat_ip6_address, &dst.ip6,
13336                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13337         {
13338           grp_set = dst_set = 1;
13339           ipv6_set = 1;
13340         }
13341       else if (unformat (line_input, "group %U",
13342                          unformat_ip6_address, &dst.ip6))
13343         {
13344           grp_set = dst_set = 1;
13345           ipv6_set = 1;
13346         }
13347       else
13348         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13349         ;
13350       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13351         ;
13352       else if (unformat (line_input, "decap-next %U",
13353                          unformat_vxlan_decap_next, &decap_next_index))
13354         ;
13355       else if (unformat (line_input, "vni %d", &vni))
13356         ;
13357       else
13358         {
13359           errmsg ("parse error '%U'", format_unformat_error, line_input);
13360           return -99;
13361         }
13362     }
13363
13364   if (src_set == 0)
13365     {
13366       errmsg ("tunnel src address not specified");
13367       return -99;
13368     }
13369   if (dst_set == 0)
13370     {
13371       errmsg ("tunnel dst address not specified");
13372       return -99;
13373     }
13374
13375   if (grp_set && !ip46_address_is_multicast (&dst))
13376     {
13377       errmsg ("tunnel group address not multicast");
13378       return -99;
13379     }
13380   if (grp_set && mcast_sw_if_index == ~0)
13381     {
13382       errmsg ("tunnel nonexistent multicast device");
13383       return -99;
13384     }
13385   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13386     {
13387       errmsg ("tunnel dst address must be unicast");
13388       return -99;
13389     }
13390
13391
13392   if (ipv4_set && ipv6_set)
13393     {
13394       errmsg ("both IPv4 and IPv6 addresses specified");
13395       return -99;
13396     }
13397
13398   if ((vni == 0) || (vni >> 24))
13399     {
13400       errmsg ("vni not specified or out of range");
13401       return -99;
13402     }
13403
13404   M (VXLAN_ADD_DEL_TUNNEL, mp);
13405
13406   if (ipv6_set)
13407     {
13408       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13409       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13410     }
13411   else
13412     {
13413       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13414       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13415     }
13416
13417   mp->instance = htonl (instance);
13418   mp->encap_vrf_id = ntohl (encap_vrf_id);
13419   mp->decap_next_index = ntohl (decap_next_index);
13420   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13421   mp->vni = ntohl (vni);
13422   mp->is_add = is_add;
13423   mp->is_ipv6 = ipv6_set;
13424
13425   S (mp);
13426   W (ret);
13427   return ret;
13428 }
13429
13430 static void vl_api_vxlan_tunnel_details_t_handler
13431   (vl_api_vxlan_tunnel_details_t * mp)
13432 {
13433   vat_main_t *vam = &vat_main;
13434   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13435   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13436
13437   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13438          ntohl (mp->sw_if_index),
13439          ntohl (mp->instance),
13440          format_ip46_address, &src, IP46_TYPE_ANY,
13441          format_ip46_address, &dst, IP46_TYPE_ANY,
13442          ntohl (mp->encap_vrf_id),
13443          ntohl (mp->decap_next_index), ntohl (mp->vni),
13444          ntohl (mp->mcast_sw_if_index));
13445 }
13446
13447 static void vl_api_vxlan_tunnel_details_t_handler_json
13448   (vl_api_vxlan_tunnel_details_t * mp)
13449 {
13450   vat_main_t *vam = &vat_main;
13451   vat_json_node_t *node = NULL;
13452
13453   if (VAT_JSON_ARRAY != vam->json_tree.type)
13454     {
13455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13456       vat_json_init_array (&vam->json_tree);
13457     }
13458   node = vat_json_array_add (&vam->json_tree);
13459
13460   vat_json_init_object (node);
13461   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13462
13463   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13464
13465   if (mp->is_ipv6)
13466     {
13467       struct in6_addr ip6;
13468
13469       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13470       vat_json_object_add_ip6 (node, "src_address", ip6);
13471       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13472       vat_json_object_add_ip6 (node, "dst_address", ip6);
13473     }
13474   else
13475     {
13476       struct in_addr ip4;
13477
13478       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13479       vat_json_object_add_ip4 (node, "src_address", ip4);
13480       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13481       vat_json_object_add_ip4 (node, "dst_address", ip4);
13482     }
13483   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13484   vat_json_object_add_uint (node, "decap_next_index",
13485                             ntohl (mp->decap_next_index));
13486   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13487   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13488   vat_json_object_add_uint (node, "mcast_sw_if_index",
13489                             ntohl (mp->mcast_sw_if_index));
13490 }
13491
13492 static int
13493 api_vxlan_tunnel_dump (vat_main_t * vam)
13494 {
13495   unformat_input_t *i = vam->input;
13496   vl_api_vxlan_tunnel_dump_t *mp;
13497   vl_api_control_ping_t *mp_ping;
13498   u32 sw_if_index;
13499   u8 sw_if_index_set = 0;
13500   int ret;
13501
13502   /* Parse args required to build the message */
13503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13504     {
13505       if (unformat (i, "sw_if_index %d", &sw_if_index))
13506         sw_if_index_set = 1;
13507       else
13508         break;
13509     }
13510
13511   if (sw_if_index_set == 0)
13512     {
13513       sw_if_index = ~0;
13514     }
13515
13516   if (!vam->json_output)
13517     {
13518       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13519              "sw_if_index", "instance", "src_address", "dst_address",
13520              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13521     }
13522
13523   /* Get list of vxlan-tunnel interfaces */
13524   M (VXLAN_TUNNEL_DUMP, mp);
13525
13526   mp->sw_if_index = htonl (sw_if_index);
13527
13528   S (mp);
13529
13530   /* Use a control ping for synchronization */
13531   MPING (CONTROL_PING, mp_ping);
13532   S (mp_ping);
13533
13534   W (ret);
13535   return ret;
13536 }
13537
13538 static uword unformat_geneve_decap_next
13539   (unformat_input_t * input, va_list * args)
13540 {
13541   u32 *result = va_arg (*args, u32 *);
13542   u32 tmp;
13543
13544   if (unformat (input, "l2"))
13545     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13546   else if (unformat (input, "%d", &tmp))
13547     *result = tmp;
13548   else
13549     return 0;
13550   return 1;
13551 }
13552
13553 static int
13554 api_geneve_add_del_tunnel (vat_main_t * vam)
13555 {
13556   unformat_input_t *line_input = vam->input;
13557   vl_api_geneve_add_del_tunnel_t *mp;
13558   ip46_address_t src, dst;
13559   u8 is_add = 1;
13560   u8 ipv4_set = 0, ipv6_set = 0;
13561   u8 src_set = 0;
13562   u8 dst_set = 0;
13563   u8 grp_set = 0;
13564   u32 mcast_sw_if_index = ~0;
13565   u32 encap_vrf_id = 0;
13566   u32 decap_next_index = ~0;
13567   u32 vni = 0;
13568   int ret;
13569
13570   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13571   memset (&src, 0, sizeof src);
13572   memset (&dst, 0, sizeof dst);
13573
13574   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13575     {
13576       if (unformat (line_input, "del"))
13577         is_add = 0;
13578       else
13579         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13580         {
13581           ipv4_set = 1;
13582           src_set = 1;
13583         }
13584       else
13585         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13586         {
13587           ipv4_set = 1;
13588           dst_set = 1;
13589         }
13590       else
13591         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13592         {
13593           ipv6_set = 1;
13594           src_set = 1;
13595         }
13596       else
13597         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13598         {
13599           ipv6_set = 1;
13600           dst_set = 1;
13601         }
13602       else if (unformat (line_input, "group %U %U",
13603                          unformat_ip4_address, &dst.ip4,
13604                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13605         {
13606           grp_set = dst_set = 1;
13607           ipv4_set = 1;
13608         }
13609       else if (unformat (line_input, "group %U",
13610                          unformat_ip4_address, &dst.ip4))
13611         {
13612           grp_set = dst_set = 1;
13613           ipv4_set = 1;
13614         }
13615       else if (unformat (line_input, "group %U %U",
13616                          unformat_ip6_address, &dst.ip6,
13617                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13618         {
13619           grp_set = dst_set = 1;
13620           ipv6_set = 1;
13621         }
13622       else if (unformat (line_input, "group %U",
13623                          unformat_ip6_address, &dst.ip6))
13624         {
13625           grp_set = dst_set = 1;
13626           ipv6_set = 1;
13627         }
13628       else
13629         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13630         ;
13631       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13632         ;
13633       else if (unformat (line_input, "decap-next %U",
13634                          unformat_geneve_decap_next, &decap_next_index))
13635         ;
13636       else if (unformat (line_input, "vni %d", &vni))
13637         ;
13638       else
13639         {
13640           errmsg ("parse error '%U'", format_unformat_error, line_input);
13641           return -99;
13642         }
13643     }
13644
13645   if (src_set == 0)
13646     {
13647       errmsg ("tunnel src address not specified");
13648       return -99;
13649     }
13650   if (dst_set == 0)
13651     {
13652       errmsg ("tunnel dst address not specified");
13653       return -99;
13654     }
13655
13656   if (grp_set && !ip46_address_is_multicast (&dst))
13657     {
13658       errmsg ("tunnel group address not multicast");
13659       return -99;
13660     }
13661   if (grp_set && mcast_sw_if_index == ~0)
13662     {
13663       errmsg ("tunnel nonexistent multicast device");
13664       return -99;
13665     }
13666   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13667     {
13668       errmsg ("tunnel dst address must be unicast");
13669       return -99;
13670     }
13671
13672
13673   if (ipv4_set && ipv6_set)
13674     {
13675       errmsg ("both IPv4 and IPv6 addresses specified");
13676       return -99;
13677     }
13678
13679   if ((vni == 0) || (vni >> 24))
13680     {
13681       errmsg ("vni not specified or out of range");
13682       return -99;
13683     }
13684
13685   M (GENEVE_ADD_DEL_TUNNEL, mp);
13686
13687   if (ipv6_set)
13688     {
13689       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13690       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13691     }
13692   else
13693     {
13694       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13695       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13696     }
13697   mp->encap_vrf_id = ntohl (encap_vrf_id);
13698   mp->decap_next_index = ntohl (decap_next_index);
13699   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13700   mp->vni = ntohl (vni);
13701   mp->is_add = is_add;
13702   mp->is_ipv6 = ipv6_set;
13703
13704   S (mp);
13705   W (ret);
13706   return ret;
13707 }
13708
13709 static void vl_api_geneve_tunnel_details_t_handler
13710   (vl_api_geneve_tunnel_details_t * mp)
13711 {
13712   vat_main_t *vam = &vat_main;
13713   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13714   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13715
13716   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13717          ntohl (mp->sw_if_index),
13718          format_ip46_address, &src, IP46_TYPE_ANY,
13719          format_ip46_address, &dst, IP46_TYPE_ANY,
13720          ntohl (mp->encap_vrf_id),
13721          ntohl (mp->decap_next_index), ntohl (mp->vni),
13722          ntohl (mp->mcast_sw_if_index));
13723 }
13724
13725 static void vl_api_geneve_tunnel_details_t_handler_json
13726   (vl_api_geneve_tunnel_details_t * mp)
13727 {
13728   vat_main_t *vam = &vat_main;
13729   vat_json_node_t *node = NULL;
13730
13731   if (VAT_JSON_ARRAY != vam->json_tree.type)
13732     {
13733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13734       vat_json_init_array (&vam->json_tree);
13735     }
13736   node = vat_json_array_add (&vam->json_tree);
13737
13738   vat_json_init_object (node);
13739   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13740   if (mp->is_ipv6)
13741     {
13742       struct in6_addr ip6;
13743
13744       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13745       vat_json_object_add_ip6 (node, "src_address", ip6);
13746       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13747       vat_json_object_add_ip6 (node, "dst_address", ip6);
13748     }
13749   else
13750     {
13751       struct in_addr ip4;
13752
13753       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13754       vat_json_object_add_ip4 (node, "src_address", ip4);
13755       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13756       vat_json_object_add_ip4 (node, "dst_address", ip4);
13757     }
13758   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13759   vat_json_object_add_uint (node, "decap_next_index",
13760                             ntohl (mp->decap_next_index));
13761   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13762   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13763   vat_json_object_add_uint (node, "mcast_sw_if_index",
13764                             ntohl (mp->mcast_sw_if_index));
13765 }
13766
13767 static int
13768 api_geneve_tunnel_dump (vat_main_t * vam)
13769 {
13770   unformat_input_t *i = vam->input;
13771   vl_api_geneve_tunnel_dump_t *mp;
13772   vl_api_control_ping_t *mp_ping;
13773   u32 sw_if_index;
13774   u8 sw_if_index_set = 0;
13775   int ret;
13776
13777   /* Parse args required to build the message */
13778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13779     {
13780       if (unformat (i, "sw_if_index %d", &sw_if_index))
13781         sw_if_index_set = 1;
13782       else
13783         break;
13784     }
13785
13786   if (sw_if_index_set == 0)
13787     {
13788       sw_if_index = ~0;
13789     }
13790
13791   if (!vam->json_output)
13792     {
13793       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13794              "sw_if_index", "local_address", "remote_address",
13795              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13796     }
13797
13798   /* Get list of geneve-tunnel interfaces */
13799   M (GENEVE_TUNNEL_DUMP, mp);
13800
13801   mp->sw_if_index = htonl (sw_if_index);
13802
13803   S (mp);
13804
13805   /* Use a control ping for synchronization */
13806   M (CONTROL_PING, mp_ping);
13807   S (mp_ping);
13808
13809   W (ret);
13810   return ret;
13811 }
13812
13813 static int
13814 api_gre_add_del_tunnel (vat_main_t * vam)
13815 {
13816   unformat_input_t *line_input = vam->input;
13817   vl_api_gre_add_del_tunnel_t *mp;
13818   ip4_address_t src4, dst4;
13819   ip6_address_t src6, dst6;
13820   u8 is_add = 1;
13821   u8 ipv4_set = 0;
13822   u8 ipv6_set = 0;
13823   u8 t_type = GRE_TUNNEL_TYPE_L3;
13824   u8 src_set = 0;
13825   u8 dst_set = 0;
13826   u32 outer_fib_id = 0;
13827   u32 session_id = 0;
13828   u32 instance = ~0;
13829   int ret;
13830
13831   memset (&src4, 0, sizeof src4);
13832   memset (&dst4, 0, sizeof dst4);
13833   memset (&src6, 0, sizeof src6);
13834   memset (&dst6, 0, sizeof dst6);
13835
13836   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13837     {
13838       if (unformat (line_input, "del"))
13839         is_add = 0;
13840       else if (unformat (line_input, "instance %d", &instance))
13841         ;
13842       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13843         {
13844           src_set = 1;
13845           ipv4_set = 1;
13846         }
13847       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13848         {
13849           dst_set = 1;
13850           ipv4_set = 1;
13851         }
13852       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13853         {
13854           src_set = 1;
13855           ipv6_set = 1;
13856         }
13857       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13858         {
13859           dst_set = 1;
13860           ipv6_set = 1;
13861         }
13862       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13863         ;
13864       else if (unformat (line_input, "teb"))
13865         t_type = GRE_TUNNEL_TYPE_TEB;
13866       else if (unformat (line_input, "erspan %d", &session_id))
13867         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13868       else
13869         {
13870           errmsg ("parse error '%U'", format_unformat_error, line_input);
13871           return -99;
13872         }
13873     }
13874
13875   if (src_set == 0)
13876     {
13877       errmsg ("tunnel src address not specified");
13878       return -99;
13879     }
13880   if (dst_set == 0)
13881     {
13882       errmsg ("tunnel dst address not specified");
13883       return -99;
13884     }
13885   if (ipv4_set && ipv6_set)
13886     {
13887       errmsg ("both IPv4 and IPv6 addresses specified");
13888       return -99;
13889     }
13890
13891
13892   M (GRE_ADD_DEL_TUNNEL, mp);
13893
13894   if (ipv4_set)
13895     {
13896       clib_memcpy (&mp->src_address, &src4, 4);
13897       clib_memcpy (&mp->dst_address, &dst4, 4);
13898     }
13899   else
13900     {
13901       clib_memcpy (&mp->src_address, &src6, 16);
13902       clib_memcpy (&mp->dst_address, &dst6, 16);
13903     }
13904   mp->instance = htonl (instance);
13905   mp->outer_fib_id = htonl (outer_fib_id);
13906   mp->is_add = is_add;
13907   mp->session_id = htons ((u16) session_id);
13908   mp->tunnel_type = t_type;
13909   mp->is_ipv6 = ipv6_set;
13910
13911   S (mp);
13912   W (ret);
13913   return ret;
13914 }
13915
13916 static void vl_api_gre_tunnel_details_t_handler
13917   (vl_api_gre_tunnel_details_t * mp)
13918 {
13919   vat_main_t *vam = &vat_main;
13920   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13921   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13922
13923   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13924          ntohl (mp->sw_if_index),
13925          ntohl (mp->instance),
13926          format_ip46_address, &src, IP46_TYPE_ANY,
13927          format_ip46_address, &dst, IP46_TYPE_ANY,
13928          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13929 }
13930
13931 static void vl_api_gre_tunnel_details_t_handler_json
13932   (vl_api_gre_tunnel_details_t * mp)
13933 {
13934   vat_main_t *vam = &vat_main;
13935   vat_json_node_t *node = NULL;
13936   struct in_addr ip4;
13937   struct in6_addr ip6;
13938
13939   if (VAT_JSON_ARRAY != vam->json_tree.type)
13940     {
13941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13942       vat_json_init_array (&vam->json_tree);
13943     }
13944   node = vat_json_array_add (&vam->json_tree);
13945
13946   vat_json_init_object (node);
13947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13948   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13949   if (!mp->is_ipv6)
13950     {
13951       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13952       vat_json_object_add_ip4 (node, "src_address", ip4);
13953       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13954       vat_json_object_add_ip4 (node, "dst_address", ip4);
13955     }
13956   else
13957     {
13958       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13959       vat_json_object_add_ip6 (node, "src_address", ip6);
13960       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13961       vat_json_object_add_ip6 (node, "dst_address", ip6);
13962     }
13963   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13964   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13965   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13966   vat_json_object_add_uint (node, "session_id", mp->session_id);
13967 }
13968
13969 static int
13970 api_gre_tunnel_dump (vat_main_t * vam)
13971 {
13972   unformat_input_t *i = vam->input;
13973   vl_api_gre_tunnel_dump_t *mp;
13974   vl_api_control_ping_t *mp_ping;
13975   u32 sw_if_index;
13976   u8 sw_if_index_set = 0;
13977   int ret;
13978
13979   /* Parse args required to build the message */
13980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13981     {
13982       if (unformat (i, "sw_if_index %d", &sw_if_index))
13983         sw_if_index_set = 1;
13984       else
13985         break;
13986     }
13987
13988   if (sw_if_index_set == 0)
13989     {
13990       sw_if_index = ~0;
13991     }
13992
13993   if (!vam->json_output)
13994     {
13995       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13996              "sw_if_index", "instance", "src_address", "dst_address",
13997              "tunnel_type", "outer_fib_id", "session_id");
13998     }
13999
14000   /* Get list of gre-tunnel interfaces */
14001   M (GRE_TUNNEL_DUMP, mp);
14002
14003   mp->sw_if_index = htonl (sw_if_index);
14004
14005   S (mp);
14006
14007   /* Use a control ping for synchronization */
14008   MPING (CONTROL_PING, mp_ping);
14009   S (mp_ping);
14010
14011   W (ret);
14012   return ret;
14013 }
14014
14015 static int
14016 api_l2_fib_clear_table (vat_main_t * vam)
14017 {
14018 //  unformat_input_t * i = vam->input;
14019   vl_api_l2_fib_clear_table_t *mp;
14020   int ret;
14021
14022   M (L2_FIB_CLEAR_TABLE, mp);
14023
14024   S (mp);
14025   W (ret);
14026   return ret;
14027 }
14028
14029 static int
14030 api_l2_interface_efp_filter (vat_main_t * vam)
14031 {
14032   unformat_input_t *i = vam->input;
14033   vl_api_l2_interface_efp_filter_t *mp;
14034   u32 sw_if_index;
14035   u8 enable = 1;
14036   u8 sw_if_index_set = 0;
14037   int ret;
14038
14039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14040     {
14041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14042         sw_if_index_set = 1;
14043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14044         sw_if_index_set = 1;
14045       else if (unformat (i, "enable"))
14046         enable = 1;
14047       else if (unformat (i, "disable"))
14048         enable = 0;
14049       else
14050         {
14051           clib_warning ("parse error '%U'", format_unformat_error, i);
14052           return -99;
14053         }
14054     }
14055
14056   if (sw_if_index_set == 0)
14057     {
14058       errmsg ("missing sw_if_index");
14059       return -99;
14060     }
14061
14062   M (L2_INTERFACE_EFP_FILTER, mp);
14063
14064   mp->sw_if_index = ntohl (sw_if_index);
14065   mp->enable_disable = enable;
14066
14067   S (mp);
14068   W (ret);
14069   return ret;
14070 }
14071
14072 #define foreach_vtr_op                          \
14073 _("disable",  L2_VTR_DISABLED)                  \
14074 _("push-1",  L2_VTR_PUSH_1)                     \
14075 _("push-2",  L2_VTR_PUSH_2)                     \
14076 _("pop-1",  L2_VTR_POP_1)                       \
14077 _("pop-2",  L2_VTR_POP_2)                       \
14078 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14079 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14080 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14081 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14082
14083 static int
14084 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14085 {
14086   unformat_input_t *i = vam->input;
14087   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14088   u32 sw_if_index;
14089   u8 sw_if_index_set = 0;
14090   u8 vtr_op_set = 0;
14091   u32 vtr_op = 0;
14092   u32 push_dot1q = 1;
14093   u32 tag1 = ~0;
14094   u32 tag2 = ~0;
14095   int ret;
14096
14097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14098     {
14099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14100         sw_if_index_set = 1;
14101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14102         sw_if_index_set = 1;
14103       else if (unformat (i, "vtr_op %d", &vtr_op))
14104         vtr_op_set = 1;
14105 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14106       foreach_vtr_op
14107 #undef _
14108         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14109         ;
14110       else if (unformat (i, "tag1 %d", &tag1))
14111         ;
14112       else if (unformat (i, "tag2 %d", &tag2))
14113         ;
14114       else
14115         {
14116           clib_warning ("parse error '%U'", format_unformat_error, i);
14117           return -99;
14118         }
14119     }
14120
14121   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14122     {
14123       errmsg ("missing vtr operation or sw_if_index");
14124       return -99;
14125     }
14126
14127   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14128   mp->sw_if_index = ntohl (sw_if_index);
14129   mp->vtr_op = ntohl (vtr_op);
14130   mp->push_dot1q = ntohl (push_dot1q);
14131   mp->tag1 = ntohl (tag1);
14132   mp->tag2 = ntohl (tag2);
14133
14134   S (mp);
14135   W (ret);
14136   return ret;
14137 }
14138
14139 static int
14140 api_create_vhost_user_if (vat_main_t * vam)
14141 {
14142   unformat_input_t *i = vam->input;
14143   vl_api_create_vhost_user_if_t *mp;
14144   u8 *file_name;
14145   u8 is_server = 0;
14146   u8 file_name_set = 0;
14147   u32 custom_dev_instance = ~0;
14148   u8 hwaddr[6];
14149   u8 use_custom_mac = 0;
14150   u8 disable_mrg_rxbuf = 0;
14151   u8 disable_indirect_desc = 0;
14152   u8 *tag = 0;
14153   int ret;
14154
14155   /* Shut up coverity */
14156   memset (hwaddr, 0, sizeof (hwaddr));
14157
14158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14159     {
14160       if (unformat (i, "socket %s", &file_name))
14161         {
14162           file_name_set = 1;
14163         }
14164       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14165         ;
14166       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14167         use_custom_mac = 1;
14168       else if (unformat (i, "server"))
14169         is_server = 1;
14170       else if (unformat (i, "disable_mrg_rxbuf"))
14171         disable_mrg_rxbuf = 1;
14172       else if (unformat (i, "disable_indirect_desc"))
14173         disable_indirect_desc = 1;
14174       else if (unformat (i, "tag %s", &tag))
14175         ;
14176       else
14177         break;
14178     }
14179
14180   if (file_name_set == 0)
14181     {
14182       errmsg ("missing socket file name");
14183       return -99;
14184     }
14185
14186   if (vec_len (file_name) > 255)
14187     {
14188       errmsg ("socket file name too long");
14189       return -99;
14190     }
14191   vec_add1 (file_name, 0);
14192
14193   M (CREATE_VHOST_USER_IF, mp);
14194
14195   mp->is_server = is_server;
14196   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14197   mp->disable_indirect_desc = disable_indirect_desc;
14198   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14199   vec_free (file_name);
14200   if (custom_dev_instance != ~0)
14201     {
14202       mp->renumber = 1;
14203       mp->custom_dev_instance = ntohl (custom_dev_instance);
14204     }
14205
14206   mp->use_custom_mac = use_custom_mac;
14207   clib_memcpy (mp->mac_address, hwaddr, 6);
14208   if (tag)
14209     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14210   vec_free (tag);
14211
14212   S (mp);
14213   W (ret);
14214   return ret;
14215 }
14216
14217 static int
14218 api_modify_vhost_user_if (vat_main_t * vam)
14219 {
14220   unformat_input_t *i = vam->input;
14221   vl_api_modify_vhost_user_if_t *mp;
14222   u8 *file_name;
14223   u8 is_server = 0;
14224   u8 file_name_set = 0;
14225   u32 custom_dev_instance = ~0;
14226   u8 sw_if_index_set = 0;
14227   u32 sw_if_index = (u32) ~ 0;
14228   int ret;
14229
14230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14231     {
14232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14233         sw_if_index_set = 1;
14234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14235         sw_if_index_set = 1;
14236       else if (unformat (i, "socket %s", &file_name))
14237         {
14238           file_name_set = 1;
14239         }
14240       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14241         ;
14242       else if (unformat (i, "server"))
14243         is_server = 1;
14244       else
14245         break;
14246     }
14247
14248   if (sw_if_index_set == 0)
14249     {
14250       errmsg ("missing sw_if_index or interface name");
14251       return -99;
14252     }
14253
14254   if (file_name_set == 0)
14255     {
14256       errmsg ("missing socket file name");
14257       return -99;
14258     }
14259
14260   if (vec_len (file_name) > 255)
14261     {
14262       errmsg ("socket file name too long");
14263       return -99;
14264     }
14265   vec_add1 (file_name, 0);
14266
14267   M (MODIFY_VHOST_USER_IF, mp);
14268
14269   mp->sw_if_index = ntohl (sw_if_index);
14270   mp->is_server = is_server;
14271   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14272   vec_free (file_name);
14273   if (custom_dev_instance != ~0)
14274     {
14275       mp->renumber = 1;
14276       mp->custom_dev_instance = ntohl (custom_dev_instance);
14277     }
14278
14279   S (mp);
14280   W (ret);
14281   return ret;
14282 }
14283
14284 static int
14285 api_delete_vhost_user_if (vat_main_t * vam)
14286 {
14287   unformat_input_t *i = vam->input;
14288   vl_api_delete_vhost_user_if_t *mp;
14289   u32 sw_if_index = ~0;
14290   u8 sw_if_index_set = 0;
14291   int ret;
14292
14293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14294     {
14295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14296         sw_if_index_set = 1;
14297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14298         sw_if_index_set = 1;
14299       else
14300         break;
14301     }
14302
14303   if (sw_if_index_set == 0)
14304     {
14305       errmsg ("missing sw_if_index or interface name");
14306       return -99;
14307     }
14308
14309
14310   M (DELETE_VHOST_USER_IF, mp);
14311
14312   mp->sw_if_index = ntohl (sw_if_index);
14313
14314   S (mp);
14315   W (ret);
14316   return ret;
14317 }
14318
14319 static void vl_api_sw_interface_vhost_user_details_t_handler
14320   (vl_api_sw_interface_vhost_user_details_t * mp)
14321 {
14322   vat_main_t *vam = &vat_main;
14323
14324   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14325          (char *) mp->interface_name,
14326          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14327          clib_net_to_host_u64 (mp->features), mp->is_server,
14328          ntohl (mp->num_regions), (char *) mp->sock_filename);
14329   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14330 }
14331
14332 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14333   (vl_api_sw_interface_vhost_user_details_t * mp)
14334 {
14335   vat_main_t *vam = &vat_main;
14336   vat_json_node_t *node = NULL;
14337
14338   if (VAT_JSON_ARRAY != vam->json_tree.type)
14339     {
14340       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14341       vat_json_init_array (&vam->json_tree);
14342     }
14343   node = vat_json_array_add (&vam->json_tree);
14344
14345   vat_json_init_object (node);
14346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14347   vat_json_object_add_string_copy (node, "interface_name",
14348                                    mp->interface_name);
14349   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14350                             ntohl (mp->virtio_net_hdr_sz));
14351   vat_json_object_add_uint (node, "features",
14352                             clib_net_to_host_u64 (mp->features));
14353   vat_json_object_add_uint (node, "is_server", mp->is_server);
14354   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14355   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14356   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14357 }
14358
14359 static int
14360 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14361 {
14362   vl_api_sw_interface_vhost_user_dump_t *mp;
14363   vl_api_control_ping_t *mp_ping;
14364   int ret;
14365   print (vam->ofp,
14366          "Interface name            idx hdr_sz features server regions filename");
14367
14368   /* Get list of vhost-user interfaces */
14369   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14370   S (mp);
14371
14372   /* Use a control ping for synchronization */
14373   MPING (CONTROL_PING, mp_ping);
14374   S (mp_ping);
14375
14376   W (ret);
14377   return ret;
14378 }
14379
14380 static int
14381 api_show_version (vat_main_t * vam)
14382 {
14383   vl_api_show_version_t *mp;
14384   int ret;
14385
14386   M (SHOW_VERSION, mp);
14387
14388   S (mp);
14389   W (ret);
14390   return ret;
14391 }
14392
14393
14394 static int
14395 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14396 {
14397   unformat_input_t *line_input = vam->input;
14398   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14399   ip4_address_t local4, remote4;
14400   ip6_address_t local6, remote6;
14401   u8 is_add = 1;
14402   u8 ipv4_set = 0, ipv6_set = 0;
14403   u8 local_set = 0;
14404   u8 remote_set = 0;
14405   u8 grp_set = 0;
14406   u32 mcast_sw_if_index = ~0;
14407   u32 encap_vrf_id = 0;
14408   u32 decap_vrf_id = 0;
14409   u8 protocol = ~0;
14410   u32 vni;
14411   u8 vni_set = 0;
14412   int ret;
14413
14414   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14415   memset (&local4, 0, sizeof local4);
14416   memset (&remote4, 0, sizeof remote4);
14417   memset (&local6, 0, sizeof local6);
14418   memset (&remote6, 0, sizeof remote6);
14419
14420   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14421     {
14422       if (unformat (line_input, "del"))
14423         is_add = 0;
14424       else if (unformat (line_input, "local %U",
14425                          unformat_ip4_address, &local4))
14426         {
14427           local_set = 1;
14428           ipv4_set = 1;
14429         }
14430       else if (unformat (line_input, "remote %U",
14431                          unformat_ip4_address, &remote4))
14432         {
14433           remote_set = 1;
14434           ipv4_set = 1;
14435         }
14436       else if (unformat (line_input, "local %U",
14437                          unformat_ip6_address, &local6))
14438         {
14439           local_set = 1;
14440           ipv6_set = 1;
14441         }
14442       else if (unformat (line_input, "remote %U",
14443                          unformat_ip6_address, &remote6))
14444         {
14445           remote_set = 1;
14446           ipv6_set = 1;
14447         }
14448       else if (unformat (line_input, "group %U %U",
14449                          unformat_ip4_address, &remote4,
14450                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14451         {
14452           grp_set = remote_set = 1;
14453           ipv4_set = 1;
14454         }
14455       else if (unformat (line_input, "group %U",
14456                          unformat_ip4_address, &remote4))
14457         {
14458           grp_set = remote_set = 1;
14459           ipv4_set = 1;
14460         }
14461       else if (unformat (line_input, "group %U %U",
14462                          unformat_ip6_address, &remote6,
14463                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14464         {
14465           grp_set = remote_set = 1;
14466           ipv6_set = 1;
14467         }
14468       else if (unformat (line_input, "group %U",
14469                          unformat_ip6_address, &remote6))
14470         {
14471           grp_set = remote_set = 1;
14472           ipv6_set = 1;
14473         }
14474       else
14475         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14476         ;
14477       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14478         ;
14479       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14480         ;
14481       else if (unformat (line_input, "vni %d", &vni))
14482         vni_set = 1;
14483       else if (unformat (line_input, "next-ip4"))
14484         protocol = 1;
14485       else if (unformat (line_input, "next-ip6"))
14486         protocol = 2;
14487       else if (unformat (line_input, "next-ethernet"))
14488         protocol = 3;
14489       else if (unformat (line_input, "next-nsh"))
14490         protocol = 4;
14491       else
14492         {
14493           errmsg ("parse error '%U'", format_unformat_error, line_input);
14494           return -99;
14495         }
14496     }
14497
14498   if (local_set == 0)
14499     {
14500       errmsg ("tunnel local address not specified");
14501       return -99;
14502     }
14503   if (remote_set == 0)
14504     {
14505       errmsg ("tunnel remote address not specified");
14506       return -99;
14507     }
14508   if (grp_set && mcast_sw_if_index == ~0)
14509     {
14510       errmsg ("tunnel nonexistent multicast device");
14511       return -99;
14512     }
14513   if (ipv4_set && ipv6_set)
14514     {
14515       errmsg ("both IPv4 and IPv6 addresses specified");
14516       return -99;
14517     }
14518
14519   if (vni_set == 0)
14520     {
14521       errmsg ("vni not specified");
14522       return -99;
14523     }
14524
14525   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14526
14527
14528   if (ipv6_set)
14529     {
14530       clib_memcpy (&mp->local, &local6, sizeof (local6));
14531       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14532     }
14533   else
14534     {
14535       clib_memcpy (&mp->local, &local4, sizeof (local4));
14536       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14537     }
14538
14539   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14540   mp->encap_vrf_id = ntohl (encap_vrf_id);
14541   mp->decap_vrf_id = ntohl (decap_vrf_id);
14542   mp->protocol = protocol;
14543   mp->vni = ntohl (vni);
14544   mp->is_add = is_add;
14545   mp->is_ipv6 = ipv6_set;
14546
14547   S (mp);
14548   W (ret);
14549   return ret;
14550 }
14551
14552 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14553   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14554 {
14555   vat_main_t *vam = &vat_main;
14556   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14557   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14558
14559   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14560          ntohl (mp->sw_if_index),
14561          format_ip46_address, &local, IP46_TYPE_ANY,
14562          format_ip46_address, &remote, IP46_TYPE_ANY,
14563          ntohl (mp->vni), mp->protocol,
14564          ntohl (mp->mcast_sw_if_index),
14565          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14566 }
14567
14568
14569 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14570   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14571 {
14572   vat_main_t *vam = &vat_main;
14573   vat_json_node_t *node = NULL;
14574   struct in_addr ip4;
14575   struct in6_addr ip6;
14576
14577   if (VAT_JSON_ARRAY != vam->json_tree.type)
14578     {
14579       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14580       vat_json_init_array (&vam->json_tree);
14581     }
14582   node = vat_json_array_add (&vam->json_tree);
14583
14584   vat_json_init_object (node);
14585   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14586   if (mp->is_ipv6)
14587     {
14588       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14589       vat_json_object_add_ip6 (node, "local", ip6);
14590       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14591       vat_json_object_add_ip6 (node, "remote", ip6);
14592     }
14593   else
14594     {
14595       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14596       vat_json_object_add_ip4 (node, "local", ip4);
14597       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14598       vat_json_object_add_ip4 (node, "remote", ip4);
14599     }
14600   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14601   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14602   vat_json_object_add_uint (node, "mcast_sw_if_index",
14603                             ntohl (mp->mcast_sw_if_index));
14604   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14605   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14606   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14607 }
14608
14609 static int
14610 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14611 {
14612   unformat_input_t *i = vam->input;
14613   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14614   vl_api_control_ping_t *mp_ping;
14615   u32 sw_if_index;
14616   u8 sw_if_index_set = 0;
14617   int ret;
14618
14619   /* Parse args required to build the message */
14620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14621     {
14622       if (unformat (i, "sw_if_index %d", &sw_if_index))
14623         sw_if_index_set = 1;
14624       else
14625         break;
14626     }
14627
14628   if (sw_if_index_set == 0)
14629     {
14630       sw_if_index = ~0;
14631     }
14632
14633   if (!vam->json_output)
14634     {
14635       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14636              "sw_if_index", "local", "remote", "vni",
14637              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14638     }
14639
14640   /* Get list of vxlan-tunnel interfaces */
14641   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14642
14643   mp->sw_if_index = htonl (sw_if_index);
14644
14645   S (mp);
14646
14647   /* Use a control ping for synchronization */
14648   MPING (CONTROL_PING, mp_ping);
14649   S (mp_ping);
14650
14651   W (ret);
14652   return ret;
14653 }
14654
14655 static void vl_api_l2_fib_table_details_t_handler
14656   (vl_api_l2_fib_table_details_t * mp)
14657 {
14658   vat_main_t *vam = &vat_main;
14659
14660   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14661          "       %d       %d     %d",
14662          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14663          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14664          mp->bvi_mac);
14665 }
14666
14667 static void vl_api_l2_fib_table_details_t_handler_json
14668   (vl_api_l2_fib_table_details_t * mp)
14669 {
14670   vat_main_t *vam = &vat_main;
14671   vat_json_node_t *node = NULL;
14672
14673   if (VAT_JSON_ARRAY != vam->json_tree.type)
14674     {
14675       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14676       vat_json_init_array (&vam->json_tree);
14677     }
14678   node = vat_json_array_add (&vam->json_tree);
14679
14680   vat_json_init_object (node);
14681   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14682   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14683   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14684   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14685   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14686   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14687 }
14688
14689 static int
14690 api_l2_fib_table_dump (vat_main_t * vam)
14691 {
14692   unformat_input_t *i = vam->input;
14693   vl_api_l2_fib_table_dump_t *mp;
14694   vl_api_control_ping_t *mp_ping;
14695   u32 bd_id;
14696   u8 bd_id_set = 0;
14697   int ret;
14698
14699   /* Parse args required to build the message */
14700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14701     {
14702       if (unformat (i, "bd_id %d", &bd_id))
14703         bd_id_set = 1;
14704       else
14705         break;
14706     }
14707
14708   if (bd_id_set == 0)
14709     {
14710       errmsg ("missing bridge domain");
14711       return -99;
14712     }
14713
14714   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14715
14716   /* Get list of l2 fib entries */
14717   M (L2_FIB_TABLE_DUMP, mp);
14718
14719   mp->bd_id = ntohl (bd_id);
14720   S (mp);
14721
14722   /* Use a control ping for synchronization */
14723   MPING (CONTROL_PING, mp_ping);
14724   S (mp_ping);
14725
14726   W (ret);
14727   return ret;
14728 }
14729
14730
14731 static int
14732 api_interface_name_renumber (vat_main_t * vam)
14733 {
14734   unformat_input_t *line_input = vam->input;
14735   vl_api_interface_name_renumber_t *mp;
14736   u32 sw_if_index = ~0;
14737   u32 new_show_dev_instance = ~0;
14738   int ret;
14739
14740   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14741     {
14742       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14743                     &sw_if_index))
14744         ;
14745       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14746         ;
14747       else if (unformat (line_input, "new_show_dev_instance %d",
14748                          &new_show_dev_instance))
14749         ;
14750       else
14751         break;
14752     }
14753
14754   if (sw_if_index == ~0)
14755     {
14756       errmsg ("missing interface name or sw_if_index");
14757       return -99;
14758     }
14759
14760   if (new_show_dev_instance == ~0)
14761     {
14762       errmsg ("missing new_show_dev_instance");
14763       return -99;
14764     }
14765
14766   M (INTERFACE_NAME_RENUMBER, mp);
14767
14768   mp->sw_if_index = ntohl (sw_if_index);
14769   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14770
14771   S (mp);
14772   W (ret);
14773   return ret;
14774 }
14775
14776 static int
14777 api_ip_probe_neighbor (vat_main_t * vam)
14778 {
14779   unformat_input_t *i = vam->input;
14780   vl_api_ip_probe_neighbor_t *mp;
14781   u8 int_set = 0;
14782   u8 adr_set = 0;
14783   u8 is_ipv6 = 0;
14784   u8 dst_adr[16];
14785   u32 sw_if_index;
14786   int ret;
14787
14788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14789     {
14790       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14791         int_set = 1;
14792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14793         int_set = 1;
14794       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14795         adr_set = 1;
14796       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14797         {
14798           adr_set = 1;
14799           is_ipv6 = 1;
14800         }
14801       else
14802         break;
14803     }
14804
14805   if (int_set == 0)
14806     {
14807       errmsg ("missing interface");
14808       return -99;
14809     }
14810
14811   if (adr_set == 0)
14812     {
14813       errmsg ("missing addresses");
14814       return -99;
14815     }
14816
14817   M (IP_PROBE_NEIGHBOR, mp);
14818
14819   mp->sw_if_index = ntohl (sw_if_index);
14820   mp->is_ipv6 = is_ipv6;
14821   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14822
14823   S (mp);
14824   W (ret);
14825   return ret;
14826 }
14827
14828 static int
14829 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14830 {
14831   unformat_input_t *i = vam->input;
14832   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14833   u8 mode = IP_SCAN_V46_NEIGHBORS;
14834   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14835   int ret;
14836
14837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14838     {
14839       if (unformat (i, "ip4"))
14840         mode = IP_SCAN_V4_NEIGHBORS;
14841       else if (unformat (i, "ip6"))
14842         mode = IP_SCAN_V6_NEIGHBORS;
14843       if (unformat (i, "both"))
14844         mode = IP_SCAN_V46_NEIGHBORS;
14845       else if (unformat (i, "disable"))
14846         mode = IP_SCAN_DISABLED;
14847       else if (unformat (i, "interval %d", &interval))
14848         ;
14849       else if (unformat (i, "max-time %d", &time))
14850         ;
14851       else if (unformat (i, "max-update %d", &update))
14852         ;
14853       else if (unformat (i, "delay %d", &delay))
14854         ;
14855       else if (unformat (i, "stale %d", &stale))
14856         ;
14857       else
14858         break;
14859     }
14860
14861   if (interval > 255)
14862     {
14863       errmsg ("interval cannot exceed 255 minutes.");
14864       return -99;
14865     }
14866   if (time > 255)
14867     {
14868       errmsg ("max-time cannot exceed 255 usec.");
14869       return -99;
14870     }
14871   if (update > 255)
14872     {
14873       errmsg ("max-update cannot exceed 255.");
14874       return -99;
14875     }
14876   if (delay > 255)
14877     {
14878       errmsg ("delay cannot exceed 255 msec.");
14879       return -99;
14880     }
14881   if (stale > 255)
14882     {
14883       errmsg ("stale cannot exceed 255 minutes.");
14884       return -99;
14885     }
14886
14887   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14888   mp->mode = mode;
14889   mp->scan_interval = interval;
14890   mp->max_proc_time = time;
14891   mp->max_update = update;
14892   mp->scan_int_delay = delay;
14893   mp->stale_threshold = stale;
14894
14895   S (mp);
14896   W (ret);
14897   return ret;
14898 }
14899
14900 static int
14901 api_want_ip4_arp_events (vat_main_t * vam)
14902 {
14903   unformat_input_t *line_input = vam->input;
14904   vl_api_want_ip4_arp_events_t *mp;
14905   ip4_address_t address;
14906   int address_set = 0;
14907   u32 enable_disable = 1;
14908   int ret;
14909
14910   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14911     {
14912       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14913         address_set = 1;
14914       else if (unformat (line_input, "del"))
14915         enable_disable = 0;
14916       else
14917         break;
14918     }
14919
14920   if (address_set == 0)
14921     {
14922       errmsg ("missing addresses");
14923       return -99;
14924     }
14925
14926   M (WANT_IP4_ARP_EVENTS, mp);
14927   mp->enable_disable = enable_disable;
14928   mp->pid = htonl (getpid ());
14929   mp->address = address.as_u32;
14930
14931   S (mp);
14932   W (ret);
14933   return ret;
14934 }
14935
14936 static int
14937 api_want_ip6_nd_events (vat_main_t * vam)
14938 {
14939   unformat_input_t *line_input = vam->input;
14940   vl_api_want_ip6_nd_events_t *mp;
14941   ip6_address_t address;
14942   int address_set = 0;
14943   u32 enable_disable = 1;
14944   int ret;
14945
14946   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14947     {
14948       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14949         address_set = 1;
14950       else if (unformat (line_input, "del"))
14951         enable_disable = 0;
14952       else
14953         break;
14954     }
14955
14956   if (address_set == 0)
14957     {
14958       errmsg ("missing addresses");
14959       return -99;
14960     }
14961
14962   M (WANT_IP6_ND_EVENTS, mp);
14963   mp->enable_disable = enable_disable;
14964   mp->pid = htonl (getpid ());
14965   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14966
14967   S (mp);
14968   W (ret);
14969   return ret;
14970 }
14971
14972 static int
14973 api_want_l2_macs_events (vat_main_t * vam)
14974 {
14975   unformat_input_t *line_input = vam->input;
14976   vl_api_want_l2_macs_events_t *mp;
14977   u8 enable_disable = 1;
14978   u32 scan_delay = 0;
14979   u32 max_macs_in_event = 0;
14980   u32 learn_limit = 0;
14981   int ret;
14982
14983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14984     {
14985       if (unformat (line_input, "learn-limit %d", &learn_limit))
14986         ;
14987       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14988         ;
14989       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14990         ;
14991       else if (unformat (line_input, "disable"))
14992         enable_disable = 0;
14993       else
14994         break;
14995     }
14996
14997   M (WANT_L2_MACS_EVENTS, mp);
14998   mp->enable_disable = enable_disable;
14999   mp->pid = htonl (getpid ());
15000   mp->learn_limit = htonl (learn_limit);
15001   mp->scan_delay = (u8) scan_delay;
15002   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15003   S (mp);
15004   W (ret);
15005   return ret;
15006 }
15007
15008 static int
15009 api_input_acl_set_interface (vat_main_t * vam)
15010 {
15011   unformat_input_t *i = vam->input;
15012   vl_api_input_acl_set_interface_t *mp;
15013   u32 sw_if_index;
15014   int sw_if_index_set;
15015   u32 ip4_table_index = ~0;
15016   u32 ip6_table_index = ~0;
15017   u32 l2_table_index = ~0;
15018   u8 is_add = 1;
15019   int ret;
15020
15021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15024         sw_if_index_set = 1;
15025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15026         sw_if_index_set = 1;
15027       else if (unformat (i, "del"))
15028         is_add = 0;
15029       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15030         ;
15031       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15032         ;
15033       else if (unformat (i, "l2-table %d", &l2_table_index))
15034         ;
15035       else
15036         {
15037           clib_warning ("parse error '%U'", format_unformat_error, i);
15038           return -99;
15039         }
15040     }
15041
15042   if (sw_if_index_set == 0)
15043     {
15044       errmsg ("missing interface name or sw_if_index");
15045       return -99;
15046     }
15047
15048   M (INPUT_ACL_SET_INTERFACE, mp);
15049
15050   mp->sw_if_index = ntohl (sw_if_index);
15051   mp->ip4_table_index = ntohl (ip4_table_index);
15052   mp->ip6_table_index = ntohl (ip6_table_index);
15053   mp->l2_table_index = ntohl (l2_table_index);
15054   mp->is_add = is_add;
15055
15056   S (mp);
15057   W (ret);
15058   return ret;
15059 }
15060
15061 static int
15062 api_output_acl_set_interface (vat_main_t * vam)
15063 {
15064   unformat_input_t *i = vam->input;
15065   vl_api_output_acl_set_interface_t *mp;
15066   u32 sw_if_index;
15067   int sw_if_index_set;
15068   u32 ip4_table_index = ~0;
15069   u32 ip6_table_index = ~0;
15070   u32 l2_table_index = ~0;
15071   u8 is_add = 1;
15072   int ret;
15073
15074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15075     {
15076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15077         sw_if_index_set = 1;
15078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15079         sw_if_index_set = 1;
15080       else if (unformat (i, "del"))
15081         is_add = 0;
15082       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15083         ;
15084       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15085         ;
15086       else if (unformat (i, "l2-table %d", &l2_table_index))
15087         ;
15088       else
15089         {
15090           clib_warning ("parse error '%U'", format_unformat_error, i);
15091           return -99;
15092         }
15093     }
15094
15095   if (sw_if_index_set == 0)
15096     {
15097       errmsg ("missing interface name or sw_if_index");
15098       return -99;
15099     }
15100
15101   M (OUTPUT_ACL_SET_INTERFACE, mp);
15102
15103   mp->sw_if_index = ntohl (sw_if_index);
15104   mp->ip4_table_index = ntohl (ip4_table_index);
15105   mp->ip6_table_index = ntohl (ip6_table_index);
15106   mp->l2_table_index = ntohl (l2_table_index);
15107   mp->is_add = is_add;
15108
15109   S (mp);
15110   W (ret);
15111   return ret;
15112 }
15113
15114 static int
15115 api_ip_address_dump (vat_main_t * vam)
15116 {
15117   unformat_input_t *i = vam->input;
15118   vl_api_ip_address_dump_t *mp;
15119   vl_api_control_ping_t *mp_ping;
15120   u32 sw_if_index = ~0;
15121   u8 sw_if_index_set = 0;
15122   u8 ipv4_set = 0;
15123   u8 ipv6_set = 0;
15124   int ret;
15125
15126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15127     {
15128       if (unformat (i, "sw_if_index %d", &sw_if_index))
15129         sw_if_index_set = 1;
15130       else
15131         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15132         sw_if_index_set = 1;
15133       else if (unformat (i, "ipv4"))
15134         ipv4_set = 1;
15135       else if (unformat (i, "ipv6"))
15136         ipv6_set = 1;
15137       else
15138         break;
15139     }
15140
15141   if (ipv4_set && ipv6_set)
15142     {
15143       errmsg ("ipv4 and ipv6 flags cannot be both set");
15144       return -99;
15145     }
15146
15147   if ((!ipv4_set) && (!ipv6_set))
15148     {
15149       errmsg ("no ipv4 nor ipv6 flag set");
15150       return -99;
15151     }
15152
15153   if (sw_if_index_set == 0)
15154     {
15155       errmsg ("missing interface name or sw_if_index");
15156       return -99;
15157     }
15158
15159   vam->current_sw_if_index = sw_if_index;
15160   vam->is_ipv6 = ipv6_set;
15161
15162   M (IP_ADDRESS_DUMP, mp);
15163   mp->sw_if_index = ntohl (sw_if_index);
15164   mp->is_ipv6 = ipv6_set;
15165   S (mp);
15166
15167   /* Use a control ping for synchronization */
15168   MPING (CONTROL_PING, mp_ping);
15169   S (mp_ping);
15170
15171   W (ret);
15172   return ret;
15173 }
15174
15175 static int
15176 api_ip_dump (vat_main_t * vam)
15177 {
15178   vl_api_ip_dump_t *mp;
15179   vl_api_control_ping_t *mp_ping;
15180   unformat_input_t *in = vam->input;
15181   int ipv4_set = 0;
15182   int ipv6_set = 0;
15183   int is_ipv6;
15184   int i;
15185   int ret;
15186
15187   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15188     {
15189       if (unformat (in, "ipv4"))
15190         ipv4_set = 1;
15191       else if (unformat (in, "ipv6"))
15192         ipv6_set = 1;
15193       else
15194         break;
15195     }
15196
15197   if (ipv4_set && ipv6_set)
15198     {
15199       errmsg ("ipv4 and ipv6 flags cannot be both set");
15200       return -99;
15201     }
15202
15203   if ((!ipv4_set) && (!ipv6_set))
15204     {
15205       errmsg ("no ipv4 nor ipv6 flag set");
15206       return -99;
15207     }
15208
15209   is_ipv6 = ipv6_set;
15210   vam->is_ipv6 = is_ipv6;
15211
15212   /* free old data */
15213   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15214     {
15215       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15216     }
15217   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15218
15219   M (IP_DUMP, mp);
15220   mp->is_ipv6 = ipv6_set;
15221   S (mp);
15222
15223   /* Use a control ping for synchronization */
15224   MPING (CONTROL_PING, mp_ping);
15225   S (mp_ping);
15226
15227   W (ret);
15228   return ret;
15229 }
15230
15231 static int
15232 api_ipsec_spd_add_del (vat_main_t * vam)
15233 {
15234   unformat_input_t *i = vam->input;
15235   vl_api_ipsec_spd_add_del_t *mp;
15236   u32 spd_id = ~0;
15237   u8 is_add = 1;
15238   int ret;
15239
15240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (i, "spd_id %d", &spd_id))
15243         ;
15244       else if (unformat (i, "del"))
15245         is_add = 0;
15246       else
15247         {
15248           clib_warning ("parse error '%U'", format_unformat_error, i);
15249           return -99;
15250         }
15251     }
15252   if (spd_id == ~0)
15253     {
15254       errmsg ("spd_id must be set");
15255       return -99;
15256     }
15257
15258   M (IPSEC_SPD_ADD_DEL, mp);
15259
15260   mp->spd_id = ntohl (spd_id);
15261   mp->is_add = is_add;
15262
15263   S (mp);
15264   W (ret);
15265   return ret;
15266 }
15267
15268 static int
15269 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15270 {
15271   unformat_input_t *i = vam->input;
15272   vl_api_ipsec_interface_add_del_spd_t *mp;
15273   u32 sw_if_index;
15274   u8 sw_if_index_set = 0;
15275   u32 spd_id = (u32) ~ 0;
15276   u8 is_add = 1;
15277   int ret;
15278
15279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15280     {
15281       if (unformat (i, "del"))
15282         is_add = 0;
15283       else if (unformat (i, "spd_id %d", &spd_id))
15284         ;
15285       else
15286         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15287         sw_if_index_set = 1;
15288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15289         sw_if_index_set = 1;
15290       else
15291         {
15292           clib_warning ("parse error '%U'", format_unformat_error, i);
15293           return -99;
15294         }
15295
15296     }
15297
15298   if (spd_id == (u32) ~ 0)
15299     {
15300       errmsg ("spd_id must be set");
15301       return -99;
15302     }
15303
15304   if (sw_if_index_set == 0)
15305     {
15306       errmsg ("missing interface name or sw_if_index");
15307       return -99;
15308     }
15309
15310   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15311
15312   mp->spd_id = ntohl (spd_id);
15313   mp->sw_if_index = ntohl (sw_if_index);
15314   mp->is_add = is_add;
15315
15316   S (mp);
15317   W (ret);
15318   return ret;
15319 }
15320
15321 static int
15322 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15323 {
15324   unformat_input_t *i = vam->input;
15325   vl_api_ipsec_spd_add_del_entry_t *mp;
15326   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15327   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15328   i32 priority = 0;
15329   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15330   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15331   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15332   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15333   int ret;
15334
15335   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15336   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15337   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15338   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15339   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15340   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15341
15342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15343     {
15344       if (unformat (i, "del"))
15345         is_add = 0;
15346       if (unformat (i, "outbound"))
15347         is_outbound = 1;
15348       if (unformat (i, "inbound"))
15349         is_outbound = 0;
15350       else if (unformat (i, "spd_id %d", &spd_id))
15351         ;
15352       else if (unformat (i, "sa_id %d", &sa_id))
15353         ;
15354       else if (unformat (i, "priority %d", &priority))
15355         ;
15356       else if (unformat (i, "protocol %d", &protocol))
15357         ;
15358       else if (unformat (i, "lport_start %d", &lport_start))
15359         ;
15360       else if (unformat (i, "lport_stop %d", &lport_stop))
15361         ;
15362       else if (unformat (i, "rport_start %d", &rport_start))
15363         ;
15364       else if (unformat (i, "rport_stop %d", &rport_stop))
15365         ;
15366       else
15367         if (unformat
15368             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15369         {
15370           is_ipv6 = 0;
15371           is_ip_any = 0;
15372         }
15373       else
15374         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15375         {
15376           is_ipv6 = 0;
15377           is_ip_any = 0;
15378         }
15379       else
15380         if (unformat
15381             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15382         {
15383           is_ipv6 = 0;
15384           is_ip_any = 0;
15385         }
15386       else
15387         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15388         {
15389           is_ipv6 = 0;
15390           is_ip_any = 0;
15391         }
15392       else
15393         if (unformat
15394             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15395         {
15396           is_ipv6 = 1;
15397           is_ip_any = 0;
15398         }
15399       else
15400         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15401         {
15402           is_ipv6 = 1;
15403           is_ip_any = 0;
15404         }
15405       else
15406         if (unformat
15407             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15408         {
15409           is_ipv6 = 1;
15410           is_ip_any = 0;
15411         }
15412       else
15413         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15414         {
15415           is_ipv6 = 1;
15416           is_ip_any = 0;
15417         }
15418       else
15419         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15420         {
15421           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15422             {
15423               clib_warning ("unsupported action: 'resolve'");
15424               return -99;
15425             }
15426         }
15427       else
15428         {
15429           clib_warning ("parse error '%U'", format_unformat_error, i);
15430           return -99;
15431         }
15432
15433     }
15434
15435   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15436
15437   mp->spd_id = ntohl (spd_id);
15438   mp->priority = ntohl (priority);
15439   mp->is_outbound = is_outbound;
15440
15441   mp->is_ipv6 = is_ipv6;
15442   if (is_ipv6 || is_ip_any)
15443     {
15444       clib_memcpy (mp->remote_address_start, &raddr6_start,
15445                    sizeof (ip6_address_t));
15446       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15447                    sizeof (ip6_address_t));
15448       clib_memcpy (mp->local_address_start, &laddr6_start,
15449                    sizeof (ip6_address_t));
15450       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15451                    sizeof (ip6_address_t));
15452     }
15453   else
15454     {
15455       clib_memcpy (mp->remote_address_start, &raddr4_start,
15456                    sizeof (ip4_address_t));
15457       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15458                    sizeof (ip4_address_t));
15459       clib_memcpy (mp->local_address_start, &laddr4_start,
15460                    sizeof (ip4_address_t));
15461       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15462                    sizeof (ip4_address_t));
15463     }
15464   mp->protocol = (u8) protocol;
15465   mp->local_port_start = ntohs ((u16) lport_start);
15466   mp->local_port_stop = ntohs ((u16) lport_stop);
15467   mp->remote_port_start = ntohs ((u16) rport_start);
15468   mp->remote_port_stop = ntohs ((u16) rport_stop);
15469   mp->policy = (u8) policy;
15470   mp->sa_id = ntohl (sa_id);
15471   mp->is_add = is_add;
15472   mp->is_ip_any = is_ip_any;
15473   S (mp);
15474   W (ret);
15475   return ret;
15476 }
15477
15478 static int
15479 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15480 {
15481   unformat_input_t *i = vam->input;
15482   vl_api_ipsec_sad_add_del_entry_t *mp;
15483   u32 sad_id = 0, spi = 0;
15484   u8 *ck = 0, *ik = 0;
15485   u8 is_add = 1;
15486
15487   u8 protocol = IPSEC_PROTOCOL_AH;
15488   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15489   u32 crypto_alg = 0, integ_alg = 0;
15490   ip4_address_t tun_src4;
15491   ip4_address_t tun_dst4;
15492   ip6_address_t tun_src6;
15493   ip6_address_t tun_dst6;
15494   int ret;
15495
15496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15497     {
15498       if (unformat (i, "del"))
15499         is_add = 0;
15500       else if (unformat (i, "sad_id %d", &sad_id))
15501         ;
15502       else if (unformat (i, "spi %d", &spi))
15503         ;
15504       else if (unformat (i, "esp"))
15505         protocol = IPSEC_PROTOCOL_ESP;
15506       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15507         {
15508           is_tunnel = 1;
15509           is_tunnel_ipv6 = 0;
15510         }
15511       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15512         {
15513           is_tunnel = 1;
15514           is_tunnel_ipv6 = 0;
15515         }
15516       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15517         {
15518           is_tunnel = 1;
15519           is_tunnel_ipv6 = 1;
15520         }
15521       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15522         {
15523           is_tunnel = 1;
15524           is_tunnel_ipv6 = 1;
15525         }
15526       else
15527         if (unformat
15528             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15529         {
15530           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15531             {
15532               clib_warning ("unsupported crypto-alg: '%U'",
15533                             format_ipsec_crypto_alg, crypto_alg);
15534               return -99;
15535             }
15536         }
15537       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15538         ;
15539       else
15540         if (unformat
15541             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15542         {
15543           if (integ_alg >= IPSEC_INTEG_N_ALG)
15544             {
15545               clib_warning ("unsupported integ-alg: '%U'",
15546                             format_ipsec_integ_alg, integ_alg);
15547               return -99;
15548             }
15549         }
15550       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15551         ;
15552       else
15553         {
15554           clib_warning ("parse error '%U'", format_unformat_error, i);
15555           return -99;
15556         }
15557
15558     }
15559
15560   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15561
15562   mp->sad_id = ntohl (sad_id);
15563   mp->is_add = is_add;
15564   mp->protocol = protocol;
15565   mp->spi = ntohl (spi);
15566   mp->is_tunnel = is_tunnel;
15567   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15568   mp->crypto_algorithm = crypto_alg;
15569   mp->integrity_algorithm = integ_alg;
15570   mp->crypto_key_length = vec_len (ck);
15571   mp->integrity_key_length = vec_len (ik);
15572
15573   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15574     mp->crypto_key_length = sizeof (mp->crypto_key);
15575
15576   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15577     mp->integrity_key_length = sizeof (mp->integrity_key);
15578
15579   if (ck)
15580     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15581   if (ik)
15582     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15583
15584   if (is_tunnel)
15585     {
15586       if (is_tunnel_ipv6)
15587         {
15588           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15589                        sizeof (ip6_address_t));
15590           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15591                        sizeof (ip6_address_t));
15592         }
15593       else
15594         {
15595           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15596                        sizeof (ip4_address_t));
15597           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15598                        sizeof (ip4_address_t));
15599         }
15600     }
15601
15602   S (mp);
15603   W (ret);
15604   return ret;
15605 }
15606
15607 static int
15608 api_ipsec_sa_set_key (vat_main_t * vam)
15609 {
15610   unformat_input_t *i = vam->input;
15611   vl_api_ipsec_sa_set_key_t *mp;
15612   u32 sa_id;
15613   u8 *ck = 0, *ik = 0;
15614   int ret;
15615
15616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15617     {
15618       if (unformat (i, "sa_id %d", &sa_id))
15619         ;
15620       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15621         ;
15622       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15623         ;
15624       else
15625         {
15626           clib_warning ("parse error '%U'", format_unformat_error, i);
15627           return -99;
15628         }
15629     }
15630
15631   M (IPSEC_SA_SET_KEY, mp);
15632
15633   mp->sa_id = ntohl (sa_id);
15634   mp->crypto_key_length = vec_len (ck);
15635   mp->integrity_key_length = vec_len (ik);
15636
15637   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15638     mp->crypto_key_length = sizeof (mp->crypto_key);
15639
15640   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15641     mp->integrity_key_length = sizeof (mp->integrity_key);
15642
15643   if (ck)
15644     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15645   if (ik)
15646     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15647
15648   S (mp);
15649   W (ret);
15650   return ret;
15651 }
15652
15653 static int
15654 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15655 {
15656   unformat_input_t *i = vam->input;
15657   vl_api_ipsec_tunnel_if_add_del_t *mp;
15658   u32 local_spi = 0, remote_spi = 0;
15659   u32 crypto_alg = 0, integ_alg = 0;
15660   u8 *lck = NULL, *rck = NULL;
15661   u8 *lik = NULL, *rik = NULL;
15662   ip4_address_t local_ip = { {0} };
15663   ip4_address_t remote_ip = { {0} };
15664   u8 is_add = 1;
15665   u8 esn = 0;
15666   u8 anti_replay = 0;
15667   u8 renumber = 0;
15668   u32 instance = ~0;
15669   int ret;
15670
15671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15672     {
15673       if (unformat (i, "del"))
15674         is_add = 0;
15675       else if (unformat (i, "esn"))
15676         esn = 1;
15677       else if (unformat (i, "anti_replay"))
15678         anti_replay = 1;
15679       else if (unformat (i, "local_spi %d", &local_spi))
15680         ;
15681       else if (unformat (i, "remote_spi %d", &remote_spi))
15682         ;
15683       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15684         ;
15685       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15686         ;
15687       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15688         ;
15689       else
15690         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15691         ;
15692       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15693         ;
15694       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15695         ;
15696       else
15697         if (unformat
15698             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15699         {
15700           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15701             {
15702               errmsg ("unsupported crypto-alg: '%U'\n",
15703                       format_ipsec_crypto_alg, crypto_alg);
15704               return -99;
15705             }
15706         }
15707       else
15708         if (unformat
15709             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15710         {
15711           if (integ_alg >= IPSEC_INTEG_N_ALG)
15712             {
15713               errmsg ("unsupported integ-alg: '%U'\n",
15714                       format_ipsec_integ_alg, integ_alg);
15715               return -99;
15716             }
15717         }
15718       else if (unformat (i, "instance %u", &instance))
15719         renumber = 1;
15720       else
15721         {
15722           errmsg ("parse error '%U'\n", format_unformat_error, i);
15723           return -99;
15724         }
15725     }
15726
15727   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15728
15729   mp->is_add = is_add;
15730   mp->esn = esn;
15731   mp->anti_replay = anti_replay;
15732
15733   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15734   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15735
15736   mp->local_spi = htonl (local_spi);
15737   mp->remote_spi = htonl (remote_spi);
15738   mp->crypto_alg = (u8) crypto_alg;
15739
15740   mp->local_crypto_key_len = 0;
15741   if (lck)
15742     {
15743       mp->local_crypto_key_len = vec_len (lck);
15744       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15745         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15746       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15747     }
15748
15749   mp->remote_crypto_key_len = 0;
15750   if (rck)
15751     {
15752       mp->remote_crypto_key_len = vec_len (rck);
15753       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15754         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15755       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15756     }
15757
15758   mp->integ_alg = (u8) integ_alg;
15759
15760   mp->local_integ_key_len = 0;
15761   if (lik)
15762     {
15763       mp->local_integ_key_len = vec_len (lik);
15764       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15765         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15766       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15767     }
15768
15769   mp->remote_integ_key_len = 0;
15770   if (rik)
15771     {
15772       mp->remote_integ_key_len = vec_len (rik);
15773       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15774         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15775       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15776     }
15777
15778   if (renumber)
15779     {
15780       mp->renumber = renumber;
15781       mp->show_instance = ntohl (instance);
15782     }
15783
15784   S (mp);
15785   W (ret);
15786   return ret;
15787 }
15788
15789 static void
15790 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15791 {
15792   vat_main_t *vam = &vat_main;
15793
15794   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15795          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15796          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15797          "tunnel_src_addr %U tunnel_dst_addr %U "
15798          "salt %u seq_outbound %lu last_seq_inbound %lu "
15799          "replay_window %lu total_data_size %lu\n",
15800          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15801          mp->protocol,
15802          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15803          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15804          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15805          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15806          mp->tunnel_src_addr,
15807          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15808          mp->tunnel_dst_addr,
15809          ntohl (mp->salt),
15810          clib_net_to_host_u64 (mp->seq_outbound),
15811          clib_net_to_host_u64 (mp->last_seq_inbound),
15812          clib_net_to_host_u64 (mp->replay_window),
15813          clib_net_to_host_u64 (mp->total_data_size));
15814 }
15815
15816 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15817 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15818
15819 static void vl_api_ipsec_sa_details_t_handler_json
15820   (vl_api_ipsec_sa_details_t * mp)
15821 {
15822   vat_main_t *vam = &vat_main;
15823   vat_json_node_t *node = NULL;
15824   struct in_addr src_ip4, dst_ip4;
15825   struct in6_addr src_ip6, dst_ip6;
15826
15827   if (VAT_JSON_ARRAY != vam->json_tree.type)
15828     {
15829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15830       vat_json_init_array (&vam->json_tree);
15831     }
15832   node = vat_json_array_add (&vam->json_tree);
15833
15834   vat_json_init_object (node);
15835   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15836   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15837   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15838   vat_json_object_add_uint (node, "proto", mp->protocol);
15839   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15840   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15841   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15842   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15843   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15844   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15845   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15846                              mp->crypto_key_len);
15847   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15848                              mp->integ_key_len);
15849   if (mp->is_tunnel_ip6)
15850     {
15851       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15852       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15853       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15854       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15855     }
15856   else
15857     {
15858       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15859       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15860       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15861       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15862     }
15863   vat_json_object_add_uint (node, "replay_window",
15864                             clib_net_to_host_u64 (mp->replay_window));
15865   vat_json_object_add_uint (node, "total_data_size",
15866                             clib_net_to_host_u64 (mp->total_data_size));
15867
15868 }
15869
15870 static int
15871 api_ipsec_sa_dump (vat_main_t * vam)
15872 {
15873   unformat_input_t *i = vam->input;
15874   vl_api_ipsec_sa_dump_t *mp;
15875   vl_api_control_ping_t *mp_ping;
15876   u32 sa_id = ~0;
15877   int ret;
15878
15879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15880     {
15881       if (unformat (i, "sa_id %d", &sa_id))
15882         ;
15883       else
15884         {
15885           clib_warning ("parse error '%U'", format_unformat_error, i);
15886           return -99;
15887         }
15888     }
15889
15890   M (IPSEC_SA_DUMP, mp);
15891
15892   mp->sa_id = ntohl (sa_id);
15893
15894   S (mp);
15895
15896   /* Use a control ping for synchronization */
15897   M (CONTROL_PING, mp_ping);
15898   S (mp_ping);
15899
15900   W (ret);
15901   return ret;
15902 }
15903
15904 static int
15905 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15906 {
15907   unformat_input_t *i = vam->input;
15908   vl_api_ipsec_tunnel_if_set_key_t *mp;
15909   u32 sw_if_index = ~0;
15910   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15911   u8 *key = 0;
15912   u32 alg = ~0;
15913   int ret;
15914
15915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15916     {
15917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15918         ;
15919       else
15920         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15921         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15922       else
15923         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15924         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15925       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15926         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15927       else
15928         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15929         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15930       else if (unformat (i, "%U", unformat_hex_string, &key))
15931         ;
15932       else
15933         {
15934           clib_warning ("parse error '%U'", format_unformat_error, i);
15935           return -99;
15936         }
15937     }
15938
15939   if (sw_if_index == ~0)
15940     {
15941       errmsg ("interface must be specified");
15942       return -99;
15943     }
15944
15945   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15946     {
15947       errmsg ("key type must be specified");
15948       return -99;
15949     }
15950
15951   if (alg == ~0)
15952     {
15953       errmsg ("algorithm must be specified");
15954       return -99;
15955     }
15956
15957   if (vec_len (key) == 0)
15958     {
15959       errmsg ("key must be specified");
15960       return -99;
15961     }
15962
15963   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15964
15965   mp->sw_if_index = htonl (sw_if_index);
15966   mp->alg = alg;
15967   mp->key_type = key_type;
15968   mp->key_len = vec_len (key);
15969   clib_memcpy (mp->key, key, vec_len (key));
15970
15971   S (mp);
15972   W (ret);
15973
15974   return ret;
15975 }
15976
15977 static int
15978 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15979 {
15980   unformat_input_t *i = vam->input;
15981   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15982   u32 sw_if_index = ~0;
15983   u32 sa_id = ~0;
15984   u8 is_outbound = (u8) ~ 0;
15985   int ret;
15986
15987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15988     {
15989       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15990         ;
15991       else if (unformat (i, "sa_id %d", &sa_id))
15992         ;
15993       else if (unformat (i, "outbound"))
15994         is_outbound = 1;
15995       else if (unformat (i, "inbound"))
15996         is_outbound = 0;
15997       else
15998         {
15999           clib_warning ("parse error '%U'", format_unformat_error, i);
16000           return -99;
16001         }
16002     }
16003
16004   if (sw_if_index == ~0)
16005     {
16006       errmsg ("interface must be specified");
16007       return -99;
16008     }
16009
16010   if (sa_id == ~0)
16011     {
16012       errmsg ("SA ID must be specified");
16013       return -99;
16014     }
16015
16016   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16017
16018   mp->sw_if_index = htonl (sw_if_index);
16019   mp->sa_id = htonl (sa_id);
16020   mp->is_outbound = is_outbound;
16021
16022   S (mp);
16023   W (ret);
16024
16025   return ret;
16026 }
16027
16028 static int
16029 api_ikev2_profile_add_del (vat_main_t * vam)
16030 {
16031   unformat_input_t *i = vam->input;
16032   vl_api_ikev2_profile_add_del_t *mp;
16033   u8 is_add = 1;
16034   u8 *name = 0;
16035   int ret;
16036
16037   const char *valid_chars = "a-zA-Z0-9_";
16038
16039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16040     {
16041       if (unformat (i, "del"))
16042         is_add = 0;
16043       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16044         vec_add1 (name, 0);
16045       else
16046         {
16047           errmsg ("parse error '%U'", format_unformat_error, i);
16048           return -99;
16049         }
16050     }
16051
16052   if (!vec_len (name))
16053     {
16054       errmsg ("profile name must be specified");
16055       return -99;
16056     }
16057
16058   if (vec_len (name) > 64)
16059     {
16060       errmsg ("profile name too long");
16061       return -99;
16062     }
16063
16064   M (IKEV2_PROFILE_ADD_DEL, mp);
16065
16066   clib_memcpy (mp->name, name, vec_len (name));
16067   mp->is_add = is_add;
16068   vec_free (name);
16069
16070   S (mp);
16071   W (ret);
16072   return ret;
16073 }
16074
16075 static int
16076 api_ikev2_profile_set_auth (vat_main_t * vam)
16077 {
16078   unformat_input_t *i = vam->input;
16079   vl_api_ikev2_profile_set_auth_t *mp;
16080   u8 *name = 0;
16081   u8 *data = 0;
16082   u32 auth_method = 0;
16083   u8 is_hex = 0;
16084   int ret;
16085
16086   const char *valid_chars = "a-zA-Z0-9_";
16087
16088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16089     {
16090       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16091         vec_add1 (name, 0);
16092       else if (unformat (i, "auth_method %U",
16093                          unformat_ikev2_auth_method, &auth_method))
16094         ;
16095       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16096         is_hex = 1;
16097       else if (unformat (i, "auth_data %v", &data))
16098         ;
16099       else
16100         {
16101           errmsg ("parse error '%U'", format_unformat_error, i);
16102           return -99;
16103         }
16104     }
16105
16106   if (!vec_len (name))
16107     {
16108       errmsg ("profile name must be specified");
16109       return -99;
16110     }
16111
16112   if (vec_len (name) > 64)
16113     {
16114       errmsg ("profile name too long");
16115       return -99;
16116     }
16117
16118   if (!vec_len (data))
16119     {
16120       errmsg ("auth_data must be specified");
16121       return -99;
16122     }
16123
16124   if (!auth_method)
16125     {
16126       errmsg ("auth_method must be specified");
16127       return -99;
16128     }
16129
16130   M (IKEV2_PROFILE_SET_AUTH, mp);
16131
16132   mp->is_hex = is_hex;
16133   mp->auth_method = (u8) auth_method;
16134   mp->data_len = vec_len (data);
16135   clib_memcpy (mp->name, name, vec_len (name));
16136   clib_memcpy (mp->data, data, vec_len (data));
16137   vec_free (name);
16138   vec_free (data);
16139
16140   S (mp);
16141   W (ret);
16142   return ret;
16143 }
16144
16145 static int
16146 api_ikev2_profile_set_id (vat_main_t * vam)
16147 {
16148   unformat_input_t *i = vam->input;
16149   vl_api_ikev2_profile_set_id_t *mp;
16150   u8 *name = 0;
16151   u8 *data = 0;
16152   u8 is_local = 0;
16153   u32 id_type = 0;
16154   ip4_address_t ip4;
16155   int ret;
16156
16157   const char *valid_chars = "a-zA-Z0-9_";
16158
16159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16160     {
16161       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16162         vec_add1 (name, 0);
16163       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16164         ;
16165       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16166         {
16167           data = vec_new (u8, 4);
16168           clib_memcpy (data, ip4.as_u8, 4);
16169         }
16170       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16171         ;
16172       else if (unformat (i, "id_data %v", &data))
16173         ;
16174       else if (unformat (i, "local"))
16175         is_local = 1;
16176       else if (unformat (i, "remote"))
16177         is_local = 0;
16178       else
16179         {
16180           errmsg ("parse error '%U'", format_unformat_error, i);
16181           return -99;
16182         }
16183     }
16184
16185   if (!vec_len (name))
16186     {
16187       errmsg ("profile name must be specified");
16188       return -99;
16189     }
16190
16191   if (vec_len (name) > 64)
16192     {
16193       errmsg ("profile name too long");
16194       return -99;
16195     }
16196
16197   if (!vec_len (data))
16198     {
16199       errmsg ("id_data must be specified");
16200       return -99;
16201     }
16202
16203   if (!id_type)
16204     {
16205       errmsg ("id_type must be specified");
16206       return -99;
16207     }
16208
16209   M (IKEV2_PROFILE_SET_ID, mp);
16210
16211   mp->is_local = is_local;
16212   mp->id_type = (u8) id_type;
16213   mp->data_len = vec_len (data);
16214   clib_memcpy (mp->name, name, vec_len (name));
16215   clib_memcpy (mp->data, data, vec_len (data));
16216   vec_free (name);
16217   vec_free (data);
16218
16219   S (mp);
16220   W (ret);
16221   return ret;
16222 }
16223
16224 static int
16225 api_ikev2_profile_set_ts (vat_main_t * vam)
16226 {
16227   unformat_input_t *i = vam->input;
16228   vl_api_ikev2_profile_set_ts_t *mp;
16229   u8 *name = 0;
16230   u8 is_local = 0;
16231   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16232   ip4_address_t start_addr, end_addr;
16233
16234   const char *valid_chars = "a-zA-Z0-9_";
16235   int ret;
16236
16237   start_addr.as_u32 = 0;
16238   end_addr.as_u32 = (u32) ~ 0;
16239
16240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16241     {
16242       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16243         vec_add1 (name, 0);
16244       else if (unformat (i, "protocol %d", &proto))
16245         ;
16246       else if (unformat (i, "start_port %d", &start_port))
16247         ;
16248       else if (unformat (i, "end_port %d", &end_port))
16249         ;
16250       else
16251         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16252         ;
16253       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16254         ;
16255       else if (unformat (i, "local"))
16256         is_local = 1;
16257       else if (unformat (i, "remote"))
16258         is_local = 0;
16259       else
16260         {
16261           errmsg ("parse error '%U'", format_unformat_error, i);
16262           return -99;
16263         }
16264     }
16265
16266   if (!vec_len (name))
16267     {
16268       errmsg ("profile name must be specified");
16269       return -99;
16270     }
16271
16272   if (vec_len (name) > 64)
16273     {
16274       errmsg ("profile name too long");
16275       return -99;
16276     }
16277
16278   M (IKEV2_PROFILE_SET_TS, mp);
16279
16280   mp->is_local = is_local;
16281   mp->proto = (u8) proto;
16282   mp->start_port = (u16) start_port;
16283   mp->end_port = (u16) end_port;
16284   mp->start_addr = start_addr.as_u32;
16285   mp->end_addr = end_addr.as_u32;
16286   clib_memcpy (mp->name, name, vec_len (name));
16287   vec_free (name);
16288
16289   S (mp);
16290   W (ret);
16291   return ret;
16292 }
16293
16294 static int
16295 api_ikev2_set_local_key (vat_main_t * vam)
16296 {
16297   unformat_input_t *i = vam->input;
16298   vl_api_ikev2_set_local_key_t *mp;
16299   u8 *file = 0;
16300   int ret;
16301
16302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16303     {
16304       if (unformat (i, "file %v", &file))
16305         vec_add1 (file, 0);
16306       else
16307         {
16308           errmsg ("parse error '%U'", format_unformat_error, i);
16309           return -99;
16310         }
16311     }
16312
16313   if (!vec_len (file))
16314     {
16315       errmsg ("RSA key file must be specified");
16316       return -99;
16317     }
16318
16319   if (vec_len (file) > 256)
16320     {
16321       errmsg ("file name too long");
16322       return -99;
16323     }
16324
16325   M (IKEV2_SET_LOCAL_KEY, mp);
16326
16327   clib_memcpy (mp->key_file, file, vec_len (file));
16328   vec_free (file);
16329
16330   S (mp);
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_ikev2_set_responder (vat_main_t * vam)
16337 {
16338   unformat_input_t *i = vam->input;
16339   vl_api_ikev2_set_responder_t *mp;
16340   int ret;
16341   u8 *name = 0;
16342   u32 sw_if_index = ~0;
16343   ip4_address_t address;
16344
16345   const char *valid_chars = "a-zA-Z0-9_";
16346
16347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16348     {
16349       if (unformat
16350           (i, "%U interface %d address %U", unformat_token, valid_chars,
16351            &name, &sw_if_index, unformat_ip4_address, &address))
16352         vec_add1 (name, 0);
16353       else
16354         {
16355           errmsg ("parse error '%U'", format_unformat_error, i);
16356           return -99;
16357         }
16358     }
16359
16360   if (!vec_len (name))
16361     {
16362       errmsg ("profile name must be specified");
16363       return -99;
16364     }
16365
16366   if (vec_len (name) > 64)
16367     {
16368       errmsg ("profile name too long");
16369       return -99;
16370     }
16371
16372   M (IKEV2_SET_RESPONDER, mp);
16373
16374   clib_memcpy (mp->name, name, vec_len (name));
16375   vec_free (name);
16376
16377   mp->sw_if_index = sw_if_index;
16378   clib_memcpy (mp->address, &address, sizeof (address));
16379
16380   S (mp);
16381   W (ret);
16382   return ret;
16383 }
16384
16385 static int
16386 api_ikev2_set_ike_transforms (vat_main_t * vam)
16387 {
16388   unformat_input_t *i = vam->input;
16389   vl_api_ikev2_set_ike_transforms_t *mp;
16390   int ret;
16391   u8 *name = 0;
16392   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16393
16394   const char *valid_chars = "a-zA-Z0-9_";
16395
16396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16397     {
16398       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16399                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16400         vec_add1 (name, 0);
16401       else
16402         {
16403           errmsg ("parse error '%U'", format_unformat_error, i);
16404           return -99;
16405         }
16406     }
16407
16408   if (!vec_len (name))
16409     {
16410       errmsg ("profile name must be specified");
16411       return -99;
16412     }
16413
16414   if (vec_len (name) > 64)
16415     {
16416       errmsg ("profile name too long");
16417       return -99;
16418     }
16419
16420   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16421
16422   clib_memcpy (mp->name, name, vec_len (name));
16423   vec_free (name);
16424   mp->crypto_alg = crypto_alg;
16425   mp->crypto_key_size = crypto_key_size;
16426   mp->integ_alg = integ_alg;
16427   mp->dh_group = dh_group;
16428
16429   S (mp);
16430   W (ret);
16431   return ret;
16432 }
16433
16434
16435 static int
16436 api_ikev2_set_esp_transforms (vat_main_t * vam)
16437 {
16438   unformat_input_t *i = vam->input;
16439   vl_api_ikev2_set_esp_transforms_t *mp;
16440   int ret;
16441   u8 *name = 0;
16442   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16443
16444   const char *valid_chars = "a-zA-Z0-9_";
16445
16446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16447     {
16448       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16449                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16450         vec_add1 (name, 0);
16451       else
16452         {
16453           errmsg ("parse error '%U'", format_unformat_error, i);
16454           return -99;
16455         }
16456     }
16457
16458   if (!vec_len (name))
16459     {
16460       errmsg ("profile name must be specified");
16461       return -99;
16462     }
16463
16464   if (vec_len (name) > 64)
16465     {
16466       errmsg ("profile name too long");
16467       return -99;
16468     }
16469
16470   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16471
16472   clib_memcpy (mp->name, name, vec_len (name));
16473   vec_free (name);
16474   mp->crypto_alg = crypto_alg;
16475   mp->crypto_key_size = crypto_key_size;
16476   mp->integ_alg = integ_alg;
16477   mp->dh_group = dh_group;
16478
16479   S (mp);
16480   W (ret);
16481   return ret;
16482 }
16483
16484 static int
16485 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16486 {
16487   unformat_input_t *i = vam->input;
16488   vl_api_ikev2_set_sa_lifetime_t *mp;
16489   int ret;
16490   u8 *name = 0;
16491   u64 lifetime, lifetime_maxdata;
16492   u32 lifetime_jitter, handover;
16493
16494   const char *valid_chars = "a-zA-Z0-9_";
16495
16496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16497     {
16498       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16499                     &lifetime, &lifetime_jitter, &handover,
16500                     &lifetime_maxdata))
16501         vec_add1 (name, 0);
16502       else
16503         {
16504           errmsg ("parse error '%U'", format_unformat_error, i);
16505           return -99;
16506         }
16507     }
16508
16509   if (!vec_len (name))
16510     {
16511       errmsg ("profile name must be specified");
16512       return -99;
16513     }
16514
16515   if (vec_len (name) > 64)
16516     {
16517       errmsg ("profile name too long");
16518       return -99;
16519     }
16520
16521   M (IKEV2_SET_SA_LIFETIME, mp);
16522
16523   clib_memcpy (mp->name, name, vec_len (name));
16524   vec_free (name);
16525   mp->lifetime = lifetime;
16526   mp->lifetime_jitter = lifetime_jitter;
16527   mp->handover = handover;
16528   mp->lifetime_maxdata = lifetime_maxdata;
16529
16530   S (mp);
16531   W (ret);
16532   return ret;
16533 }
16534
16535 static int
16536 api_ikev2_initiate_sa_init (vat_main_t * vam)
16537 {
16538   unformat_input_t *i = vam->input;
16539   vl_api_ikev2_initiate_sa_init_t *mp;
16540   int ret;
16541   u8 *name = 0;
16542
16543   const char *valid_chars = "a-zA-Z0-9_";
16544
16545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16546     {
16547       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16548         vec_add1 (name, 0);
16549       else
16550         {
16551           errmsg ("parse error '%U'", format_unformat_error, i);
16552           return -99;
16553         }
16554     }
16555
16556   if (!vec_len (name))
16557     {
16558       errmsg ("profile name must be specified");
16559       return -99;
16560     }
16561
16562   if (vec_len (name) > 64)
16563     {
16564       errmsg ("profile name too long");
16565       return -99;
16566     }
16567
16568   M (IKEV2_INITIATE_SA_INIT, mp);
16569
16570   clib_memcpy (mp->name, name, vec_len (name));
16571   vec_free (name);
16572
16573   S (mp);
16574   W (ret);
16575   return ret;
16576 }
16577
16578 static int
16579 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16580 {
16581   unformat_input_t *i = vam->input;
16582   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16583   int ret;
16584   u64 ispi;
16585
16586
16587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16588     {
16589       if (unformat (i, "%lx", &ispi))
16590         ;
16591       else
16592         {
16593           errmsg ("parse error '%U'", format_unformat_error, i);
16594           return -99;
16595         }
16596     }
16597
16598   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16599
16600   mp->ispi = ispi;
16601
16602   S (mp);
16603   W (ret);
16604   return ret;
16605 }
16606
16607 static int
16608 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16609 {
16610   unformat_input_t *i = vam->input;
16611   vl_api_ikev2_initiate_del_child_sa_t *mp;
16612   int ret;
16613   u32 ispi;
16614
16615
16616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16617     {
16618       if (unformat (i, "%x", &ispi))
16619         ;
16620       else
16621         {
16622           errmsg ("parse error '%U'", format_unformat_error, i);
16623           return -99;
16624         }
16625     }
16626
16627   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16628
16629   mp->ispi = ispi;
16630
16631   S (mp);
16632   W (ret);
16633   return ret;
16634 }
16635
16636 static int
16637 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16638 {
16639   unformat_input_t *i = vam->input;
16640   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16641   int ret;
16642   u32 ispi;
16643
16644
16645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16646     {
16647       if (unformat (i, "%x", &ispi))
16648         ;
16649       else
16650         {
16651           errmsg ("parse error '%U'", format_unformat_error, i);
16652           return -99;
16653         }
16654     }
16655
16656   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16657
16658   mp->ispi = ispi;
16659
16660   S (mp);
16661   W (ret);
16662   return ret;
16663 }
16664
16665 static int
16666 api_get_first_msg_id (vat_main_t * vam)
16667 {
16668   vl_api_get_first_msg_id_t *mp;
16669   unformat_input_t *i = vam->input;
16670   u8 *name;
16671   u8 name_set = 0;
16672   int ret;
16673
16674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16675     {
16676       if (unformat (i, "client %s", &name))
16677         name_set = 1;
16678       else
16679         break;
16680     }
16681
16682   if (name_set == 0)
16683     {
16684       errmsg ("missing client name");
16685       return -99;
16686     }
16687   vec_add1 (name, 0);
16688
16689   if (vec_len (name) > 63)
16690     {
16691       errmsg ("client name too long");
16692       return -99;
16693     }
16694
16695   M (GET_FIRST_MSG_ID, mp);
16696   clib_memcpy (mp->name, name, vec_len (name));
16697   S (mp);
16698   W (ret);
16699   return ret;
16700 }
16701
16702 static int
16703 api_cop_interface_enable_disable (vat_main_t * vam)
16704 {
16705   unformat_input_t *line_input = vam->input;
16706   vl_api_cop_interface_enable_disable_t *mp;
16707   u32 sw_if_index = ~0;
16708   u8 enable_disable = 1;
16709   int ret;
16710
16711   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16712     {
16713       if (unformat (line_input, "disable"))
16714         enable_disable = 0;
16715       if (unformat (line_input, "enable"))
16716         enable_disable = 1;
16717       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16718                          vam, &sw_if_index))
16719         ;
16720       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16721         ;
16722       else
16723         break;
16724     }
16725
16726   if (sw_if_index == ~0)
16727     {
16728       errmsg ("missing interface name or sw_if_index");
16729       return -99;
16730     }
16731
16732   /* Construct the API message */
16733   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16734   mp->sw_if_index = ntohl (sw_if_index);
16735   mp->enable_disable = enable_disable;
16736
16737   /* send it... */
16738   S (mp);
16739   /* Wait for the reply */
16740   W (ret);
16741   return ret;
16742 }
16743
16744 static int
16745 api_cop_whitelist_enable_disable (vat_main_t * vam)
16746 {
16747   unformat_input_t *line_input = vam->input;
16748   vl_api_cop_whitelist_enable_disable_t *mp;
16749   u32 sw_if_index = ~0;
16750   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16751   u32 fib_id = 0;
16752   int ret;
16753
16754   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16755     {
16756       if (unformat (line_input, "ip4"))
16757         ip4 = 1;
16758       else if (unformat (line_input, "ip6"))
16759         ip6 = 1;
16760       else if (unformat (line_input, "default"))
16761         default_cop = 1;
16762       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16763                          vam, &sw_if_index))
16764         ;
16765       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16766         ;
16767       else if (unformat (line_input, "fib-id %d", &fib_id))
16768         ;
16769       else
16770         break;
16771     }
16772
16773   if (sw_if_index == ~0)
16774     {
16775       errmsg ("missing interface name or sw_if_index");
16776       return -99;
16777     }
16778
16779   /* Construct the API message */
16780   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16781   mp->sw_if_index = ntohl (sw_if_index);
16782   mp->fib_id = ntohl (fib_id);
16783   mp->ip4 = ip4;
16784   mp->ip6 = ip6;
16785   mp->default_cop = default_cop;
16786
16787   /* send it... */
16788   S (mp);
16789   /* Wait for the reply */
16790   W (ret);
16791   return ret;
16792 }
16793
16794 static int
16795 api_get_node_graph (vat_main_t * vam)
16796 {
16797   vl_api_get_node_graph_t *mp;
16798   int ret;
16799
16800   M (GET_NODE_GRAPH, mp);
16801
16802   /* send it... */
16803   S (mp);
16804   /* Wait for the reply */
16805   W (ret);
16806   return ret;
16807 }
16808
16809 /* *INDENT-OFF* */
16810 /** Used for parsing LISP eids */
16811 typedef CLIB_PACKED(struct{
16812   u8 addr[16];   /**< eid address */
16813   u32 len;       /**< prefix length if IP */
16814   u8 type;      /**< type of eid */
16815 }) lisp_eid_vat_t;
16816 /* *INDENT-ON* */
16817
16818 static uword
16819 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16820 {
16821   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16822
16823   memset (a, 0, sizeof (a[0]));
16824
16825   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16826     {
16827       a->type = 0;              /* ipv4 type */
16828     }
16829   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16830     {
16831       a->type = 1;              /* ipv6 type */
16832     }
16833   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16834     {
16835       a->type = 2;              /* mac type */
16836     }
16837   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16838     {
16839       a->type = 3;              /* NSH type */
16840       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16841       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16842     }
16843   else
16844     {
16845       return 0;
16846     }
16847
16848   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16849     {
16850       return 0;
16851     }
16852
16853   return 1;
16854 }
16855
16856 static int
16857 lisp_eid_size_vat (u8 type)
16858 {
16859   switch (type)
16860     {
16861     case 0:
16862       return 4;
16863     case 1:
16864       return 16;
16865     case 2:
16866       return 6;
16867     case 3:
16868       return 5;
16869     }
16870   return 0;
16871 }
16872
16873 static void
16874 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16875 {
16876   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16877 }
16878
16879 static int
16880 api_one_add_del_locator_set (vat_main_t * vam)
16881 {
16882   unformat_input_t *input = vam->input;
16883   vl_api_one_add_del_locator_set_t *mp;
16884   u8 is_add = 1;
16885   u8 *locator_set_name = NULL;
16886   u8 locator_set_name_set = 0;
16887   vl_api_local_locator_t locator, *locators = 0;
16888   u32 sw_if_index, priority, weight;
16889   u32 data_len = 0;
16890
16891   int ret;
16892   /* Parse args required to build the message */
16893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16894     {
16895       if (unformat (input, "del"))
16896         {
16897           is_add = 0;
16898         }
16899       else if (unformat (input, "locator-set %s", &locator_set_name))
16900         {
16901           locator_set_name_set = 1;
16902         }
16903       else if (unformat (input, "sw_if_index %u p %u w %u",
16904                          &sw_if_index, &priority, &weight))
16905         {
16906           locator.sw_if_index = htonl (sw_if_index);
16907           locator.priority = priority;
16908           locator.weight = weight;
16909           vec_add1 (locators, locator);
16910         }
16911       else
16912         if (unformat
16913             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16914              &sw_if_index, &priority, &weight))
16915         {
16916           locator.sw_if_index = htonl (sw_if_index);
16917           locator.priority = priority;
16918           locator.weight = weight;
16919           vec_add1 (locators, locator);
16920         }
16921       else
16922         break;
16923     }
16924
16925   if (locator_set_name_set == 0)
16926     {
16927       errmsg ("missing locator-set name");
16928       vec_free (locators);
16929       return -99;
16930     }
16931
16932   if (vec_len (locator_set_name) > 64)
16933     {
16934       errmsg ("locator-set name too long");
16935       vec_free (locator_set_name);
16936       vec_free (locators);
16937       return -99;
16938     }
16939   vec_add1 (locator_set_name, 0);
16940
16941   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16942
16943   /* Construct the API message */
16944   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16945
16946   mp->is_add = is_add;
16947   clib_memcpy (mp->locator_set_name, locator_set_name,
16948                vec_len (locator_set_name));
16949   vec_free (locator_set_name);
16950
16951   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16952   if (locators)
16953     clib_memcpy (mp->locators, locators, data_len);
16954   vec_free (locators);
16955
16956   /* send it... */
16957   S (mp);
16958
16959   /* Wait for a reply... */
16960   W (ret);
16961   return ret;
16962 }
16963
16964 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16965
16966 static int
16967 api_one_add_del_locator (vat_main_t * vam)
16968 {
16969   unformat_input_t *input = vam->input;
16970   vl_api_one_add_del_locator_t *mp;
16971   u32 tmp_if_index = ~0;
16972   u32 sw_if_index = ~0;
16973   u8 sw_if_index_set = 0;
16974   u8 sw_if_index_if_name_set = 0;
16975   u32 priority = ~0;
16976   u8 priority_set = 0;
16977   u32 weight = ~0;
16978   u8 weight_set = 0;
16979   u8 is_add = 1;
16980   u8 *locator_set_name = NULL;
16981   u8 locator_set_name_set = 0;
16982   int ret;
16983
16984   /* Parse args required to build the message */
16985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16986     {
16987       if (unformat (input, "del"))
16988         {
16989           is_add = 0;
16990         }
16991       else if (unformat (input, "locator-set %s", &locator_set_name))
16992         {
16993           locator_set_name_set = 1;
16994         }
16995       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16996                          &tmp_if_index))
16997         {
16998           sw_if_index_if_name_set = 1;
16999           sw_if_index = tmp_if_index;
17000         }
17001       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17002         {
17003           sw_if_index_set = 1;
17004           sw_if_index = tmp_if_index;
17005         }
17006       else if (unformat (input, "p %d", &priority))
17007         {
17008           priority_set = 1;
17009         }
17010       else if (unformat (input, "w %d", &weight))
17011         {
17012           weight_set = 1;
17013         }
17014       else
17015         break;
17016     }
17017
17018   if (locator_set_name_set == 0)
17019     {
17020       errmsg ("missing locator-set name");
17021       return -99;
17022     }
17023
17024   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17025     {
17026       errmsg ("missing sw_if_index");
17027       vec_free (locator_set_name);
17028       return -99;
17029     }
17030
17031   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17032     {
17033       errmsg ("cannot use both params interface name and sw_if_index");
17034       vec_free (locator_set_name);
17035       return -99;
17036     }
17037
17038   if (priority_set == 0)
17039     {
17040       errmsg ("missing locator-set priority");
17041       vec_free (locator_set_name);
17042       return -99;
17043     }
17044
17045   if (weight_set == 0)
17046     {
17047       errmsg ("missing locator-set weight");
17048       vec_free (locator_set_name);
17049       return -99;
17050     }
17051
17052   if (vec_len (locator_set_name) > 64)
17053     {
17054       errmsg ("locator-set name too long");
17055       vec_free (locator_set_name);
17056       return -99;
17057     }
17058   vec_add1 (locator_set_name, 0);
17059
17060   /* Construct the API message */
17061   M (ONE_ADD_DEL_LOCATOR, mp);
17062
17063   mp->is_add = is_add;
17064   mp->sw_if_index = ntohl (sw_if_index);
17065   mp->priority = priority;
17066   mp->weight = weight;
17067   clib_memcpy (mp->locator_set_name, locator_set_name,
17068                vec_len (locator_set_name));
17069   vec_free (locator_set_name);
17070
17071   /* send it... */
17072   S (mp);
17073
17074   /* Wait for a reply... */
17075   W (ret);
17076   return ret;
17077 }
17078
17079 #define api_lisp_add_del_locator api_one_add_del_locator
17080
17081 uword
17082 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17083 {
17084   u32 *key_id = va_arg (*args, u32 *);
17085   u8 *s = 0;
17086
17087   if (unformat (input, "%s", &s))
17088     {
17089       if (!strcmp ((char *) s, "sha1"))
17090         key_id[0] = HMAC_SHA_1_96;
17091       else if (!strcmp ((char *) s, "sha256"))
17092         key_id[0] = HMAC_SHA_256_128;
17093       else
17094         {
17095           clib_warning ("invalid key_id: '%s'", s);
17096           key_id[0] = HMAC_NO_KEY;
17097         }
17098     }
17099   else
17100     return 0;
17101
17102   vec_free (s);
17103   return 1;
17104 }
17105
17106 static int
17107 api_one_add_del_local_eid (vat_main_t * vam)
17108 {
17109   unformat_input_t *input = vam->input;
17110   vl_api_one_add_del_local_eid_t *mp;
17111   u8 is_add = 1;
17112   u8 eid_set = 0;
17113   lisp_eid_vat_t _eid, *eid = &_eid;
17114   u8 *locator_set_name = 0;
17115   u8 locator_set_name_set = 0;
17116   u32 vni = 0;
17117   u16 key_id = 0;
17118   u8 *key = 0;
17119   int ret;
17120
17121   /* Parse args required to build the message */
17122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17123     {
17124       if (unformat (input, "del"))
17125         {
17126           is_add = 0;
17127         }
17128       else if (unformat (input, "vni %d", &vni))
17129         {
17130           ;
17131         }
17132       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17133         {
17134           eid_set = 1;
17135         }
17136       else if (unformat (input, "locator-set %s", &locator_set_name))
17137         {
17138           locator_set_name_set = 1;
17139         }
17140       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17141         ;
17142       else if (unformat (input, "secret-key %_%v%_", &key))
17143         ;
17144       else
17145         break;
17146     }
17147
17148   if (locator_set_name_set == 0)
17149     {
17150       errmsg ("missing locator-set name");
17151       return -99;
17152     }
17153
17154   if (0 == eid_set)
17155     {
17156       errmsg ("EID address not set!");
17157       vec_free (locator_set_name);
17158       return -99;
17159     }
17160
17161   if (key && (0 == key_id))
17162     {
17163       errmsg ("invalid key_id!");
17164       return -99;
17165     }
17166
17167   if (vec_len (key) > 64)
17168     {
17169       errmsg ("key too long");
17170       vec_free (key);
17171       return -99;
17172     }
17173
17174   if (vec_len (locator_set_name) > 64)
17175     {
17176       errmsg ("locator-set name too long");
17177       vec_free (locator_set_name);
17178       return -99;
17179     }
17180   vec_add1 (locator_set_name, 0);
17181
17182   /* Construct the API message */
17183   M (ONE_ADD_DEL_LOCAL_EID, mp);
17184
17185   mp->is_add = is_add;
17186   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17187   mp->eid_type = eid->type;
17188   mp->prefix_len = eid->len;
17189   mp->vni = clib_host_to_net_u32 (vni);
17190   mp->key_id = clib_host_to_net_u16 (key_id);
17191   clib_memcpy (mp->locator_set_name, locator_set_name,
17192                vec_len (locator_set_name));
17193   clib_memcpy (mp->key, key, vec_len (key));
17194
17195   vec_free (locator_set_name);
17196   vec_free (key);
17197
17198   /* send it... */
17199   S (mp);
17200
17201   /* Wait for a reply... */
17202   W (ret);
17203   return ret;
17204 }
17205
17206 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17207
17208 static int
17209 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17210 {
17211   u32 dp_table = 0, vni = 0;;
17212   unformat_input_t *input = vam->input;
17213   vl_api_gpe_add_del_fwd_entry_t *mp;
17214   u8 is_add = 1;
17215   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17216   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17217   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17218   u32 action = ~0, w;
17219   ip4_address_t rmt_rloc4, lcl_rloc4;
17220   ip6_address_t rmt_rloc6, lcl_rloc6;
17221   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17222   int ret;
17223
17224   memset (&rloc, 0, sizeof (rloc));
17225
17226   /* Parse args required to build the message */
17227   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17228     {
17229       if (unformat (input, "del"))
17230         is_add = 0;
17231       else if (unformat (input, "add"))
17232         is_add = 1;
17233       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17234         {
17235           rmt_eid_set = 1;
17236         }
17237       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17238         {
17239           lcl_eid_set = 1;
17240         }
17241       else if (unformat (input, "vrf %d", &dp_table))
17242         ;
17243       else if (unformat (input, "bd %d", &dp_table))
17244         ;
17245       else if (unformat (input, "vni %d", &vni))
17246         ;
17247       else if (unformat (input, "w %d", &w))
17248         {
17249           if (!curr_rloc)
17250             {
17251               errmsg ("No RLOC configured for setting priority/weight!");
17252               return -99;
17253             }
17254           curr_rloc->weight = w;
17255         }
17256       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17257                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17258         {
17259           rloc.is_ip4 = 1;
17260
17261           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17262           rloc.weight = 0;
17263           vec_add1 (lcl_locs, rloc);
17264
17265           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17266           vec_add1 (rmt_locs, rloc);
17267           /* weight saved in rmt loc */
17268           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17269         }
17270       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17271                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17272         {
17273           rloc.is_ip4 = 0;
17274           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17275           rloc.weight = 0;
17276           vec_add1 (lcl_locs, rloc);
17277
17278           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17279           vec_add1 (rmt_locs, rloc);
17280           /* weight saved in rmt loc */
17281           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17282         }
17283       else if (unformat (input, "action %d", &action))
17284         {
17285           ;
17286         }
17287       else
17288         {
17289           clib_warning ("parse error '%U'", format_unformat_error, input);
17290           return -99;
17291         }
17292     }
17293
17294   if (!rmt_eid_set)
17295     {
17296       errmsg ("remote eid addresses not set");
17297       return -99;
17298     }
17299
17300   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17301     {
17302       errmsg ("eid types don't match");
17303       return -99;
17304     }
17305
17306   if (0 == rmt_locs && (u32) ~ 0 == action)
17307     {
17308       errmsg ("action not set for negative mapping");
17309       return -99;
17310     }
17311
17312   /* Construct the API message */
17313   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17314       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17315
17316   mp->is_add = is_add;
17317   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17318   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17319   mp->eid_type = rmt_eid->type;
17320   mp->dp_table = clib_host_to_net_u32 (dp_table);
17321   mp->vni = clib_host_to_net_u32 (vni);
17322   mp->rmt_len = rmt_eid->len;
17323   mp->lcl_len = lcl_eid->len;
17324   mp->action = action;
17325
17326   if (0 != rmt_locs && 0 != lcl_locs)
17327     {
17328       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17329       clib_memcpy (mp->locs, lcl_locs,
17330                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17331
17332       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17333       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17334                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17335     }
17336   vec_free (lcl_locs);
17337   vec_free (rmt_locs);
17338
17339   /* send it... */
17340   S (mp);
17341
17342   /* Wait for a reply... */
17343   W (ret);
17344   return ret;
17345 }
17346
17347 static int
17348 api_one_add_del_map_server (vat_main_t * vam)
17349 {
17350   unformat_input_t *input = vam->input;
17351   vl_api_one_add_del_map_server_t *mp;
17352   u8 is_add = 1;
17353   u8 ipv4_set = 0;
17354   u8 ipv6_set = 0;
17355   ip4_address_t ipv4;
17356   ip6_address_t ipv6;
17357   int ret;
17358
17359   /* Parse args required to build the message */
17360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17361     {
17362       if (unformat (input, "del"))
17363         {
17364           is_add = 0;
17365         }
17366       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17367         {
17368           ipv4_set = 1;
17369         }
17370       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17371         {
17372           ipv6_set = 1;
17373         }
17374       else
17375         break;
17376     }
17377
17378   if (ipv4_set && ipv6_set)
17379     {
17380       errmsg ("both eid v4 and v6 addresses set");
17381       return -99;
17382     }
17383
17384   if (!ipv4_set && !ipv6_set)
17385     {
17386       errmsg ("eid addresses not set");
17387       return -99;
17388     }
17389
17390   /* Construct the API message */
17391   M (ONE_ADD_DEL_MAP_SERVER, mp);
17392
17393   mp->is_add = is_add;
17394   if (ipv6_set)
17395     {
17396       mp->is_ipv6 = 1;
17397       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17398     }
17399   else
17400     {
17401       mp->is_ipv6 = 0;
17402       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17403     }
17404
17405   /* send it... */
17406   S (mp);
17407
17408   /* Wait for a reply... */
17409   W (ret);
17410   return ret;
17411 }
17412
17413 #define api_lisp_add_del_map_server api_one_add_del_map_server
17414
17415 static int
17416 api_one_add_del_map_resolver (vat_main_t * vam)
17417 {
17418   unformat_input_t *input = vam->input;
17419   vl_api_one_add_del_map_resolver_t *mp;
17420   u8 is_add = 1;
17421   u8 ipv4_set = 0;
17422   u8 ipv6_set = 0;
17423   ip4_address_t ipv4;
17424   ip6_address_t ipv6;
17425   int ret;
17426
17427   /* Parse args required to build the message */
17428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17429     {
17430       if (unformat (input, "del"))
17431         {
17432           is_add = 0;
17433         }
17434       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17435         {
17436           ipv4_set = 1;
17437         }
17438       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17439         {
17440           ipv6_set = 1;
17441         }
17442       else
17443         break;
17444     }
17445
17446   if (ipv4_set && ipv6_set)
17447     {
17448       errmsg ("both eid v4 and v6 addresses set");
17449       return -99;
17450     }
17451
17452   if (!ipv4_set && !ipv6_set)
17453     {
17454       errmsg ("eid addresses not set");
17455       return -99;
17456     }
17457
17458   /* Construct the API message */
17459   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17460
17461   mp->is_add = is_add;
17462   if (ipv6_set)
17463     {
17464       mp->is_ipv6 = 1;
17465       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17466     }
17467   else
17468     {
17469       mp->is_ipv6 = 0;
17470       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17471     }
17472
17473   /* send it... */
17474   S (mp);
17475
17476   /* Wait for a reply... */
17477   W (ret);
17478   return ret;
17479 }
17480
17481 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17482
17483 static int
17484 api_lisp_gpe_enable_disable (vat_main_t * vam)
17485 {
17486   unformat_input_t *input = vam->input;
17487   vl_api_gpe_enable_disable_t *mp;
17488   u8 is_set = 0;
17489   u8 is_en = 1;
17490   int ret;
17491
17492   /* Parse args required to build the message */
17493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17494     {
17495       if (unformat (input, "enable"))
17496         {
17497           is_set = 1;
17498           is_en = 1;
17499         }
17500       else if (unformat (input, "disable"))
17501         {
17502           is_set = 1;
17503           is_en = 0;
17504         }
17505       else
17506         break;
17507     }
17508
17509   if (is_set == 0)
17510     {
17511       errmsg ("Value not set");
17512       return -99;
17513     }
17514
17515   /* Construct the API message */
17516   M (GPE_ENABLE_DISABLE, mp);
17517
17518   mp->is_en = is_en;
17519
17520   /* send it... */
17521   S (mp);
17522
17523   /* Wait for a reply... */
17524   W (ret);
17525   return ret;
17526 }
17527
17528 static int
17529 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17530 {
17531   unformat_input_t *input = vam->input;
17532   vl_api_one_rloc_probe_enable_disable_t *mp;
17533   u8 is_set = 0;
17534   u8 is_en = 0;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (input, "enable"))
17541         {
17542           is_set = 1;
17543           is_en = 1;
17544         }
17545       else if (unformat (input, "disable"))
17546         is_set = 1;
17547       else
17548         break;
17549     }
17550
17551   if (!is_set)
17552     {
17553       errmsg ("Value not set");
17554       return -99;
17555     }
17556
17557   /* Construct the API message */
17558   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17559
17560   mp->is_enabled = is_en;
17561
17562   /* send it... */
17563   S (mp);
17564
17565   /* Wait for a reply... */
17566   W (ret);
17567   return ret;
17568 }
17569
17570 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17571
17572 static int
17573 api_one_map_register_enable_disable (vat_main_t * vam)
17574 {
17575   unformat_input_t *input = vam->input;
17576   vl_api_one_map_register_enable_disable_t *mp;
17577   u8 is_set = 0;
17578   u8 is_en = 0;
17579   int ret;
17580
17581   /* Parse args required to build the message */
17582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17583     {
17584       if (unformat (input, "enable"))
17585         {
17586           is_set = 1;
17587           is_en = 1;
17588         }
17589       else if (unformat (input, "disable"))
17590         is_set = 1;
17591       else
17592         break;
17593     }
17594
17595   if (!is_set)
17596     {
17597       errmsg ("Value not set");
17598       return -99;
17599     }
17600
17601   /* Construct the API message */
17602   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17603
17604   mp->is_enabled = is_en;
17605
17606   /* send it... */
17607   S (mp);
17608
17609   /* Wait for a reply... */
17610   W (ret);
17611   return ret;
17612 }
17613
17614 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17615
17616 static int
17617 api_one_enable_disable (vat_main_t * vam)
17618 {
17619   unformat_input_t *input = vam->input;
17620   vl_api_one_enable_disable_t *mp;
17621   u8 is_set = 0;
17622   u8 is_en = 0;
17623   int ret;
17624
17625   /* Parse args required to build the message */
17626   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17627     {
17628       if (unformat (input, "enable"))
17629         {
17630           is_set = 1;
17631           is_en = 1;
17632         }
17633       else if (unformat (input, "disable"))
17634         {
17635           is_set = 1;
17636         }
17637       else
17638         break;
17639     }
17640
17641   if (!is_set)
17642     {
17643       errmsg ("Value not set");
17644       return -99;
17645     }
17646
17647   /* Construct the API message */
17648   M (ONE_ENABLE_DISABLE, mp);
17649
17650   mp->is_en = is_en;
17651
17652   /* send it... */
17653   S (mp);
17654
17655   /* Wait for a reply... */
17656   W (ret);
17657   return ret;
17658 }
17659
17660 #define api_lisp_enable_disable api_one_enable_disable
17661
17662 static int
17663 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17664 {
17665   unformat_input_t *input = vam->input;
17666   vl_api_one_enable_disable_xtr_mode_t *mp;
17667   u8 is_set = 0;
17668   u8 is_en = 0;
17669   int ret;
17670
17671   /* Parse args required to build the message */
17672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17673     {
17674       if (unformat (input, "enable"))
17675         {
17676           is_set = 1;
17677           is_en = 1;
17678         }
17679       else if (unformat (input, "disable"))
17680         {
17681           is_set = 1;
17682         }
17683       else
17684         break;
17685     }
17686
17687   if (!is_set)
17688     {
17689       errmsg ("Value not set");
17690       return -99;
17691     }
17692
17693   /* Construct the API message */
17694   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17695
17696   mp->is_en = is_en;
17697
17698   /* send it... */
17699   S (mp);
17700
17701   /* Wait for a reply... */
17702   W (ret);
17703   return ret;
17704 }
17705
17706 static int
17707 api_one_show_xtr_mode (vat_main_t * vam)
17708 {
17709   vl_api_one_show_xtr_mode_t *mp;
17710   int ret;
17711
17712   /* Construct the API message */
17713   M (ONE_SHOW_XTR_MODE, mp);
17714
17715   /* send it... */
17716   S (mp);
17717
17718   /* Wait for a reply... */
17719   W (ret);
17720   return ret;
17721 }
17722
17723 static int
17724 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17725 {
17726   unformat_input_t *input = vam->input;
17727   vl_api_one_enable_disable_pitr_mode_t *mp;
17728   u8 is_set = 0;
17729   u8 is_en = 0;
17730   int ret;
17731
17732   /* Parse args required to build the message */
17733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17734     {
17735       if (unformat (input, "enable"))
17736         {
17737           is_set = 1;
17738           is_en = 1;
17739         }
17740       else if (unformat (input, "disable"))
17741         {
17742           is_set = 1;
17743         }
17744       else
17745         break;
17746     }
17747
17748   if (!is_set)
17749     {
17750       errmsg ("Value not set");
17751       return -99;
17752     }
17753
17754   /* Construct the API message */
17755   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17756
17757   mp->is_en = is_en;
17758
17759   /* send it... */
17760   S (mp);
17761
17762   /* Wait for a reply... */
17763   W (ret);
17764   return ret;
17765 }
17766
17767 static int
17768 api_one_show_pitr_mode (vat_main_t * vam)
17769 {
17770   vl_api_one_show_pitr_mode_t *mp;
17771   int ret;
17772
17773   /* Construct the API message */
17774   M (ONE_SHOW_PITR_MODE, mp);
17775
17776   /* send it... */
17777   S (mp);
17778
17779   /* Wait for a reply... */
17780   W (ret);
17781   return ret;
17782 }
17783
17784 static int
17785 api_one_enable_disable_petr_mode (vat_main_t * vam)
17786 {
17787   unformat_input_t *input = vam->input;
17788   vl_api_one_enable_disable_petr_mode_t *mp;
17789   u8 is_set = 0;
17790   u8 is_en = 0;
17791   int ret;
17792
17793   /* Parse args required to build the message */
17794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17795     {
17796       if (unformat (input, "enable"))
17797         {
17798           is_set = 1;
17799           is_en = 1;
17800         }
17801       else if (unformat (input, "disable"))
17802         {
17803           is_set = 1;
17804         }
17805       else
17806         break;
17807     }
17808
17809   if (!is_set)
17810     {
17811       errmsg ("Value not set");
17812       return -99;
17813     }
17814
17815   /* Construct the API message */
17816   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17817
17818   mp->is_en = is_en;
17819
17820   /* send it... */
17821   S (mp);
17822
17823   /* Wait for a reply... */
17824   W (ret);
17825   return ret;
17826 }
17827
17828 static int
17829 api_one_show_petr_mode (vat_main_t * vam)
17830 {
17831   vl_api_one_show_petr_mode_t *mp;
17832   int ret;
17833
17834   /* Construct the API message */
17835   M (ONE_SHOW_PETR_MODE, mp);
17836
17837   /* send it... */
17838   S (mp);
17839
17840   /* Wait for a reply... */
17841   W (ret);
17842   return ret;
17843 }
17844
17845 static int
17846 api_show_one_map_register_state (vat_main_t * vam)
17847 {
17848   vl_api_show_one_map_register_state_t *mp;
17849   int ret;
17850
17851   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17852
17853   /* send */
17854   S (mp);
17855
17856   /* wait for reply */
17857   W (ret);
17858   return ret;
17859 }
17860
17861 #define api_show_lisp_map_register_state api_show_one_map_register_state
17862
17863 static int
17864 api_show_one_rloc_probe_state (vat_main_t * vam)
17865 {
17866   vl_api_show_one_rloc_probe_state_t *mp;
17867   int ret;
17868
17869   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17870
17871   /* send */
17872   S (mp);
17873
17874   /* wait for reply */
17875   W (ret);
17876   return ret;
17877 }
17878
17879 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17880
17881 static int
17882 api_one_add_del_ndp_entry (vat_main_t * vam)
17883 {
17884   vl_api_one_add_del_ndp_entry_t *mp;
17885   unformat_input_t *input = vam->input;
17886   u8 is_add = 1;
17887   u8 mac_set = 0;
17888   u8 bd_set = 0;
17889   u8 ip_set = 0;
17890   u8 mac[6] = { 0, };
17891   u8 ip6[16] = { 0, };
17892   u32 bd = ~0;
17893   int ret;
17894
17895   /* Parse args required to build the message */
17896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (input, "del"))
17899         is_add = 0;
17900       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17901         mac_set = 1;
17902       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17903         ip_set = 1;
17904       else if (unformat (input, "bd %d", &bd))
17905         bd_set = 1;
17906       else
17907         {
17908           errmsg ("parse error '%U'", format_unformat_error, input);
17909           return -99;
17910         }
17911     }
17912
17913   if (!bd_set || !ip_set || (!mac_set && is_add))
17914     {
17915       errmsg ("Missing BD, IP or MAC!");
17916       return -99;
17917     }
17918
17919   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17920   mp->is_add = is_add;
17921   clib_memcpy (mp->mac, mac, 6);
17922   mp->bd = clib_host_to_net_u32 (bd);
17923   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17924
17925   /* send */
17926   S (mp);
17927
17928   /* wait for reply */
17929   W (ret);
17930   return ret;
17931 }
17932
17933 static int
17934 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17935 {
17936   vl_api_one_add_del_l2_arp_entry_t *mp;
17937   unformat_input_t *input = vam->input;
17938   u8 is_add = 1;
17939   u8 mac_set = 0;
17940   u8 bd_set = 0;
17941   u8 ip_set = 0;
17942   u8 mac[6] = { 0, };
17943   u32 ip4 = 0, bd = ~0;
17944   int ret;
17945
17946   /* Parse args required to build the message */
17947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17948     {
17949       if (unformat (input, "del"))
17950         is_add = 0;
17951       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17952         mac_set = 1;
17953       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17954         ip_set = 1;
17955       else if (unformat (input, "bd %d", &bd))
17956         bd_set = 1;
17957       else
17958         {
17959           errmsg ("parse error '%U'", format_unformat_error, input);
17960           return -99;
17961         }
17962     }
17963
17964   if (!bd_set || !ip_set || (!mac_set && is_add))
17965     {
17966       errmsg ("Missing BD, IP or MAC!");
17967       return -99;
17968     }
17969
17970   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17971   mp->is_add = is_add;
17972   clib_memcpy (mp->mac, mac, 6);
17973   mp->bd = clib_host_to_net_u32 (bd);
17974   mp->ip4 = ip4;
17975
17976   /* send */
17977   S (mp);
17978
17979   /* wait for reply */
17980   W (ret);
17981   return ret;
17982 }
17983
17984 static int
17985 api_one_ndp_bd_get (vat_main_t * vam)
17986 {
17987   vl_api_one_ndp_bd_get_t *mp;
17988   int ret;
17989
17990   M (ONE_NDP_BD_GET, mp);
17991
17992   /* send */
17993   S (mp);
17994
17995   /* wait for reply */
17996   W (ret);
17997   return ret;
17998 }
17999
18000 static int
18001 api_one_ndp_entries_get (vat_main_t * vam)
18002 {
18003   vl_api_one_ndp_entries_get_t *mp;
18004   unformat_input_t *input = vam->input;
18005   u8 bd_set = 0;
18006   u32 bd = ~0;
18007   int ret;
18008
18009   /* Parse args required to build the message */
18010   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18011     {
18012       if (unformat (input, "bd %d", &bd))
18013         bd_set = 1;
18014       else
18015         {
18016           errmsg ("parse error '%U'", format_unformat_error, input);
18017           return -99;
18018         }
18019     }
18020
18021   if (!bd_set)
18022     {
18023       errmsg ("Expected bridge domain!");
18024       return -99;
18025     }
18026
18027   M (ONE_NDP_ENTRIES_GET, mp);
18028   mp->bd = clib_host_to_net_u32 (bd);
18029
18030   /* send */
18031   S (mp);
18032
18033   /* wait for reply */
18034   W (ret);
18035   return ret;
18036 }
18037
18038 static int
18039 api_one_l2_arp_bd_get (vat_main_t * vam)
18040 {
18041   vl_api_one_l2_arp_bd_get_t *mp;
18042   int ret;
18043
18044   M (ONE_L2_ARP_BD_GET, mp);
18045
18046   /* send */
18047   S (mp);
18048
18049   /* wait for reply */
18050   W (ret);
18051   return ret;
18052 }
18053
18054 static int
18055 api_one_l2_arp_entries_get (vat_main_t * vam)
18056 {
18057   vl_api_one_l2_arp_entries_get_t *mp;
18058   unformat_input_t *input = vam->input;
18059   u8 bd_set = 0;
18060   u32 bd = ~0;
18061   int ret;
18062
18063   /* Parse args required to build the message */
18064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18065     {
18066       if (unformat (input, "bd %d", &bd))
18067         bd_set = 1;
18068       else
18069         {
18070           errmsg ("parse error '%U'", format_unformat_error, input);
18071           return -99;
18072         }
18073     }
18074
18075   if (!bd_set)
18076     {
18077       errmsg ("Expected bridge domain!");
18078       return -99;
18079     }
18080
18081   M (ONE_L2_ARP_ENTRIES_GET, mp);
18082   mp->bd = clib_host_to_net_u32 (bd);
18083
18084   /* send */
18085   S (mp);
18086
18087   /* wait for reply */
18088   W (ret);
18089   return ret;
18090 }
18091
18092 static int
18093 api_one_stats_enable_disable (vat_main_t * vam)
18094 {
18095   vl_api_one_stats_enable_disable_t *mp;
18096   unformat_input_t *input = vam->input;
18097   u8 is_set = 0;
18098   u8 is_en = 0;
18099   int ret;
18100
18101   /* Parse args required to build the message */
18102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18103     {
18104       if (unformat (input, "enable"))
18105         {
18106           is_set = 1;
18107           is_en = 1;
18108         }
18109       else if (unformat (input, "disable"))
18110         {
18111           is_set = 1;
18112         }
18113       else
18114         break;
18115     }
18116
18117   if (!is_set)
18118     {
18119       errmsg ("Value not set");
18120       return -99;
18121     }
18122
18123   M (ONE_STATS_ENABLE_DISABLE, mp);
18124   mp->is_en = is_en;
18125
18126   /* send */
18127   S (mp);
18128
18129   /* wait for reply */
18130   W (ret);
18131   return ret;
18132 }
18133
18134 static int
18135 api_show_one_stats_enable_disable (vat_main_t * vam)
18136 {
18137   vl_api_show_one_stats_enable_disable_t *mp;
18138   int ret;
18139
18140   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18141
18142   /* send */
18143   S (mp);
18144
18145   /* wait for reply */
18146   W (ret);
18147   return ret;
18148 }
18149
18150 static int
18151 api_show_one_map_request_mode (vat_main_t * vam)
18152 {
18153   vl_api_show_one_map_request_mode_t *mp;
18154   int ret;
18155
18156   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18157
18158   /* send */
18159   S (mp);
18160
18161   /* wait for reply */
18162   W (ret);
18163   return ret;
18164 }
18165
18166 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18167
18168 static int
18169 api_one_map_request_mode (vat_main_t * vam)
18170 {
18171   unformat_input_t *input = vam->input;
18172   vl_api_one_map_request_mode_t *mp;
18173   u8 mode = 0;
18174   int ret;
18175
18176   /* Parse args required to build the message */
18177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18178     {
18179       if (unformat (input, "dst-only"))
18180         mode = 0;
18181       else if (unformat (input, "src-dst"))
18182         mode = 1;
18183       else
18184         {
18185           errmsg ("parse error '%U'", format_unformat_error, input);
18186           return -99;
18187         }
18188     }
18189
18190   M (ONE_MAP_REQUEST_MODE, mp);
18191
18192   mp->mode = mode;
18193
18194   /* send */
18195   S (mp);
18196
18197   /* wait for reply */
18198   W (ret);
18199   return ret;
18200 }
18201
18202 #define api_lisp_map_request_mode api_one_map_request_mode
18203
18204 /**
18205  * Enable/disable ONE proxy ITR.
18206  *
18207  * @param vam vpp API test context
18208  * @return return code
18209  */
18210 static int
18211 api_one_pitr_set_locator_set (vat_main_t * vam)
18212 {
18213   u8 ls_name_set = 0;
18214   unformat_input_t *input = vam->input;
18215   vl_api_one_pitr_set_locator_set_t *mp;
18216   u8 is_add = 1;
18217   u8 *ls_name = 0;
18218   int ret;
18219
18220   /* Parse args required to build the message */
18221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18222     {
18223       if (unformat (input, "del"))
18224         is_add = 0;
18225       else if (unformat (input, "locator-set %s", &ls_name))
18226         ls_name_set = 1;
18227       else
18228         {
18229           errmsg ("parse error '%U'", format_unformat_error, input);
18230           return -99;
18231         }
18232     }
18233
18234   if (!ls_name_set)
18235     {
18236       errmsg ("locator-set name not set!");
18237       return -99;
18238     }
18239
18240   M (ONE_PITR_SET_LOCATOR_SET, mp);
18241
18242   mp->is_add = is_add;
18243   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18244   vec_free (ls_name);
18245
18246   /* send */
18247   S (mp);
18248
18249   /* wait for reply */
18250   W (ret);
18251   return ret;
18252 }
18253
18254 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18255
18256 static int
18257 api_one_nsh_set_locator_set (vat_main_t * vam)
18258 {
18259   u8 ls_name_set = 0;
18260   unformat_input_t *input = vam->input;
18261   vl_api_one_nsh_set_locator_set_t *mp;
18262   u8 is_add = 1;
18263   u8 *ls_name = 0;
18264   int ret;
18265
18266   /* Parse args required to build the message */
18267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18268     {
18269       if (unformat (input, "del"))
18270         is_add = 0;
18271       else if (unformat (input, "ls %s", &ls_name))
18272         ls_name_set = 1;
18273       else
18274         {
18275           errmsg ("parse error '%U'", format_unformat_error, input);
18276           return -99;
18277         }
18278     }
18279
18280   if (!ls_name_set && is_add)
18281     {
18282       errmsg ("locator-set name not set!");
18283       return -99;
18284     }
18285
18286   M (ONE_NSH_SET_LOCATOR_SET, mp);
18287
18288   mp->is_add = is_add;
18289   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18290   vec_free (ls_name);
18291
18292   /* send */
18293   S (mp);
18294
18295   /* wait for reply */
18296   W (ret);
18297   return ret;
18298 }
18299
18300 static int
18301 api_show_one_pitr (vat_main_t * vam)
18302 {
18303   vl_api_show_one_pitr_t *mp;
18304   int ret;
18305
18306   if (!vam->json_output)
18307     {
18308       print (vam->ofp, "%=20s", "lisp status:");
18309     }
18310
18311   M (SHOW_ONE_PITR, mp);
18312   /* send it... */
18313   S (mp);
18314
18315   /* Wait for a reply... */
18316   W (ret);
18317   return ret;
18318 }
18319
18320 #define api_show_lisp_pitr api_show_one_pitr
18321
18322 static int
18323 api_one_use_petr (vat_main_t * vam)
18324 {
18325   unformat_input_t *input = vam->input;
18326   vl_api_one_use_petr_t *mp;
18327   u8 is_add = 0;
18328   ip_address_t ip;
18329   int ret;
18330
18331   memset (&ip, 0, sizeof (ip));
18332
18333   /* Parse args required to build the message */
18334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18335     {
18336       if (unformat (input, "disable"))
18337         is_add = 0;
18338       else
18339         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18340         {
18341           is_add = 1;
18342           ip_addr_version (&ip) = IP4;
18343         }
18344       else
18345         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18346         {
18347           is_add = 1;
18348           ip_addr_version (&ip) = IP6;
18349         }
18350       else
18351         {
18352           errmsg ("parse error '%U'", format_unformat_error, input);
18353           return -99;
18354         }
18355     }
18356
18357   M (ONE_USE_PETR, mp);
18358
18359   mp->is_add = is_add;
18360   if (is_add)
18361     {
18362       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18363       if (mp->is_ip4)
18364         clib_memcpy (mp->address, &ip, 4);
18365       else
18366         clib_memcpy (mp->address, &ip, 16);
18367     }
18368
18369   /* send */
18370   S (mp);
18371
18372   /* wait for reply */
18373   W (ret);
18374   return ret;
18375 }
18376
18377 #define api_lisp_use_petr api_one_use_petr
18378
18379 static int
18380 api_show_one_nsh_mapping (vat_main_t * vam)
18381 {
18382   vl_api_show_one_use_petr_t *mp;
18383   int ret;
18384
18385   if (!vam->json_output)
18386     {
18387       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18388     }
18389
18390   M (SHOW_ONE_NSH_MAPPING, mp);
18391   /* send it... */
18392   S (mp);
18393
18394   /* Wait for a reply... */
18395   W (ret);
18396   return ret;
18397 }
18398
18399 static int
18400 api_show_one_use_petr (vat_main_t * vam)
18401 {
18402   vl_api_show_one_use_petr_t *mp;
18403   int ret;
18404
18405   if (!vam->json_output)
18406     {
18407       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18408     }
18409
18410   M (SHOW_ONE_USE_PETR, mp);
18411   /* send it... */
18412   S (mp);
18413
18414   /* Wait for a reply... */
18415   W (ret);
18416   return ret;
18417 }
18418
18419 #define api_show_lisp_use_petr api_show_one_use_petr
18420
18421 /**
18422  * Add/delete mapping between vni and vrf
18423  */
18424 static int
18425 api_one_eid_table_add_del_map (vat_main_t * vam)
18426 {
18427   unformat_input_t *input = vam->input;
18428   vl_api_one_eid_table_add_del_map_t *mp;
18429   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18430   u32 vni, vrf, bd_index;
18431   int ret;
18432
18433   /* Parse args required to build the message */
18434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18435     {
18436       if (unformat (input, "del"))
18437         is_add = 0;
18438       else if (unformat (input, "vrf %d", &vrf))
18439         vrf_set = 1;
18440       else if (unformat (input, "bd_index %d", &bd_index))
18441         bd_index_set = 1;
18442       else if (unformat (input, "vni %d", &vni))
18443         vni_set = 1;
18444       else
18445         break;
18446     }
18447
18448   if (!vni_set || (!vrf_set && !bd_index_set))
18449     {
18450       errmsg ("missing arguments!");
18451       return -99;
18452     }
18453
18454   if (vrf_set && bd_index_set)
18455     {
18456       errmsg ("error: both vrf and bd entered!");
18457       return -99;
18458     }
18459
18460   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18461
18462   mp->is_add = is_add;
18463   mp->vni = htonl (vni);
18464   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18465   mp->is_l2 = bd_index_set;
18466
18467   /* send */
18468   S (mp);
18469
18470   /* wait for reply */
18471   W (ret);
18472   return ret;
18473 }
18474
18475 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18476
18477 uword
18478 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18479 {
18480   u32 *action = va_arg (*args, u32 *);
18481   u8 *s = 0;
18482
18483   if (unformat (input, "%s", &s))
18484     {
18485       if (!strcmp ((char *) s, "no-action"))
18486         action[0] = 0;
18487       else if (!strcmp ((char *) s, "natively-forward"))
18488         action[0] = 1;
18489       else if (!strcmp ((char *) s, "send-map-request"))
18490         action[0] = 2;
18491       else if (!strcmp ((char *) s, "drop"))
18492         action[0] = 3;
18493       else
18494         {
18495           clib_warning ("invalid action: '%s'", s);
18496           action[0] = 3;
18497         }
18498     }
18499   else
18500     return 0;
18501
18502   vec_free (s);
18503   return 1;
18504 }
18505
18506 /**
18507  * Add/del remote mapping to/from ONE control plane
18508  *
18509  * @param vam vpp API test context
18510  * @return return code
18511  */
18512 static int
18513 api_one_add_del_remote_mapping (vat_main_t * vam)
18514 {
18515   unformat_input_t *input = vam->input;
18516   vl_api_one_add_del_remote_mapping_t *mp;
18517   u32 vni = 0;
18518   lisp_eid_vat_t _eid, *eid = &_eid;
18519   lisp_eid_vat_t _seid, *seid = &_seid;
18520   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18521   u32 action = ~0, p, w, data_len;
18522   ip4_address_t rloc4;
18523   ip6_address_t rloc6;
18524   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18525   int ret;
18526
18527   memset (&rloc, 0, sizeof (rloc));
18528
18529   /* Parse args required to build the message */
18530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18531     {
18532       if (unformat (input, "del-all"))
18533         {
18534           del_all = 1;
18535         }
18536       else if (unformat (input, "del"))
18537         {
18538           is_add = 0;
18539         }
18540       else if (unformat (input, "add"))
18541         {
18542           is_add = 1;
18543         }
18544       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18545         {
18546           eid_set = 1;
18547         }
18548       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18549         {
18550           seid_set = 1;
18551         }
18552       else if (unformat (input, "vni %d", &vni))
18553         {
18554           ;
18555         }
18556       else if (unformat (input, "p %d w %d", &p, &w))
18557         {
18558           if (!curr_rloc)
18559             {
18560               errmsg ("No RLOC configured for setting priority/weight!");
18561               return -99;
18562             }
18563           curr_rloc->priority = p;
18564           curr_rloc->weight = w;
18565         }
18566       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18567         {
18568           rloc.is_ip4 = 1;
18569           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18570           vec_add1 (rlocs, rloc);
18571           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18572         }
18573       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18574         {
18575           rloc.is_ip4 = 0;
18576           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18577           vec_add1 (rlocs, rloc);
18578           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18579         }
18580       else if (unformat (input, "action %U",
18581                          unformat_negative_mapping_action, &action))
18582         {
18583           ;
18584         }
18585       else
18586         {
18587           clib_warning ("parse error '%U'", format_unformat_error, input);
18588           return -99;
18589         }
18590     }
18591
18592   if (0 == eid_set)
18593     {
18594       errmsg ("missing params!");
18595       return -99;
18596     }
18597
18598   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18599     {
18600       errmsg ("no action set for negative map-reply!");
18601       return -99;
18602     }
18603
18604   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18605
18606   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18607   mp->is_add = is_add;
18608   mp->vni = htonl (vni);
18609   mp->action = (u8) action;
18610   mp->is_src_dst = seid_set;
18611   mp->eid_len = eid->len;
18612   mp->seid_len = seid->len;
18613   mp->del_all = del_all;
18614   mp->eid_type = eid->type;
18615   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18616   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18617
18618   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18619   clib_memcpy (mp->rlocs, rlocs, data_len);
18620   vec_free (rlocs);
18621
18622   /* send it... */
18623   S (mp);
18624
18625   /* Wait for a reply... */
18626   W (ret);
18627   return ret;
18628 }
18629
18630 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18631
18632 /**
18633  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18634  * forwarding entries in data-plane accordingly.
18635  *
18636  * @param vam vpp API test context
18637  * @return return code
18638  */
18639 static int
18640 api_one_add_del_adjacency (vat_main_t * vam)
18641 {
18642   unformat_input_t *input = vam->input;
18643   vl_api_one_add_del_adjacency_t *mp;
18644   u32 vni = 0;
18645   ip4_address_t leid4, reid4;
18646   ip6_address_t leid6, reid6;
18647   u8 reid_mac[6] = { 0 };
18648   u8 leid_mac[6] = { 0 };
18649   u8 reid_type, leid_type;
18650   u32 leid_len = 0, reid_len = 0, len;
18651   u8 is_add = 1;
18652   int ret;
18653
18654   leid_type = reid_type = (u8) ~ 0;
18655
18656   /* Parse args required to build the message */
18657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18658     {
18659       if (unformat (input, "del"))
18660         {
18661           is_add = 0;
18662         }
18663       else if (unformat (input, "add"))
18664         {
18665           is_add = 1;
18666         }
18667       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18668                          &reid4, &len))
18669         {
18670           reid_type = 0;        /* ipv4 */
18671           reid_len = len;
18672         }
18673       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18674                          &reid6, &len))
18675         {
18676           reid_type = 1;        /* ipv6 */
18677           reid_len = len;
18678         }
18679       else if (unformat (input, "reid %U", unformat_ethernet_address,
18680                          reid_mac))
18681         {
18682           reid_type = 2;        /* mac */
18683         }
18684       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18685                          &leid4, &len))
18686         {
18687           leid_type = 0;        /* ipv4 */
18688           leid_len = len;
18689         }
18690       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18691                          &leid6, &len))
18692         {
18693           leid_type = 1;        /* ipv6 */
18694           leid_len = len;
18695         }
18696       else if (unformat (input, "leid %U", unformat_ethernet_address,
18697                          leid_mac))
18698         {
18699           leid_type = 2;        /* mac */
18700         }
18701       else if (unformat (input, "vni %d", &vni))
18702         {
18703           ;
18704         }
18705       else
18706         {
18707           errmsg ("parse error '%U'", format_unformat_error, input);
18708           return -99;
18709         }
18710     }
18711
18712   if ((u8) ~ 0 == reid_type)
18713     {
18714       errmsg ("missing params!");
18715       return -99;
18716     }
18717
18718   if (leid_type != reid_type)
18719     {
18720       errmsg ("remote and local EIDs are of different types!");
18721       return -99;
18722     }
18723
18724   M (ONE_ADD_DEL_ADJACENCY, mp);
18725   mp->is_add = is_add;
18726   mp->vni = htonl (vni);
18727   mp->leid_len = leid_len;
18728   mp->reid_len = reid_len;
18729   mp->eid_type = reid_type;
18730
18731   switch (mp->eid_type)
18732     {
18733     case 0:
18734       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18735       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18736       break;
18737     case 1:
18738       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18739       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18740       break;
18741     case 2:
18742       clib_memcpy (mp->leid, leid_mac, 6);
18743       clib_memcpy (mp->reid, reid_mac, 6);
18744       break;
18745     default:
18746       errmsg ("unknown EID type %d!", mp->eid_type);
18747       return 0;
18748     }
18749
18750   /* send it... */
18751   S (mp);
18752
18753   /* Wait for a reply... */
18754   W (ret);
18755   return ret;
18756 }
18757
18758 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18759
18760 uword
18761 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18762 {
18763   u32 *mode = va_arg (*args, u32 *);
18764
18765   if (unformat (input, "lisp"))
18766     *mode = 0;
18767   else if (unformat (input, "vxlan"))
18768     *mode = 1;
18769   else
18770     return 0;
18771
18772   return 1;
18773 }
18774
18775 static int
18776 api_gpe_get_encap_mode (vat_main_t * vam)
18777 {
18778   vl_api_gpe_get_encap_mode_t *mp;
18779   int ret;
18780
18781   /* Construct the API message */
18782   M (GPE_GET_ENCAP_MODE, mp);
18783
18784   /* send it... */
18785   S (mp);
18786
18787   /* Wait for a reply... */
18788   W (ret);
18789   return ret;
18790 }
18791
18792 static int
18793 api_gpe_set_encap_mode (vat_main_t * vam)
18794 {
18795   unformat_input_t *input = vam->input;
18796   vl_api_gpe_set_encap_mode_t *mp;
18797   int ret;
18798   u32 mode = 0;
18799
18800   /* Parse args required to build the message */
18801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18802     {
18803       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18804         ;
18805       else
18806         break;
18807     }
18808
18809   /* Construct the API message */
18810   M (GPE_SET_ENCAP_MODE, mp);
18811
18812   mp->mode = mode;
18813
18814   /* send it... */
18815   S (mp);
18816
18817   /* Wait for a reply... */
18818   W (ret);
18819   return ret;
18820 }
18821
18822 static int
18823 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18824 {
18825   unformat_input_t *input = vam->input;
18826   vl_api_gpe_add_del_iface_t *mp;
18827   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18828   u32 dp_table = 0, vni = 0;
18829   int ret;
18830
18831   /* Parse args required to build the message */
18832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18833     {
18834       if (unformat (input, "up"))
18835         {
18836           action_set = 1;
18837           is_add = 1;
18838         }
18839       else if (unformat (input, "down"))
18840         {
18841           action_set = 1;
18842           is_add = 0;
18843         }
18844       else if (unformat (input, "table_id %d", &dp_table))
18845         {
18846           dp_table_set = 1;
18847         }
18848       else if (unformat (input, "bd_id %d", &dp_table))
18849         {
18850           dp_table_set = 1;
18851           is_l2 = 1;
18852         }
18853       else if (unformat (input, "vni %d", &vni))
18854         {
18855           vni_set = 1;
18856         }
18857       else
18858         break;
18859     }
18860
18861   if (action_set == 0)
18862     {
18863       errmsg ("Action not set");
18864       return -99;
18865     }
18866   if (dp_table_set == 0 || vni_set == 0)
18867     {
18868       errmsg ("vni and dp_table must be set");
18869       return -99;
18870     }
18871
18872   /* Construct the API message */
18873   M (GPE_ADD_DEL_IFACE, mp);
18874
18875   mp->is_add = is_add;
18876   mp->dp_table = clib_host_to_net_u32 (dp_table);
18877   mp->is_l2 = is_l2;
18878   mp->vni = clib_host_to_net_u32 (vni);
18879
18880   /* send it... */
18881   S (mp);
18882
18883   /* Wait for a reply... */
18884   W (ret);
18885   return ret;
18886 }
18887
18888 static int
18889 api_one_map_register_fallback_threshold (vat_main_t * vam)
18890 {
18891   unformat_input_t *input = vam->input;
18892   vl_api_one_map_register_fallback_threshold_t *mp;
18893   u32 value = 0;
18894   u8 is_set = 0;
18895   int ret;
18896
18897   /* Parse args required to build the message */
18898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18899     {
18900       if (unformat (input, "%u", &value))
18901         is_set = 1;
18902       else
18903         {
18904           clib_warning ("parse error '%U'", format_unformat_error, input);
18905           return -99;
18906         }
18907     }
18908
18909   if (!is_set)
18910     {
18911       errmsg ("fallback threshold value is missing!");
18912       return -99;
18913     }
18914
18915   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18916   mp->value = clib_host_to_net_u32 (value);
18917
18918   /* send it... */
18919   S (mp);
18920
18921   /* Wait for a reply... */
18922   W (ret);
18923   return ret;
18924 }
18925
18926 static int
18927 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18928 {
18929   vl_api_show_one_map_register_fallback_threshold_t *mp;
18930   int ret;
18931
18932   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18933
18934   /* send it... */
18935   S (mp);
18936
18937   /* Wait for a reply... */
18938   W (ret);
18939   return ret;
18940 }
18941
18942 uword
18943 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18944 {
18945   u32 *proto = va_arg (*args, u32 *);
18946
18947   if (unformat (input, "udp"))
18948     *proto = 1;
18949   else if (unformat (input, "api"))
18950     *proto = 2;
18951   else
18952     return 0;
18953
18954   return 1;
18955 }
18956
18957 static int
18958 api_one_set_transport_protocol (vat_main_t * vam)
18959 {
18960   unformat_input_t *input = vam->input;
18961   vl_api_one_set_transport_protocol_t *mp;
18962   u8 is_set = 0;
18963   u32 protocol = 0;
18964   int ret;
18965
18966   /* Parse args required to build the message */
18967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18968     {
18969       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18970         is_set = 1;
18971       else
18972         {
18973           clib_warning ("parse error '%U'", format_unformat_error, input);
18974           return -99;
18975         }
18976     }
18977
18978   if (!is_set)
18979     {
18980       errmsg ("Transport protocol missing!");
18981       return -99;
18982     }
18983
18984   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18985   mp->protocol = (u8) protocol;
18986
18987   /* send it... */
18988   S (mp);
18989
18990   /* Wait for a reply... */
18991   W (ret);
18992   return ret;
18993 }
18994
18995 static int
18996 api_one_get_transport_protocol (vat_main_t * vam)
18997 {
18998   vl_api_one_get_transport_protocol_t *mp;
18999   int ret;
19000
19001   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19002
19003   /* send it... */
19004   S (mp);
19005
19006   /* Wait for a reply... */
19007   W (ret);
19008   return ret;
19009 }
19010
19011 static int
19012 api_one_map_register_set_ttl (vat_main_t * vam)
19013 {
19014   unformat_input_t *input = vam->input;
19015   vl_api_one_map_register_set_ttl_t *mp;
19016   u32 ttl = 0;
19017   u8 is_set = 0;
19018   int ret;
19019
19020   /* Parse args required to build the message */
19021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19022     {
19023       if (unformat (input, "%u", &ttl))
19024         is_set = 1;
19025       else
19026         {
19027           clib_warning ("parse error '%U'", format_unformat_error, input);
19028           return -99;
19029         }
19030     }
19031
19032   if (!is_set)
19033     {
19034       errmsg ("TTL value missing!");
19035       return -99;
19036     }
19037
19038   M (ONE_MAP_REGISTER_SET_TTL, mp);
19039   mp->ttl = clib_host_to_net_u32 (ttl);
19040
19041   /* send it... */
19042   S (mp);
19043
19044   /* Wait for a reply... */
19045   W (ret);
19046   return ret;
19047 }
19048
19049 static int
19050 api_show_one_map_register_ttl (vat_main_t * vam)
19051 {
19052   vl_api_show_one_map_register_ttl_t *mp;
19053   int ret;
19054
19055   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19056
19057   /* send it... */
19058   S (mp);
19059
19060   /* Wait for a reply... */
19061   W (ret);
19062   return ret;
19063 }
19064
19065 /**
19066  * Add/del map request itr rlocs from ONE control plane and updates
19067  *
19068  * @param vam vpp API test context
19069  * @return return code
19070  */
19071 static int
19072 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19073 {
19074   unformat_input_t *input = vam->input;
19075   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19076   u8 *locator_set_name = 0;
19077   u8 locator_set_name_set = 0;
19078   u8 is_add = 1;
19079   int ret;
19080
19081   /* Parse args required to build the message */
19082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19083     {
19084       if (unformat (input, "del"))
19085         {
19086           is_add = 0;
19087         }
19088       else if (unformat (input, "%_%v%_", &locator_set_name))
19089         {
19090           locator_set_name_set = 1;
19091         }
19092       else
19093         {
19094           clib_warning ("parse error '%U'", format_unformat_error, input);
19095           return -99;
19096         }
19097     }
19098
19099   if (is_add && !locator_set_name_set)
19100     {
19101       errmsg ("itr-rloc is not set!");
19102       return -99;
19103     }
19104
19105   if (is_add && vec_len (locator_set_name) > 64)
19106     {
19107       errmsg ("itr-rloc locator-set name too long");
19108       vec_free (locator_set_name);
19109       return -99;
19110     }
19111
19112   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19113   mp->is_add = is_add;
19114   if (is_add)
19115     {
19116       clib_memcpy (mp->locator_set_name, locator_set_name,
19117                    vec_len (locator_set_name));
19118     }
19119   else
19120     {
19121       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19122     }
19123   vec_free (locator_set_name);
19124
19125   /* send it... */
19126   S (mp);
19127
19128   /* Wait for a reply... */
19129   W (ret);
19130   return ret;
19131 }
19132
19133 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19134
19135 static int
19136 api_one_locator_dump (vat_main_t * vam)
19137 {
19138   unformat_input_t *input = vam->input;
19139   vl_api_one_locator_dump_t *mp;
19140   vl_api_control_ping_t *mp_ping;
19141   u8 is_index_set = 0, is_name_set = 0;
19142   u8 *ls_name = 0;
19143   u32 ls_index = ~0;
19144   int ret;
19145
19146   /* Parse args required to build the message */
19147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19148     {
19149       if (unformat (input, "ls_name %_%v%_", &ls_name))
19150         {
19151           is_name_set = 1;
19152         }
19153       else if (unformat (input, "ls_index %d", &ls_index))
19154         {
19155           is_index_set = 1;
19156         }
19157       else
19158         {
19159           errmsg ("parse error '%U'", format_unformat_error, input);
19160           return -99;
19161         }
19162     }
19163
19164   if (!is_index_set && !is_name_set)
19165     {
19166       errmsg ("error: expected one of index or name!");
19167       return -99;
19168     }
19169
19170   if (is_index_set && is_name_set)
19171     {
19172       errmsg ("error: only one param expected!");
19173       return -99;
19174     }
19175
19176   if (vec_len (ls_name) > 62)
19177     {
19178       errmsg ("error: locator set name too long!");
19179       return -99;
19180     }
19181
19182   if (!vam->json_output)
19183     {
19184       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19185     }
19186
19187   M (ONE_LOCATOR_DUMP, mp);
19188   mp->is_index_set = is_index_set;
19189
19190   if (is_index_set)
19191     mp->ls_index = clib_host_to_net_u32 (ls_index);
19192   else
19193     {
19194       vec_add1 (ls_name, 0);
19195       strncpy ((char *) mp->ls_name, (char *) ls_name,
19196                sizeof (mp->ls_name) - 1);
19197     }
19198
19199   /* send it... */
19200   S (mp);
19201
19202   /* Use a control ping for synchronization */
19203   MPING (CONTROL_PING, mp_ping);
19204   S (mp_ping);
19205
19206   /* Wait for a reply... */
19207   W (ret);
19208   return ret;
19209 }
19210
19211 #define api_lisp_locator_dump api_one_locator_dump
19212
19213 static int
19214 api_one_locator_set_dump (vat_main_t * vam)
19215 {
19216   vl_api_one_locator_set_dump_t *mp;
19217   vl_api_control_ping_t *mp_ping;
19218   unformat_input_t *input = vam->input;
19219   u8 filter = 0;
19220   int ret;
19221
19222   /* Parse args required to build the message */
19223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19224     {
19225       if (unformat (input, "local"))
19226         {
19227           filter = 1;
19228         }
19229       else if (unformat (input, "remote"))
19230         {
19231           filter = 2;
19232         }
19233       else
19234         {
19235           errmsg ("parse error '%U'", format_unformat_error, input);
19236           return -99;
19237         }
19238     }
19239
19240   if (!vam->json_output)
19241     {
19242       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19243     }
19244
19245   M (ONE_LOCATOR_SET_DUMP, mp);
19246
19247   mp->filter = filter;
19248
19249   /* send it... */
19250   S (mp);
19251
19252   /* Use a control ping for synchronization */
19253   MPING (CONTROL_PING, mp_ping);
19254   S (mp_ping);
19255
19256   /* Wait for a reply... */
19257   W (ret);
19258   return ret;
19259 }
19260
19261 #define api_lisp_locator_set_dump api_one_locator_set_dump
19262
19263 static int
19264 api_one_eid_table_map_dump (vat_main_t * vam)
19265 {
19266   u8 is_l2 = 0;
19267   u8 mode_set = 0;
19268   unformat_input_t *input = vam->input;
19269   vl_api_one_eid_table_map_dump_t *mp;
19270   vl_api_control_ping_t *mp_ping;
19271   int ret;
19272
19273   /* Parse args required to build the message */
19274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19275     {
19276       if (unformat (input, "l2"))
19277         {
19278           is_l2 = 1;
19279           mode_set = 1;
19280         }
19281       else if (unformat (input, "l3"))
19282         {
19283           is_l2 = 0;
19284           mode_set = 1;
19285         }
19286       else
19287         {
19288           errmsg ("parse error '%U'", format_unformat_error, input);
19289           return -99;
19290         }
19291     }
19292
19293   if (!mode_set)
19294     {
19295       errmsg ("expected one of 'l2' or 'l3' parameter!");
19296       return -99;
19297     }
19298
19299   if (!vam->json_output)
19300     {
19301       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19302     }
19303
19304   M (ONE_EID_TABLE_MAP_DUMP, mp);
19305   mp->is_l2 = is_l2;
19306
19307   /* send it... */
19308   S (mp);
19309
19310   /* Use a control ping for synchronization */
19311   MPING (CONTROL_PING, mp_ping);
19312   S (mp_ping);
19313
19314   /* Wait for a reply... */
19315   W (ret);
19316   return ret;
19317 }
19318
19319 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19320
19321 static int
19322 api_one_eid_table_vni_dump (vat_main_t * vam)
19323 {
19324   vl_api_one_eid_table_vni_dump_t *mp;
19325   vl_api_control_ping_t *mp_ping;
19326   int ret;
19327
19328   if (!vam->json_output)
19329     {
19330       print (vam->ofp, "VNI");
19331     }
19332
19333   M (ONE_EID_TABLE_VNI_DUMP, mp);
19334
19335   /* send it... */
19336   S (mp);
19337
19338   /* Use a control ping for synchronization */
19339   MPING (CONTROL_PING, mp_ping);
19340   S (mp_ping);
19341
19342   /* Wait for a reply... */
19343   W (ret);
19344   return ret;
19345 }
19346
19347 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19348
19349 static int
19350 api_one_eid_table_dump (vat_main_t * vam)
19351 {
19352   unformat_input_t *i = vam->input;
19353   vl_api_one_eid_table_dump_t *mp;
19354   vl_api_control_ping_t *mp_ping;
19355   struct in_addr ip4;
19356   struct in6_addr ip6;
19357   u8 mac[6];
19358   u8 eid_type = ~0, eid_set = 0;
19359   u32 prefix_length = ~0, t, vni = 0;
19360   u8 filter = 0;
19361   int ret;
19362   lisp_nsh_api_t nsh;
19363
19364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19365     {
19366       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19367         {
19368           eid_set = 1;
19369           eid_type = 0;
19370           prefix_length = t;
19371         }
19372       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19373         {
19374           eid_set = 1;
19375           eid_type = 1;
19376           prefix_length = t;
19377         }
19378       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19379         {
19380           eid_set = 1;
19381           eid_type = 2;
19382         }
19383       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19384         {
19385           eid_set = 1;
19386           eid_type = 3;
19387         }
19388       else if (unformat (i, "vni %d", &t))
19389         {
19390           vni = t;
19391         }
19392       else if (unformat (i, "local"))
19393         {
19394           filter = 1;
19395         }
19396       else if (unformat (i, "remote"))
19397         {
19398           filter = 2;
19399         }
19400       else
19401         {
19402           errmsg ("parse error '%U'", format_unformat_error, i);
19403           return -99;
19404         }
19405     }
19406
19407   if (!vam->json_output)
19408     {
19409       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19410              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19411     }
19412
19413   M (ONE_EID_TABLE_DUMP, mp);
19414
19415   mp->filter = filter;
19416   if (eid_set)
19417     {
19418       mp->eid_set = 1;
19419       mp->vni = htonl (vni);
19420       mp->eid_type = eid_type;
19421       switch (eid_type)
19422         {
19423         case 0:
19424           mp->prefix_length = prefix_length;
19425           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19426           break;
19427         case 1:
19428           mp->prefix_length = prefix_length;
19429           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19430           break;
19431         case 2:
19432           clib_memcpy (mp->eid, mac, sizeof (mac));
19433           break;
19434         case 3:
19435           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19436           break;
19437         default:
19438           errmsg ("unknown EID type %d!", eid_type);
19439           return -99;
19440         }
19441     }
19442
19443   /* send it... */
19444   S (mp);
19445
19446   /* Use a control ping for synchronization */
19447   MPING (CONTROL_PING, mp_ping);
19448   S (mp_ping);
19449
19450   /* Wait for a reply... */
19451   W (ret);
19452   return ret;
19453 }
19454
19455 #define api_lisp_eid_table_dump api_one_eid_table_dump
19456
19457 static int
19458 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19459 {
19460   unformat_input_t *i = vam->input;
19461   vl_api_gpe_fwd_entries_get_t *mp;
19462   u8 vni_set = 0;
19463   u32 vni = ~0;
19464   int ret;
19465
19466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19467     {
19468       if (unformat (i, "vni %d", &vni))
19469         {
19470           vni_set = 1;
19471         }
19472       else
19473         {
19474           errmsg ("parse error '%U'", format_unformat_error, i);
19475           return -99;
19476         }
19477     }
19478
19479   if (!vni_set)
19480     {
19481       errmsg ("vni not set!");
19482       return -99;
19483     }
19484
19485   if (!vam->json_output)
19486     {
19487       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19488              "leid", "reid");
19489     }
19490
19491   M (GPE_FWD_ENTRIES_GET, mp);
19492   mp->vni = clib_host_to_net_u32 (vni);
19493
19494   /* send it... */
19495   S (mp);
19496
19497   /* Wait for a reply... */
19498   W (ret);
19499   return ret;
19500 }
19501
19502 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19503 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19504 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19505 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19506 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19507 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19508 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19509 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19510
19511 static int
19512 api_one_adjacencies_get (vat_main_t * vam)
19513 {
19514   unformat_input_t *i = vam->input;
19515   vl_api_one_adjacencies_get_t *mp;
19516   u8 vni_set = 0;
19517   u32 vni = ~0;
19518   int ret;
19519
19520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19521     {
19522       if (unformat (i, "vni %d", &vni))
19523         {
19524           vni_set = 1;
19525         }
19526       else
19527         {
19528           errmsg ("parse error '%U'", format_unformat_error, i);
19529           return -99;
19530         }
19531     }
19532
19533   if (!vni_set)
19534     {
19535       errmsg ("vni not set!");
19536       return -99;
19537     }
19538
19539   if (!vam->json_output)
19540     {
19541       print (vam->ofp, "%s %40s", "leid", "reid");
19542     }
19543
19544   M (ONE_ADJACENCIES_GET, mp);
19545   mp->vni = clib_host_to_net_u32 (vni);
19546
19547   /* send it... */
19548   S (mp);
19549
19550   /* Wait for a reply... */
19551   W (ret);
19552   return ret;
19553 }
19554
19555 #define api_lisp_adjacencies_get api_one_adjacencies_get
19556
19557 static int
19558 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19559 {
19560   unformat_input_t *i = vam->input;
19561   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19562   int ret;
19563   u8 ip_family_set = 0, is_ip4 = 1;
19564
19565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19566     {
19567       if (unformat (i, "ip4"))
19568         {
19569           ip_family_set = 1;
19570           is_ip4 = 1;
19571         }
19572       else if (unformat (i, "ip6"))
19573         {
19574           ip_family_set = 1;
19575           is_ip4 = 0;
19576         }
19577       else
19578         {
19579           errmsg ("parse error '%U'", format_unformat_error, i);
19580           return -99;
19581         }
19582     }
19583
19584   if (!ip_family_set)
19585     {
19586       errmsg ("ip family not set!");
19587       return -99;
19588     }
19589
19590   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19591   mp->is_ip4 = is_ip4;
19592
19593   /* send it... */
19594   S (mp);
19595
19596   /* Wait for a reply... */
19597   W (ret);
19598   return ret;
19599 }
19600
19601 static int
19602 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19603 {
19604   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19605   int ret;
19606
19607   if (!vam->json_output)
19608     {
19609       print (vam->ofp, "VNIs");
19610     }
19611
19612   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19613
19614   /* send it... */
19615   S (mp);
19616
19617   /* Wait for a reply... */
19618   W (ret);
19619   return ret;
19620 }
19621
19622 static int
19623 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19624 {
19625   unformat_input_t *i = vam->input;
19626   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19627   int ret = 0;
19628   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19629   struct in_addr ip4;
19630   struct in6_addr ip6;
19631   u32 table_id = 0, nh_sw_if_index = ~0;
19632
19633   memset (&ip4, 0, sizeof (ip4));
19634   memset (&ip6, 0, sizeof (ip6));
19635
19636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19637     {
19638       if (unformat (i, "del"))
19639         is_add = 0;
19640       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19641                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19642         {
19643           ip_set = 1;
19644           is_ip4 = 1;
19645         }
19646       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19647                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19648         {
19649           ip_set = 1;
19650           is_ip4 = 0;
19651         }
19652       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19653         {
19654           ip_set = 1;
19655           is_ip4 = 1;
19656           nh_sw_if_index = ~0;
19657         }
19658       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19659         {
19660           ip_set = 1;
19661           is_ip4 = 0;
19662           nh_sw_if_index = ~0;
19663         }
19664       else if (unformat (i, "table %d", &table_id))
19665         ;
19666       else
19667         {
19668           errmsg ("parse error '%U'", format_unformat_error, i);
19669           return -99;
19670         }
19671     }
19672
19673   if (!ip_set)
19674     {
19675       errmsg ("nh addr not set!");
19676       return -99;
19677     }
19678
19679   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19680   mp->is_add = is_add;
19681   mp->table_id = clib_host_to_net_u32 (table_id);
19682   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19683   mp->is_ip4 = is_ip4;
19684   if (is_ip4)
19685     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19686   else
19687     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19688
19689   /* send it... */
19690   S (mp);
19691
19692   /* Wait for a reply... */
19693   W (ret);
19694   return ret;
19695 }
19696
19697 static int
19698 api_one_map_server_dump (vat_main_t * vam)
19699 {
19700   vl_api_one_map_server_dump_t *mp;
19701   vl_api_control_ping_t *mp_ping;
19702   int ret;
19703
19704   if (!vam->json_output)
19705     {
19706       print (vam->ofp, "%=20s", "Map server");
19707     }
19708
19709   M (ONE_MAP_SERVER_DUMP, mp);
19710   /* send it... */
19711   S (mp);
19712
19713   /* Use a control ping for synchronization */
19714   MPING (CONTROL_PING, mp_ping);
19715   S (mp_ping);
19716
19717   /* Wait for a reply... */
19718   W (ret);
19719   return ret;
19720 }
19721
19722 #define api_lisp_map_server_dump api_one_map_server_dump
19723
19724 static int
19725 api_one_map_resolver_dump (vat_main_t * vam)
19726 {
19727   vl_api_one_map_resolver_dump_t *mp;
19728   vl_api_control_ping_t *mp_ping;
19729   int ret;
19730
19731   if (!vam->json_output)
19732     {
19733       print (vam->ofp, "%=20s", "Map resolver");
19734     }
19735
19736   M (ONE_MAP_RESOLVER_DUMP, mp);
19737   /* send it... */
19738   S (mp);
19739
19740   /* Use a control ping for synchronization */
19741   MPING (CONTROL_PING, mp_ping);
19742   S (mp_ping);
19743
19744   /* Wait for a reply... */
19745   W (ret);
19746   return ret;
19747 }
19748
19749 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19750
19751 static int
19752 api_one_stats_flush (vat_main_t * vam)
19753 {
19754   vl_api_one_stats_flush_t *mp;
19755   int ret = 0;
19756
19757   M (ONE_STATS_FLUSH, mp);
19758   S (mp);
19759   W (ret);
19760   return ret;
19761 }
19762
19763 static int
19764 api_one_stats_dump (vat_main_t * vam)
19765 {
19766   vl_api_one_stats_dump_t *mp;
19767   vl_api_control_ping_t *mp_ping;
19768   int ret;
19769
19770   M (ONE_STATS_DUMP, mp);
19771   /* send it... */
19772   S (mp);
19773
19774   /* Use a control ping for synchronization */
19775   MPING (CONTROL_PING, mp_ping);
19776   S (mp_ping);
19777
19778   /* Wait for a reply... */
19779   W (ret);
19780   return ret;
19781 }
19782
19783 static int
19784 api_show_one_status (vat_main_t * vam)
19785 {
19786   vl_api_show_one_status_t *mp;
19787   int ret;
19788
19789   if (!vam->json_output)
19790     {
19791       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19792     }
19793
19794   M (SHOW_ONE_STATUS, mp);
19795   /* send it... */
19796   S (mp);
19797   /* Wait for a reply... */
19798   W (ret);
19799   return ret;
19800 }
19801
19802 #define api_show_lisp_status api_show_one_status
19803
19804 static int
19805 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19806 {
19807   vl_api_gpe_fwd_entry_path_dump_t *mp;
19808   vl_api_control_ping_t *mp_ping;
19809   unformat_input_t *i = vam->input;
19810   u32 fwd_entry_index = ~0;
19811   int ret;
19812
19813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19814     {
19815       if (unformat (i, "index %d", &fwd_entry_index))
19816         ;
19817       else
19818         break;
19819     }
19820
19821   if (~0 == fwd_entry_index)
19822     {
19823       errmsg ("no index specified!");
19824       return -99;
19825     }
19826
19827   if (!vam->json_output)
19828     {
19829       print (vam->ofp, "first line");
19830     }
19831
19832   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19833
19834   /* send it... */
19835   S (mp);
19836   /* Use a control ping for synchronization */
19837   MPING (CONTROL_PING, mp_ping);
19838   S (mp_ping);
19839
19840   /* Wait for a reply... */
19841   W (ret);
19842   return ret;
19843 }
19844
19845 static int
19846 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19847 {
19848   vl_api_one_get_map_request_itr_rlocs_t *mp;
19849   int ret;
19850
19851   if (!vam->json_output)
19852     {
19853       print (vam->ofp, "%=20s", "itr-rlocs:");
19854     }
19855
19856   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19857   /* send it... */
19858   S (mp);
19859   /* Wait for a reply... */
19860   W (ret);
19861   return ret;
19862 }
19863
19864 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19865
19866 static int
19867 api_af_packet_create (vat_main_t * vam)
19868 {
19869   unformat_input_t *i = vam->input;
19870   vl_api_af_packet_create_t *mp;
19871   u8 *host_if_name = 0;
19872   u8 hw_addr[6];
19873   u8 random_hw_addr = 1;
19874   int ret;
19875
19876   memset (hw_addr, 0, sizeof (hw_addr));
19877
19878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19879     {
19880       if (unformat (i, "name %s", &host_if_name))
19881         vec_add1 (host_if_name, 0);
19882       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19883         random_hw_addr = 0;
19884       else
19885         break;
19886     }
19887
19888   if (!vec_len (host_if_name))
19889     {
19890       errmsg ("host-interface name must be specified");
19891       return -99;
19892     }
19893
19894   if (vec_len (host_if_name) > 64)
19895     {
19896       errmsg ("host-interface name too long");
19897       return -99;
19898     }
19899
19900   M (AF_PACKET_CREATE, mp);
19901
19902   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19903   clib_memcpy (mp->hw_addr, hw_addr, 6);
19904   mp->use_random_hw_addr = random_hw_addr;
19905   vec_free (host_if_name);
19906
19907   S (mp);
19908
19909   /* *INDENT-OFF* */
19910   W2 (ret,
19911       ({
19912         if (ret == 0)
19913           fprintf (vam->ofp ? vam->ofp : stderr,
19914                    " new sw_if_index = %d\n", vam->sw_if_index);
19915       }));
19916   /* *INDENT-ON* */
19917   return ret;
19918 }
19919
19920 static int
19921 api_af_packet_delete (vat_main_t * vam)
19922 {
19923   unformat_input_t *i = vam->input;
19924   vl_api_af_packet_delete_t *mp;
19925   u8 *host_if_name = 0;
19926   int ret;
19927
19928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19929     {
19930       if (unformat (i, "name %s", &host_if_name))
19931         vec_add1 (host_if_name, 0);
19932       else
19933         break;
19934     }
19935
19936   if (!vec_len (host_if_name))
19937     {
19938       errmsg ("host-interface name must be specified");
19939       return -99;
19940     }
19941
19942   if (vec_len (host_if_name) > 64)
19943     {
19944       errmsg ("host-interface name too long");
19945       return -99;
19946     }
19947
19948   M (AF_PACKET_DELETE, mp);
19949
19950   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19951   vec_free (host_if_name);
19952
19953   S (mp);
19954   W (ret);
19955   return ret;
19956 }
19957
19958 static void vl_api_af_packet_details_t_handler
19959   (vl_api_af_packet_details_t * mp)
19960 {
19961   vat_main_t *vam = &vat_main;
19962
19963   print (vam->ofp, "%-16s %d",
19964          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19965 }
19966
19967 static void vl_api_af_packet_details_t_handler_json
19968   (vl_api_af_packet_details_t * mp)
19969 {
19970   vat_main_t *vam = &vat_main;
19971   vat_json_node_t *node = NULL;
19972
19973   if (VAT_JSON_ARRAY != vam->json_tree.type)
19974     {
19975       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19976       vat_json_init_array (&vam->json_tree);
19977     }
19978   node = vat_json_array_add (&vam->json_tree);
19979
19980   vat_json_init_object (node);
19981   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19982   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19983 }
19984
19985 static int
19986 api_af_packet_dump (vat_main_t * vam)
19987 {
19988   vl_api_af_packet_dump_t *mp;
19989   vl_api_control_ping_t *mp_ping;
19990   int ret;
19991
19992   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19993   /* Get list of tap interfaces */
19994   M (AF_PACKET_DUMP, mp);
19995   S (mp);
19996
19997   /* Use a control ping for synchronization */
19998   MPING (CONTROL_PING, mp_ping);
19999   S (mp_ping);
20000
20001   W (ret);
20002   return ret;
20003 }
20004
20005 static int
20006 api_policer_add_del (vat_main_t * vam)
20007 {
20008   unformat_input_t *i = vam->input;
20009   vl_api_policer_add_del_t *mp;
20010   u8 is_add = 1;
20011   u8 *name = 0;
20012   u32 cir = 0;
20013   u32 eir = 0;
20014   u64 cb = 0;
20015   u64 eb = 0;
20016   u8 rate_type = 0;
20017   u8 round_type = 0;
20018   u8 type = 0;
20019   u8 color_aware = 0;
20020   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20021   int ret;
20022
20023   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20024   conform_action.dscp = 0;
20025   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20026   exceed_action.dscp = 0;
20027   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20028   violate_action.dscp = 0;
20029
20030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20031     {
20032       if (unformat (i, "del"))
20033         is_add = 0;
20034       else if (unformat (i, "name %s", &name))
20035         vec_add1 (name, 0);
20036       else if (unformat (i, "cir %u", &cir))
20037         ;
20038       else if (unformat (i, "eir %u", &eir))
20039         ;
20040       else if (unformat (i, "cb %u", &cb))
20041         ;
20042       else if (unformat (i, "eb %u", &eb))
20043         ;
20044       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20045                          &rate_type))
20046         ;
20047       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20048                          &round_type))
20049         ;
20050       else if (unformat (i, "type %U", unformat_policer_type, &type))
20051         ;
20052       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20053                          &conform_action))
20054         ;
20055       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20056                          &exceed_action))
20057         ;
20058       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20059                          &violate_action))
20060         ;
20061       else if (unformat (i, "color-aware"))
20062         color_aware = 1;
20063       else
20064         break;
20065     }
20066
20067   if (!vec_len (name))
20068     {
20069       errmsg ("policer name must be specified");
20070       return -99;
20071     }
20072
20073   if (vec_len (name) > 64)
20074     {
20075       errmsg ("policer name too long");
20076       return -99;
20077     }
20078
20079   M (POLICER_ADD_DEL, mp);
20080
20081   clib_memcpy (mp->name, name, vec_len (name));
20082   vec_free (name);
20083   mp->is_add = is_add;
20084   mp->cir = ntohl (cir);
20085   mp->eir = ntohl (eir);
20086   mp->cb = clib_net_to_host_u64 (cb);
20087   mp->eb = clib_net_to_host_u64 (eb);
20088   mp->rate_type = rate_type;
20089   mp->round_type = round_type;
20090   mp->type = type;
20091   mp->conform_action_type = conform_action.action_type;
20092   mp->conform_dscp = conform_action.dscp;
20093   mp->exceed_action_type = exceed_action.action_type;
20094   mp->exceed_dscp = exceed_action.dscp;
20095   mp->violate_action_type = violate_action.action_type;
20096   mp->violate_dscp = violate_action.dscp;
20097   mp->color_aware = color_aware;
20098
20099   S (mp);
20100   W (ret);
20101   return ret;
20102 }
20103
20104 static int
20105 api_policer_dump (vat_main_t * vam)
20106 {
20107   unformat_input_t *i = vam->input;
20108   vl_api_policer_dump_t *mp;
20109   vl_api_control_ping_t *mp_ping;
20110   u8 *match_name = 0;
20111   u8 match_name_valid = 0;
20112   int ret;
20113
20114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20115     {
20116       if (unformat (i, "name %s", &match_name))
20117         {
20118           vec_add1 (match_name, 0);
20119           match_name_valid = 1;
20120         }
20121       else
20122         break;
20123     }
20124
20125   M (POLICER_DUMP, mp);
20126   mp->match_name_valid = match_name_valid;
20127   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20128   vec_free (match_name);
20129   /* send it... */
20130   S (mp);
20131
20132   /* Use a control ping for synchronization */
20133   MPING (CONTROL_PING, mp_ping);
20134   S (mp_ping);
20135
20136   /* Wait for a reply... */
20137   W (ret);
20138   return ret;
20139 }
20140
20141 static int
20142 api_policer_classify_set_interface (vat_main_t * vam)
20143 {
20144   unformat_input_t *i = vam->input;
20145   vl_api_policer_classify_set_interface_t *mp;
20146   u32 sw_if_index;
20147   int sw_if_index_set;
20148   u32 ip4_table_index = ~0;
20149   u32 ip6_table_index = ~0;
20150   u32 l2_table_index = ~0;
20151   u8 is_add = 1;
20152   int ret;
20153
20154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20155     {
20156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20157         sw_if_index_set = 1;
20158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20159         sw_if_index_set = 1;
20160       else if (unformat (i, "del"))
20161         is_add = 0;
20162       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20163         ;
20164       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20165         ;
20166       else if (unformat (i, "l2-table %d", &l2_table_index))
20167         ;
20168       else
20169         {
20170           clib_warning ("parse error '%U'", format_unformat_error, i);
20171           return -99;
20172         }
20173     }
20174
20175   if (sw_if_index_set == 0)
20176     {
20177       errmsg ("missing interface name or sw_if_index");
20178       return -99;
20179     }
20180
20181   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20182
20183   mp->sw_if_index = ntohl (sw_if_index);
20184   mp->ip4_table_index = ntohl (ip4_table_index);
20185   mp->ip6_table_index = ntohl (ip6_table_index);
20186   mp->l2_table_index = ntohl (l2_table_index);
20187   mp->is_add = is_add;
20188
20189   S (mp);
20190   W (ret);
20191   return ret;
20192 }
20193
20194 static int
20195 api_policer_classify_dump (vat_main_t * vam)
20196 {
20197   unformat_input_t *i = vam->input;
20198   vl_api_policer_classify_dump_t *mp;
20199   vl_api_control_ping_t *mp_ping;
20200   u8 type = POLICER_CLASSIFY_N_TABLES;
20201   int ret;
20202
20203   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20204     ;
20205   else
20206     {
20207       errmsg ("classify table type must be specified");
20208       return -99;
20209     }
20210
20211   if (!vam->json_output)
20212     {
20213       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20214     }
20215
20216   M (POLICER_CLASSIFY_DUMP, mp);
20217   mp->type = type;
20218   /* send it... */
20219   S (mp);
20220
20221   /* Use a control ping for synchronization */
20222   MPING (CONTROL_PING, mp_ping);
20223   S (mp_ping);
20224
20225   /* Wait for a reply... */
20226   W (ret);
20227   return ret;
20228 }
20229
20230 static int
20231 api_netmap_create (vat_main_t * vam)
20232 {
20233   unformat_input_t *i = vam->input;
20234   vl_api_netmap_create_t *mp;
20235   u8 *if_name = 0;
20236   u8 hw_addr[6];
20237   u8 random_hw_addr = 1;
20238   u8 is_pipe = 0;
20239   u8 is_master = 0;
20240   int ret;
20241
20242   memset (hw_addr, 0, sizeof (hw_addr));
20243
20244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20245     {
20246       if (unformat (i, "name %s", &if_name))
20247         vec_add1 (if_name, 0);
20248       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20249         random_hw_addr = 0;
20250       else if (unformat (i, "pipe"))
20251         is_pipe = 1;
20252       else if (unformat (i, "master"))
20253         is_master = 1;
20254       else if (unformat (i, "slave"))
20255         is_master = 0;
20256       else
20257         break;
20258     }
20259
20260   if (!vec_len (if_name))
20261     {
20262       errmsg ("interface name must be specified");
20263       return -99;
20264     }
20265
20266   if (vec_len (if_name) > 64)
20267     {
20268       errmsg ("interface name too long");
20269       return -99;
20270     }
20271
20272   M (NETMAP_CREATE, mp);
20273
20274   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20275   clib_memcpy (mp->hw_addr, hw_addr, 6);
20276   mp->use_random_hw_addr = random_hw_addr;
20277   mp->is_pipe = is_pipe;
20278   mp->is_master = is_master;
20279   vec_free (if_name);
20280
20281   S (mp);
20282   W (ret);
20283   return ret;
20284 }
20285
20286 static int
20287 api_netmap_delete (vat_main_t * vam)
20288 {
20289   unformat_input_t *i = vam->input;
20290   vl_api_netmap_delete_t *mp;
20291   u8 *if_name = 0;
20292   int ret;
20293
20294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20295     {
20296       if (unformat (i, "name %s", &if_name))
20297         vec_add1 (if_name, 0);
20298       else
20299         break;
20300     }
20301
20302   if (!vec_len (if_name))
20303     {
20304       errmsg ("interface name must be specified");
20305       return -99;
20306     }
20307
20308   if (vec_len (if_name) > 64)
20309     {
20310       errmsg ("interface name too long");
20311       return -99;
20312     }
20313
20314   M (NETMAP_DELETE, mp);
20315
20316   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20317   vec_free (if_name);
20318
20319   S (mp);
20320   W (ret);
20321   return ret;
20322 }
20323
20324 static void
20325 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20326 {
20327   if (fp->afi == IP46_TYPE_IP6)
20328     print (vam->ofp,
20329            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20330            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20331            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20332            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20333            format_ip6_address, fp->next_hop);
20334   else if (fp->afi == IP46_TYPE_IP4)
20335     print (vam->ofp,
20336            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20337            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20338            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20339            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20340            format_ip4_address, fp->next_hop);
20341 }
20342
20343 static void
20344 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20345                                  vl_api_fib_path_t * fp)
20346 {
20347   struct in_addr ip4;
20348   struct in6_addr ip6;
20349
20350   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20351   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20352   vat_json_object_add_uint (node, "is_local", fp->is_local);
20353   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20354   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20355   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20356   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20357   if (fp->afi == IP46_TYPE_IP4)
20358     {
20359       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20360       vat_json_object_add_ip4 (node, "next_hop", ip4);
20361     }
20362   else if (fp->afi == IP46_TYPE_IP6)
20363     {
20364       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20365       vat_json_object_add_ip6 (node, "next_hop", ip6);
20366     }
20367 }
20368
20369 static void
20370 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20371 {
20372   vat_main_t *vam = &vat_main;
20373   int count = ntohl (mp->mt_count);
20374   vl_api_fib_path_t *fp;
20375   i32 i;
20376
20377   print (vam->ofp, "[%d]: sw_if_index %d via:",
20378          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20379   fp = mp->mt_paths;
20380   for (i = 0; i < count; i++)
20381     {
20382       vl_api_mpls_fib_path_print (vam, fp);
20383       fp++;
20384     }
20385
20386   print (vam->ofp, "");
20387 }
20388
20389 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20390 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20391
20392 static void
20393 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20394 {
20395   vat_main_t *vam = &vat_main;
20396   vat_json_node_t *node = NULL;
20397   int count = ntohl (mp->mt_count);
20398   vl_api_fib_path_t *fp;
20399   i32 i;
20400
20401   if (VAT_JSON_ARRAY != vam->json_tree.type)
20402     {
20403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20404       vat_json_init_array (&vam->json_tree);
20405     }
20406   node = vat_json_array_add (&vam->json_tree);
20407
20408   vat_json_init_object (node);
20409   vat_json_object_add_uint (node, "tunnel_index",
20410                             ntohl (mp->mt_tunnel_index));
20411   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20412
20413   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20414
20415   fp = mp->mt_paths;
20416   for (i = 0; i < count; i++)
20417     {
20418       vl_api_mpls_fib_path_json_print (node, fp);
20419       fp++;
20420     }
20421 }
20422
20423 static int
20424 api_mpls_tunnel_dump (vat_main_t * vam)
20425 {
20426   vl_api_mpls_tunnel_dump_t *mp;
20427   vl_api_control_ping_t *mp_ping;
20428   u32 sw_if_index = ~0;
20429   int ret;
20430
20431   /* Parse args required to build the message */
20432   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20433     {
20434       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20435         ;
20436     }
20437
20438   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20439
20440   M (MPLS_TUNNEL_DUMP, mp);
20441   mp->sw_if_index = htonl (sw_if_index);
20442   S (mp);
20443
20444   /* Use a control ping for synchronization */
20445   MPING (CONTROL_PING, mp_ping);
20446   S (mp_ping);
20447
20448   W (ret);
20449   return ret;
20450 }
20451
20452 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20453 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20454
20455
20456 static void
20457 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20458 {
20459   vat_main_t *vam = &vat_main;
20460   int count = ntohl (mp->count);
20461   vl_api_fib_path_t *fp;
20462   int i;
20463
20464   print (vam->ofp,
20465          "table-id %d, label %u, ess_bit %u",
20466          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20467   fp = mp->path;
20468   for (i = 0; i < count; i++)
20469     {
20470       vl_api_mpls_fib_path_print (vam, fp);
20471       fp++;
20472     }
20473 }
20474
20475 static void vl_api_mpls_fib_details_t_handler_json
20476   (vl_api_mpls_fib_details_t * mp)
20477 {
20478   vat_main_t *vam = &vat_main;
20479   int count = ntohl (mp->count);
20480   vat_json_node_t *node = NULL;
20481   vl_api_fib_path_t *fp;
20482   int i;
20483
20484   if (VAT_JSON_ARRAY != vam->json_tree.type)
20485     {
20486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20487       vat_json_init_array (&vam->json_tree);
20488     }
20489   node = vat_json_array_add (&vam->json_tree);
20490
20491   vat_json_init_object (node);
20492   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20493   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20494   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20495   vat_json_object_add_uint (node, "path_count", count);
20496   fp = mp->path;
20497   for (i = 0; i < count; i++)
20498     {
20499       vl_api_mpls_fib_path_json_print (node, fp);
20500       fp++;
20501     }
20502 }
20503
20504 static int
20505 api_mpls_fib_dump (vat_main_t * vam)
20506 {
20507   vl_api_mpls_fib_dump_t *mp;
20508   vl_api_control_ping_t *mp_ping;
20509   int ret;
20510
20511   M (MPLS_FIB_DUMP, mp);
20512   S (mp);
20513
20514   /* Use a control ping for synchronization */
20515   MPING (CONTROL_PING, mp_ping);
20516   S (mp_ping);
20517
20518   W (ret);
20519   return ret;
20520 }
20521
20522 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20523 #define vl_api_ip_fib_details_t_print vl_noop_handler
20524
20525 static void
20526 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20527 {
20528   vat_main_t *vam = &vat_main;
20529   int count = ntohl (mp->count);
20530   vl_api_fib_path_t *fp;
20531   int i;
20532
20533   print (vam->ofp,
20534          "table-id %d, prefix %U/%d stats-index %d",
20535          ntohl (mp->table_id), format_ip4_address, mp->address,
20536          mp->address_length, ntohl (mp->stats_index));
20537   fp = mp->path;
20538   for (i = 0; i < count; i++)
20539     {
20540       if (fp->afi == IP46_TYPE_IP6)
20541         print (vam->ofp,
20542                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20543                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20544                "next_hop_table %d",
20545                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20546                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20547                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20548       else if (fp->afi == IP46_TYPE_IP4)
20549         print (vam->ofp,
20550                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20551                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20552                "next_hop_table %d",
20553                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20554                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20555                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20556       fp++;
20557     }
20558 }
20559
20560 static void vl_api_ip_fib_details_t_handler_json
20561   (vl_api_ip_fib_details_t * mp)
20562 {
20563   vat_main_t *vam = &vat_main;
20564   int count = ntohl (mp->count);
20565   vat_json_node_t *node = NULL;
20566   struct in_addr ip4;
20567   struct in6_addr ip6;
20568   vl_api_fib_path_t *fp;
20569   int i;
20570
20571   if (VAT_JSON_ARRAY != vam->json_tree.type)
20572     {
20573       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20574       vat_json_init_array (&vam->json_tree);
20575     }
20576   node = vat_json_array_add (&vam->json_tree);
20577
20578   vat_json_init_object (node);
20579   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20580   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20581   vat_json_object_add_ip4 (node, "prefix", ip4);
20582   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20583   vat_json_object_add_uint (node, "path_count", count);
20584   fp = mp->path;
20585   for (i = 0; i < count; i++)
20586     {
20587       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20588       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20589       vat_json_object_add_uint (node, "is_local", fp->is_local);
20590       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20591       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20592       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20593       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20594       if (fp->afi == IP46_TYPE_IP4)
20595         {
20596           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20597           vat_json_object_add_ip4 (node, "next_hop", ip4);
20598         }
20599       else if (fp->afi == IP46_TYPE_IP6)
20600         {
20601           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20602           vat_json_object_add_ip6 (node, "next_hop", ip6);
20603         }
20604     }
20605 }
20606
20607 static int
20608 api_ip_fib_dump (vat_main_t * vam)
20609 {
20610   vl_api_ip_fib_dump_t *mp;
20611   vl_api_control_ping_t *mp_ping;
20612   int ret;
20613
20614   M (IP_FIB_DUMP, mp);
20615   S (mp);
20616
20617   /* Use a control ping for synchronization */
20618   MPING (CONTROL_PING, mp_ping);
20619   S (mp_ping);
20620
20621   W (ret);
20622   return ret;
20623 }
20624
20625 static int
20626 api_ip_mfib_dump (vat_main_t * vam)
20627 {
20628   vl_api_ip_mfib_dump_t *mp;
20629   vl_api_control_ping_t *mp_ping;
20630   int ret;
20631
20632   M (IP_MFIB_DUMP, mp);
20633   S (mp);
20634
20635   /* Use a control ping for synchronization */
20636   MPING (CONTROL_PING, mp_ping);
20637   S (mp_ping);
20638
20639   W (ret);
20640   return ret;
20641 }
20642
20643 static void vl_api_ip_neighbor_details_t_handler
20644   (vl_api_ip_neighbor_details_t * mp)
20645 {
20646   vat_main_t *vam = &vat_main;
20647
20648   print (vam->ofp, "%c %U %U",
20649          (mp->is_static) ? 'S' : 'D',
20650          format_ethernet_address, &mp->mac_address,
20651          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20652          &mp->ip_address);
20653 }
20654
20655 static void vl_api_ip_neighbor_details_t_handler_json
20656   (vl_api_ip_neighbor_details_t * mp)
20657 {
20658
20659   vat_main_t *vam = &vat_main;
20660   vat_json_node_t *node;
20661   struct in_addr ip4;
20662   struct in6_addr ip6;
20663
20664   if (VAT_JSON_ARRAY != vam->json_tree.type)
20665     {
20666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20667       vat_json_init_array (&vam->json_tree);
20668     }
20669   node = vat_json_array_add (&vam->json_tree);
20670
20671   vat_json_init_object (node);
20672   vat_json_object_add_string_copy (node, "flag",
20673                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20674                                    "dynamic");
20675
20676   vat_json_object_add_string_copy (node, "link_layer",
20677                                    format (0, "%U", format_ethernet_address,
20678                                            &mp->mac_address));
20679
20680   if (mp->is_ipv6)
20681     {
20682       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20683       vat_json_object_add_ip6 (node, "ip_address", ip6);
20684     }
20685   else
20686     {
20687       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20688       vat_json_object_add_ip4 (node, "ip_address", ip4);
20689     }
20690 }
20691
20692 static int
20693 api_ip_neighbor_dump (vat_main_t * vam)
20694 {
20695   unformat_input_t *i = vam->input;
20696   vl_api_ip_neighbor_dump_t *mp;
20697   vl_api_control_ping_t *mp_ping;
20698   u8 is_ipv6 = 0;
20699   u32 sw_if_index = ~0;
20700   int ret;
20701
20702   /* Parse args required to build the message */
20703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20704     {
20705       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20706         ;
20707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20708         ;
20709       else if (unformat (i, "ip6"))
20710         is_ipv6 = 1;
20711       else
20712         break;
20713     }
20714
20715   if (sw_if_index == ~0)
20716     {
20717       errmsg ("missing interface name or sw_if_index");
20718       return -99;
20719     }
20720
20721   M (IP_NEIGHBOR_DUMP, mp);
20722   mp->is_ipv6 = (u8) is_ipv6;
20723   mp->sw_if_index = ntohl (sw_if_index);
20724   S (mp);
20725
20726   /* Use a control ping for synchronization */
20727   MPING (CONTROL_PING, mp_ping);
20728   S (mp_ping);
20729
20730   W (ret);
20731   return ret;
20732 }
20733
20734 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20735 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20736
20737 static void
20738 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20739 {
20740   vat_main_t *vam = &vat_main;
20741   int count = ntohl (mp->count);
20742   vl_api_fib_path_t *fp;
20743   int i;
20744
20745   print (vam->ofp,
20746          "table-id %d, prefix %U/%d stats-index %d",
20747          ntohl (mp->table_id), format_ip6_address, mp->address,
20748          mp->address_length, ntohl (mp->stats_index));
20749   fp = mp->path;
20750   for (i = 0; i < count; i++)
20751     {
20752       if (fp->afi == IP46_TYPE_IP6)
20753         print (vam->ofp,
20754                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20755                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20756                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20757                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20758                format_ip6_address, fp->next_hop);
20759       else if (fp->afi == IP46_TYPE_IP4)
20760         print (vam->ofp,
20761                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20762                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20763                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20764                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20765                format_ip4_address, fp->next_hop);
20766       fp++;
20767     }
20768 }
20769
20770 static void vl_api_ip6_fib_details_t_handler_json
20771   (vl_api_ip6_fib_details_t * mp)
20772 {
20773   vat_main_t *vam = &vat_main;
20774   int count = ntohl (mp->count);
20775   vat_json_node_t *node = NULL;
20776   struct in_addr ip4;
20777   struct in6_addr ip6;
20778   vl_api_fib_path_t *fp;
20779   int i;
20780
20781   if (VAT_JSON_ARRAY != vam->json_tree.type)
20782     {
20783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20784       vat_json_init_array (&vam->json_tree);
20785     }
20786   node = vat_json_array_add (&vam->json_tree);
20787
20788   vat_json_init_object (node);
20789   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20790   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20791   vat_json_object_add_ip6 (node, "prefix", ip6);
20792   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20793   vat_json_object_add_uint (node, "path_count", count);
20794   fp = mp->path;
20795   for (i = 0; i < count; i++)
20796     {
20797       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20798       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20799       vat_json_object_add_uint (node, "is_local", fp->is_local);
20800       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20801       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20802       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20803       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20804       if (fp->afi == IP46_TYPE_IP4)
20805         {
20806           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20807           vat_json_object_add_ip4 (node, "next_hop", ip4);
20808         }
20809       else if (fp->afi == IP46_TYPE_IP6)
20810         {
20811           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20812           vat_json_object_add_ip6 (node, "next_hop", ip6);
20813         }
20814     }
20815 }
20816
20817 static int
20818 api_ip6_fib_dump (vat_main_t * vam)
20819 {
20820   vl_api_ip6_fib_dump_t *mp;
20821   vl_api_control_ping_t *mp_ping;
20822   int ret;
20823
20824   M (IP6_FIB_DUMP, mp);
20825   S (mp);
20826
20827   /* Use a control ping for synchronization */
20828   MPING (CONTROL_PING, mp_ping);
20829   S (mp_ping);
20830
20831   W (ret);
20832   return ret;
20833 }
20834
20835 static int
20836 api_ip6_mfib_dump (vat_main_t * vam)
20837 {
20838   vl_api_ip6_mfib_dump_t *mp;
20839   vl_api_control_ping_t *mp_ping;
20840   int ret;
20841
20842   M (IP6_MFIB_DUMP, mp);
20843   S (mp);
20844
20845   /* Use a control ping for synchronization */
20846   MPING (CONTROL_PING, mp_ping);
20847   S (mp_ping);
20848
20849   W (ret);
20850   return ret;
20851 }
20852
20853 int
20854 api_classify_table_ids (vat_main_t * vam)
20855 {
20856   vl_api_classify_table_ids_t *mp;
20857   int ret;
20858
20859   /* Construct the API message */
20860   M (CLASSIFY_TABLE_IDS, mp);
20861   mp->context = 0;
20862
20863   S (mp);
20864   W (ret);
20865   return ret;
20866 }
20867
20868 int
20869 api_classify_table_by_interface (vat_main_t * vam)
20870 {
20871   unformat_input_t *input = vam->input;
20872   vl_api_classify_table_by_interface_t *mp;
20873
20874   u32 sw_if_index = ~0;
20875   int ret;
20876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20877     {
20878       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20879         ;
20880       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20881         ;
20882       else
20883         break;
20884     }
20885   if (sw_if_index == ~0)
20886     {
20887       errmsg ("missing interface name or sw_if_index");
20888       return -99;
20889     }
20890
20891   /* Construct the API message */
20892   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20893   mp->context = 0;
20894   mp->sw_if_index = ntohl (sw_if_index);
20895
20896   S (mp);
20897   W (ret);
20898   return ret;
20899 }
20900
20901 int
20902 api_classify_table_info (vat_main_t * vam)
20903 {
20904   unformat_input_t *input = vam->input;
20905   vl_api_classify_table_info_t *mp;
20906
20907   u32 table_id = ~0;
20908   int ret;
20909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20910     {
20911       if (unformat (input, "table_id %d", &table_id))
20912         ;
20913       else
20914         break;
20915     }
20916   if (table_id == ~0)
20917     {
20918       errmsg ("missing table id");
20919       return -99;
20920     }
20921
20922   /* Construct the API message */
20923   M (CLASSIFY_TABLE_INFO, mp);
20924   mp->context = 0;
20925   mp->table_id = ntohl (table_id);
20926
20927   S (mp);
20928   W (ret);
20929   return ret;
20930 }
20931
20932 int
20933 api_classify_session_dump (vat_main_t * vam)
20934 {
20935   unformat_input_t *input = vam->input;
20936   vl_api_classify_session_dump_t *mp;
20937   vl_api_control_ping_t *mp_ping;
20938
20939   u32 table_id = ~0;
20940   int ret;
20941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20942     {
20943       if (unformat (input, "table_id %d", &table_id))
20944         ;
20945       else
20946         break;
20947     }
20948   if (table_id == ~0)
20949     {
20950       errmsg ("missing table id");
20951       return -99;
20952     }
20953
20954   /* Construct the API message */
20955   M (CLASSIFY_SESSION_DUMP, mp);
20956   mp->context = 0;
20957   mp->table_id = ntohl (table_id);
20958   S (mp);
20959
20960   /* Use a control ping for synchronization */
20961   MPING (CONTROL_PING, mp_ping);
20962   S (mp_ping);
20963
20964   W (ret);
20965   return ret;
20966 }
20967
20968 static void
20969 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20970 {
20971   vat_main_t *vam = &vat_main;
20972
20973   print (vam->ofp, "collector_address %U, collector_port %d, "
20974          "src_address %U, vrf_id %d, path_mtu %u, "
20975          "template_interval %u, udp_checksum %d",
20976          format_ip4_address, mp->collector_address,
20977          ntohs (mp->collector_port),
20978          format_ip4_address, mp->src_address,
20979          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20980          ntohl (mp->template_interval), mp->udp_checksum);
20981
20982   vam->retval = 0;
20983   vam->result_ready = 1;
20984 }
20985
20986 static void
20987   vl_api_ipfix_exporter_details_t_handler_json
20988   (vl_api_ipfix_exporter_details_t * mp)
20989 {
20990   vat_main_t *vam = &vat_main;
20991   vat_json_node_t node;
20992   struct in_addr collector_address;
20993   struct in_addr src_address;
20994
20995   vat_json_init_object (&node);
20996   clib_memcpy (&collector_address, &mp->collector_address,
20997                sizeof (collector_address));
20998   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20999   vat_json_object_add_uint (&node, "collector_port",
21000                             ntohs (mp->collector_port));
21001   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21002   vat_json_object_add_ip4 (&node, "src_address", src_address);
21003   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21004   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21005   vat_json_object_add_uint (&node, "template_interval",
21006                             ntohl (mp->template_interval));
21007   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21008
21009   vat_json_print (vam->ofp, &node);
21010   vat_json_free (&node);
21011   vam->retval = 0;
21012   vam->result_ready = 1;
21013 }
21014
21015 int
21016 api_ipfix_exporter_dump (vat_main_t * vam)
21017 {
21018   vl_api_ipfix_exporter_dump_t *mp;
21019   int ret;
21020
21021   /* Construct the API message */
21022   M (IPFIX_EXPORTER_DUMP, mp);
21023   mp->context = 0;
21024
21025   S (mp);
21026   W (ret);
21027   return ret;
21028 }
21029
21030 static int
21031 api_ipfix_classify_stream_dump (vat_main_t * vam)
21032 {
21033   vl_api_ipfix_classify_stream_dump_t *mp;
21034   int ret;
21035
21036   /* Construct the API message */
21037   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21038   mp->context = 0;
21039
21040   S (mp);
21041   W (ret);
21042   return ret;
21043   /* NOTREACHED */
21044   return 0;
21045 }
21046
21047 static void
21048   vl_api_ipfix_classify_stream_details_t_handler
21049   (vl_api_ipfix_classify_stream_details_t * mp)
21050 {
21051   vat_main_t *vam = &vat_main;
21052   print (vam->ofp, "domain_id %d, src_port %d",
21053          ntohl (mp->domain_id), ntohs (mp->src_port));
21054   vam->retval = 0;
21055   vam->result_ready = 1;
21056 }
21057
21058 static void
21059   vl_api_ipfix_classify_stream_details_t_handler_json
21060   (vl_api_ipfix_classify_stream_details_t * mp)
21061 {
21062   vat_main_t *vam = &vat_main;
21063   vat_json_node_t node;
21064
21065   vat_json_init_object (&node);
21066   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21067   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21068
21069   vat_json_print (vam->ofp, &node);
21070   vat_json_free (&node);
21071   vam->retval = 0;
21072   vam->result_ready = 1;
21073 }
21074
21075 static int
21076 api_ipfix_classify_table_dump (vat_main_t * vam)
21077 {
21078   vl_api_ipfix_classify_table_dump_t *mp;
21079   vl_api_control_ping_t *mp_ping;
21080   int ret;
21081
21082   if (!vam->json_output)
21083     {
21084       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21085              "transport_protocol");
21086     }
21087
21088   /* Construct the API message */
21089   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21090
21091   /* send it... */
21092   S (mp);
21093
21094   /* Use a control ping for synchronization */
21095   MPING (CONTROL_PING, mp_ping);
21096   S (mp_ping);
21097
21098   W (ret);
21099   return ret;
21100 }
21101
21102 static void
21103   vl_api_ipfix_classify_table_details_t_handler
21104   (vl_api_ipfix_classify_table_details_t * mp)
21105 {
21106   vat_main_t *vam = &vat_main;
21107   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21108          mp->transport_protocol);
21109 }
21110
21111 static void
21112   vl_api_ipfix_classify_table_details_t_handler_json
21113   (vl_api_ipfix_classify_table_details_t * mp)
21114 {
21115   vat_json_node_t *node = NULL;
21116   vat_main_t *vam = &vat_main;
21117
21118   if (VAT_JSON_ARRAY != vam->json_tree.type)
21119     {
21120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21121       vat_json_init_array (&vam->json_tree);
21122     }
21123
21124   node = vat_json_array_add (&vam->json_tree);
21125   vat_json_init_object (node);
21126
21127   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21128   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21129   vat_json_object_add_uint (node, "transport_protocol",
21130                             mp->transport_protocol);
21131 }
21132
21133 static int
21134 api_sw_interface_span_enable_disable (vat_main_t * vam)
21135 {
21136   unformat_input_t *i = vam->input;
21137   vl_api_sw_interface_span_enable_disable_t *mp;
21138   u32 src_sw_if_index = ~0;
21139   u32 dst_sw_if_index = ~0;
21140   u8 state = 3;
21141   int ret;
21142   u8 is_l2 = 0;
21143
21144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21145     {
21146       if (unformat
21147           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21148         ;
21149       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21150         ;
21151       else
21152         if (unformat
21153             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21154         ;
21155       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21156         ;
21157       else if (unformat (i, "disable"))
21158         state = 0;
21159       else if (unformat (i, "rx"))
21160         state = 1;
21161       else if (unformat (i, "tx"))
21162         state = 2;
21163       else if (unformat (i, "both"))
21164         state = 3;
21165       else if (unformat (i, "l2"))
21166         is_l2 = 1;
21167       else
21168         break;
21169     }
21170
21171   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21172
21173   mp->sw_if_index_from = htonl (src_sw_if_index);
21174   mp->sw_if_index_to = htonl (dst_sw_if_index);
21175   mp->state = state;
21176   mp->is_l2 = is_l2;
21177
21178   S (mp);
21179   W (ret);
21180   return ret;
21181 }
21182
21183 static void
21184 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21185                                             * mp)
21186 {
21187   vat_main_t *vam = &vat_main;
21188   u8 *sw_if_from_name = 0;
21189   u8 *sw_if_to_name = 0;
21190   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21191   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21192   char *states[] = { "none", "rx", "tx", "both" };
21193   hash_pair_t *p;
21194
21195   /* *INDENT-OFF* */
21196   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21197   ({
21198     if ((u32) p->value[0] == sw_if_index_from)
21199       {
21200         sw_if_from_name = (u8 *)(p->key);
21201         if (sw_if_to_name)
21202           break;
21203       }
21204     if ((u32) p->value[0] == sw_if_index_to)
21205       {
21206         sw_if_to_name = (u8 *)(p->key);
21207         if (sw_if_from_name)
21208           break;
21209       }
21210   }));
21211   /* *INDENT-ON* */
21212   print (vam->ofp, "%20s => %20s (%s) %s",
21213          sw_if_from_name, sw_if_to_name, states[mp->state],
21214          mp->is_l2 ? "l2" : "device");
21215 }
21216
21217 static void
21218   vl_api_sw_interface_span_details_t_handler_json
21219   (vl_api_sw_interface_span_details_t * mp)
21220 {
21221   vat_main_t *vam = &vat_main;
21222   vat_json_node_t *node = NULL;
21223   u8 *sw_if_from_name = 0;
21224   u8 *sw_if_to_name = 0;
21225   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21226   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21227   hash_pair_t *p;
21228
21229   /* *INDENT-OFF* */
21230   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21231   ({
21232     if ((u32) p->value[0] == sw_if_index_from)
21233       {
21234         sw_if_from_name = (u8 *)(p->key);
21235         if (sw_if_to_name)
21236           break;
21237       }
21238     if ((u32) p->value[0] == sw_if_index_to)
21239       {
21240         sw_if_to_name = (u8 *)(p->key);
21241         if (sw_if_from_name)
21242           break;
21243       }
21244   }));
21245   /* *INDENT-ON* */
21246
21247   if (VAT_JSON_ARRAY != vam->json_tree.type)
21248     {
21249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21250       vat_json_init_array (&vam->json_tree);
21251     }
21252   node = vat_json_array_add (&vam->json_tree);
21253
21254   vat_json_init_object (node);
21255   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21256   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21257   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21258   if (0 != sw_if_to_name)
21259     {
21260       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21261     }
21262   vat_json_object_add_uint (node, "state", mp->state);
21263   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21264 }
21265
21266 static int
21267 api_sw_interface_span_dump (vat_main_t * vam)
21268 {
21269   unformat_input_t *input = vam->input;
21270   vl_api_sw_interface_span_dump_t *mp;
21271   vl_api_control_ping_t *mp_ping;
21272   u8 is_l2 = 0;
21273   int ret;
21274
21275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21276     {
21277       if (unformat (input, "l2"))
21278         is_l2 = 1;
21279       else
21280         break;
21281     }
21282
21283   M (SW_INTERFACE_SPAN_DUMP, mp);
21284   mp->is_l2 = is_l2;
21285   S (mp);
21286
21287   /* Use a control ping for synchronization */
21288   MPING (CONTROL_PING, mp_ping);
21289   S (mp_ping);
21290
21291   W (ret);
21292   return ret;
21293 }
21294
21295 int
21296 api_pg_create_interface (vat_main_t * vam)
21297 {
21298   unformat_input_t *input = vam->input;
21299   vl_api_pg_create_interface_t *mp;
21300
21301   u32 if_id = ~0;
21302   int ret;
21303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21304     {
21305       if (unformat (input, "if_id %d", &if_id))
21306         ;
21307       else
21308         break;
21309     }
21310   if (if_id == ~0)
21311     {
21312       errmsg ("missing pg interface index");
21313       return -99;
21314     }
21315
21316   /* Construct the API message */
21317   M (PG_CREATE_INTERFACE, mp);
21318   mp->context = 0;
21319   mp->interface_id = ntohl (if_id);
21320
21321   S (mp);
21322   W (ret);
21323   return ret;
21324 }
21325
21326 int
21327 api_pg_capture (vat_main_t * vam)
21328 {
21329   unformat_input_t *input = vam->input;
21330   vl_api_pg_capture_t *mp;
21331
21332   u32 if_id = ~0;
21333   u8 enable = 1;
21334   u32 count = 1;
21335   u8 pcap_file_set = 0;
21336   u8 *pcap_file = 0;
21337   int ret;
21338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21339     {
21340       if (unformat (input, "if_id %d", &if_id))
21341         ;
21342       else if (unformat (input, "pcap %s", &pcap_file))
21343         pcap_file_set = 1;
21344       else if (unformat (input, "count %d", &count))
21345         ;
21346       else if (unformat (input, "disable"))
21347         enable = 0;
21348       else
21349         break;
21350     }
21351   if (if_id == ~0)
21352     {
21353       errmsg ("missing pg interface index");
21354       return -99;
21355     }
21356   if (pcap_file_set > 0)
21357     {
21358       if (vec_len (pcap_file) > 255)
21359         {
21360           errmsg ("pcap file name is too long");
21361           return -99;
21362         }
21363     }
21364
21365   u32 name_len = vec_len (pcap_file);
21366   /* Construct the API message */
21367   M (PG_CAPTURE, mp);
21368   mp->context = 0;
21369   mp->interface_id = ntohl (if_id);
21370   mp->is_enabled = enable;
21371   mp->count = ntohl (count);
21372   mp->pcap_name_length = ntohl (name_len);
21373   if (pcap_file_set != 0)
21374     {
21375       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21376     }
21377   vec_free (pcap_file);
21378
21379   S (mp);
21380   W (ret);
21381   return ret;
21382 }
21383
21384 int
21385 api_pg_enable_disable (vat_main_t * vam)
21386 {
21387   unformat_input_t *input = vam->input;
21388   vl_api_pg_enable_disable_t *mp;
21389
21390   u8 enable = 1;
21391   u8 stream_name_set = 0;
21392   u8 *stream_name = 0;
21393   int ret;
21394   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21395     {
21396       if (unformat (input, "stream %s", &stream_name))
21397         stream_name_set = 1;
21398       else if (unformat (input, "disable"))
21399         enable = 0;
21400       else
21401         break;
21402     }
21403
21404   if (stream_name_set > 0)
21405     {
21406       if (vec_len (stream_name) > 255)
21407         {
21408           errmsg ("stream name too long");
21409           return -99;
21410         }
21411     }
21412
21413   u32 name_len = vec_len (stream_name);
21414   /* Construct the API message */
21415   M (PG_ENABLE_DISABLE, mp);
21416   mp->context = 0;
21417   mp->is_enabled = enable;
21418   if (stream_name_set != 0)
21419     {
21420       mp->stream_name_length = ntohl (name_len);
21421       clib_memcpy (mp->stream_name, stream_name, name_len);
21422     }
21423   vec_free (stream_name);
21424
21425   S (mp);
21426   W (ret);
21427   return ret;
21428 }
21429
21430 int
21431 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21432 {
21433   unformat_input_t *input = vam->input;
21434   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21435
21436   u16 *low_ports = 0;
21437   u16 *high_ports = 0;
21438   u16 this_low;
21439   u16 this_hi;
21440   ip4_address_t ip4_addr;
21441   ip6_address_t ip6_addr;
21442   u32 length;
21443   u32 tmp, tmp2;
21444   u8 prefix_set = 0;
21445   u32 vrf_id = ~0;
21446   u8 is_add = 1;
21447   u8 is_ipv6 = 0;
21448   int ret;
21449
21450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21451     {
21452       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21453         {
21454           prefix_set = 1;
21455         }
21456       else
21457         if (unformat
21458             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21459         {
21460           prefix_set = 1;
21461           is_ipv6 = 1;
21462         }
21463       else if (unformat (input, "vrf %d", &vrf_id))
21464         ;
21465       else if (unformat (input, "del"))
21466         is_add = 0;
21467       else if (unformat (input, "port %d", &tmp))
21468         {
21469           if (tmp == 0 || tmp > 65535)
21470             {
21471               errmsg ("port %d out of range", tmp);
21472               return -99;
21473             }
21474           this_low = tmp;
21475           this_hi = this_low + 1;
21476           vec_add1 (low_ports, this_low);
21477           vec_add1 (high_ports, this_hi);
21478         }
21479       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21480         {
21481           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21482             {
21483               errmsg ("incorrect range parameters");
21484               return -99;
21485             }
21486           this_low = tmp;
21487           /* Note: in debug CLI +1 is added to high before
21488              passing to real fn that does "the work"
21489              (ip_source_and_port_range_check_add_del).
21490              This fn is a wrapper around the binary API fn a
21491              control plane will call, which expects this increment
21492              to have occurred. Hence letting the binary API control
21493              plane fn do the increment for consistency between VAT
21494              and other control planes.
21495            */
21496           this_hi = tmp2;
21497           vec_add1 (low_ports, this_low);
21498           vec_add1 (high_ports, this_hi);
21499         }
21500       else
21501         break;
21502     }
21503
21504   if (prefix_set == 0)
21505     {
21506       errmsg ("<address>/<mask> not specified");
21507       return -99;
21508     }
21509
21510   if (vrf_id == ~0)
21511     {
21512       errmsg ("VRF ID required, not specified");
21513       return -99;
21514     }
21515
21516   if (vrf_id == 0)
21517     {
21518       errmsg
21519         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21520       return -99;
21521     }
21522
21523   if (vec_len (low_ports) == 0)
21524     {
21525       errmsg ("At least one port or port range required");
21526       return -99;
21527     }
21528
21529   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21530
21531   mp->is_add = is_add;
21532
21533   if (is_ipv6)
21534     {
21535       mp->is_ipv6 = 1;
21536       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21537     }
21538   else
21539     {
21540       mp->is_ipv6 = 0;
21541       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21542     }
21543
21544   mp->mask_length = length;
21545   mp->number_of_ranges = vec_len (low_ports);
21546
21547   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21548   vec_free (low_ports);
21549
21550   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21551   vec_free (high_ports);
21552
21553   mp->vrf_id = ntohl (vrf_id);
21554
21555   S (mp);
21556   W (ret);
21557   return ret;
21558 }
21559
21560 int
21561 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21562 {
21563   unformat_input_t *input = vam->input;
21564   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21565   u32 sw_if_index = ~0;
21566   int vrf_set = 0;
21567   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21568   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21569   u8 is_add = 1;
21570   int ret;
21571
21572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21573     {
21574       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21575         ;
21576       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21577         ;
21578       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21579         vrf_set = 1;
21580       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21581         vrf_set = 1;
21582       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21583         vrf_set = 1;
21584       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21585         vrf_set = 1;
21586       else if (unformat (input, "del"))
21587         is_add = 0;
21588       else
21589         break;
21590     }
21591
21592   if (sw_if_index == ~0)
21593     {
21594       errmsg ("Interface required but not specified");
21595       return -99;
21596     }
21597
21598   if (vrf_set == 0)
21599     {
21600       errmsg ("VRF ID required but not specified");
21601       return -99;
21602     }
21603
21604   if (tcp_out_vrf_id == 0
21605       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21606     {
21607       errmsg
21608         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21609       return -99;
21610     }
21611
21612   /* Construct the API message */
21613   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21614
21615   mp->sw_if_index = ntohl (sw_if_index);
21616   mp->is_add = is_add;
21617   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21618   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21619   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21620   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21621
21622   /* send it... */
21623   S (mp);
21624
21625   /* Wait for a reply... */
21626   W (ret);
21627   return ret;
21628 }
21629
21630 static int
21631 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21632 {
21633   unformat_input_t *i = vam->input;
21634   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21635   u32 local_sa_id = 0;
21636   u32 remote_sa_id = 0;
21637   ip4_address_t src_address;
21638   ip4_address_t dst_address;
21639   u8 is_add = 1;
21640   int ret;
21641
21642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21643     {
21644       if (unformat (i, "local_sa %d", &local_sa_id))
21645         ;
21646       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21647         ;
21648       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21649         ;
21650       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21651         ;
21652       else if (unformat (i, "del"))
21653         is_add = 0;
21654       else
21655         {
21656           clib_warning ("parse error '%U'", format_unformat_error, i);
21657           return -99;
21658         }
21659     }
21660
21661   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21662
21663   mp->local_sa_id = ntohl (local_sa_id);
21664   mp->remote_sa_id = ntohl (remote_sa_id);
21665   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21666   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21667   mp->is_add = is_add;
21668
21669   S (mp);
21670   W (ret);
21671   return ret;
21672 }
21673
21674 static int
21675 api_punt (vat_main_t * vam)
21676 {
21677   unformat_input_t *i = vam->input;
21678   vl_api_punt_t *mp;
21679   u32 ipv = ~0;
21680   u32 protocol = ~0;
21681   u32 port = ~0;
21682   int is_add = 1;
21683   int ret;
21684
21685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21686     {
21687       if (unformat (i, "ip %d", &ipv))
21688         ;
21689       else if (unformat (i, "protocol %d", &protocol))
21690         ;
21691       else if (unformat (i, "port %d", &port))
21692         ;
21693       else if (unformat (i, "del"))
21694         is_add = 0;
21695       else
21696         {
21697           clib_warning ("parse error '%U'", format_unformat_error, i);
21698           return -99;
21699         }
21700     }
21701
21702   M (PUNT, mp);
21703
21704   mp->is_add = (u8) is_add;
21705   mp->ipv = (u8) ipv;
21706   mp->l4_protocol = (u8) protocol;
21707   mp->l4_port = htons ((u16) port);
21708
21709   S (mp);
21710   W (ret);
21711   return ret;
21712 }
21713
21714 static void vl_api_ipsec_gre_tunnel_details_t_handler
21715   (vl_api_ipsec_gre_tunnel_details_t * mp)
21716 {
21717   vat_main_t *vam = &vat_main;
21718
21719   print (vam->ofp, "%11d%15U%15U%14d%14d",
21720          ntohl (mp->sw_if_index),
21721          format_ip4_address, &mp->src_address,
21722          format_ip4_address, &mp->dst_address,
21723          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21724 }
21725
21726 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21727   (vl_api_ipsec_gre_tunnel_details_t * mp)
21728 {
21729   vat_main_t *vam = &vat_main;
21730   vat_json_node_t *node = NULL;
21731   struct in_addr ip4;
21732
21733   if (VAT_JSON_ARRAY != vam->json_tree.type)
21734     {
21735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21736       vat_json_init_array (&vam->json_tree);
21737     }
21738   node = vat_json_array_add (&vam->json_tree);
21739
21740   vat_json_init_object (node);
21741   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21742   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21743   vat_json_object_add_ip4 (node, "src_address", ip4);
21744   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21745   vat_json_object_add_ip4 (node, "dst_address", ip4);
21746   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21747   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21748 }
21749
21750 static int
21751 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21752 {
21753   unformat_input_t *i = vam->input;
21754   vl_api_ipsec_gre_tunnel_dump_t *mp;
21755   vl_api_control_ping_t *mp_ping;
21756   u32 sw_if_index;
21757   u8 sw_if_index_set = 0;
21758   int ret;
21759
21760   /* Parse args required to build the message */
21761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21762     {
21763       if (unformat (i, "sw_if_index %d", &sw_if_index))
21764         sw_if_index_set = 1;
21765       else
21766         break;
21767     }
21768
21769   if (sw_if_index_set == 0)
21770     {
21771       sw_if_index = ~0;
21772     }
21773
21774   if (!vam->json_output)
21775     {
21776       print (vam->ofp, "%11s%15s%15s%14s%14s",
21777              "sw_if_index", "src_address", "dst_address",
21778              "local_sa_id", "remote_sa_id");
21779     }
21780
21781   /* Get list of gre-tunnel interfaces */
21782   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21783
21784   mp->sw_if_index = htonl (sw_if_index);
21785
21786   S (mp);
21787
21788   /* Use a control ping for synchronization */
21789   MPING (CONTROL_PING, mp_ping);
21790   S (mp_ping);
21791
21792   W (ret);
21793   return ret;
21794 }
21795
21796 static int
21797 api_delete_subif (vat_main_t * vam)
21798 {
21799   unformat_input_t *i = vam->input;
21800   vl_api_delete_subif_t *mp;
21801   u32 sw_if_index = ~0;
21802   int ret;
21803
21804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21805     {
21806       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21807         ;
21808       if (unformat (i, "sw_if_index %d", &sw_if_index))
21809         ;
21810       else
21811         break;
21812     }
21813
21814   if (sw_if_index == ~0)
21815     {
21816       errmsg ("missing sw_if_index");
21817       return -99;
21818     }
21819
21820   /* Construct the API message */
21821   M (DELETE_SUBIF, mp);
21822   mp->sw_if_index = ntohl (sw_if_index);
21823
21824   S (mp);
21825   W (ret);
21826   return ret;
21827 }
21828
21829 #define foreach_pbb_vtr_op      \
21830 _("disable",  L2_VTR_DISABLED)  \
21831 _("pop",  L2_VTR_POP_2)         \
21832 _("push",  L2_VTR_PUSH_2)
21833
21834 static int
21835 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21836 {
21837   unformat_input_t *i = vam->input;
21838   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21839   u32 sw_if_index = ~0, vtr_op = ~0;
21840   u16 outer_tag = ~0;
21841   u8 dmac[6], smac[6];
21842   u8 dmac_set = 0, smac_set = 0;
21843   u16 vlanid = 0;
21844   u32 sid = ~0;
21845   u32 tmp;
21846   int ret;
21847
21848   /* Shut up coverity */
21849   memset (dmac, 0, sizeof (dmac));
21850   memset (smac, 0, sizeof (smac));
21851
21852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21853     {
21854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21855         ;
21856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21857         ;
21858       else if (unformat (i, "vtr_op %d", &vtr_op))
21859         ;
21860 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21861       foreach_pbb_vtr_op
21862 #undef _
21863         else if (unformat (i, "translate_pbb_stag"))
21864         {
21865           if (unformat (i, "%d", &tmp))
21866             {
21867               vtr_op = L2_VTR_TRANSLATE_2_1;
21868               outer_tag = tmp;
21869             }
21870           else
21871             {
21872               errmsg
21873                 ("translate_pbb_stag operation requires outer tag definition");
21874               return -99;
21875             }
21876         }
21877       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21878         dmac_set++;
21879       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21880         smac_set++;
21881       else if (unformat (i, "sid %d", &sid))
21882         ;
21883       else if (unformat (i, "vlanid %d", &tmp))
21884         vlanid = tmp;
21885       else
21886         {
21887           clib_warning ("parse error '%U'", format_unformat_error, i);
21888           return -99;
21889         }
21890     }
21891
21892   if ((sw_if_index == ~0) || (vtr_op == ~0))
21893     {
21894       errmsg ("missing sw_if_index or vtr operation");
21895       return -99;
21896     }
21897   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21898       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21899     {
21900       errmsg
21901         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21902       return -99;
21903     }
21904
21905   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21906   mp->sw_if_index = ntohl (sw_if_index);
21907   mp->vtr_op = ntohl (vtr_op);
21908   mp->outer_tag = ntohs (outer_tag);
21909   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21910   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21911   mp->b_vlanid = ntohs (vlanid);
21912   mp->i_sid = ntohl (sid);
21913
21914   S (mp);
21915   W (ret);
21916   return ret;
21917 }
21918
21919 static int
21920 api_flow_classify_set_interface (vat_main_t * vam)
21921 {
21922   unformat_input_t *i = vam->input;
21923   vl_api_flow_classify_set_interface_t *mp;
21924   u32 sw_if_index;
21925   int sw_if_index_set;
21926   u32 ip4_table_index = ~0;
21927   u32 ip6_table_index = ~0;
21928   u8 is_add = 1;
21929   int ret;
21930
21931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21932     {
21933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21934         sw_if_index_set = 1;
21935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21936         sw_if_index_set = 1;
21937       else if (unformat (i, "del"))
21938         is_add = 0;
21939       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21940         ;
21941       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21942         ;
21943       else
21944         {
21945           clib_warning ("parse error '%U'", format_unformat_error, i);
21946           return -99;
21947         }
21948     }
21949
21950   if (sw_if_index_set == 0)
21951     {
21952       errmsg ("missing interface name or sw_if_index");
21953       return -99;
21954     }
21955
21956   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21957
21958   mp->sw_if_index = ntohl (sw_if_index);
21959   mp->ip4_table_index = ntohl (ip4_table_index);
21960   mp->ip6_table_index = ntohl (ip6_table_index);
21961   mp->is_add = is_add;
21962
21963   S (mp);
21964   W (ret);
21965   return ret;
21966 }
21967
21968 static int
21969 api_flow_classify_dump (vat_main_t * vam)
21970 {
21971   unformat_input_t *i = vam->input;
21972   vl_api_flow_classify_dump_t *mp;
21973   vl_api_control_ping_t *mp_ping;
21974   u8 type = FLOW_CLASSIFY_N_TABLES;
21975   int ret;
21976
21977   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21978     ;
21979   else
21980     {
21981       errmsg ("classify table type must be specified");
21982       return -99;
21983     }
21984
21985   if (!vam->json_output)
21986     {
21987       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21988     }
21989
21990   M (FLOW_CLASSIFY_DUMP, mp);
21991   mp->type = type;
21992   /* send it... */
21993   S (mp);
21994
21995   /* Use a control ping for synchronization */
21996   MPING (CONTROL_PING, mp_ping);
21997   S (mp_ping);
21998
21999   /* Wait for a reply... */
22000   W (ret);
22001   return ret;
22002 }
22003
22004 static int
22005 api_feature_enable_disable (vat_main_t * vam)
22006 {
22007   unformat_input_t *i = vam->input;
22008   vl_api_feature_enable_disable_t *mp;
22009   u8 *arc_name = 0;
22010   u8 *feature_name = 0;
22011   u32 sw_if_index = ~0;
22012   u8 enable = 1;
22013   int ret;
22014
22015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22016     {
22017       if (unformat (i, "arc_name %s", &arc_name))
22018         ;
22019       else if (unformat (i, "feature_name %s", &feature_name))
22020         ;
22021       else
22022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22023         ;
22024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22025         ;
22026       else if (unformat (i, "disable"))
22027         enable = 0;
22028       else
22029         break;
22030     }
22031
22032   if (arc_name == 0)
22033     {
22034       errmsg ("missing arc name");
22035       return -99;
22036     }
22037   if (vec_len (arc_name) > 63)
22038     {
22039       errmsg ("arc name too long");
22040     }
22041
22042   if (feature_name == 0)
22043     {
22044       errmsg ("missing feature name");
22045       return -99;
22046     }
22047   if (vec_len (feature_name) > 63)
22048     {
22049       errmsg ("feature name too long");
22050     }
22051
22052   if (sw_if_index == ~0)
22053     {
22054       errmsg ("missing interface name or sw_if_index");
22055       return -99;
22056     }
22057
22058   /* Construct the API message */
22059   M (FEATURE_ENABLE_DISABLE, mp);
22060   mp->sw_if_index = ntohl (sw_if_index);
22061   mp->enable = enable;
22062   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22063   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22064   vec_free (arc_name);
22065   vec_free (feature_name);
22066
22067   S (mp);
22068   W (ret);
22069   return ret;
22070 }
22071
22072 static int
22073 api_sw_interface_tag_add_del (vat_main_t * vam)
22074 {
22075   unformat_input_t *i = vam->input;
22076   vl_api_sw_interface_tag_add_del_t *mp;
22077   u32 sw_if_index = ~0;
22078   u8 *tag = 0;
22079   u8 enable = 1;
22080   int ret;
22081
22082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22083     {
22084       if (unformat (i, "tag %s", &tag))
22085         ;
22086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22087         ;
22088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22089         ;
22090       else if (unformat (i, "del"))
22091         enable = 0;
22092       else
22093         break;
22094     }
22095
22096   if (sw_if_index == ~0)
22097     {
22098       errmsg ("missing interface name or sw_if_index");
22099       return -99;
22100     }
22101
22102   if (enable && (tag == 0))
22103     {
22104       errmsg ("no tag specified");
22105       return -99;
22106     }
22107
22108   /* Construct the API message */
22109   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22110   mp->sw_if_index = ntohl (sw_if_index);
22111   mp->is_add = enable;
22112   if (enable)
22113     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22114   vec_free (tag);
22115
22116   S (mp);
22117   W (ret);
22118   return ret;
22119 }
22120
22121 static void vl_api_l2_xconnect_details_t_handler
22122   (vl_api_l2_xconnect_details_t * mp)
22123 {
22124   vat_main_t *vam = &vat_main;
22125
22126   print (vam->ofp, "%15d%15d",
22127          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22128 }
22129
22130 static void vl_api_l2_xconnect_details_t_handler_json
22131   (vl_api_l2_xconnect_details_t * mp)
22132 {
22133   vat_main_t *vam = &vat_main;
22134   vat_json_node_t *node = NULL;
22135
22136   if (VAT_JSON_ARRAY != vam->json_tree.type)
22137     {
22138       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22139       vat_json_init_array (&vam->json_tree);
22140     }
22141   node = vat_json_array_add (&vam->json_tree);
22142
22143   vat_json_init_object (node);
22144   vat_json_object_add_uint (node, "rx_sw_if_index",
22145                             ntohl (mp->rx_sw_if_index));
22146   vat_json_object_add_uint (node, "tx_sw_if_index",
22147                             ntohl (mp->tx_sw_if_index));
22148 }
22149
22150 static int
22151 api_l2_xconnect_dump (vat_main_t * vam)
22152 {
22153   vl_api_l2_xconnect_dump_t *mp;
22154   vl_api_control_ping_t *mp_ping;
22155   int ret;
22156
22157   if (!vam->json_output)
22158     {
22159       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22160     }
22161
22162   M (L2_XCONNECT_DUMP, mp);
22163
22164   S (mp);
22165
22166   /* Use a control ping for synchronization */
22167   MPING (CONTROL_PING, mp_ping);
22168   S (mp_ping);
22169
22170   W (ret);
22171   return ret;
22172 }
22173
22174 static int
22175 api_hw_interface_set_mtu (vat_main_t * vam)
22176 {
22177   unformat_input_t *i = vam->input;
22178   vl_api_hw_interface_set_mtu_t *mp;
22179   u32 sw_if_index = ~0;
22180   u32 mtu = 0;
22181   int ret;
22182
22183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22184     {
22185       if (unformat (i, "mtu %d", &mtu))
22186         ;
22187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22188         ;
22189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22190         ;
22191       else
22192         break;
22193     }
22194
22195   if (sw_if_index == ~0)
22196     {
22197       errmsg ("missing interface name or sw_if_index");
22198       return -99;
22199     }
22200
22201   if (mtu == 0)
22202     {
22203       errmsg ("no mtu specified");
22204       return -99;
22205     }
22206
22207   /* Construct the API message */
22208   M (HW_INTERFACE_SET_MTU, mp);
22209   mp->sw_if_index = ntohl (sw_if_index);
22210   mp->mtu = ntohs ((u16) mtu);
22211
22212   S (mp);
22213   W (ret);
22214   return ret;
22215 }
22216
22217 static int
22218 api_p2p_ethernet_add (vat_main_t * vam)
22219 {
22220   unformat_input_t *i = vam->input;
22221   vl_api_p2p_ethernet_add_t *mp;
22222   u32 parent_if_index = ~0;
22223   u32 sub_id = ~0;
22224   u8 remote_mac[6];
22225   u8 mac_set = 0;
22226   int ret;
22227
22228   memset (remote_mac, 0, sizeof (remote_mac));
22229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22230     {
22231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22232         ;
22233       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22234         ;
22235       else
22236         if (unformat
22237             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22238         mac_set++;
22239       else if (unformat (i, "sub_id %d", &sub_id))
22240         ;
22241       else
22242         {
22243           clib_warning ("parse error '%U'", format_unformat_error, i);
22244           return -99;
22245         }
22246     }
22247
22248   if (parent_if_index == ~0)
22249     {
22250       errmsg ("missing interface name or sw_if_index");
22251       return -99;
22252     }
22253   if (mac_set == 0)
22254     {
22255       errmsg ("missing remote mac address");
22256       return -99;
22257     }
22258   if (sub_id == ~0)
22259     {
22260       errmsg ("missing sub-interface id");
22261       return -99;
22262     }
22263
22264   M (P2P_ETHERNET_ADD, mp);
22265   mp->parent_if_index = ntohl (parent_if_index);
22266   mp->subif_id = ntohl (sub_id);
22267   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22268
22269   S (mp);
22270   W (ret);
22271   return ret;
22272 }
22273
22274 static int
22275 api_p2p_ethernet_del (vat_main_t * vam)
22276 {
22277   unformat_input_t *i = vam->input;
22278   vl_api_p2p_ethernet_del_t *mp;
22279   u32 parent_if_index = ~0;
22280   u8 remote_mac[6];
22281   u8 mac_set = 0;
22282   int ret;
22283
22284   memset (remote_mac, 0, sizeof (remote_mac));
22285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22286     {
22287       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22288         ;
22289       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22290         ;
22291       else
22292         if (unformat
22293             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22294         mac_set++;
22295       else
22296         {
22297           clib_warning ("parse error '%U'", format_unformat_error, i);
22298           return -99;
22299         }
22300     }
22301
22302   if (parent_if_index == ~0)
22303     {
22304       errmsg ("missing interface name or sw_if_index");
22305       return -99;
22306     }
22307   if (mac_set == 0)
22308     {
22309       errmsg ("missing remote mac address");
22310       return -99;
22311     }
22312
22313   M (P2P_ETHERNET_DEL, mp);
22314   mp->parent_if_index = ntohl (parent_if_index);
22315   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22316
22317   S (mp);
22318   W (ret);
22319   return ret;
22320 }
22321
22322 static int
22323 api_lldp_config (vat_main_t * vam)
22324 {
22325   unformat_input_t *i = vam->input;
22326   vl_api_lldp_config_t *mp;
22327   int tx_hold = 0;
22328   int tx_interval = 0;
22329   u8 *sys_name = NULL;
22330   int ret;
22331
22332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22333     {
22334       if (unformat (i, "system-name %s", &sys_name))
22335         ;
22336       else if (unformat (i, "tx-hold %d", &tx_hold))
22337         ;
22338       else if (unformat (i, "tx-interval %d", &tx_interval))
22339         ;
22340       else
22341         {
22342           clib_warning ("parse error '%U'", format_unformat_error, i);
22343           return -99;
22344         }
22345     }
22346
22347   vec_add1 (sys_name, 0);
22348
22349   M (LLDP_CONFIG, mp);
22350   mp->tx_hold = htonl (tx_hold);
22351   mp->tx_interval = htonl (tx_interval);
22352   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22353   vec_free (sys_name);
22354
22355   S (mp);
22356   W (ret);
22357   return ret;
22358 }
22359
22360 static int
22361 api_sw_interface_set_lldp (vat_main_t * vam)
22362 {
22363   unformat_input_t *i = vam->input;
22364   vl_api_sw_interface_set_lldp_t *mp;
22365   u32 sw_if_index = ~0;
22366   u32 enable = 1;
22367   u8 *port_desc = NULL, *mgmt_oid = NULL;
22368   ip4_address_t ip4_addr;
22369   ip6_address_t ip6_addr;
22370   int ret;
22371
22372   memset (&ip4_addr, 0, sizeof (ip4_addr));
22373   memset (&ip6_addr, 0, sizeof (ip6_addr));
22374
22375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22376     {
22377       if (unformat (i, "disable"))
22378         enable = 0;
22379       else
22380         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22381         ;
22382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22383         ;
22384       else if (unformat (i, "port-desc %s", &port_desc))
22385         ;
22386       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22387         ;
22388       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22389         ;
22390       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22391         ;
22392       else
22393         break;
22394     }
22395
22396   if (sw_if_index == ~0)
22397     {
22398       errmsg ("missing interface name or sw_if_index");
22399       return -99;
22400     }
22401
22402   /* Construct the API message */
22403   vec_add1 (port_desc, 0);
22404   vec_add1 (mgmt_oid, 0);
22405   M (SW_INTERFACE_SET_LLDP, mp);
22406   mp->sw_if_index = ntohl (sw_if_index);
22407   mp->enable = enable;
22408   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22409   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22410   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22411   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22412   vec_free (port_desc);
22413   vec_free (mgmt_oid);
22414
22415   S (mp);
22416   W (ret);
22417   return ret;
22418 }
22419
22420 static int
22421 api_tcp_configure_src_addresses (vat_main_t * vam)
22422 {
22423   vl_api_tcp_configure_src_addresses_t *mp;
22424   unformat_input_t *i = vam->input;
22425   ip4_address_t v4first, v4last;
22426   ip6_address_t v6first, v6last;
22427   u8 range_set = 0;
22428   u32 vrf_id = 0;
22429   int ret;
22430
22431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22432     {
22433       if (unformat (i, "%U - %U",
22434                     unformat_ip4_address, &v4first,
22435                     unformat_ip4_address, &v4last))
22436         {
22437           if (range_set)
22438             {
22439               errmsg ("one range per message (range already set)");
22440               return -99;
22441             }
22442           range_set = 1;
22443         }
22444       else if (unformat (i, "%U - %U",
22445                          unformat_ip6_address, &v6first,
22446                          unformat_ip6_address, &v6last))
22447         {
22448           if (range_set)
22449             {
22450               errmsg ("one range per message (range already set)");
22451               return -99;
22452             }
22453           range_set = 2;
22454         }
22455       else if (unformat (i, "vrf %d", &vrf_id))
22456         ;
22457       else
22458         break;
22459     }
22460
22461   if (range_set == 0)
22462     {
22463       errmsg ("address range not set");
22464       return -99;
22465     }
22466
22467   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22468   mp->vrf_id = ntohl (vrf_id);
22469   /* ipv6? */
22470   if (range_set == 2)
22471     {
22472       mp->is_ipv6 = 1;
22473       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22474       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22475     }
22476   else
22477     {
22478       mp->is_ipv6 = 0;
22479       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22480       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22481     }
22482   S (mp);
22483   W (ret);
22484   return ret;
22485 }
22486
22487 static void vl_api_app_namespace_add_del_reply_t_handler
22488   (vl_api_app_namespace_add_del_reply_t * mp)
22489 {
22490   vat_main_t *vam = &vat_main;
22491   i32 retval = ntohl (mp->retval);
22492   if (vam->async_mode)
22493     {
22494       vam->async_errors += (retval < 0);
22495     }
22496   else
22497     {
22498       vam->retval = retval;
22499       if (retval == 0)
22500         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22501       vam->result_ready = 1;
22502     }
22503 }
22504
22505 static void vl_api_app_namespace_add_del_reply_t_handler_json
22506   (vl_api_app_namespace_add_del_reply_t * mp)
22507 {
22508   vat_main_t *vam = &vat_main;
22509   vat_json_node_t node;
22510
22511   vat_json_init_object (&node);
22512   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22513   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22514
22515   vat_json_print (vam->ofp, &node);
22516   vat_json_free (&node);
22517
22518   vam->retval = ntohl (mp->retval);
22519   vam->result_ready = 1;
22520 }
22521
22522 static int
22523 api_app_namespace_add_del (vat_main_t * vam)
22524 {
22525   vl_api_app_namespace_add_del_t *mp;
22526   unformat_input_t *i = vam->input;
22527   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22528   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22529   u64 secret;
22530   int ret;
22531
22532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22533     {
22534       if (unformat (i, "id %_%v%_", &ns_id))
22535         ;
22536       else if (unformat (i, "secret %lu", &secret))
22537         secret_set = 1;
22538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22539         sw_if_index_set = 1;
22540       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22541         ;
22542       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22543         ;
22544       else
22545         break;
22546     }
22547   if (!ns_id || !secret_set || !sw_if_index_set)
22548     {
22549       errmsg ("namespace id, secret and sw_if_index must be set");
22550       return -99;
22551     }
22552   if (vec_len (ns_id) > 64)
22553     {
22554       errmsg ("namespace id too long");
22555       return -99;
22556     }
22557   M (APP_NAMESPACE_ADD_DEL, mp);
22558
22559   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22560   mp->namespace_id_len = vec_len (ns_id);
22561   mp->secret = clib_host_to_net_u64 (secret);
22562   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22563   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22564   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22565   vec_free (ns_id);
22566   S (mp);
22567   W (ret);
22568   return ret;
22569 }
22570
22571 static int
22572 api_sock_init_shm (vat_main_t * vam)
22573 {
22574 #if VPP_API_TEST_BUILTIN == 0
22575   unformat_input_t *i = vam->input;
22576   vl_api_shm_elem_config_t *config = 0;
22577   u64 size = 64 << 20;
22578   int rv;
22579
22580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22581     {
22582       if (unformat (i, "size %U", unformat_memory_size, &size))
22583         ;
22584       else
22585         break;
22586     }
22587
22588   /*
22589    * Canned custom ring allocator config.
22590    * Should probably parse all of this
22591    */
22592   vec_validate (config, 6);
22593   config[0].type = VL_API_VLIB_RING;
22594   config[0].size = 256;
22595   config[0].count = 32;
22596
22597   config[1].type = VL_API_VLIB_RING;
22598   config[1].size = 1024;
22599   config[1].count = 16;
22600
22601   config[2].type = VL_API_VLIB_RING;
22602   config[2].size = 4096;
22603   config[2].count = 2;
22604
22605   config[3].type = VL_API_CLIENT_RING;
22606   config[3].size = 256;
22607   config[3].count = 32;
22608
22609   config[4].type = VL_API_CLIENT_RING;
22610   config[4].size = 1024;
22611   config[4].count = 16;
22612
22613   config[5].type = VL_API_CLIENT_RING;
22614   config[5].size = 4096;
22615   config[5].count = 2;
22616
22617   config[6].type = VL_API_QUEUE;
22618   config[6].count = 128;
22619   config[6].size = sizeof (uword);
22620
22621   rv = vl_socket_client_init_shm (config);
22622   if (!rv)
22623     vam->client_index_invalid = 1;
22624   return rv;
22625 #else
22626   return -99;
22627 #endif
22628 }
22629
22630 static int
22631 api_dns_enable_disable (vat_main_t * vam)
22632 {
22633   unformat_input_t *line_input = vam->input;
22634   vl_api_dns_enable_disable_t *mp;
22635   u8 enable_disable = 1;
22636   int ret;
22637
22638   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22639     {
22640       if (unformat (line_input, "disable"))
22641         enable_disable = 0;
22642       if (unformat (line_input, "enable"))
22643         enable_disable = 1;
22644       else
22645         break;
22646     }
22647
22648   /* Construct the API message */
22649   M (DNS_ENABLE_DISABLE, mp);
22650   mp->enable = enable_disable;
22651
22652   /* send it... */
22653   S (mp);
22654   /* Wait for the reply */
22655   W (ret);
22656   return ret;
22657 }
22658
22659 static int
22660 api_dns_resolve_name (vat_main_t * vam)
22661 {
22662   unformat_input_t *line_input = vam->input;
22663   vl_api_dns_resolve_name_t *mp;
22664   u8 *name = 0;
22665   int ret;
22666
22667   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22668     {
22669       if (unformat (line_input, "%s", &name))
22670         ;
22671       else
22672         break;
22673     }
22674
22675   if (vec_len (name) > 127)
22676     {
22677       errmsg ("name too long");
22678       return -99;
22679     }
22680
22681   /* Construct the API message */
22682   M (DNS_RESOLVE_NAME, mp);
22683   memcpy (mp->name, name, vec_len (name));
22684   vec_free (name);
22685
22686   /* send it... */
22687   S (mp);
22688   /* Wait for the reply */
22689   W (ret);
22690   return ret;
22691 }
22692
22693 static int
22694 api_dns_resolve_ip (vat_main_t * vam)
22695 {
22696   unformat_input_t *line_input = vam->input;
22697   vl_api_dns_resolve_ip_t *mp;
22698   int is_ip6 = -1;
22699   ip4_address_t addr4;
22700   ip6_address_t addr6;
22701   int ret;
22702
22703   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22704     {
22705       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22706         is_ip6 = 1;
22707       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22708         is_ip6 = 0;
22709       else
22710         break;
22711     }
22712
22713   if (is_ip6 == -1)
22714     {
22715       errmsg ("missing address");
22716       return -99;
22717     }
22718
22719   /* Construct the API message */
22720   M (DNS_RESOLVE_IP, mp);
22721   mp->is_ip6 = is_ip6;
22722   if (is_ip6)
22723     memcpy (mp->address, &addr6, sizeof (addr6));
22724   else
22725     memcpy (mp->address, &addr4, sizeof (addr4));
22726
22727   /* send it... */
22728   S (mp);
22729   /* Wait for the reply */
22730   W (ret);
22731   return ret;
22732 }
22733
22734 static int
22735 api_dns_name_server_add_del (vat_main_t * vam)
22736 {
22737   unformat_input_t *i = vam->input;
22738   vl_api_dns_name_server_add_del_t *mp;
22739   u8 is_add = 1;
22740   ip6_address_t ip6_server;
22741   ip4_address_t ip4_server;
22742   int ip6_set = 0;
22743   int ip4_set = 0;
22744   int ret = 0;
22745
22746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22747     {
22748       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22749         ip6_set = 1;
22750       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22751         ip4_set = 1;
22752       else if (unformat (i, "del"))
22753         is_add = 0;
22754       else
22755         {
22756           clib_warning ("parse error '%U'", format_unformat_error, i);
22757           return -99;
22758         }
22759     }
22760
22761   if (ip4_set && ip6_set)
22762     {
22763       errmsg ("Only one server address allowed per message");
22764       return -99;
22765     }
22766   if ((ip4_set + ip6_set) == 0)
22767     {
22768       errmsg ("Server address required");
22769       return -99;
22770     }
22771
22772   /* Construct the API message */
22773   M (DNS_NAME_SERVER_ADD_DEL, mp);
22774
22775   if (ip6_set)
22776     {
22777       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22778       mp->is_ip6 = 1;
22779     }
22780   else
22781     {
22782       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22783       mp->is_ip6 = 0;
22784     }
22785
22786   mp->is_add = is_add;
22787
22788   /* send it... */
22789   S (mp);
22790
22791   /* Wait for a reply, return good/bad news  */
22792   W (ret);
22793   return ret;
22794 }
22795
22796 static void
22797 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22798 {
22799   vat_main_t *vam = &vat_main;
22800
22801   if (mp->is_ip4)
22802     {
22803       print (vam->ofp,
22804              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22805              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22806              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22807              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22808              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22809              clib_net_to_host_u32 (mp->action_index), mp->tag);
22810     }
22811   else
22812     {
22813       print (vam->ofp,
22814              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22815              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22816              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22817              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22818              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22819              clib_net_to_host_u32 (mp->action_index), mp->tag);
22820     }
22821 }
22822
22823 static void
22824 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22825                                              mp)
22826 {
22827   vat_main_t *vam = &vat_main;
22828   vat_json_node_t *node = NULL;
22829   struct in6_addr ip6;
22830   struct in_addr ip4;
22831
22832   if (VAT_JSON_ARRAY != vam->json_tree.type)
22833     {
22834       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22835       vat_json_init_array (&vam->json_tree);
22836     }
22837   node = vat_json_array_add (&vam->json_tree);
22838   vat_json_init_object (node);
22839
22840   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22841   vat_json_object_add_uint (node, "appns_index",
22842                             clib_net_to_host_u32 (mp->appns_index));
22843   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22844   vat_json_object_add_uint (node, "scope", mp->scope);
22845   vat_json_object_add_uint (node, "action_index",
22846                             clib_net_to_host_u32 (mp->action_index));
22847   vat_json_object_add_uint (node, "lcl_port",
22848                             clib_net_to_host_u16 (mp->lcl_port));
22849   vat_json_object_add_uint (node, "rmt_port",
22850                             clib_net_to_host_u16 (mp->rmt_port));
22851   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22852   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22853   vat_json_object_add_string_copy (node, "tag", mp->tag);
22854   if (mp->is_ip4)
22855     {
22856       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22857       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22858       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22859       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22860     }
22861   else
22862     {
22863       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22864       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22865       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22866       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22867     }
22868 }
22869
22870 static int
22871 api_session_rule_add_del (vat_main_t * vam)
22872 {
22873   vl_api_session_rule_add_del_t *mp;
22874   unformat_input_t *i = vam->input;
22875   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22876   u32 appns_index = 0, scope = 0;
22877   ip4_address_t lcl_ip4, rmt_ip4;
22878   ip6_address_t lcl_ip6, rmt_ip6;
22879   u8 is_ip4 = 1, conn_set = 0;
22880   u8 is_add = 1, *tag = 0;
22881   int ret;
22882
22883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22884     {
22885       if (unformat (i, "del"))
22886         is_add = 0;
22887       else if (unformat (i, "add"))
22888         ;
22889       else if (unformat (i, "proto tcp"))
22890         proto = 0;
22891       else if (unformat (i, "proto udp"))
22892         proto = 1;
22893       else if (unformat (i, "appns %d", &appns_index))
22894         ;
22895       else if (unformat (i, "scope %d", &scope))
22896         ;
22897       else if (unformat (i, "tag %_%v%_", &tag))
22898         ;
22899       else
22900         if (unformat
22901             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22902              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22903              &rmt_port))
22904         {
22905           is_ip4 = 1;
22906           conn_set = 1;
22907         }
22908       else
22909         if (unformat
22910             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22911              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22912              &rmt_port))
22913         {
22914           is_ip4 = 0;
22915           conn_set = 1;
22916         }
22917       else if (unformat (i, "action %d", &action))
22918         ;
22919       else
22920         break;
22921     }
22922   if (proto == ~0 || !conn_set || action == ~0)
22923     {
22924       errmsg ("transport proto, connection and action must be set");
22925       return -99;
22926     }
22927
22928   if (scope > 3)
22929     {
22930       errmsg ("scope should be 0-3");
22931       return -99;
22932     }
22933
22934   M (SESSION_RULE_ADD_DEL, mp);
22935
22936   mp->is_ip4 = is_ip4;
22937   mp->transport_proto = proto;
22938   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22939   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22940   mp->lcl_plen = lcl_plen;
22941   mp->rmt_plen = rmt_plen;
22942   mp->action_index = clib_host_to_net_u32 (action);
22943   mp->appns_index = clib_host_to_net_u32 (appns_index);
22944   mp->scope = scope;
22945   mp->is_add = is_add;
22946   if (is_ip4)
22947     {
22948       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22949       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22950     }
22951   else
22952     {
22953       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22954       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22955     }
22956   if (tag)
22957     {
22958       clib_memcpy (mp->tag, tag, vec_len (tag));
22959       vec_free (tag);
22960     }
22961
22962   S (mp);
22963   W (ret);
22964   return ret;
22965 }
22966
22967 static int
22968 api_session_rules_dump (vat_main_t * vam)
22969 {
22970   vl_api_session_rules_dump_t *mp;
22971   vl_api_control_ping_t *mp_ping;
22972   int ret;
22973
22974   if (!vam->json_output)
22975     {
22976       print (vam->ofp, "%=20s", "Session Rules");
22977     }
22978
22979   M (SESSION_RULES_DUMP, mp);
22980   /* send it... */
22981   S (mp);
22982
22983   /* Use a control ping for synchronization */
22984   MPING (CONTROL_PING, mp_ping);
22985   S (mp_ping);
22986
22987   /* Wait for a reply... */
22988   W (ret);
22989   return ret;
22990 }
22991
22992 static int
22993 api_ip_container_proxy_add_del (vat_main_t * vam)
22994 {
22995   vl_api_ip_container_proxy_add_del_t *mp;
22996   unformat_input_t *i = vam->input;
22997   u32 plen = ~0, sw_if_index = ~0;
22998   ip4_address_t ip4;
22999   ip6_address_t ip6;
23000   u8 is_ip4 = 1;
23001   u8 is_add = 1;
23002   int ret;
23003
23004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23005     {
23006       if (unformat (i, "del"))
23007         is_add = 0;
23008       else if (unformat (i, "add"))
23009         ;
23010       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23011         {
23012           is_ip4 = 1;
23013           plen = 32;
23014         }
23015       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23016         {
23017           is_ip4 = 0;
23018           plen = 128;
23019         }
23020       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23021         ;
23022       else
23023         break;
23024     }
23025   if (sw_if_index == ~0 || plen == ~0)
23026     {
23027       errmsg ("address and sw_if_index must be set");
23028       return -99;
23029     }
23030
23031   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23032
23033   mp->is_ip4 = is_ip4;
23034   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23035   mp->plen = plen;
23036   mp->is_add = is_add;
23037   if (is_ip4)
23038     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23039   else
23040     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23041
23042   S (mp);
23043   W (ret);
23044   return ret;
23045 }
23046
23047 static int
23048 api_qos_record_enable_disable (vat_main_t * vam)
23049 {
23050   unformat_input_t *i = vam->input;
23051   vl_api_qos_record_enable_disable_t *mp;
23052   u32 sw_if_index, qs = 0xff;
23053   u8 sw_if_index_set = 0;
23054   u8 enable = 1;
23055   int ret;
23056
23057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23058     {
23059       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23060         sw_if_index_set = 1;
23061       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23062         sw_if_index_set = 1;
23063       else if (unformat (i, "%U", unformat_qos_source, &qs))
23064         ;
23065       else if (unformat (i, "disable"))
23066         enable = 0;
23067       else
23068         {
23069           clib_warning ("parse error '%U'", format_unformat_error, i);
23070           return -99;
23071         }
23072     }
23073
23074   if (sw_if_index_set == 0)
23075     {
23076       errmsg ("missing interface name or sw_if_index");
23077       return -99;
23078     }
23079   if (qs == 0xff)
23080     {
23081       errmsg ("input location must be specified");
23082       return -99;
23083     }
23084
23085   M (QOS_RECORD_ENABLE_DISABLE, mp);
23086
23087   mp->sw_if_index = ntohl (sw_if_index);
23088   mp->input_source = qs;
23089   mp->enable = enable;
23090
23091   S (mp);
23092   W (ret);
23093   return ret;
23094 }
23095
23096
23097 static int
23098 q_or_quit (vat_main_t * vam)
23099 {
23100 #if VPP_API_TEST_BUILTIN == 0
23101   longjmp (vam->jump_buf, 1);
23102 #endif
23103   return 0;                     /* not so much */
23104 }
23105
23106 static int
23107 q (vat_main_t * vam)
23108 {
23109   return q_or_quit (vam);
23110 }
23111
23112 static int
23113 quit (vat_main_t * vam)
23114 {
23115   return q_or_quit (vam);
23116 }
23117
23118 static int
23119 comment (vat_main_t * vam)
23120 {
23121   return 0;
23122 }
23123
23124 static int
23125 statseg (vat_main_t * vam)
23126 {
23127   ssvm_private_t *ssvmp = &vam->stat_segment;
23128   ssvm_shared_header_t *shared_header = ssvmp->sh;
23129   vlib_counter_t **counters;
23130   u64 thread0_index1_packets;
23131   u64 thread0_index1_bytes;
23132   f64 vector_rate, input_rate;
23133   uword *p;
23134
23135   uword *counter_vector_by_name;
23136   if (vam->stat_segment_lockp == 0)
23137     {
23138       errmsg ("Stat segment not mapped...");
23139       return -99;
23140     }
23141
23142   /* look up "/if/rx for sw_if_index 1 as a test */
23143
23144   clib_spinlock_lock (vam->stat_segment_lockp);
23145
23146   counter_vector_by_name = (uword *) shared_header->opaque[1];
23147
23148   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23149   if (p == 0)
23150     {
23151       clib_spinlock_unlock (vam->stat_segment_lockp);
23152       errmsg ("/if/tx not found?");
23153       return -99;
23154     }
23155
23156   /* Fish per-thread vector of combined counters from shared memory */
23157   counters = (vlib_counter_t **) p[0];
23158
23159   if (vec_len (counters[0]) < 2)
23160     {
23161       clib_spinlock_unlock (vam->stat_segment_lockp);
23162       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23163       return -99;
23164     }
23165
23166   /* Read thread 0 sw_if_index 1 counter */
23167   thread0_index1_packets = counters[0][1].packets;
23168   thread0_index1_bytes = counters[0][1].bytes;
23169
23170   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23171   if (p == 0)
23172     {
23173       clib_spinlock_unlock (vam->stat_segment_lockp);
23174       errmsg ("vector_rate not found?");
23175       return -99;
23176     }
23177
23178   vector_rate = *(f64 *) (p[0]);
23179   p = hash_get_mem (counter_vector_by_name, "input_rate");
23180   if (p == 0)
23181     {
23182       clib_spinlock_unlock (vam->stat_segment_lockp);
23183       errmsg ("input_rate not found?");
23184       return -99;
23185     }
23186   input_rate = *(f64 *) (p[0]);
23187
23188   clib_spinlock_unlock (vam->stat_segment_lockp);
23189
23190   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23191          vector_rate, input_rate);
23192   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23193          thread0_index1_packets, thread0_index1_bytes);
23194
23195   return 0;
23196 }
23197
23198 static int
23199 cmd_cmp (void *a1, void *a2)
23200 {
23201   u8 **c1 = a1;
23202   u8 **c2 = a2;
23203
23204   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23205 }
23206
23207 static int
23208 help (vat_main_t * vam)
23209 {
23210   u8 **cmds = 0;
23211   u8 *name = 0;
23212   hash_pair_t *p;
23213   unformat_input_t *i = vam->input;
23214   int j;
23215
23216   if (unformat (i, "%s", &name))
23217     {
23218       uword *hs;
23219
23220       vec_add1 (name, 0);
23221
23222       hs = hash_get_mem (vam->help_by_name, name);
23223       if (hs)
23224         print (vam->ofp, "usage: %s %s", name, hs[0]);
23225       else
23226         print (vam->ofp, "No such msg / command '%s'", name);
23227       vec_free (name);
23228       return 0;
23229     }
23230
23231   print (vam->ofp, "Help is available for the following:");
23232
23233     /* *INDENT-OFF* */
23234     hash_foreach_pair (p, vam->function_by_name,
23235     ({
23236       vec_add1 (cmds, (u8 *)(p->key));
23237     }));
23238     /* *INDENT-ON* */
23239
23240   vec_sort_with_function (cmds, cmd_cmp);
23241
23242   for (j = 0; j < vec_len (cmds); j++)
23243     print (vam->ofp, "%s", cmds[j]);
23244
23245   vec_free (cmds);
23246   return 0;
23247 }
23248
23249 static int
23250 set (vat_main_t * vam)
23251 {
23252   u8 *name = 0, *value = 0;
23253   unformat_input_t *i = vam->input;
23254
23255   if (unformat (i, "%s", &name))
23256     {
23257       /* The input buffer is a vector, not a string. */
23258       value = vec_dup (i->buffer);
23259       vec_delete (value, i->index, 0);
23260       /* Almost certainly has a trailing newline */
23261       if (value[vec_len (value) - 1] == '\n')
23262         value[vec_len (value) - 1] = 0;
23263       /* Make sure it's a proper string, one way or the other */
23264       vec_add1 (value, 0);
23265       (void) clib_macro_set_value (&vam->macro_main,
23266                                    (char *) name, (char *) value);
23267     }
23268   else
23269     errmsg ("usage: set <name> <value>");
23270
23271   vec_free (name);
23272   vec_free (value);
23273   return 0;
23274 }
23275
23276 static int
23277 unset (vat_main_t * vam)
23278 {
23279   u8 *name = 0;
23280
23281   if (unformat (vam->input, "%s", &name))
23282     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23283       errmsg ("unset: %s wasn't set", name);
23284   vec_free (name);
23285   return 0;
23286 }
23287
23288 typedef struct
23289 {
23290   u8 *name;
23291   u8 *value;
23292 } macro_sort_t;
23293
23294
23295 static int
23296 macro_sort_cmp (void *a1, void *a2)
23297 {
23298   macro_sort_t *s1 = a1;
23299   macro_sort_t *s2 = a2;
23300
23301   return strcmp ((char *) (s1->name), (char *) (s2->name));
23302 }
23303
23304 static int
23305 dump_macro_table (vat_main_t * vam)
23306 {
23307   macro_sort_t *sort_me = 0, *sm;
23308   int i;
23309   hash_pair_t *p;
23310
23311     /* *INDENT-OFF* */
23312     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23313     ({
23314       vec_add2 (sort_me, sm, 1);
23315       sm->name = (u8 *)(p->key);
23316       sm->value = (u8 *) (p->value[0]);
23317     }));
23318     /* *INDENT-ON* */
23319
23320   vec_sort_with_function (sort_me, macro_sort_cmp);
23321
23322   if (vec_len (sort_me))
23323     print (vam->ofp, "%-15s%s", "Name", "Value");
23324   else
23325     print (vam->ofp, "The macro table is empty...");
23326
23327   for (i = 0; i < vec_len (sort_me); i++)
23328     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23329   return 0;
23330 }
23331
23332 static int
23333 dump_node_table (vat_main_t * vam)
23334 {
23335   int i, j;
23336   vlib_node_t *node, *next_node;
23337
23338   if (vec_len (vam->graph_nodes) == 0)
23339     {
23340       print (vam->ofp, "Node table empty, issue get_node_graph...");
23341       return 0;
23342     }
23343
23344   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23345     {
23346       node = vam->graph_nodes[0][i];
23347       print (vam->ofp, "[%d] %s", i, node->name);
23348       for (j = 0; j < vec_len (node->next_nodes); j++)
23349         {
23350           if (node->next_nodes[j] != ~0)
23351             {
23352               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23353               print (vam->ofp, "  [%d] %s", j, next_node->name);
23354             }
23355         }
23356     }
23357   return 0;
23358 }
23359
23360 static int
23361 value_sort_cmp (void *a1, void *a2)
23362 {
23363   name_sort_t *n1 = a1;
23364   name_sort_t *n2 = a2;
23365
23366   if (n1->value < n2->value)
23367     return -1;
23368   if (n1->value > n2->value)
23369     return 1;
23370   return 0;
23371 }
23372
23373
23374 static int
23375 dump_msg_api_table (vat_main_t * vam)
23376 {
23377   api_main_t *am = &api_main;
23378   name_sort_t *nses = 0, *ns;
23379   hash_pair_t *hp;
23380   int i;
23381
23382   /* *INDENT-OFF* */
23383   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23384   ({
23385     vec_add2 (nses, ns, 1);
23386     ns->name = (u8 *)(hp->key);
23387     ns->value = (u32) hp->value[0];
23388   }));
23389   /* *INDENT-ON* */
23390
23391   vec_sort_with_function (nses, value_sort_cmp);
23392
23393   for (i = 0; i < vec_len (nses); i++)
23394     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23395   vec_free (nses);
23396   return 0;
23397 }
23398
23399 static int
23400 get_msg_id (vat_main_t * vam)
23401 {
23402   u8 *name_and_crc;
23403   u32 message_index;
23404
23405   if (unformat (vam->input, "%s", &name_and_crc))
23406     {
23407       message_index = vl_msg_api_get_msg_index (name_and_crc);
23408       if (message_index == ~0)
23409         {
23410           print (vam->ofp, " '%s' not found", name_and_crc);
23411           return 0;
23412         }
23413       print (vam->ofp, " '%s' has message index %d",
23414              name_and_crc, message_index);
23415       return 0;
23416     }
23417   errmsg ("name_and_crc required...");
23418   return 0;
23419 }
23420
23421 static int
23422 search_node_table (vat_main_t * vam)
23423 {
23424   unformat_input_t *line_input = vam->input;
23425   u8 *node_to_find;
23426   int j;
23427   vlib_node_t *node, *next_node;
23428   uword *p;
23429
23430   if (vam->graph_node_index_by_name == 0)
23431     {
23432       print (vam->ofp, "Node table empty, issue get_node_graph...");
23433       return 0;
23434     }
23435
23436   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23437     {
23438       if (unformat (line_input, "%s", &node_to_find))
23439         {
23440           vec_add1 (node_to_find, 0);
23441           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23442           if (p == 0)
23443             {
23444               print (vam->ofp, "%s not found...", node_to_find);
23445               goto out;
23446             }
23447           node = vam->graph_nodes[0][p[0]];
23448           print (vam->ofp, "[%d] %s", p[0], node->name);
23449           for (j = 0; j < vec_len (node->next_nodes); j++)
23450             {
23451               if (node->next_nodes[j] != ~0)
23452                 {
23453                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23454                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23455                 }
23456             }
23457         }
23458
23459       else
23460         {
23461           clib_warning ("parse error '%U'", format_unformat_error,
23462                         line_input);
23463           return -99;
23464         }
23465
23466     out:
23467       vec_free (node_to_find);
23468
23469     }
23470
23471   return 0;
23472 }
23473
23474
23475 static int
23476 script (vat_main_t * vam)
23477 {
23478 #if (VPP_API_TEST_BUILTIN==0)
23479   u8 *s = 0;
23480   char *save_current_file;
23481   unformat_input_t save_input;
23482   jmp_buf save_jump_buf;
23483   u32 save_line_number;
23484
23485   FILE *new_fp, *save_ifp;
23486
23487   if (unformat (vam->input, "%s", &s))
23488     {
23489       new_fp = fopen ((char *) s, "r");
23490       if (new_fp == 0)
23491         {
23492           errmsg ("Couldn't open script file %s", s);
23493           vec_free (s);
23494           return -99;
23495         }
23496     }
23497   else
23498     {
23499       errmsg ("Missing script name");
23500       return -99;
23501     }
23502
23503   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23504   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23505   save_ifp = vam->ifp;
23506   save_line_number = vam->input_line_number;
23507   save_current_file = (char *) vam->current_file;
23508
23509   vam->input_line_number = 0;
23510   vam->ifp = new_fp;
23511   vam->current_file = s;
23512   do_one_file (vam);
23513
23514   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23515   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23516   vam->ifp = save_ifp;
23517   vam->input_line_number = save_line_number;
23518   vam->current_file = (u8 *) save_current_file;
23519   vec_free (s);
23520
23521   return 0;
23522 #else
23523   clib_warning ("use the exec command...");
23524   return -99;
23525 #endif
23526 }
23527
23528 static int
23529 echo (vat_main_t * vam)
23530 {
23531   print (vam->ofp, "%v", vam->input->buffer);
23532   return 0;
23533 }
23534
23535 /* List of API message constructors, CLI names map to api_xxx */
23536 #define foreach_vpe_api_msg                                             \
23537 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23538 _(sw_interface_dump,"")                                                 \
23539 _(sw_interface_set_flags,                                               \
23540   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23541 _(sw_interface_add_del_address,                                         \
23542   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23543 _(sw_interface_set_rx_mode,                                             \
23544   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23545 _(sw_interface_set_rx_placement,                                        \
23546   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23547 _(sw_interface_rx_placement_dump,                                       \
23548   "[<intfc> | sw_if_index <id>]")                                         \
23549 _(sw_interface_set_table,                                               \
23550   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23551 _(sw_interface_set_mpls_enable,                                         \
23552   "<intfc> | sw_if_index [disable | dis]")                              \
23553 _(sw_interface_set_vpath,                                               \
23554   "<intfc> | sw_if_index <id> enable | disable")                        \
23555 _(sw_interface_set_vxlan_bypass,                                        \
23556   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23557 _(sw_interface_set_geneve_bypass,                                       \
23558   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23559 _(sw_interface_set_l2_xconnect,                                         \
23560   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23561   "enable | disable")                                                   \
23562 _(sw_interface_set_l2_bridge,                                           \
23563   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23564   "[shg <split-horizon-group>] [bvi]\n"                                 \
23565   "enable | disable")                                                   \
23566 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23567 _(bridge_domain_add_del,                                                \
23568   "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") \
23569 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23570 _(l2fib_add_del,                                                        \
23571   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23572 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23573 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23574 _(l2_flags,                                                             \
23575   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23576 _(bridge_flags,                                                         \
23577   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23578 _(tap_connect,                                                          \
23579   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23580 _(tap_modify,                                                           \
23581   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23582 _(tap_delete,                                                           \
23583   "<vpp-if-name> | sw_if_index <id>")                                   \
23584 _(sw_interface_tap_dump, "")                                            \
23585 _(tap_create_v2,                                                        \
23586   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23587 _(tap_delete_v2,                                                        \
23588   "<vpp-if-name> | sw_if_index <id>")                                   \
23589 _(sw_interface_tap_v2_dump, "")                                         \
23590 _(bond_create,                                                          \
23591   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23592   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23593 _(bond_delete,                                                          \
23594   "<vpp-if-name> | sw_if_index <id>")                                   \
23595 _(bond_enslave,                                                         \
23596   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23597 _(bond_detach_slave,                                                    \
23598   "sw_if_index <n>")                                                    \
23599 _(sw_interface_bond_dump, "")                                           \
23600 _(sw_interface_slave_dump,                                              \
23601   "<vpp-if-name> | sw_if_index <id>")                                   \
23602 _(ip_table_add_del,                                                     \
23603   "table <n> [ipv6] [add | del]\n")                                     \
23604 _(ip_add_del_route,                                                     \
23605   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23606   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23607   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23608   "[multipath] [count <n>]")                                            \
23609 _(ip_mroute_add_del,                                                    \
23610   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23611   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23612 _(mpls_table_add_del,                                                   \
23613   "table <n> [add | del]\n")                                            \
23614 _(mpls_route_add_del,                                                   \
23615   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23616   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23617   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23618   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23619   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23620 _(mpls_ip_bind_unbind,                                                  \
23621   "<label> <addr/len>")                                                 \
23622 _(mpls_tunnel_add_del,                                                  \
23623   " via <addr> [table-id <n>]\n"                                        \
23624   "sw_if_index <id>] [l2]  [del]")                                      \
23625 _(sr_mpls_policy_add,                                                   \
23626   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23627 _(sr_mpls_policy_del,                                                   \
23628   "bsid <id>")                                                          \
23629 _(bier_table_add_del,                                                   \
23630   "<label> <sub-domain> <set> <bsl> [del]")                             \
23631 _(bier_route_add_del,                                                   \
23632   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23633   "[<intfc> | sw_if_index <id>]"                                        \
23634   "[weight <n>] [del] [multipath]")                                     \
23635 _(proxy_arp_add_del,                                                    \
23636   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23637 _(proxy_arp_intfc_enable_disable,                                       \
23638   "<intfc> | sw_if_index <id> enable | disable")                        \
23639 _(sw_interface_set_unnumbered,                                          \
23640   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23641 _(ip_neighbor_add_del,                                                  \
23642   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23643   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23644 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23645 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23646   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23647   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23648   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23649 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23650 _(reset_fib, "vrf <n> [ipv6]")                                          \
23651 _(dhcp_proxy_config,                                                    \
23652   "svr <v46-address> src <v46-address>\n"                               \
23653    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23654 _(dhcp_proxy_set_vss,                                                   \
23655   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23656 _(dhcp_proxy_dump, "ip6")                                               \
23657 _(dhcp_client_config,                                                   \
23658   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23659 _(set_ip_flow_hash,                                                     \
23660   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23661 _(sw_interface_ip6_enable_disable,                                      \
23662   "<intfc> | sw_if_index <id> enable | disable")                        \
23663 _(sw_interface_ip6_set_link_local_address,                              \
23664   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23665 _(ip6nd_proxy_add_del,                                                  \
23666   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23667 _(ip6nd_proxy_dump, "")                                                 \
23668 _(sw_interface_ip6nd_ra_prefix,                                         \
23669   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23670   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23671   "[nolink] [isno]")                                                    \
23672 _(sw_interface_ip6nd_ra_config,                                         \
23673   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23674   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23675   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23676 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23677 _(l2_patch_add_del,                                                     \
23678   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23679   "enable | disable")                                                   \
23680 _(sr_localsid_add_del,                                                  \
23681   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23682   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23683 _(classify_add_del_table,                                               \
23684   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23685   " [del] [del-chain] mask <mask-value>\n"                              \
23686   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23687   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23688 _(classify_add_del_session,                                             \
23689   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23690   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23691   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23692   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23693 _(classify_set_interface_ip_table,                                      \
23694   "<intfc> | sw_if_index <nn> table <nn>")                              \
23695 _(classify_set_interface_l2_tables,                                     \
23696   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23697   "  [other-table <nn>]")                                               \
23698 _(get_node_index, "node <node-name")                                    \
23699 _(add_node_next, "node <node-name> next <next-node-name>")              \
23700 _(l2tpv3_create_tunnel,                                                 \
23701   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23702   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23703   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23704 _(l2tpv3_set_tunnel_cookies,                                            \
23705   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23706   "[new_remote_cookie <nn>]\n")                                         \
23707 _(l2tpv3_interface_enable_disable,                                      \
23708   "<intfc> | sw_if_index <nn> enable | disable")                        \
23709 _(l2tpv3_set_lookup_key,                                                \
23710   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23711 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23712 _(vxlan_offload_rx,                                                     \
23713   "hw { <interface name> | hw_if_index <nn>} "                          \
23714   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23715 _(vxlan_add_del_tunnel,                                                 \
23716   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23717   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23718   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23719 _(geneve_add_del_tunnel,                                                \
23720   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23721   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23722   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23723 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23724 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23725 _(gre_add_del_tunnel,                                                   \
23726   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23727   "[teb | erspan <session-id>] [del]")                                  \
23728 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23729 _(l2_fib_clear_table, "")                                               \
23730 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23731 _(l2_interface_vlan_tag_rewrite,                                        \
23732   "<intfc> | sw_if_index <nn> \n"                                       \
23733   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23734   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23735 _(create_vhost_user_if,                                                 \
23736         "socket <filename> [server] [renumber <dev_instance>] "         \
23737         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23738         "[mac <mac_address>]")                                          \
23739 _(modify_vhost_user_if,                                                 \
23740         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23741         "[server] [renumber <dev_instance>]")                           \
23742 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23743 _(sw_interface_vhost_user_dump, "")                                     \
23744 _(show_version, "")                                                     \
23745 _(vxlan_gpe_add_del_tunnel,                                             \
23746   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23747   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23748   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23749   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23750 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23751 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23752 _(interface_name_renumber,                                              \
23753   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23754 _(input_acl_set_interface,                                              \
23755   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23756   "  [l2-table <nn>] [del]")                                            \
23757 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23758 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23759   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23760 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23761 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23762 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23763 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23764 _(ip_dump, "ipv4 | ipv6")                                               \
23765 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23766 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23767   "  spid_id <n> ")                                                     \
23768 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23769   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23770   "  integ_alg <alg> integ_key <hex>")                                  \
23771 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23772   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23773   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23774   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23775 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23776 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23777   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23778   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23779   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23780   "  [instance <n>]")     \
23781 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23782 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23783   "  <alg> <hex>\n")                                                    \
23784 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23785 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23786 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23787   "(auth_data 0x<data> | auth_data <data>)")                            \
23788 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23789   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23790 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23791   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23792   "(local|remote)")                                                     \
23793 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23794 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23795 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23796 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23797 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23798 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23799 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23800 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23801 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23802 _(delete_loopback,"sw_if_index <nn>")                                   \
23803 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23804 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23805 _(want_interface_events,  "enable|disable")                             \
23806 _(want_stats,"enable|disable")                                          \
23807 _(get_first_msg_id, "client <name>")                                    \
23808 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23809 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23810   "fib-id <nn> [ip4][ip6][default]")                                    \
23811 _(get_node_graph, " ")                                                  \
23812 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23813 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23814 _(ioam_disable, "")                                                     \
23815 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23816                             " sw_if_index <sw_if_index> p <priority> "  \
23817                             "w <weight>] [del]")                        \
23818 _(one_add_del_locator, "locator-set <locator_name> "                    \
23819                         "iface <intf> | sw_if_index <sw_if_index> "     \
23820                         "p <priority> w <weight> [del]")                \
23821 _(one_add_del_local_eid,"vni <vni> eid "                                \
23822                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23823                          "locator-set <locator_name> [del]"             \
23824                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23825 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23826 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23827 _(one_enable_disable, "enable|disable")                                 \
23828 _(one_map_register_enable_disable, "enable|disable")                    \
23829 _(one_map_register_fallback_threshold, "<value>")                       \
23830 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23831 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23832                                "[seid <seid>] "                         \
23833                                "rloc <locator> p <prio> "               \
23834                                "w <weight> [rloc <loc> ... ] "          \
23835                                "action <action> [del-all]")             \
23836 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23837                           "<local-eid>")                                \
23838 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23839 _(one_use_petr, "ip-address> | disable")                                \
23840 _(one_map_request_mode, "src-dst|dst-only")                             \
23841 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23842 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23843 _(one_locator_set_dump, "[local | remote]")                             \
23844 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23845 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23846                        "[local] | [remote]")                            \
23847 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23848 _(one_ndp_bd_get, "")                                                   \
23849 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23850 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23851 _(one_l2_arp_bd_get, "")                                                \
23852 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23853 _(one_stats_enable_disable, "enable|disable")                           \
23854 _(show_one_stats_enable_disable, "")                                    \
23855 _(one_eid_table_vni_dump, "")                                           \
23856 _(one_eid_table_map_dump, "l2|l3")                                      \
23857 _(one_map_resolver_dump, "")                                            \
23858 _(one_map_server_dump, "")                                              \
23859 _(one_adjacencies_get, "vni <vni>")                                     \
23860 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23861 _(show_one_rloc_probe_state, "")                                        \
23862 _(show_one_map_register_state, "")                                      \
23863 _(show_one_status, "")                                                  \
23864 _(one_stats_dump, "")                                                   \
23865 _(one_stats_flush, "")                                                  \
23866 _(one_get_map_request_itr_rlocs, "")                                    \
23867 _(one_map_register_set_ttl, "<ttl>")                                    \
23868 _(one_set_transport_protocol, "udp|api")                                \
23869 _(one_get_transport_protocol, "")                                       \
23870 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23871 _(one_show_xtr_mode, "")                                                \
23872 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23873 _(one_show_pitr_mode, "")                                               \
23874 _(one_enable_disable_petr_mode, "enable|disable")                       \
23875 _(one_show_petr_mode, "")                                               \
23876 _(show_one_nsh_mapping, "")                                             \
23877 _(show_one_pitr, "")                                                    \
23878 _(show_one_use_petr, "")                                                \
23879 _(show_one_map_request_mode, "")                                        \
23880 _(show_one_map_register_ttl, "")                                        \
23881 _(show_one_map_register_fallback_threshold, "")                         \
23882 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23883                             " sw_if_index <sw_if_index> p <priority> "  \
23884                             "w <weight>] [del]")                        \
23885 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23886                         "iface <intf> | sw_if_index <sw_if_index> "     \
23887                         "p <priority> w <weight> [del]")                \
23888 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23889                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23890                          "locator-set <locator_name> [del]"             \
23891                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23892 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23893 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23894 _(lisp_enable_disable, "enable|disable")                                \
23895 _(lisp_map_register_enable_disable, "enable|disable")                   \
23896 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23897 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23898                                "[seid <seid>] "                         \
23899                                "rloc <locator> p <prio> "               \
23900                                "w <weight> [rloc <loc> ... ] "          \
23901                                "action <action> [del-all]")             \
23902 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23903                           "<local-eid>")                                \
23904 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23905 _(lisp_use_petr, "<ip-address> | disable")                              \
23906 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23907 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23908 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23909 _(lisp_locator_set_dump, "[local | remote]")                            \
23910 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23911 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23912                        "[local] | [remote]")                            \
23913 _(lisp_eid_table_vni_dump, "")                                          \
23914 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23915 _(lisp_map_resolver_dump, "")                                           \
23916 _(lisp_map_server_dump, "")                                             \
23917 _(lisp_adjacencies_get, "vni <vni>")                                    \
23918 _(gpe_fwd_entry_vnis_get, "")                                           \
23919 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23920 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23921                                 "[table <table-id>]")                   \
23922 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23923 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23924 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23925 _(gpe_get_encap_mode, "")                                               \
23926 _(lisp_gpe_add_del_iface, "up|down")                                    \
23927 _(lisp_gpe_enable_disable, "enable|disable")                            \
23928 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23929   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23930 _(show_lisp_rloc_probe_state, "")                                       \
23931 _(show_lisp_map_register_state, "")                                     \
23932 _(show_lisp_status, "")                                                 \
23933 _(lisp_get_map_request_itr_rlocs, "")                                   \
23934 _(show_lisp_pitr, "")                                                   \
23935 _(show_lisp_use_petr, "")                                               \
23936 _(show_lisp_map_request_mode, "")                                       \
23937 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23938 _(af_packet_delete, "name <host interface name>")                       \
23939 _(af_packet_dump, "")                                                   \
23940 _(policer_add_del, "name <policer name> <params> [del]")                \
23941 _(policer_dump, "[name <policer name>]")                                \
23942 _(policer_classify_set_interface,                                       \
23943   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23944   "  [l2-table <nn>] [del]")                                            \
23945 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23946 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23947     "[master|slave]")                                                   \
23948 _(netmap_delete, "name <interface name>")                               \
23949 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23950 _(mpls_fib_dump, "")                                                    \
23951 _(classify_table_ids, "")                                               \
23952 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23953 _(classify_table_info, "table_id <nn>")                                 \
23954 _(classify_session_dump, "table_id <nn>")                               \
23955 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23956     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23957     "[template_interval <nn>] [udp_checksum]")                          \
23958 _(ipfix_exporter_dump, "")                                              \
23959 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23960 _(ipfix_classify_stream_dump, "")                                       \
23961 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23962 _(ipfix_classify_table_dump, "")                                        \
23963 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23964 _(sw_interface_span_dump, "[l2]")                                           \
23965 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23966 _(pg_create_interface, "if_id <nn>")                                    \
23967 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23968 _(pg_enable_disable, "[stream <id>] disable")                           \
23969 _(ip_source_and_port_range_check_add_del,                               \
23970   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23971 _(ip_source_and_port_range_check_interface_add_del,                     \
23972   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23973   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23974 _(ipsec_gre_add_del_tunnel,                                             \
23975   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23976 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23977 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23978 _(l2_interface_pbb_tag_rewrite,                                         \
23979   "<intfc> | sw_if_index <nn> \n"                                       \
23980   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23981   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23982 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23983 _(flow_classify_set_interface,                                          \
23984   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23985 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23986 _(ip_fib_dump, "")                                                      \
23987 _(ip_mfib_dump, "")                                                     \
23988 _(ip6_fib_dump, "")                                                     \
23989 _(ip6_mfib_dump, "")                                                    \
23990 _(feature_enable_disable, "arc_name <arc_name> "                        \
23991   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23992 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23993 "[disable]")                                                            \
23994 _(l2_xconnect_dump, "")                                                 \
23995 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23996 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23997 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23998 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23999 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24000 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24001 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24002   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24003 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24004 _(sock_init_shm, "size <nnn>")                                          \
24005 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24006 _(dns_enable_disable, "[enable][disable]")                              \
24007 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24008 _(dns_resolve_name, "<hostname>")                                       \
24009 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24010 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24011 _(dns_resolve_name, "<hostname>")                                       \
24012 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24013   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24014 _(session_rules_dump, "")                                               \
24015 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24016 _(output_acl_set_interface,                                             \
24017   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24018   "  [l2-table <nn>] [del]")                                            \
24019 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24020
24021 /* List of command functions, CLI names map directly to functions */
24022 #define foreach_cli_function                                    \
24023 _(comment, "usage: comment <ignore-rest-of-line>")              \
24024 _(dump_interface_table, "usage: dump_interface_table")          \
24025 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24026 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24027 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24028 _(dump_stats_table, "usage: dump_stats_table")                  \
24029 _(dump_macro_table, "usage: dump_macro_table ")                 \
24030 _(dump_node_table, "usage: dump_node_table")                    \
24031 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24032 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24033 _(echo, "usage: echo <message>")                                \
24034 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24035 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24036 _(help, "usage: help")                                          \
24037 _(q, "usage: quit")                                             \
24038 _(quit, "usage: quit")                                          \
24039 _(search_node_table, "usage: search_node_table <name>...")      \
24040 _(set, "usage: set <variable-name> <value>")                    \
24041 _(script, "usage: script <file-name>")                          \
24042 _(statseg, "usage: statseg");                                   \
24043 _(unset, "usage: unset <variable-name>")
24044
24045 #define _(N,n)                                  \
24046     static void vl_api_##n##_t_handler_uni      \
24047     (vl_api_##n##_t * mp)                       \
24048     {                                           \
24049         vat_main_t * vam = &vat_main;           \
24050         if (vam->json_output) {                 \
24051             vl_api_##n##_t_handler_json(mp);    \
24052         } else {                                \
24053             vl_api_##n##_t_handler(mp);         \
24054         }                                       \
24055     }
24056 foreach_vpe_api_reply_msg;
24057 #if VPP_API_TEST_BUILTIN == 0
24058 foreach_standalone_reply_msg;
24059 #endif
24060 #undef _
24061
24062 void
24063 vat_api_hookup (vat_main_t * vam)
24064 {
24065 #define _(N,n)                                                  \
24066     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24067                            vl_api_##n##_t_handler_uni,          \
24068                            vl_noop_handler,                     \
24069                            vl_api_##n##_t_endian,               \
24070                            vl_api_##n##_t_print,                \
24071                            sizeof(vl_api_##n##_t), 1);
24072   foreach_vpe_api_reply_msg;
24073 #if VPP_API_TEST_BUILTIN == 0
24074   foreach_standalone_reply_msg;
24075 #endif
24076 #undef _
24077
24078 #if (VPP_API_TEST_BUILTIN==0)
24079   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24080
24081   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24082
24083   vam->function_by_name = hash_create_string (0, sizeof (uword));
24084
24085   vam->help_by_name = hash_create_string (0, sizeof (uword));
24086 #endif
24087
24088   /* API messages we can send */
24089 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24090   foreach_vpe_api_msg;
24091 #undef _
24092
24093   /* Help strings */
24094 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24095   foreach_vpe_api_msg;
24096 #undef _
24097
24098   /* CLI functions */
24099 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24100   foreach_cli_function;
24101 #undef _
24102
24103   /* Help strings */
24104 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24105   foreach_cli_function;
24106 #undef _
24107 }
24108
24109 #if VPP_API_TEST_BUILTIN
24110 static clib_error_t *
24111 vat_api_hookup_shim (vlib_main_t * vm)
24112 {
24113   vat_api_hookup (&vat_main);
24114   return 0;
24115 }
24116
24117 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24118 #endif
24119
24120 /*
24121  * fd.io coding-style-patch-verification: ON
24122  *
24123  * Local Variables:
24124  * eval: (c-set-style "gnu")
24125  * End:
24126  */