rx-placement: Add API call for interface rx-placement
[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 recived 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 %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1398
1399   if (n_sw_ifs)
1400     {
1401       vl_api_bridge_domain_sw_if_t *sw_ifs;
1402       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1403              "Interface Name");
1404
1405       sw_ifs = mp->sw_if_details;
1406       for (i = 0; i < n_sw_ifs; i++)
1407         {
1408           u8 *sw_if_name = 0;
1409           u32 sw_if_index;
1410           hash_pair_t *p;
1411
1412           sw_if_index = ntohl (sw_ifs->sw_if_index);
1413
1414           /* *INDENT-OFF* */
1415           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1416                              ({
1417                                if ((u32) p->value[0] == sw_if_index)
1418                                  {
1419                                    sw_if_name = (u8 *)(p->key);
1420                                    break;
1421                                  }
1422                              }));
1423           /* *INDENT-ON* */
1424           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1425                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1426                  "sw_if_index not found!");
1427
1428           sw_ifs++;
1429         }
1430     }
1431 }
1432
1433 static void vl_api_bridge_domain_details_t_handler_json
1434   (vl_api_bridge_domain_details_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   vat_json_node_t *node, *array = NULL;
1438   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1439
1440   if (VAT_JSON_ARRAY != vam->json_tree.type)
1441     {
1442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1443       vat_json_init_array (&vam->json_tree);
1444     }
1445   node = vat_json_array_add (&vam->json_tree);
1446
1447   vat_json_init_object (node);
1448   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1449   vat_json_object_add_uint (node, "flood", mp->flood);
1450   vat_json_object_add_uint (node, "forward", mp->forward);
1451   vat_json_object_add_uint (node, "learn", mp->learn);
1452   vat_json_object_add_uint (node, "bvi_sw_if_index",
1453                             ntohl (mp->bvi_sw_if_index));
1454   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1455   array = vat_json_object_add (node, "sw_if");
1456   vat_json_init_array (array);
1457
1458
1459
1460   if (n_sw_ifs)
1461     {
1462       vl_api_bridge_domain_sw_if_t *sw_ifs;
1463       int i;
1464
1465       sw_ifs = mp->sw_if_details;
1466       for (i = 0; i < n_sw_ifs; i++)
1467         {
1468           node = vat_json_array_add (array);
1469           vat_json_init_object (node);
1470           vat_json_object_add_uint (node, "sw_if_index",
1471                                     ntohl (sw_ifs->sw_if_index));
1472           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1473           sw_ifs++;
1474         }
1475     }
1476 }
1477
1478 static void vl_api_control_ping_reply_t_handler
1479   (vl_api_control_ping_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   i32 retval = ntohl (mp->retval);
1483   if (vam->async_mode)
1484     {
1485       vam->async_errors += (retval < 0);
1486     }
1487   else
1488     {
1489       vam->retval = retval;
1490       vam->result_ready = 1;
1491     }
1492   if (vam->socket_client_main)
1493     vam->socket_client_main->control_pings_outstanding--;
1494 }
1495
1496 static void vl_api_control_ping_reply_t_handler_json
1497   (vl_api_control_ping_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501
1502   if (VAT_JSON_NONE != vam->json_tree.type)
1503     {
1504       vat_json_print (vam->ofp, &vam->json_tree);
1505       vat_json_free (&vam->json_tree);
1506       vam->json_tree.type = VAT_JSON_NONE;
1507     }
1508   else
1509     {
1510       /* just print [] */
1511       vat_json_init_array (&vam->json_tree);
1512       vat_json_print (vam->ofp, &vam->json_tree);
1513       vam->json_tree.type = VAT_JSON_NONE;
1514     }
1515
1516   vam->retval = retval;
1517   vam->result_ready = 1;
1518 }
1519
1520 static void
1521   vl_api_bridge_domain_set_mac_age_reply_t_handler
1522   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   i32 retval = ntohl (mp->retval);
1526   if (vam->async_mode)
1527     {
1528       vam->async_errors += (retval < 0);
1529     }
1530   else
1531     {
1532       vam->retval = retval;
1533       vam->result_ready = 1;
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1538   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t node;
1542
1543   vat_json_init_object (&node);
1544   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1545
1546   vat_json_print (vam->ofp, &node);
1547   vat_json_free (&node);
1548
1549   vam->retval = ntohl (mp->retval);
1550   vam->result_ready = 1;
1551 }
1552
1553 static void
1554 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_l2_flags_reply_t_handler_json
1570   (vl_api_l2_flags_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1578                             ntohl (mp->resulting_feature_bitmap));
1579
1580   vat_json_print (vam->ofp, &node);
1581   vat_json_free (&node);
1582
1583   vam->retval = ntohl (mp->retval);
1584   vam->result_ready = 1;
1585 }
1586
1587 static void vl_api_bridge_flags_reply_t_handler
1588   (vl_api_bridge_flags_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_bridge_flags_reply_t_handler_json
1604   (vl_api_bridge_flags_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1612                             ntohl (mp->resulting_feature_bitmap));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void vl_api_tap_connect_reply_t_handler
1622   (vl_api_tap_connect_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->sw_if_index = ntohl (mp->sw_if_index);
1634       vam->result_ready = 1;
1635     }
1636
1637 }
1638
1639 static void vl_api_tap_connect_reply_t_handler_json
1640   (vl_api_tap_connect_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   vat_json_node_t node;
1644
1645   vat_json_init_object (&node);
1646   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654
1655 }
1656
1657 static void
1658 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->sw_if_index = ntohl (mp->sw_if_index);
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_tap_modify_reply_t_handler_json
1675   (vl_api_tap_modify_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void
1692 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_tap_delete_reply_t_handler_json
1708   (vl_api_tap_delete_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715
1716   vat_json_print (vam->ofp, &node);
1717   vat_json_free (&node);
1718
1719   vam->retval = ntohl (mp->retval);
1720   vam->result_ready = 1;
1721 }
1722
1723 static void
1724 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   i32 retval = ntohl (mp->retval);
1728   if (vam->async_mode)
1729     {
1730       vam->async_errors += (retval < 0);
1731     }
1732   else
1733     {
1734       vam->retval = retval;
1735       vam->sw_if_index = ntohl (mp->sw_if_index);
1736       vam->result_ready = 1;
1737     }
1738
1739 }
1740
1741 static void vl_api_tap_create_v2_reply_t_handler_json
1742   (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   vat_json_node_t node;
1746
1747   vat_json_init_object (&node);
1748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751   vat_json_print (vam->ofp, &node);
1752   vat_json_free (&node);
1753
1754   vam->retval = ntohl (mp->retval);
1755   vam->result_ready = 1;
1756
1757 }
1758
1759 static void
1760 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->result_ready = 1;
1772     }
1773 }
1774
1775 static void vl_api_tap_delete_v2_reply_t_handler_json
1776   (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   vat_json_node_t node;
1780
1781   vat_json_init_object (&node);
1782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784   vat_json_print (vam->ofp, &node);
1785   vat_json_free (&node);
1786
1787   vam->retval = ntohl (mp->retval);
1788   vam->result_ready = 1;
1789 }
1790
1791 static void
1792 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796
1797   if (vam->async_mode)
1798     {
1799       vam->async_errors += (retval < 0);
1800     }
1801   else
1802     {
1803       vam->retval = retval;
1804       vam->sw_if_index = ntohl (mp->sw_if_index);
1805       vam->result_ready = 1;
1806     }
1807 }
1808
1809 static void vl_api_bond_create_reply_t_handler_json
1810   (vl_api_bond_create_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   vat_json_node_t node;
1814
1815   vat_json_init_object (&node);
1816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819   vat_json_print (vam->ofp, &node);
1820   vat_json_free (&node);
1821
1822   vam->retval = ntohl (mp->retval);
1823   vam->result_ready = 1;
1824 }
1825
1826 static void
1827 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   i32 retval = ntohl (mp->retval);
1831
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->result_ready = 1;
1840     }
1841 }
1842
1843 static void vl_api_bond_delete_reply_t_handler_json
1844   (vl_api_bond_delete_reply_t * mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   vat_json_node_t node;
1848
1849   vat_json_init_object (&node);
1850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   i32 retval = ntohl (mp->retval);
1864
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_bond_enslave_reply_t_handler_json
1877   (vl_api_bond_enslave_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1894                                           mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   i32 retval = ntohl (mp->retval);
1898
1899   if (vam->async_mode)
1900     {
1901       vam->async_errors += (retval < 0);
1902     }
1903   else
1904     {
1905       vam->retval = retval;
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_detach_slave_reply_t_handler_json
1911   (vl_api_bond_detach_slave_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918
1919   vat_json_print (vam->ofp, &node);
1920   vat_json_free (&node);
1921
1922   vam->retval = ntohl (mp->retval);
1923   vam->result_ready = 1;
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   print (vam->ofp,
1932          "%-16s %-12d %-12U %-13U %-14u %-14u",
1933          mp->interface_name, ntohl (mp->sw_if_index),
1934          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1935          ntohl (mp->active_slaves), ntohl (mp->slaves));
1936 }
1937
1938 static void vl_api_sw_interface_bond_details_t_handler_json
1939   (vl_api_sw_interface_bond_details_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   vat_json_node_t *node = NULL;
1943
1944   if (VAT_JSON_ARRAY != vam->json_tree.type)
1945     {
1946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1947       vat_json_init_array (&vam->json_tree);
1948     }
1949   node = vat_json_array_add (&vam->json_tree);
1950
1951   vat_json_init_object (node);
1952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1953   vat_json_object_add_string_copy (node, "interface_name",
1954                                    mp->interface_name);
1955   vat_json_object_add_uint (node, "mode", mp->mode);
1956   vat_json_object_add_uint (node, "load_balance", mp->lb);
1957   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1958   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1959 }
1960
1961 static int
1962 api_sw_interface_bond_dump (vat_main_t * vam)
1963 {
1964   vl_api_sw_interface_bond_dump_t *mp;
1965   vl_api_control_ping_t *mp_ping;
1966   int ret;
1967
1968   print (vam->ofp,
1969          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1970          "interface name", "sw_if_index", "mode", "load balance",
1971          "active slaves", "slaves");
1972
1973   /* Get list of bond interfaces */
1974   M (SW_INTERFACE_BOND_DUMP, mp);
1975   S (mp);
1976
1977   /* Use a control ping for synchronization */
1978   MPING (CONTROL_PING, mp_ping);
1979   S (mp_ping);
1980
1981   W (ret);
1982   return ret;
1983 }
1984
1985 static void vl_api_sw_interface_slave_details_t_handler
1986   (vl_api_sw_interface_slave_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-25s %-12d %-12d %d", mp->interface_name,
1992          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1993 }
1994
1995 static void vl_api_sw_interface_slave_details_t_handler_json
1996   (vl_api_sw_interface_slave_details_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t *node = NULL;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006   node = vat_json_array_add (&vam->json_tree);
2007
2008   vat_json_init_object (node);
2009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2010   vat_json_object_add_string_copy (node, "interface_name",
2011                                    mp->interface_name);
2012   vat_json_object_add_uint (node, "passive", mp->is_passive);
2013   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2014 }
2015
2016 static int
2017 api_sw_interface_slave_dump (vat_main_t * vam)
2018 {
2019   unformat_input_t *i = vam->input;
2020   vl_api_sw_interface_slave_dump_t *mp;
2021   vl_api_control_ping_t *mp_ping;
2022   u32 sw_if_index = ~0;
2023   u8 sw_if_index_set = 0;
2024   int ret;
2025
2026   /* Parse args required to build the message */
2027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2028     {
2029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2030         sw_if_index_set = 1;
2031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2032         sw_if_index_set = 1;
2033       else
2034         break;
2035     }
2036
2037   if (sw_if_index_set == 0)
2038     {
2039       errmsg ("missing vpp interface name. ");
2040       return -99;
2041     }
2042
2043   print (vam->ofp,
2044          "\n%-25s %-12s %-12s %s",
2045          "slave interface name", "sw_if_index", "passive", "long_timeout");
2046
2047   /* Get list of bond interfaces */
2048   M (SW_INTERFACE_SLAVE_DUMP, mp);
2049   mp->sw_if_index = ntohl (sw_if_index);
2050   S (mp);
2051
2052   /* Use a control ping for synchronization */
2053   MPING (CONTROL_PING, mp_ping);
2054   S (mp_ping);
2055
2056   W (ret);
2057   return ret;
2058 }
2059
2060 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2061   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->result_ready = 1;
2073     }
2074 }
2075
2076 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2077   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   vat_json_node_t node;
2081
2082   vat_json_init_object (&node);
2083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2084   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2085                             ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2095   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2112   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2129   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   i32 retval = ntohl (mp->retval);
2133   if (vam->async_mode)
2134     {
2135       vam->async_errors += (retval < 0);
2136     }
2137   else
2138     {
2139       vam->retval = retval;
2140       vam->result_ready = 1;
2141     }
2142 }
2143
2144 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2145   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   vat_json_node_t node;
2149
2150   vat_json_init_object (&node);
2151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2152   vat_json_object_add_uint (&node, "fwd_entry_index",
2153                             clib_net_to_host_u32 (mp->fwd_entry_index));
2154
2155   vat_json_print (vam->ofp, &node);
2156   vat_json_free (&node);
2157
2158   vam->retval = ntohl (mp->retval);
2159   vam->result_ready = 1;
2160 }
2161
2162 u8 *
2163 format_lisp_transport_protocol (u8 * s, va_list * args)
2164 {
2165   u32 proto = va_arg (*args, u32);
2166
2167   switch (proto)
2168     {
2169     case 1:
2170       return format (s, "udp");
2171     case 2:
2172       return format (s, "api");
2173     default:
2174       return 0;
2175     }
2176   return 0;
2177 }
2178
2179 static void vl_api_one_get_transport_protocol_reply_t_handler
2180   (vl_api_one_get_transport_protocol_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       u32 proto = mp->protocol;
2191       print (vam->ofp, "Transport protocol: %U",
2192              format_lisp_transport_protocol, proto);
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2199   (vl_api_one_get_transport_protocol_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203   u8 *s;
2204
2205   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2206   vec_add1 (s, 0);
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2211
2212   vec_free (s);
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_one_add_del_locator_set_reply_t_handler
2221   (vl_api_one_add_del_locator_set_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2237   (vl_api_one_add_del_locator_set_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2254   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->sw_if_index = ntohl (mp->sw_if_index);
2266       vam->result_ready = 1;
2267     }
2268   vam->regenerate_interface_table = 1;
2269 }
2270
2271 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2272   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 static void vl_api_vxlan_offload_rx_reply_t_handler
2289   (vl_api_vxlan_offload_rx_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       vam->retval = retval;
2300       vam->result_ready = 1;
2301     }
2302 }
2303
2304 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2305   (vl_api_vxlan_offload_rx_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   vat_json_node_t node;
2309
2310   vat_json_init_object (&node);
2311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2312
2313   vat_json_print (vam->ofp, &node);
2314   vat_json_free (&node);
2315
2316   vam->retval = ntohl (mp->retval);
2317   vam->result_ready = 1;
2318 }
2319
2320 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2321   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325   if (vam->async_mode)
2326     {
2327       vam->async_errors += (retval < 0);
2328     }
2329   else
2330     {
2331       vam->retval = retval;
2332       vam->sw_if_index = ntohl (mp->sw_if_index);
2333       vam->result_ready = 1;
2334     }
2335 }
2336
2337 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2338   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   vat_json_node_t node;
2342
2343   vat_json_init_object (&node);
2344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2345   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2346
2347   vat_json_print (vam->ofp, &node);
2348   vat_json_free (&node);
2349
2350   vam->retval = ntohl (mp->retval);
2351   vam->result_ready = 1;
2352 }
2353
2354 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2355   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   i32 retval = ntohl (mp->retval);
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->sw_if_index = ntohl (mp->sw_if_index);
2367       vam->result_ready = 1;
2368     }
2369   vam->regenerate_interface_table = 1;
2370 }
2371
2372 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2373   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_gre_add_del_tunnel_reply_t_handler
2390   (vl_api_gre_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2407   (vl_api_gre_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_create_vhost_user_if_reply_t_handler
2424   (vl_api_create_vhost_user_if_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_create_vhost_user_if_reply_t_handler_json
2442   (vl_api_create_vhost_user_if_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_dns_resolve_name_reply_t_handler
2459   (vl_api_dns_resolve_name_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471
2472       if (retval == 0)
2473         {
2474           if (mp->ip4_set)
2475             clib_warning ("ip4 address %U", format_ip4_address,
2476                           (ip4_address_t *) mp->ip4_address);
2477           if (mp->ip6_set)
2478             clib_warning ("ip6 address %U", format_ip6_address,
2479                           (ip6_address_t *) mp->ip6_address);
2480         }
2481       else
2482         clib_warning ("retval %d", retval);
2483     }
2484 }
2485
2486 static void vl_api_dns_resolve_name_reply_t_handler_json
2487   (vl_api_dns_resolve_name_reply_t * mp)
2488 {
2489   clib_warning ("not implemented");
2490 }
2491
2492 static void vl_api_dns_resolve_ip_reply_t_handler
2493   (vl_api_dns_resolve_ip_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   i32 retval = ntohl (mp->retval);
2497   if (vam->async_mode)
2498     {
2499       vam->async_errors += (retval < 0);
2500     }
2501   else
2502     {
2503       vam->retval = retval;
2504       vam->result_ready = 1;
2505
2506       if (retval == 0)
2507         {
2508           clib_warning ("canonical name %s", mp->name);
2509         }
2510       else
2511         clib_warning ("retval %d", retval);
2512     }
2513 }
2514
2515 static void vl_api_dns_resolve_ip_reply_t_handler_json
2516   (vl_api_dns_resolve_ip_reply_t * mp)
2517 {
2518   clib_warning ("not implemented");
2519 }
2520
2521
2522 static void vl_api_ip_address_details_t_handler
2523   (vl_api_ip_address_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   static ip_address_details_t empty_ip_address_details = { {0} };
2527   ip_address_details_t *address = NULL;
2528   ip_details_t *current_ip_details = NULL;
2529   ip_details_t *details = NULL;
2530
2531   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2532
2533   if (!details || vam->current_sw_if_index >= vec_len (details)
2534       || !details[vam->current_sw_if_index].present)
2535     {
2536       errmsg ("ip address details arrived but not stored");
2537       errmsg ("ip_dump should be called first");
2538       return;
2539     }
2540
2541   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2542
2543 #define addresses (current_ip_details->addr)
2544
2545   vec_validate_init_empty (addresses, vec_len (addresses),
2546                            empty_ip_address_details);
2547
2548   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2549
2550   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2551   address->prefix_length = mp->prefix_length;
2552 #undef addresses
2553 }
2554
2555 static void vl_api_ip_address_details_t_handler_json
2556   (vl_api_ip_address_details_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t *node = NULL;
2560   struct in6_addr ip6;
2561   struct in_addr ip4;
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   if (vam->is_ipv6)
2572     {
2573       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2574       vat_json_object_add_ip6 (node, "ip", ip6);
2575     }
2576   else
2577     {
2578       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2579       vat_json_object_add_ip4 (node, "ip", ip4);
2580     }
2581   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2582 }
2583
2584 static void
2585 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_details_t empty_ip_details = { 0 };
2589   ip_details_t *ip = NULL;
2590   u32 sw_if_index = ~0;
2591
2592   sw_if_index = ntohl (mp->sw_if_index);
2593
2594   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2595                            sw_if_index, empty_ip_details);
2596
2597   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2598                          sw_if_index);
2599
2600   ip->present = 1;
2601 }
2602
2603 static void
2604 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607
2608   if (VAT_JSON_ARRAY != vam->json_tree.type)
2609     {
2610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611       vat_json_init_array (&vam->json_tree);
2612     }
2613   vat_json_array_add_uint (&vam->json_tree,
2614                            clib_net_to_host_u32 (mp->sw_if_index));
2615 }
2616
2617 static void
2618 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2619 {
2620   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2621           "router_addr %U host_mac %U",
2622           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2623           mp->lease.hostname,
2624           format_ip4_address, &mp->lease.host_address,
2625           format_ip4_address, &mp->lease.router_address,
2626           format_ethernet_address, mp->lease.host_mac);
2627 }
2628
2629 static void vl_api_dhcp_compl_event_t_handler_json
2630   (vl_api_dhcp_compl_event_t * mp)
2631 {
2632   /* JSON output not supported */
2633 }
2634
2635 static void
2636 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2637                               u32 counter)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static u64 default_counter = 0;
2641
2642   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2643                            NULL);
2644   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2645                            sw_if_index, default_counter);
2646   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2647 }
2648
2649 static void
2650 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2651                                 interface_counter_t counter)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   static interface_counter_t default_counter = { 0, };
2655
2656   vec_validate_init_empty (vam->combined_interface_counters,
2657                            vnet_counter_type, NULL);
2658   vec_validate_init_empty (vam->combined_interface_counters
2659                            [vnet_counter_type], sw_if_index, default_counter);
2660   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2661 }
2662
2663 static void vl_api_vnet_interface_simple_counters_t_handler
2664   (vl_api_vnet_interface_simple_counters_t * mp)
2665 {
2666   /* not supported */
2667 }
2668
2669 static void vl_api_vnet_interface_combined_counters_t_handler
2670   (vl_api_vnet_interface_combined_counters_t * mp)
2671 {
2672   /* not supported */
2673 }
2674
2675 static void vl_api_vnet_interface_simple_counters_t_handler_json
2676   (vl_api_vnet_interface_simple_counters_t * mp)
2677 {
2678   u64 *v_packets;
2679   u64 packets;
2680   u32 count;
2681   u32 first_sw_if_index;
2682   int i;
2683
2684   count = ntohl (mp->count);
2685   first_sw_if_index = ntohl (mp->first_sw_if_index);
2686
2687   v_packets = (u64 *) & mp->data;
2688   for (i = 0; i < count; i++)
2689     {
2690       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2691       set_simple_interface_counter (mp->vnet_counter_type,
2692                                     first_sw_if_index + i, packets);
2693       v_packets++;
2694     }
2695 }
2696
2697 static void vl_api_vnet_interface_combined_counters_t_handler_json
2698   (vl_api_vnet_interface_combined_counters_t * mp)
2699 {
2700   interface_counter_t counter;
2701   vlib_counter_t *v;
2702   u32 first_sw_if_index;
2703   int i;
2704   u32 count;
2705
2706   count = ntohl (mp->count);
2707   first_sw_if_index = ntohl (mp->first_sw_if_index);
2708
2709   v = (vlib_counter_t *) & mp->data;
2710   for (i = 0; i < count; i++)
2711     {
2712       counter.packets =
2713         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2714       counter.bytes =
2715         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2716       set_combined_interface_counter (mp->vnet_counter_type,
2717                                       first_sw_if_index + i, counter);
2718       v++;
2719     }
2720 }
2721
2722 static u32
2723 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   u32 i;
2727
2728   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2729     {
2730       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2731         {
2732           return i;
2733         }
2734     }
2735   return ~0;
2736 }
2737
2738 static u32
2739 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   u32 i;
2743
2744   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2745     {
2746       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2747         {
2748           return i;
2749         }
2750     }
2751   return ~0;
2752 }
2753
2754 static void vl_api_vnet_ip4_fib_counters_t_handler
2755   (vl_api_vnet_ip4_fib_counters_t * mp)
2756 {
2757   /* not supported */
2758 }
2759
2760 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2761   (vl_api_vnet_ip4_fib_counters_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vl_api_ip4_fib_counter_t *v;
2765   ip4_fib_counter_t *counter;
2766   struct in_addr ip4;
2767   u32 vrf_id;
2768   u32 vrf_index;
2769   u32 count;
2770   int i;
2771
2772   vrf_id = ntohl (mp->vrf_id);
2773   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2774   if (~0 == vrf_index)
2775     {
2776       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2777       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2778       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2779       vec_validate (vam->ip4_fib_counters, vrf_index);
2780       vam->ip4_fib_counters[vrf_index] = NULL;
2781     }
2782
2783   vec_free (vam->ip4_fib_counters[vrf_index]);
2784   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2785   count = ntohl (mp->count);
2786   for (i = 0; i < count; i++)
2787     {
2788       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2789       counter = &vam->ip4_fib_counters[vrf_index][i];
2790       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2791       counter->address = ip4;
2792       counter->address_length = v->address_length;
2793       counter->packets = clib_net_to_host_u64 (v->packets);
2794       counter->bytes = clib_net_to_host_u64 (v->bytes);
2795       v++;
2796     }
2797 }
2798
2799 static void vl_api_vnet_ip4_nbr_counters_t_handler
2800   (vl_api_vnet_ip4_nbr_counters_t * mp)
2801 {
2802   /* not supported */
2803 }
2804
2805 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2806   (vl_api_vnet_ip4_nbr_counters_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vl_api_ip4_nbr_counter_t *v;
2810   ip4_nbr_counter_t *counter;
2811   u32 sw_if_index;
2812   u32 count;
2813   int i;
2814
2815   sw_if_index = ntohl (mp->sw_if_index);
2816   count = ntohl (mp->count);
2817   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2818
2819   if (mp->begin)
2820     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2821
2822   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2823   for (i = 0; i < count; i++)
2824     {
2825       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2826       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2827       counter->address.s_addr = v->address;
2828       counter->packets = clib_net_to_host_u64 (v->packets);
2829       counter->bytes = clib_net_to_host_u64 (v->bytes);
2830       counter->linkt = v->link_type;
2831       v++;
2832     }
2833 }
2834
2835 static void vl_api_vnet_ip6_fib_counters_t_handler
2836   (vl_api_vnet_ip6_fib_counters_t * mp)
2837 {
2838   /* not supported */
2839 }
2840
2841 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2842   (vl_api_vnet_ip6_fib_counters_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   vl_api_ip6_fib_counter_t *v;
2846   ip6_fib_counter_t *counter;
2847   struct in6_addr ip6;
2848   u32 vrf_id;
2849   u32 vrf_index;
2850   u32 count;
2851   int i;
2852
2853   vrf_id = ntohl (mp->vrf_id);
2854   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2855   if (~0 == vrf_index)
2856     {
2857       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2858       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2859       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2860       vec_validate (vam->ip6_fib_counters, vrf_index);
2861       vam->ip6_fib_counters[vrf_index] = NULL;
2862     }
2863
2864   vec_free (vam->ip6_fib_counters[vrf_index]);
2865   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2866   count = ntohl (mp->count);
2867   for (i = 0; i < count; i++)
2868     {
2869       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2870       counter = &vam->ip6_fib_counters[vrf_index][i];
2871       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2872       counter->address = ip6;
2873       counter->address_length = v->address_length;
2874       counter->packets = clib_net_to_host_u64 (v->packets);
2875       counter->bytes = clib_net_to_host_u64 (v->bytes);
2876       v++;
2877     }
2878 }
2879
2880 static void vl_api_vnet_ip6_nbr_counters_t_handler
2881   (vl_api_vnet_ip6_nbr_counters_t * mp)
2882 {
2883   /* not supported */
2884 }
2885
2886 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2887   (vl_api_vnet_ip6_nbr_counters_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vl_api_ip6_nbr_counter_t *v;
2891   ip6_nbr_counter_t *counter;
2892   struct in6_addr ip6;
2893   u32 sw_if_index;
2894   u32 count;
2895   int i;
2896
2897   sw_if_index = ntohl (mp->sw_if_index);
2898   count = ntohl (mp->count);
2899   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2900
2901   if (mp->begin)
2902     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2903
2904   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2905   for (i = 0; i < count; i++)
2906     {
2907       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2908       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2909       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2910       counter->address = ip6;
2911       counter->packets = clib_net_to_host_u64 (v->packets);
2912       counter->bytes = clib_net_to_host_u64 (v->bytes);
2913       v++;
2914     }
2915 }
2916
2917 static void vl_api_get_first_msg_id_reply_t_handler
2918   (vl_api_get_first_msg_id_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   i32 retval = ntohl (mp->retval);
2922
2923   if (vam->async_mode)
2924     {
2925       vam->async_errors += (retval < 0);
2926     }
2927   else
2928     {
2929       vam->retval = retval;
2930       vam->result_ready = 1;
2931     }
2932   if (retval >= 0)
2933     {
2934       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2935     }
2936 }
2937
2938 static void vl_api_get_first_msg_id_reply_t_handler_json
2939   (vl_api_get_first_msg_id_reply_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942   vat_json_node_t node;
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2946   vat_json_object_add_uint (&node, "first_msg_id",
2947                             (uint) ntohs (mp->first_msg_id));
2948
2949   vat_json_print (vam->ofp, &node);
2950   vat_json_free (&node);
2951
2952   vam->retval = ntohl (mp->retval);
2953   vam->result_ready = 1;
2954 }
2955
2956 static void vl_api_get_node_graph_reply_t_handler
2957   (vl_api_get_node_graph_reply_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   api_main_t *am = &api_main;
2961   i32 retval = ntohl (mp->retval);
2962   u8 *pvt_copy, *reply;
2963   void *oldheap;
2964   vlib_node_t *node;
2965   int i;
2966
2967   if (vam->async_mode)
2968     {
2969       vam->async_errors += (retval < 0);
2970     }
2971   else
2972     {
2973       vam->retval = retval;
2974       vam->result_ready = 1;
2975     }
2976
2977   /* "Should never happen..." */
2978   if (retval != 0)
2979     return;
2980
2981   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2982   pvt_copy = vec_dup (reply);
2983
2984   /* Toss the shared-memory original... */
2985   pthread_mutex_lock (&am->vlib_rp->mutex);
2986   oldheap = svm_push_data_heap (am->vlib_rp);
2987
2988   vec_free (reply);
2989
2990   svm_pop_heap (oldheap);
2991   pthread_mutex_unlock (&am->vlib_rp->mutex);
2992
2993   if (vam->graph_nodes)
2994     {
2995       hash_free (vam->graph_node_index_by_name);
2996
2997       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2998         {
2999           node = vam->graph_nodes[0][i];
3000           vec_free (node->name);
3001           vec_free (node->next_nodes);
3002           vec_free (node);
3003         }
3004       vec_free (vam->graph_nodes[0]);
3005       vec_free (vam->graph_nodes);
3006     }
3007
3008   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3009   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3010   vec_free (pvt_copy);
3011
3012   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3013     {
3014       node = vam->graph_nodes[0][i];
3015       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3016     }
3017 }
3018
3019 static void vl_api_get_node_graph_reply_t_handler_json
3020   (vl_api_get_node_graph_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   api_main_t *am = &api_main;
3024   void *oldheap;
3025   vat_json_node_t node;
3026   u8 *reply;
3027
3028   /* $$$$ make this real? */
3029   vat_json_init_object (&node);
3030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3031   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3032
3033   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3034
3035   /* Toss the shared-memory original... */
3036   pthread_mutex_lock (&am->vlib_rp->mutex);
3037   oldheap = svm_push_data_heap (am->vlib_rp);
3038
3039   vec_free (reply);
3040
3041   svm_pop_heap (oldheap);
3042   pthread_mutex_unlock (&am->vlib_rp->mutex);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   u8 *s = 0;
3056
3057   if (mp->local)
3058     {
3059       s = format (s, "%=16d%=16d%=16d",
3060                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3061     }
3062   else
3063     {
3064       s = format (s, "%=16U%=16d%=16d",
3065                   mp->is_ipv6 ? format_ip6_address :
3066                   format_ip4_address,
3067                   mp->ip_address, mp->priority, mp->weight);
3068     }
3069
3070   print (vam->ofp, "%v", s);
3071   vec_free (s);
3072 }
3073
3074 static void
3075 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = NULL;
3079   struct in6_addr ip6;
3080   struct in_addr ip4;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088   vat_json_init_object (node);
3089
3090   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3091   vat_json_object_add_uint (node, "priority", mp->priority);
3092   vat_json_object_add_uint (node, "weight", mp->weight);
3093
3094   if (mp->local)
3095     vat_json_object_add_uint (node, "sw_if_index",
3096                               clib_net_to_host_u32 (mp->sw_if_index));
3097   else
3098     {
3099       if (mp->is_ipv6)
3100         {
3101           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3102           vat_json_object_add_ip6 (node, "address", ip6);
3103         }
3104       else
3105         {
3106           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3107           vat_json_object_add_ip4 (node, "address", ip4);
3108         }
3109     }
3110 }
3111
3112 static void
3113 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3114                                           mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   u8 *ls_name = 0;
3118
3119   ls_name = format (0, "%s", mp->ls_name);
3120
3121   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3122          ls_name);
3123   vec_free (ls_name);
3124 }
3125
3126 static void
3127   vl_api_one_locator_set_details_t_handler_json
3128   (vl_api_one_locator_set_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = 0;
3132   u8 *ls_name = 0;
3133
3134   ls_name = format (0, "%s", mp->ls_name);
3135   vec_add1 (ls_name, 0);
3136
3137   if (VAT_JSON_ARRAY != vam->json_tree.type)
3138     {
3139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3140       vat_json_init_array (&vam->json_tree);
3141     }
3142   node = vat_json_array_add (&vam->json_tree);
3143
3144   vat_json_init_object (node);
3145   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3146   vat_json_object_add_uint (node, "ls_index",
3147                             clib_net_to_host_u32 (mp->ls_index));
3148   vec_free (ls_name);
3149 }
3150
3151 typedef struct
3152 {
3153   u32 spi;
3154   u8 si;
3155 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3156
3157 uword
3158 unformat_nsh_address (unformat_input_t * input, va_list * args)
3159 {
3160   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3161   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3162 }
3163
3164 u8 *
3165 format_nsh_address_vat (u8 * s, va_list * args)
3166 {
3167   nsh_t *a = va_arg (*args, nsh_t *);
3168   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3169 }
3170
3171 static u8 *
3172 format_lisp_flat_eid (u8 * s, va_list * args)
3173 {
3174   u32 type = va_arg (*args, u32);
3175   u8 *eid = va_arg (*args, u8 *);
3176   u32 eid_len = va_arg (*args, u32);
3177
3178   switch (type)
3179     {
3180     case 0:
3181       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3182     case 1:
3183       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3184     case 2:
3185       return format (s, "%U", format_ethernet_address, eid);
3186     case 3:
3187       return format (s, "%U", format_nsh_address_vat, eid);
3188     }
3189   return 0;
3190 }
3191
3192 static u8 *
3193 format_lisp_eid_vat (u8 * s, va_list * args)
3194 {
3195   u32 type = va_arg (*args, u32);
3196   u8 *eid = va_arg (*args, u8 *);
3197   u32 eid_len = va_arg (*args, u32);
3198   u8 *seid = va_arg (*args, u8 *);
3199   u32 seid_len = va_arg (*args, u32);
3200   u32 is_src_dst = va_arg (*args, u32);
3201
3202   if (is_src_dst)
3203     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3204
3205   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   u8 *s = 0, *eid = 0;
3215
3216   if (~0 == mp->locator_set_index)
3217     s = format (0, "action: %d", mp->action);
3218   else
3219     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3220
3221   eid = format (0, "%U", format_lisp_eid_vat,
3222                 mp->eid_type,
3223                 mp->eid,
3224                 mp->eid_prefix_len,
3225                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3226   vec_add1 (eid, 0);
3227
3228   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3229          clib_net_to_host_u32 (mp->vni),
3230          eid,
3231          mp->is_local ? "local" : "remote",
3232          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3233          clib_net_to_host_u16 (mp->key_id), mp->key);
3234
3235   vec_free (s);
3236   vec_free (eid);
3237 }
3238
3239 static void
3240 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3241                                              * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t *node = 0;
3245   u8 *eid = 0;
3246
3247   if (VAT_JSON_ARRAY != vam->json_tree.type)
3248     {
3249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3250       vat_json_init_array (&vam->json_tree);
3251     }
3252   node = vat_json_array_add (&vam->json_tree);
3253
3254   vat_json_init_object (node);
3255   if (~0 == mp->locator_set_index)
3256     vat_json_object_add_uint (node, "action", mp->action);
3257   else
3258     vat_json_object_add_uint (node, "locator_set_index",
3259                               clib_net_to_host_u32 (mp->locator_set_index));
3260
3261   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3262   if (mp->eid_type == 3)
3263     {
3264       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3265       vat_json_init_object (nsh_json);
3266       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3267       vat_json_object_add_uint (nsh_json, "spi",
3268                                 clib_net_to_host_u32 (nsh->spi));
3269       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3270     }
3271   else
3272     {
3273       eid = format (0, "%U", format_lisp_eid_vat,
3274                     mp->eid_type,
3275                     mp->eid,
3276                     mp->eid_prefix_len,
3277                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3278       vec_add1 (eid, 0);
3279       vat_json_object_add_string_copy (node, "eid", eid);
3280       vec_free (eid);
3281     }
3282   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3283   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3284   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3285
3286   if (mp->key_id)
3287     {
3288       vat_json_object_add_uint (node, "key_id",
3289                                 clib_net_to_host_u16 (mp->key_id));
3290       vat_json_object_add_string_copy (node, "key", mp->key);
3291     }
3292 }
3293
3294 static void
3295 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   u8 *seid = 0, *deid = 0;
3299   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3300
3301   deid = format (0, "%U", format_lisp_eid_vat,
3302                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3303
3304   seid = format (0, "%U", format_lisp_eid_vat,
3305                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3306
3307   vec_add1 (deid, 0);
3308   vec_add1 (seid, 0);
3309
3310   if (mp->is_ip4)
3311     format_ip_address_fcn = format_ip4_address;
3312   else
3313     format_ip_address_fcn = format_ip6_address;
3314
3315
3316   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3317          clib_net_to_host_u32 (mp->vni),
3318          seid, deid,
3319          format_ip_address_fcn, mp->lloc,
3320          format_ip_address_fcn, mp->rloc,
3321          clib_net_to_host_u32 (mp->pkt_count),
3322          clib_net_to_host_u32 (mp->bytes));
3323
3324   vec_free (deid);
3325   vec_free (seid);
3326 }
3327
3328 static void
3329 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3330 {
3331   struct in6_addr ip6;
3332   struct in_addr ip4;
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = 0;
3335   u8 *deid = 0, *seid = 0;
3336
3337   if (VAT_JSON_ARRAY != vam->json_tree.type)
3338     {
3339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3340       vat_json_init_array (&vam->json_tree);
3341     }
3342   node = vat_json_array_add (&vam->json_tree);
3343
3344   vat_json_init_object (node);
3345   deid = format (0, "%U", format_lisp_eid_vat,
3346                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3347
3348   seid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3350
3351   vec_add1 (deid, 0);
3352   vec_add1 (seid, 0);
3353
3354   vat_json_object_add_string_copy (node, "seid", seid);
3355   vat_json_object_add_string_copy (node, "deid", deid);
3356   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3357
3358   if (mp->is_ip4)
3359     {
3360       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3361       vat_json_object_add_ip4 (node, "lloc", ip4);
3362       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3363       vat_json_object_add_ip4 (node, "rloc", ip4);
3364     }
3365   else
3366     {
3367       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3368       vat_json_object_add_ip6 (node, "lloc", ip6);
3369       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3370       vat_json_object_add_ip6 (node, "rloc", ip6);
3371     }
3372   vat_json_object_add_uint (node, "pkt_count",
3373                             clib_net_to_host_u32 (mp->pkt_count));
3374   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3375
3376   vec_free (deid);
3377   vec_free (seid);
3378 }
3379
3380 static void
3381   vl_api_one_eid_table_map_details_t_handler
3382   (vl_api_one_eid_table_map_details_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385
3386   u8 *line = format (0, "%=10d%=10d",
3387                      clib_net_to_host_u32 (mp->vni),
3388                      clib_net_to_host_u32 (mp->dp_table));
3389   print (vam->ofp, "%v", line);
3390   vec_free (line);
3391 }
3392
3393 static void
3394   vl_api_one_eid_table_map_details_t_handler_json
3395   (vl_api_one_eid_table_map_details_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398   vat_json_node_t *node = NULL;
3399
3400   if (VAT_JSON_ARRAY != vam->json_tree.type)
3401     {
3402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3403       vat_json_init_array (&vam->json_tree);
3404     }
3405   node = vat_json_array_add (&vam->json_tree);
3406   vat_json_init_object (node);
3407   vat_json_object_add_uint (node, "dp_table",
3408                             clib_net_to_host_u32 (mp->dp_table));
3409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3410 }
3411
3412 static void
3413   vl_api_one_eid_table_vni_details_t_handler
3414   (vl_api_one_eid_table_vni_details_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417
3418   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3419   print (vam->ofp, "%v", line);
3420   vec_free (line);
3421 }
3422
3423 static void
3424   vl_api_one_eid_table_vni_details_t_handler_json
3425   (vl_api_one_eid_table_vni_details_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = NULL;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436   vat_json_init_object (node);
3437   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3438 }
3439
3440 static void
3441   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3442   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   int retval = clib_net_to_host_u32 (mp->retval);
3446
3447   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3448   print (vam->ofp, "fallback threshold value: %d", mp->value);
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3456   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3463   vat_json_init_object (node);
3464   vat_json_object_add_uint (node, "value", mp->value);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_show_one_map_register_state_reply_t_handler
3475   (vl_api_show_one_map_register_state_reply_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479
3480   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3481
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_show_one_map_register_state_reply_t_handler_json
3488   (vl_api_show_one_map_register_state_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t _node, *node = &_node;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3495
3496   vat_json_init_object (node);
3497   vat_json_object_add_string_copy (node, "state", s);
3498
3499   vat_json_print (vam->ofp, node);
3500   vat_json_free (node);
3501
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504   vec_free (s);
3505 }
3506
3507 static void
3508   vl_api_show_one_rloc_probe_state_reply_t_handler
3509   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513
3514   if (retval)
3515     goto end;
3516
3517   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3518 end:
3519   vam->retval = retval;
3520   vam->result_ready = 1;
3521 }
3522
3523 static void
3524   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3525   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t _node, *node = &_node;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530
3531   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3532   vat_json_init_object (node);
3533   vat_json_object_add_string_copy (node, "state", s);
3534
3535   vat_json_print (vam->ofp, node);
3536   vat_json_free (node);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540   vec_free (s);
3541 }
3542
3543 static void
3544   vl_api_show_one_stats_enable_disable_reply_t_handler
3545   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   if (retval)
3551     goto end;
3552
3553   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3561   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t _node, *node = &_node;
3565   int retval = clib_net_to_host_u32 (mp->retval);
3566
3567   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3568   vat_json_init_object (node);
3569   vat_json_object_add_string_copy (node, "state", s);
3570
3571   vat_json_print (vam->ofp, node);
3572   vat_json_free (node);
3573
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576   vec_free (s);
3577 }
3578
3579 static void
3580 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3581 {
3582   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3583   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3584   e->vni = clib_net_to_host_u32 (e->vni);
3585 }
3586
3587 static void
3588   gpe_fwd_entries_get_reply_t_net_to_host
3589   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3590 {
3591   u32 i;
3592
3593   mp->count = clib_net_to_host_u32 (mp->count);
3594   for (i = 0; i < mp->count; i++)
3595     {
3596       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3597     }
3598 }
3599
3600 static u8 *
3601 format_gpe_encap_mode (u8 * s, va_list * args)
3602 {
3603   u32 mode = va_arg (*args, u32);
3604
3605   switch (mode)
3606     {
3607     case 0:
3608       return format (s, "lisp");
3609     case 1:
3610       return format (s, "vxlan");
3611     }
3612   return 0;
3613 }
3614
3615 static void
3616   vl_api_gpe_get_encap_mode_reply_t_handler
3617   (vl_api_gpe_get_encap_mode_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620
3621   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3622   vam->retval = ntohl (mp->retval);
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_get_encap_mode_reply_t_handler_json
3628   (vl_api_gpe_get_encap_mode_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t node;
3632
3633   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3634   vec_add1 (encap_mode, 0);
3635
3636   vat_json_init_object (&node);
3637   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3638
3639   vec_free (encap_mode);
3640   vat_json_print (vam->ofp, &node);
3641   vat_json_free (&node);
3642
3643   vam->retval = ntohl (mp->retval);
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_fwd_entry_path_details_t_handler
3649   (vl_api_gpe_fwd_entry_path_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3653
3654   if (mp->lcl_loc.is_ip4)
3655     format_ip_address_fcn = format_ip4_address;
3656   else
3657     format_ip_address_fcn = format_ip6_address;
3658
3659   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3660          format_ip_address_fcn, &mp->lcl_loc,
3661          format_ip_address_fcn, &mp->rmt_loc);
3662 }
3663
3664 static void
3665 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3666 {
3667   struct in6_addr ip6;
3668   struct in_addr ip4;
3669
3670   if (loc->is_ip4)
3671     {
3672       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3673       vat_json_object_add_ip4 (n, "address", ip4);
3674     }
3675   else
3676     {
3677       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3678       vat_json_object_add_ip6 (n, "address", ip6);
3679     }
3680   vat_json_object_add_uint (n, "weight", loc->weight);
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_path_details_t_handler_json
3685   (vl_api_gpe_fwd_entry_path_details_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t *node = NULL;
3689   vat_json_node_t *loc_node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697   vat_json_init_object (node);
3698
3699   loc_node = vat_json_object_add (node, "local_locator");
3700   vat_json_init_object (loc_node);
3701   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3702
3703   loc_node = vat_json_object_add (node, "remote_locator");
3704   vat_json_init_object (loc_node);
3705   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entries_get_reply_t_handler
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_fwd_entry_t *e;
3716
3717   if (retval)
3718     goto end;
3719
3720   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3721
3722   for (i = 0; i < mp->count; i++)
3723     {
3724       e = &mp->entries[i];
3725       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3726              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3727              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3728     }
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3737   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3738 {
3739   u8 *s = 0;
3740   vat_main_t *vam = &vat_main;
3741   vat_json_node_t *e = 0, root;
3742   u32 i;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744   vl_api_gpe_fwd_entry_t *fwd;
3745
3746   if (retval)
3747     goto end;
3748
3749   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3750   vat_json_init_array (&root);
3751
3752   for (i = 0; i < mp->count; i++)
3753     {
3754       e = vat_json_array_add (&root);
3755       fwd = &mp->entries[i];
3756
3757       vat_json_init_object (e);
3758       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3759       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3760       vat_json_object_add_int (e, "vni", fwd->vni);
3761       vat_json_object_add_int (e, "action", fwd->action);
3762
3763       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3764                   fwd->leid_prefix_len);
3765       vec_add1 (s, 0);
3766       vat_json_object_add_string_copy (e, "leid", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3770                   fwd->reid_prefix_len);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "reid", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3786   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_native_fwd_rpath_t *r;
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     {
3800       r = &mp->entries[i];
3801       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3802              clib_net_to_host_u32 (r->fib_index),
3803              clib_net_to_host_u32 (r->nh_sw_if_index),
3804              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3814   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   vat_json_node_t root, *e;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820   vl_api_gpe_native_fwd_rpath_t *r;
3821   u8 *s;
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       vat_json_init_object (e);
3833       r = &mp->entries[i];
3834       s =
3835         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3836                 r->nh_addr);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840
3841       vat_json_object_add_uint (e, "fib_index",
3842                                 clib_net_to_host_u32 (r->fib_index));
3843       vat_json_object_add_uint (e, "nh_sw_if_index",
3844                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3845     }
3846
3847   vat_json_print (vam->ofp, &root);
3848   vat_json_free (&root);
3849
3850 end:
3851   vam->retval = retval;
3852   vam->result_ready = 1;
3853 }
3854
3855 static void
3856   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3857   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3858 {
3859   vat_main_t *vam = &vat_main;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867
3868   for (i = 0; i < n; i++)
3869     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3878   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   vat_json_node_t root;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_one_ndp_entries_get_reply_t_handler
3904   (vl_api_one_ndp_entries_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3917            format_ethernet_address, mp->entries[i].mac);
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_ndp_entries_get_reply_t_handler_json
3926   (vl_api_one_ndp_entries_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_ndp_entry_t *arp_entry;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       arp_entry = &mp->entries[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3948       vec_add1 (s, 0);
3949
3950       vat_json_object_add_string_copy (e, "mac", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3954       vec_add1 (s, 0);
3955       vat_json_object_add_string_copy (e, "ip6", s);
3956       vec_free (s);
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_l2_arp_entries_get_reply_t_handler
3969   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3982            format_ethernet_address, mp->entries[i].mac);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3992 {
3993   u8 *s = 0;
3994   vat_main_t *vam = &vat_main;
3995   vat_json_node_t *e = 0, root;
3996   u32 i, n;
3997   int retval = clib_net_to_host_u32 (mp->retval);
3998   vl_api_one_l2_arp_entry_t *arp_entry;
3999
4000   if (retval)
4001     goto end;
4002
4003   n = clib_net_to_host_u32 (mp->count);
4004   vat_json_init_array (&root);
4005
4006   for (i = 0; i < n; i++)
4007     {
4008       e = vat_json_array_add (&root);
4009       arp_entry = &mp->entries[i];
4010
4011       vat_json_init_object (e);
4012       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4013       vec_add1 (s, 0);
4014
4015       vat_json_object_add_string_copy (e, "mac", s);
4016       vec_free (s);
4017
4018       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "ip4", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4047     }
4048
4049 end:
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_one_ndp_bd_get_reply_t_handler_json
4056   (vl_api_one_ndp_bd_get_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t root;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067   vat_json_init_array (&root);
4068
4069   for (i = 0; i < n; i++)
4070     {
4071       vat_json_array_add_uint (&root,
4072                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4073     }
4074
4075   vat_json_print (vam->ofp, &root);
4076   vat_json_free (&root);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_bd_get_reply_t_handler
4085   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   u32 i, n;
4089   int retval = clib_net_to_host_u32 (mp->retval);
4090
4091   if (retval)
4092     goto end;
4093
4094   n = clib_net_to_host_u32 (mp->count);
4095
4096   for (i = 0; i < n; i++)
4097     {
4098       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4099     }
4100
4101 end:
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4108   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t root;
4112   u32 i, n;
4113   int retval = clib_net_to_host_u32 (mp->retval);
4114
4115   if (retval)
4116     goto end;
4117
4118   n = clib_net_to_host_u32 (mp->count);
4119   vat_json_init_array (&root);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       vat_json_array_add_uint (&root,
4124                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_adjacencies_get_reply_t_handler
4137   (vl_api_one_adjacencies_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142   vl_api_one_adjacency_t *a;
4143
4144   if (retval)
4145     goto end;
4146
4147   n = clib_net_to_host_u32 (mp->count);
4148
4149   for (i = 0; i < n; i++)
4150     {
4151       a = &mp->adjacencies[i];
4152       print (vam->ofp, "%U %40U",
4153              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4154              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4155     }
4156
4157 end:
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_adjacencies_get_reply_t_handler_json
4164   (vl_api_one_adjacencies_get_reply_t * mp)
4165 {
4166   u8 *s = 0;
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t *e = 0, root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171   vl_api_one_adjacency_t *a;
4172
4173   if (retval)
4174     goto end;
4175
4176   n = clib_net_to_host_u32 (mp->count);
4177   vat_json_init_array (&root);
4178
4179   for (i = 0; i < n; i++)
4180     {
4181       e = vat_json_array_add (&root);
4182       a = &mp->adjacencies[i];
4183
4184       vat_json_init_object (e);
4185       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4186                   a->leid_prefix_len);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "leid", s);
4189       vec_free (s);
4190
4191       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4192                   a->reid_prefix_len);
4193       vec_add1 (s, 0);
4194       vat_json_object_add_string_copy (e, "reid", s);
4195       vec_free (s);
4196     }
4197
4198   vat_json_print (vam->ofp, &root);
4199   vat_json_free (&root);
4200
4201 end:
4202   vam->retval = retval;
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210
4211   print (vam->ofp, "%=20U",
4212          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4213          mp->ip_address);
4214 }
4215
4216 static void
4217   vl_api_one_map_server_details_t_handler_json
4218   (vl_api_one_map_server_details_t * mp)
4219 {
4220   vat_main_t *vam = &vat_main;
4221   vat_json_node_t *node = NULL;
4222   struct in6_addr ip6;
4223   struct in_addr ip4;
4224
4225   if (VAT_JSON_ARRAY != vam->json_tree.type)
4226     {
4227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4228       vat_json_init_array (&vam->json_tree);
4229     }
4230   node = vat_json_array_add (&vam->json_tree);
4231
4232   vat_json_init_object (node);
4233   if (mp->is_ipv6)
4234     {
4235       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4236       vat_json_object_add_ip6 (node, "map-server", ip6);
4237     }
4238   else
4239     {
4240       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4241       vat_json_object_add_ip4 (node, "map-server", ip4);
4242     }
4243 }
4244
4245 static void
4246 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4247                                            * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250
4251   print (vam->ofp, "%=20U",
4252          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4253          mp->ip_address);
4254 }
4255
4256 static void
4257   vl_api_one_map_resolver_details_t_handler_json
4258   (vl_api_one_map_resolver_details_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *node = NULL;
4262   struct in6_addr ip6;
4263   struct in_addr ip4;
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   if (mp->is_ipv6)
4274     {
4275       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4276       vat_json_object_add_ip6 (node, "map resolver", ip6);
4277     }
4278   else
4279     {
4280       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4281       vat_json_object_add_ip4 (node, "map resolver", ip4);
4282     }
4283 }
4284
4285 static void
4286 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "feature: %s\ngpe: %s",
4294              mp->feature_status ? "enabled" : "disabled",
4295              mp->gpe_status ? "enabled" : "disabled");
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_status_reply_t_handler_json
4304   (vl_api_show_one_status_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *gpe_status = NULL;
4309   u8 *feature_status = NULL;
4310
4311   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4312   feature_status = format (0, "%s",
4313                            mp->feature_status ? "enabled" : "disabled");
4314   vec_add1 (gpe_status, 0);
4315   vec_add1 (feature_status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4319   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4320
4321   vec_free (gpe_status);
4322   vec_free (feature_status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4333   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (retval >= 0)
4339     {
4340       print (vam->ofp, "%=20s", mp->locator_set_name);
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t *node = NULL;
4353
4354   if (VAT_JSON_ARRAY != vam->json_tree.type)
4355     {
4356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4357       vat_json_init_array (&vam->json_tree);
4358     }
4359   node = vat_json_array_add (&vam->json_tree);
4360
4361   vat_json_init_object (node);
4362   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4363
4364   vat_json_print (vam->ofp, node);
4365   vat_json_free (node);
4366
4367   vam->retval = ntohl (mp->retval);
4368   vam->result_ready = 1;
4369 }
4370
4371 static u8 *
4372 format_lisp_map_request_mode (u8 * s, va_list * args)
4373 {
4374   u32 mode = va_arg (*args, u32);
4375
4376   switch (mode)
4377     {
4378     case 0:
4379       return format (0, "dst-only");
4380     case 1:
4381       return format (0, "src-dst");
4382     }
4383   return 0;
4384 }
4385
4386 static void
4387   vl_api_show_one_map_request_mode_reply_t_handler
4388   (vl_api_show_one_map_request_mode_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392
4393   if (0 <= retval)
4394     {
4395       u32 mode = mp->mode;
4396       print (vam->ofp, "map_request_mode: %U",
4397              format_lisp_map_request_mode, mode);
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_show_one_map_request_mode_reply_t_handler_json
4406   (vl_api_show_one_map_request_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *s = 0;
4411   u32 mode;
4412
4413   mode = mp->mode;
4414   s = format (0, "%U", format_lisp_map_request_mode, mode);
4415   vec_add1 (s, 0);
4416
4417   vat_json_init_object (&node);
4418   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4419   vat_json_print (vam->ofp, &node);
4420   vat_json_free (&node);
4421
4422   vec_free (s);
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_xtr_mode_reply_t_handler
4429   (vl_api_one_show_xtr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4437     }
4438
4439   vam->retval = retval;
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_one_show_xtr_mode_reply_t_handler_json
4445   (vl_api_one_show_xtr_mode_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456
4457   vec_free (status);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_one_show_pitr_mode_reply_t_handler
4468   (vl_api_one_show_pitr_mode_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   i32 retval = ntohl (mp->retval);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_one_show_pitr_mode_reply_t_handler_json
4484   (vl_api_one_show_pitr_mode_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495
4496   vec_free (status);
4497
4498   vat_json_print (vam->ofp, &node);
4499   vat_json_free (&node);
4500
4501   vam->retval = ntohl (mp->retval);
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_one_show_petr_mode_reply_t_handler
4507   (vl_api_one_show_petr_mode_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   i32 retval = ntohl (mp->retval);
4511
4512   if (0 <= retval)
4513     {
4514       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_petr_mode_reply_t_handler_json
4523   (vl_api_one_show_petr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "status", status);
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static void
4545   vl_api_show_one_use_petr_reply_t_handler
4546   (vl_api_show_one_use_petr_reply_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   i32 retval = ntohl (mp->retval);
4550
4551   if (0 <= retval)
4552     {
4553       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4554       if (mp->status)
4555         {
4556           print (vam->ofp, "Proxy-ETR address; %U",
4557                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4558                  mp->address);
4559         }
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_use_petr_reply_t_handler_json
4568   (vl_api_show_one_use_petr_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572   u8 *status = 0;
4573   struct in_addr ip4;
4574   struct in6_addr ip6;
4575
4576   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581   if (mp->status)
4582     {
4583       if (mp->is_ip4)
4584         {
4585           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4586           vat_json_object_add_ip6 (&node, "address", ip6);
4587         }
4588       else
4589         {
4590           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4591           vat_json_object_add_ip4 (&node, "address", ip4);
4592         }
4593     }
4594
4595   vec_free (status);
4596
4597   vat_json_print (vam->ofp, &node);
4598   vat_json_free (&node);
4599
4600   vam->retval = ntohl (mp->retval);
4601   vam->result_ready = 1;
4602 }
4603
4604 static void
4605   vl_api_show_one_nsh_mapping_reply_t_handler
4606   (vl_api_show_one_nsh_mapping_reply_t * mp)
4607 {
4608   vat_main_t *vam = &vat_main;
4609   i32 retval = ntohl (mp->retval);
4610
4611   if (0 <= retval)
4612     {
4613       print (vam->ofp, "%-20s%-16s",
4614              mp->is_set ? "set" : "not-set",
4615              mp->is_set ? (char *) mp->locator_set_name : "");
4616     }
4617
4618   vam->retval = retval;
4619   vam->result_ready = 1;
4620 }
4621
4622 static void
4623   vl_api_show_one_nsh_mapping_reply_t_handler_json
4624   (vl_api_show_one_nsh_mapping_reply_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t node;
4628   u8 *status = 0;
4629
4630   status = format (0, "%s", mp->is_set ? "yes" : "no");
4631   vec_add1 (status, 0);
4632
4633   vat_json_init_object (&node);
4634   vat_json_object_add_string_copy (&node, "is_set", status);
4635   if (mp->is_set)
4636     {
4637       vat_json_object_add_string_copy (&node, "locator_set",
4638                                        mp->locator_set_name);
4639     }
4640
4641   vec_free (status);
4642
4643   vat_json_print (vam->ofp, &node);
4644   vat_json_free (&node);
4645
4646   vam->retval = ntohl (mp->retval);
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_show_one_map_register_ttl_reply_t_handler
4652   (vl_api_show_one_map_register_ttl_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   i32 retval = ntohl (mp->retval);
4656
4657   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "ttl: %u", mp->ttl);
4662     }
4663
4664   vam->retval = retval;
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_show_one_map_register_ttl_reply_t_handler_json
4670   (vl_api_show_one_map_register_ttl_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   vat_json_node_t node;
4674
4675   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4676   vat_json_init_object (&node);
4677   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4678
4679   vat_json_print (vam->ofp, &node);
4680   vat_json_free (&node);
4681
4682   vam->retval = ntohl (mp->retval);
4683   vam->result_ready = 1;
4684 }
4685
4686 static void
4687 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   i32 retval = ntohl (mp->retval);
4691
4692   if (0 <= retval)
4693     {
4694       print (vam->ofp, "%-20s%-16s",
4695              mp->status ? "enabled" : "disabled",
4696              mp->status ? (char *) mp->locator_set_name : "");
4697     }
4698
4699   vam->retval = retval;
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t node;
4708   u8 *status = 0;
4709
4710   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4711   vec_add1 (status, 0);
4712
4713   vat_json_init_object (&node);
4714   vat_json_object_add_string_copy (&node, "status", status);
4715   if (mp->status)
4716     {
4717       vat_json_object_add_string_copy (&node, "locator_set",
4718                                        mp->locator_set_name);
4719     }
4720
4721   vec_free (status);
4722
4723   vat_json_print (vam->ofp, &node);
4724   vat_json_free (&node);
4725
4726   vam->retval = ntohl (mp->retval);
4727   vam->result_ready = 1;
4728 }
4729
4730 static u8 *
4731 format_policer_type (u8 * s, va_list * va)
4732 {
4733   u32 i = va_arg (*va, u32);
4734
4735   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4736     s = format (s, "1r2c");
4737   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4738     s = format (s, "1r3c");
4739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4740     s = format (s, "2r3c-2698");
4741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4742     s = format (s, "2r3c-4115");
4743   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4744     s = format (s, "2r3c-mef5cf1");
4745   else
4746     s = format (s, "ILLEGAL");
4747   return s;
4748 }
4749
4750 static u8 *
4751 format_policer_rate_type (u8 * s, va_list * va)
4752 {
4753   u32 i = va_arg (*va, u32);
4754
4755   if (i == SSE2_QOS_RATE_KBPS)
4756     s = format (s, "kbps");
4757   else if (i == SSE2_QOS_RATE_PPS)
4758     s = format (s, "pps");
4759   else
4760     s = format (s, "ILLEGAL");
4761   return s;
4762 }
4763
4764 static u8 *
4765 format_policer_round_type (u8 * s, va_list * va)
4766 {
4767   u32 i = va_arg (*va, u32);
4768
4769   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4770     s = format (s, "closest");
4771   else if (i == SSE2_QOS_ROUND_TO_UP)
4772     s = format (s, "up");
4773   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4774     s = format (s, "down");
4775   else
4776     s = format (s, "ILLEGAL");
4777   return s;
4778 }
4779
4780 static u8 *
4781 format_policer_action_type (u8 * s, va_list * va)
4782 {
4783   u32 i = va_arg (*va, u32);
4784
4785   if (i == SSE2_QOS_ACTION_DROP)
4786     s = format (s, "drop");
4787   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4788     s = format (s, "transmit");
4789   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4790     s = format (s, "mark-and-transmit");
4791   else
4792     s = format (s, "ILLEGAL");
4793   return s;
4794 }
4795
4796 static u8 *
4797 format_dscp (u8 * s, va_list * va)
4798 {
4799   u32 i = va_arg (*va, u32);
4800   char *t = 0;
4801
4802   switch (i)
4803     {
4804 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4805       foreach_vnet_dscp
4806 #undef _
4807     default:
4808       return format (s, "ILLEGAL");
4809     }
4810   s = format (s, "%s", t);
4811   return s;
4812 }
4813
4814 static void
4815 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4816 {
4817   vat_main_t *vam = &vat_main;
4818   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4819
4820   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4821     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822   else
4823     conform_dscp_str = format (0, "");
4824
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4827   else
4828     exceed_dscp_str = format (0, "");
4829
4830   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4831     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4832   else
4833     violate_dscp_str = format (0, "");
4834
4835   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4836          "rate type %U, round type %U, %s rate, %s color-aware, "
4837          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4838          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4839          "conform action %U%s, exceed action %U%s, violate action %U%s",
4840          mp->name,
4841          format_policer_type, mp->type,
4842          ntohl (mp->cir),
4843          ntohl (mp->eir),
4844          clib_net_to_host_u64 (mp->cb),
4845          clib_net_to_host_u64 (mp->eb),
4846          format_policer_rate_type, mp->rate_type,
4847          format_policer_round_type, mp->round_type,
4848          mp->single_rate ? "single" : "dual",
4849          mp->color_aware ? "is" : "not",
4850          ntohl (mp->cir_tokens_per_period),
4851          ntohl (mp->pir_tokens_per_period),
4852          ntohl (mp->scale),
4853          ntohl (mp->current_limit),
4854          ntohl (mp->current_bucket),
4855          ntohl (mp->extended_limit),
4856          ntohl (mp->extended_bucket),
4857          clib_net_to_host_u64 (mp->last_update_time),
4858          format_policer_action_type, mp->conform_action_type,
4859          conform_dscp_str,
4860          format_policer_action_type, mp->exceed_action_type,
4861          exceed_dscp_str,
4862          format_policer_action_type, mp->violate_action_type,
4863          violate_dscp_str);
4864
4865   vec_free (conform_dscp_str);
4866   vec_free (exceed_dscp_str);
4867   vec_free (violate_dscp_str);
4868 }
4869
4870 static void vl_api_policer_details_t_handler_json
4871   (vl_api_policer_details_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t *node;
4875   u8 *rate_type_str, *round_type_str, *type_str;
4876   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4877
4878   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4879   round_type_str =
4880     format (0, "%U", format_policer_round_type, mp->round_type);
4881   type_str = format (0, "%U", format_policer_type, mp->type);
4882   conform_action_str = format (0, "%U", format_policer_action_type,
4883                                mp->conform_action_type);
4884   exceed_action_str = format (0, "%U", format_policer_action_type,
4885                               mp->exceed_action_type);
4886   violate_action_str = format (0, "%U", format_policer_action_type,
4887                                mp->violate_action_type);
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_string_copy (node, "name", mp->name);
4898   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4899   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4900   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4901   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4902   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4903   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4904   vat_json_object_add_string_copy (node, "type", type_str);
4905   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4906   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4907   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4908   vat_json_object_add_uint (node, "cir_tokens_per_period",
4909                             ntohl (mp->cir_tokens_per_period));
4910   vat_json_object_add_uint (node, "eir_tokens_per_period",
4911                             ntohl (mp->pir_tokens_per_period));
4912   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4913   vat_json_object_add_uint (node, "current_bucket",
4914                             ntohl (mp->current_bucket));
4915   vat_json_object_add_uint (node, "extended_limit",
4916                             ntohl (mp->extended_limit));
4917   vat_json_object_add_uint (node, "extended_bucket",
4918                             ntohl (mp->extended_bucket));
4919   vat_json_object_add_uint (node, "last_update_time",
4920                             ntohl (mp->last_update_time));
4921   vat_json_object_add_string_copy (node, "conform_action",
4922                                    conform_action_str);
4923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     {
4925       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4926       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4927       vec_free (dscp_str);
4928     }
4929   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4930   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4931     {
4932       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4933       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4934       vec_free (dscp_str);
4935     }
4936   vat_json_object_add_string_copy (node, "violate_action",
4937                                    violate_action_str);
4938   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4939     {
4940       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4942       vec_free (dscp_str);
4943     }
4944
4945   vec_free (rate_type_str);
4946   vec_free (round_type_str);
4947   vec_free (type_str);
4948   vec_free (conform_action_str);
4949   vec_free (exceed_action_str);
4950   vec_free (violate_action_str);
4951 }
4952
4953 static void
4954 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4955                                            mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   int i, count = ntohl (mp->count);
4959
4960   if (count > 0)
4961     print (vam->ofp, "classify table ids (%d) : ", count);
4962   for (i = 0; i < count; i++)
4963     {
4964       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4965       print (vam->ofp, (i < count - 1) ? "," : "");
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void
4972   vl_api_classify_table_ids_reply_t_handler_json
4973   (vl_api_classify_table_ids_reply_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976   int i, count = ntohl (mp->count);
4977
4978   if (count > 0)
4979     {
4980       vat_json_node_t node;
4981
4982       vat_json_init_object (&node);
4983       for (i = 0; i < count; i++)
4984         {
4985           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4986         }
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995   vl_api_classify_table_by_interface_reply_t_handler
4996   (vl_api_classify_table_by_interface_reply_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   u32 table_id;
5000
5001   table_id = ntohl (mp->l2_table_id);
5002   if (table_id != ~0)
5003     print (vam->ofp, "l2 table id : %d", table_id);
5004   else
5005     print (vam->ofp, "l2 table id : No input ACL tables configured");
5006   table_id = ntohl (mp->ip4_table_id);
5007   if (table_id != ~0)
5008     print (vam->ofp, "ip4 table id : %d", table_id);
5009   else
5010     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5011   table_id = ntohl (mp->ip6_table_id);
5012   if (table_id != ~0)
5013     print (vam->ofp, "ip6 table id : %d", table_id);
5014   else
5015     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_by_interface_reply_t_handler_json
5022   (vl_api_classify_table_by_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   vat_json_init_object (&node);
5028
5029   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5030   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5031   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5032
5033   vat_json_print (vam->ofp, &node);
5034   vat_json_free (&node);
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_add_del_reply_t_handler
5041   (vl_api_policer_add_del_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   i32 retval = ntohl (mp->retval);
5045   if (vam->async_mode)
5046     {
5047       vam->async_errors += (retval < 0);
5048     }
5049   else
5050     {
5051       vam->retval = retval;
5052       vam->result_ready = 1;
5053       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5054         /*
5055          * Note: this is just barely thread-safe, depends on
5056          * the main thread spinning waiting for an answer...
5057          */
5058         errmsg ("policer index %d", ntohl (mp->policer_index));
5059     }
5060 }
5061
5062 static void vl_api_policer_add_del_reply_t_handler_json
5063   (vl_api_policer_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t node;
5067
5068   vat_json_init_object (&node);
5069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5070   vat_json_object_add_uint (&node, "policer_index",
5071                             ntohl (mp->policer_index));
5072
5073   vat_json_print (vam->ofp, &node);
5074   vat_json_free (&node);
5075
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 /* Format hex dump. */
5081 u8 *
5082 format_hex_bytes (u8 * s, va_list * va)
5083 {
5084   u8 *bytes = va_arg (*va, u8 *);
5085   int n_bytes = va_arg (*va, int);
5086   uword i;
5087
5088   /* Print short or long form depending on byte count. */
5089   uword short_form = n_bytes <= 32;
5090   u32 indent = format_get_indent (s);
5091
5092   if (n_bytes == 0)
5093     return s;
5094
5095   for (i = 0; i < n_bytes; i++)
5096     {
5097       if (!short_form && (i % 32) == 0)
5098         s = format (s, "%08x: ", i);
5099       s = format (s, "%02x", bytes[i]);
5100       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5101         s = format (s, "\n%U", format_white_space, indent);
5102     }
5103
5104   return s;
5105 }
5106
5107 static void
5108 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5109                                             * mp)
5110 {
5111   vat_main_t *vam = &vat_main;
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       print (vam->ofp, "classify table info :");
5116       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5117              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5118              ntohl (mp->miss_next_index));
5119       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5120              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5121              ntohl (mp->match_n_vectors));
5122       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5123              ntohl (mp->mask_length));
5124     }
5125   vam->retval = retval;
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_info_reply_t_handler_json
5131   (vl_api_classify_table_info_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   i32 retval = ntohl (mp->retval);
5137   if (retval == 0)
5138     {
5139       vat_json_init_object (&node);
5140
5141       vat_json_object_add_int (&node, "sessions",
5142                                ntohl (mp->active_sessions));
5143       vat_json_object_add_int (&node, "nexttbl",
5144                                ntohl (mp->next_table_index));
5145       vat_json_object_add_int (&node, "nextnode",
5146                                ntohl (mp->miss_next_index));
5147       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5148       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5149       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5150       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5151                       ntohl (mp->mask_length), 0);
5152       vat_json_object_add_string_copy (&node, "mask", s);
5153
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5163                                            mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166
5167   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5168          ntohl (mp->hit_next_index), ntohl (mp->advance),
5169          ntohl (mp->opaque_index));
5170   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5171          ntohl (mp->match_length));
5172 }
5173
5174 static void
5175   vl_api_classify_session_details_t_handler_json
5176   (vl_api_classify_session_details_t * mp)
5177 {
5178   vat_main_t *vam = &vat_main;
5179   vat_json_node_t *node = NULL;
5180
5181   if (VAT_JSON_ARRAY != vam->json_tree.type)
5182     {
5183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5184       vat_json_init_array (&vam->json_tree);
5185     }
5186   node = vat_json_array_add (&vam->json_tree);
5187
5188   vat_json_init_object (node);
5189   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5190   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5191   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5192   u8 *s =
5193     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5194             0);
5195   vat_json_object_add_string_copy (node, "match", s);
5196 }
5197
5198 static void vl_api_pg_create_interface_reply_t_handler
5199   (vl_api_pg_create_interface_reply_t * mp)
5200 {
5201   vat_main_t *vam = &vat_main;
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_pg_create_interface_reply_t_handler_json
5208   (vl_api_pg_create_interface_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5219
5220       vat_json_print (vam->ofp, &node);
5221       vat_json_free (&node);
5222     }
5223   vam->retval = ntohl (mp->retval);
5224   vam->result_ready = 1;
5225 }
5226
5227 static void vl_api_policer_classify_details_t_handler
5228   (vl_api_policer_classify_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231
5232   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5233          ntohl (mp->table_index));
5234 }
5235
5236 static void vl_api_policer_classify_details_t_handler_json
5237   (vl_api_policer_classify_details_t * mp)
5238 {
5239   vat_main_t *vam = &vat_main;
5240   vat_json_node_t *node;
5241
5242   if (VAT_JSON_ARRAY != vam->json_tree.type)
5243     {
5244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5245       vat_json_init_array (&vam->json_tree);
5246     }
5247   node = vat_json_array_add (&vam->json_tree);
5248
5249   vat_json_init_object (node);
5250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5251   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5252 }
5253
5254 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5255   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   i32 retval = ntohl (mp->retval);
5259   if (vam->async_mode)
5260     {
5261       vam->async_errors += (retval < 0);
5262     }
5263   else
5264     {
5265       vam->retval = retval;
5266       vam->sw_if_index = ntohl (mp->sw_if_index);
5267       vam->result_ready = 1;
5268     }
5269   vam->regenerate_interface_table = 1;
5270 }
5271
5272 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5273   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5274 {
5275   vat_main_t *vam = &vat_main;
5276   vat_json_node_t node;
5277
5278   vat_json_init_object (&node);
5279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5281
5282   vat_json_print (vam->ofp, &node);
5283   vat_json_free (&node);
5284
5285   vam->retval = ntohl (mp->retval);
5286   vam->result_ready = 1;
5287 }
5288
5289 static void vl_api_flow_classify_details_t_handler
5290   (vl_api_flow_classify_details_t * mp)
5291 {
5292   vat_main_t *vam = &vat_main;
5293
5294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5295          ntohl (mp->table_index));
5296 }
5297
5298 static void vl_api_flow_classify_details_t_handler_json
5299   (vl_api_flow_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t *node;
5303
5304   if (VAT_JSON_ARRAY != vam->json_tree.type)
5305     {
5306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5307       vat_json_init_array (&vam->json_tree);
5308     }
5309   node = vat_json_array_add (&vam->json_tree);
5310
5311   vat_json_init_object (node);
5312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5314 }
5315
5316 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5317 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5318 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5320 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5322 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5324 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5326 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5328 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5330 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5333 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5334 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5336 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5338
5339 /*
5340  * Generate boilerplate reply handlers, which
5341  * dig the return value out of the xxx_reply_t API message,
5342  * stick it into vam->retval, and set vam->result_ready
5343  *
5344  * Could also do this by pointing N message decode slots at
5345  * a single function, but that could break in subtle ways.
5346  */
5347
5348 #define foreach_standard_reply_retval_handler           \
5349 _(sw_interface_set_flags_reply)                         \
5350 _(sw_interface_add_del_address_reply)                   \
5351 _(sw_interface_set_rx_mode_reply)                       \
5352 _(sw_interface_set_rx_placement_reply)                  \
5353 _(sw_interface_set_table_reply)                         \
5354 _(sw_interface_set_mpls_enable_reply)                   \
5355 _(sw_interface_set_vpath_reply)                         \
5356 _(sw_interface_set_vxlan_bypass_reply)                  \
5357 _(sw_interface_set_geneve_bypass_reply)                 \
5358 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5359 _(sw_interface_set_l2_bridge_reply)                     \
5360 _(bridge_domain_add_del_reply)                          \
5361 _(sw_interface_set_l2_xconnect_reply)                   \
5362 _(l2fib_add_del_reply)                                  \
5363 _(l2fib_flush_int_reply)                                \
5364 _(l2fib_flush_bd_reply)                                 \
5365 _(ip_add_del_route_reply)                               \
5366 _(ip_table_add_del_reply)                               \
5367 _(ip_mroute_add_del_reply)                              \
5368 _(mpls_route_add_del_reply)                             \
5369 _(mpls_table_add_del_reply)                             \
5370 _(mpls_ip_bind_unbind_reply)                            \
5371 _(bier_route_add_del_reply)                             \
5372 _(bier_table_add_del_reply)                             \
5373 _(proxy_arp_add_del_reply)                              \
5374 _(proxy_arp_intfc_enable_disable_reply)                 \
5375 _(sw_interface_set_unnumbered_reply)                    \
5376 _(ip_neighbor_add_del_reply)                            \
5377 _(oam_add_del_reply)                                    \
5378 _(reset_fib_reply)                                      \
5379 _(dhcp_proxy_config_reply)                              \
5380 _(dhcp_proxy_set_vss_reply)                             \
5381 _(dhcp_client_config_reply)                             \
5382 _(set_ip_flow_hash_reply)                               \
5383 _(sw_interface_ip6_enable_disable_reply)                \
5384 _(sw_interface_ip6_set_link_local_address_reply)        \
5385 _(ip6nd_proxy_add_del_reply)                            \
5386 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5387 _(sw_interface_ip6nd_ra_config_reply)                   \
5388 _(set_arp_neighbor_limit_reply)                         \
5389 _(l2_patch_add_del_reply)                               \
5390 _(sr_policy_add_reply)                                  \
5391 _(sr_policy_mod_reply)                                  \
5392 _(sr_policy_del_reply)                                  \
5393 _(sr_localsid_add_del_reply)                            \
5394 _(sr_steering_add_del_reply)                            \
5395 _(classify_add_del_session_reply)                       \
5396 _(classify_set_interface_ip_table_reply)                \
5397 _(classify_set_interface_l2_tables_reply)               \
5398 _(l2tpv3_set_tunnel_cookies_reply)                      \
5399 _(l2tpv3_interface_enable_disable_reply)                \
5400 _(l2tpv3_set_lookup_key_reply)                          \
5401 _(l2_fib_clear_table_reply)                             \
5402 _(l2_interface_efp_filter_reply)                        \
5403 _(l2_interface_vlan_tag_rewrite_reply)                  \
5404 _(modify_vhost_user_if_reply)                           \
5405 _(delete_vhost_user_if_reply)                           \
5406 _(ip_probe_neighbor_reply)                              \
5407 _(ip_scan_neighbor_enable_disable_reply)                \
5408 _(want_ip4_arp_events_reply)                            \
5409 _(want_ip6_nd_events_reply)                             \
5410 _(want_l2_macs_events_reply)                            \
5411 _(input_acl_set_interface_reply)                        \
5412 _(ipsec_spd_add_del_reply)                              \
5413 _(ipsec_interface_add_del_spd_reply)                    \
5414 _(ipsec_spd_add_del_entry_reply)                        \
5415 _(ipsec_sad_add_del_entry_reply)                        \
5416 _(ipsec_sa_set_key_reply)                               \
5417 _(ipsec_tunnel_if_add_del_reply)                        \
5418 _(ipsec_tunnel_if_set_key_reply)                        \
5419 _(ipsec_tunnel_if_set_sa_reply)                         \
5420 _(ikev2_profile_add_del_reply)                          \
5421 _(ikev2_profile_set_auth_reply)                         \
5422 _(ikev2_profile_set_id_reply)                           \
5423 _(ikev2_profile_set_ts_reply)                           \
5424 _(ikev2_set_local_key_reply)                            \
5425 _(ikev2_set_responder_reply)                            \
5426 _(ikev2_set_ike_transforms_reply)                       \
5427 _(ikev2_set_esp_transforms_reply)                       \
5428 _(ikev2_set_sa_lifetime_reply)                          \
5429 _(ikev2_initiate_sa_init_reply)                         \
5430 _(ikev2_initiate_del_ike_sa_reply)                      \
5431 _(ikev2_initiate_del_child_sa_reply)                    \
5432 _(ikev2_initiate_rekey_child_sa_reply)                  \
5433 _(delete_loopback_reply)                                \
5434 _(bd_ip_mac_add_del_reply)                              \
5435 _(want_interface_events_reply)                          \
5436 _(want_stats_reply)                                     \
5437 _(cop_interface_enable_disable_reply)                   \
5438 _(cop_whitelist_enable_disable_reply)                   \
5439 _(sw_interface_clear_stats_reply)                       \
5440 _(ioam_enable_reply)                                    \
5441 _(ioam_disable_reply)                                   \
5442 _(one_add_del_locator_reply)                            \
5443 _(one_add_del_local_eid_reply)                          \
5444 _(one_add_del_remote_mapping_reply)                     \
5445 _(one_add_del_adjacency_reply)                          \
5446 _(one_add_del_map_resolver_reply)                       \
5447 _(one_add_del_map_server_reply)                         \
5448 _(one_enable_disable_reply)                             \
5449 _(one_rloc_probe_enable_disable_reply)                  \
5450 _(one_map_register_enable_disable_reply)                \
5451 _(one_map_register_set_ttl_reply)                       \
5452 _(one_set_transport_protocol_reply)                     \
5453 _(one_map_register_fallback_threshold_reply)            \
5454 _(one_pitr_set_locator_set_reply)                       \
5455 _(one_map_request_mode_reply)                           \
5456 _(one_add_del_map_request_itr_rlocs_reply)              \
5457 _(one_eid_table_add_del_map_reply)                      \
5458 _(one_use_petr_reply)                                   \
5459 _(one_stats_enable_disable_reply)                       \
5460 _(one_add_del_l2_arp_entry_reply)                       \
5461 _(one_add_del_ndp_entry_reply)                          \
5462 _(one_stats_flush_reply)                                \
5463 _(one_enable_disable_xtr_mode_reply)                    \
5464 _(one_enable_disable_pitr_mode_reply)                   \
5465 _(one_enable_disable_petr_mode_reply)                   \
5466 _(gpe_enable_disable_reply)                             \
5467 _(gpe_set_encap_mode_reply)                             \
5468 _(gpe_add_del_iface_reply)                              \
5469 _(gpe_add_del_native_fwd_rpath_reply)                   \
5470 _(af_packet_delete_reply)                               \
5471 _(policer_classify_set_interface_reply)                 \
5472 _(netmap_create_reply)                                  \
5473 _(netmap_delete_reply)                                  \
5474 _(set_ipfix_exporter_reply)                             \
5475 _(set_ipfix_classify_stream_reply)                      \
5476 _(ipfix_classify_table_add_del_reply)                   \
5477 _(flow_classify_set_interface_reply)                    \
5478 _(sw_interface_span_enable_disable_reply)               \
5479 _(pg_capture_reply)                                     \
5480 _(pg_enable_disable_reply)                              \
5481 _(ip_source_and_port_range_check_add_del_reply)         \
5482 _(ip_source_and_port_range_check_interface_add_del_reply)\
5483 _(delete_subif_reply)                                   \
5484 _(l2_interface_pbb_tag_rewrite_reply)                   \
5485 _(punt_reply)                                           \
5486 _(feature_enable_disable_reply)                         \
5487 _(sw_interface_tag_add_del_reply)                       \
5488 _(hw_interface_set_mtu_reply)                           \
5489 _(p2p_ethernet_add_reply)                               \
5490 _(p2p_ethernet_del_reply)                               \
5491 _(lldp_config_reply)                                    \
5492 _(sw_interface_set_lldp_reply)                          \
5493 _(tcp_configure_src_addresses_reply)                    \
5494 _(dns_enable_disable_reply)                             \
5495 _(dns_name_server_add_del_reply)                        \
5496 _(session_rule_add_del_reply)                           \
5497 _(ip_container_proxy_add_del_reply)                     \
5498 _(output_acl_set_interface_reply)                       \
5499 _(qos_record_enable_disable_reply)
5500
5501 #define _(n)                                    \
5502     static void vl_api_##n##_t_handler          \
5503     (vl_api_##n##_t * mp)                       \
5504     {                                           \
5505         vat_main_t * vam = &vat_main;           \
5506         i32 retval = ntohl(mp->retval);         \
5507         if (vam->async_mode) {                  \
5508             vam->async_errors += (retval < 0);  \
5509         } else {                                \
5510             vam->retval = retval;               \
5511             vam->result_ready = 1;              \
5512         }                                       \
5513     }
5514 foreach_standard_reply_retval_handler;
5515 #undef _
5516
5517 #define _(n)                                    \
5518     static void vl_api_##n##_t_handler_json     \
5519     (vl_api_##n##_t * mp)                       \
5520     {                                           \
5521         vat_main_t * vam = &vat_main;           \
5522         vat_json_node_t node;                   \
5523         vat_json_init_object(&node);            \
5524         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5525         vat_json_print(vam->ofp, &node);        \
5526         vam->retval = ntohl(mp->retval);        \
5527         vam->result_ready = 1;                  \
5528     }
5529 foreach_standard_reply_retval_handler;
5530 #undef _
5531
5532 /*
5533  * Table of message reply handlers, must include boilerplate handlers
5534  * we just generated
5535  */
5536
5537 #define foreach_vpe_api_reply_msg                                       \
5538 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5539 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5540 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5541 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5542 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5543 _(CLI_REPLY, cli_reply)                                                 \
5544 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5545 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5546   sw_interface_add_del_address_reply)                                   \
5547 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5548 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5549 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5550 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5551 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5552 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5553 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5554 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5555 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5556   sw_interface_set_l2_xconnect_reply)                                   \
5557 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5558   sw_interface_set_l2_bridge_reply)                                     \
5559 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5560 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5561 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5562 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5563 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5564 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5565 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5566 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5567 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5568 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5569 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5570 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5571 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5572 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5573 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5574 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5575 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5576 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5577 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5578 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5579 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5580 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5581 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5582 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5583 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5584 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5585 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5586 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5587 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5588 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5589 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5590   proxy_arp_intfc_enable_disable_reply)                                 \
5591 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5592 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5593   sw_interface_set_unnumbered_reply)                                    \
5594 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5595 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5596 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5597 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5598 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5599 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5600 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5601 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5602 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5603 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5604 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5605   sw_interface_ip6_enable_disable_reply)                                \
5606 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5607   sw_interface_ip6_set_link_local_address_reply)                        \
5608 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5609 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5610 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5611   sw_interface_ip6nd_ra_prefix_reply)                                   \
5612 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5613   sw_interface_ip6nd_ra_config_reply)                                   \
5614 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5615 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5616 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5617 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5618 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5619 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5620 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5621 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5622 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5623 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5624 classify_set_interface_ip_table_reply)                                  \
5625 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5626   classify_set_interface_l2_tables_reply)                               \
5627 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5628 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5629 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5630 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5631 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5632   l2tpv3_interface_enable_disable_reply)                                \
5633 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5634 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5635 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5636 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5637 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5638 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5639 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5640 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5641 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5642 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5643 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5644 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5645 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5646 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5647 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5648 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5649 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5650 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5651 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5652 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5653 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5654 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5655 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5656 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5657 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5658 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5659 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5660 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5661 _(L2_MACS_EVENT, l2_macs_event)                                         \
5662 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5663 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5664 _(IP_DETAILS, ip_details)                                               \
5665 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5666 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5667 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5668 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5669 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5670 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5671 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5672 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5673 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5674 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5675 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5676 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5677 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5678 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5679 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5680 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5681 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5682 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5683 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5684 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5685 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5686 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5687 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5688 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5689 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5690 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5691 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5692 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5693 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5694 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5695 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5696 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5697 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5698 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5699 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5700 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5701 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5702 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5703 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5704 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5705 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5706 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5707 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5708 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5709   one_map_register_enable_disable_reply)                                \
5710 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5711 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5712 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5713 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5714   one_map_register_fallback_threshold_reply)                            \
5715 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5716   one_rloc_probe_enable_disable_reply)                                  \
5717 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5718 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5719 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5720 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5721 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5722 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5723 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5724 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5725 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5726 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5727 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5728 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5729 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5730 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5731 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5732 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5733   show_one_stats_enable_disable_reply)                                  \
5734 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5735 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5736 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5737 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5738 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5739 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5740 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5741 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5742   one_enable_disable_pitr_mode_reply)                                   \
5743 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5744   one_enable_disable_petr_mode_reply)                                   \
5745 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5746 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5747 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5748 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5749 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5750 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5751 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5752 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5753 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5754 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5755 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5756 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5757   gpe_add_del_native_fwd_rpath_reply)                                   \
5758 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5759   gpe_fwd_entry_path_details)                                           \
5760 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5761 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5762   one_add_del_map_request_itr_rlocs_reply)                              \
5763 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5764   one_get_map_request_itr_rlocs_reply)                                  \
5765 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5766 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5767 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5768 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5769 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5770 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5771   show_one_map_register_state_reply)                                    \
5772 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5773 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5774   show_one_map_register_fallback_threshold_reply)                       \
5775 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5776 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5777 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5778 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5779 _(POLICER_DETAILS, policer_details)                                     \
5780 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5781 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5782 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5783 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5784 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5785 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5786 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5787 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5788 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5789 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5790 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5791 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5792 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5793 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5794 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5795 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5796 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5797 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5798 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5799 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5800 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5801 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5802 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5803 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5804 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5805  ip_source_and_port_range_check_add_del_reply)                          \
5806 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5807  ip_source_and_port_range_check_interface_add_del_reply)                \
5808 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5809 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5810 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5811 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5812 _(PUNT_REPLY, punt_reply)                                               \
5813 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5814 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5815 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5816 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5817 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5818 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5819 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5820 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5821 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5822 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5823 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5824 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5825 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5826 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5827 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5828 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5829 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5830 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5831 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5832 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5833 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5834 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5835 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5836
5837 #define foreach_standalone_reply_msg                                    \
5838 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5839 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5840 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5841 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5842 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5843 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5844 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5845
5846 typedef struct
5847 {
5848   u8 *name;
5849   u32 value;
5850 } name_sort_t;
5851
5852 #define STR_VTR_OP_CASE(op)     \
5853     case L2_VTR_ ## op:         \
5854         return "" # op;
5855
5856 static const char *
5857 str_vtr_op (u32 vtr_op)
5858 {
5859   switch (vtr_op)
5860     {
5861       STR_VTR_OP_CASE (DISABLED);
5862       STR_VTR_OP_CASE (PUSH_1);
5863       STR_VTR_OP_CASE (PUSH_2);
5864       STR_VTR_OP_CASE (POP_1);
5865       STR_VTR_OP_CASE (POP_2);
5866       STR_VTR_OP_CASE (TRANSLATE_1_1);
5867       STR_VTR_OP_CASE (TRANSLATE_1_2);
5868       STR_VTR_OP_CASE (TRANSLATE_2_1);
5869       STR_VTR_OP_CASE (TRANSLATE_2_2);
5870     }
5871
5872   return "UNKNOWN";
5873 }
5874
5875 static int
5876 dump_sub_interface_table (vat_main_t * vam)
5877 {
5878   const sw_interface_subif_t *sub = NULL;
5879
5880   if (vam->json_output)
5881     {
5882       clib_warning
5883         ("JSON output supported only for VPE API calls and dump_stats_table");
5884       return -99;
5885     }
5886
5887   print (vam->ofp,
5888          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5889          "Interface", "sw_if_index",
5890          "sub id", "dot1ad", "tags", "outer id",
5891          "inner id", "exact", "default", "outer any", "inner any");
5892
5893   vec_foreach (sub, vam->sw_if_subif_table)
5894   {
5895     print (vam->ofp,
5896            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5897            sub->interface_name,
5898            sub->sw_if_index,
5899            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5900            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5901            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5902            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5903     if (sub->vtr_op != L2_VTR_DISABLED)
5904       {
5905         print (vam->ofp,
5906                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5907                "tag1: %d tag2: %d ]",
5908                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5909                sub->vtr_tag1, sub->vtr_tag2);
5910       }
5911   }
5912
5913   return 0;
5914 }
5915
5916 static int
5917 name_sort_cmp (void *a1, void *a2)
5918 {
5919   name_sort_t *n1 = a1;
5920   name_sort_t *n2 = a2;
5921
5922   return strcmp ((char *) n1->name, (char *) n2->name);
5923 }
5924
5925 static int
5926 dump_interface_table (vat_main_t * vam)
5927 {
5928   hash_pair_t *p;
5929   name_sort_t *nses = 0, *ns;
5930
5931   if (vam->json_output)
5932     {
5933       clib_warning
5934         ("JSON output supported only for VPE API calls and dump_stats_table");
5935       return -99;
5936     }
5937
5938   /* *INDENT-OFF* */
5939   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5940   ({
5941     vec_add2 (nses, ns, 1);
5942     ns->name = (u8 *)(p->key);
5943     ns->value = (u32) p->value[0];
5944   }));
5945   /* *INDENT-ON* */
5946
5947   vec_sort_with_function (nses, name_sort_cmp);
5948
5949   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5950   vec_foreach (ns, nses)
5951   {
5952     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5953   }
5954   vec_free (nses);
5955   return 0;
5956 }
5957
5958 static int
5959 dump_ip_table (vat_main_t * vam, int is_ipv6)
5960 {
5961   const ip_details_t *det = NULL;
5962   const ip_address_details_t *address = NULL;
5963   u32 i = ~0;
5964
5965   print (vam->ofp, "%-12s", "sw_if_index");
5966
5967   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5968   {
5969     i++;
5970     if (!det->present)
5971       {
5972         continue;
5973       }
5974     print (vam->ofp, "%-12d", i);
5975     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5976     if (!det->addr)
5977       {
5978         continue;
5979       }
5980     vec_foreach (address, det->addr)
5981     {
5982       print (vam->ofp,
5983              "            %-30U%-13d",
5984              is_ipv6 ? format_ip6_address : format_ip4_address,
5985              address->ip, address->prefix_length);
5986     }
5987   }
5988
5989   return 0;
5990 }
5991
5992 static int
5993 dump_ipv4_table (vat_main_t * vam)
5994 {
5995   if (vam->json_output)
5996     {
5997       clib_warning
5998         ("JSON output supported only for VPE API calls and dump_stats_table");
5999       return -99;
6000     }
6001
6002   return dump_ip_table (vam, 0);
6003 }
6004
6005 static int
6006 dump_ipv6_table (vat_main_t * vam)
6007 {
6008   if (vam->json_output)
6009     {
6010       clib_warning
6011         ("JSON output supported only for VPE API calls and dump_stats_table");
6012       return -99;
6013     }
6014
6015   return dump_ip_table (vam, 1);
6016 }
6017
6018 static char *
6019 counter_type_to_str (u8 counter_type, u8 is_combined)
6020 {
6021   if (!is_combined)
6022     {
6023       switch (counter_type)
6024         {
6025         case VNET_INTERFACE_COUNTER_DROP:
6026           return "drop";
6027         case VNET_INTERFACE_COUNTER_PUNT:
6028           return "punt";
6029         case VNET_INTERFACE_COUNTER_IP4:
6030           return "ip4";
6031         case VNET_INTERFACE_COUNTER_IP6:
6032           return "ip6";
6033         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6034           return "rx-no-buf";
6035         case VNET_INTERFACE_COUNTER_RX_MISS:
6036           return "rx-miss";
6037         case VNET_INTERFACE_COUNTER_RX_ERROR:
6038           return "rx-error";
6039         case VNET_INTERFACE_COUNTER_TX_ERROR:
6040           return "tx-error";
6041         default:
6042           return "INVALID-COUNTER-TYPE";
6043         }
6044     }
6045   else
6046     {
6047       switch (counter_type)
6048         {
6049         case VNET_INTERFACE_COUNTER_RX:
6050           return "rx";
6051         case VNET_INTERFACE_COUNTER_TX:
6052           return "tx";
6053         default:
6054           return "INVALID-COUNTER-TYPE";
6055         }
6056     }
6057 }
6058
6059 static int
6060 dump_stats_table (vat_main_t * vam)
6061 {
6062   vat_json_node_t node;
6063   vat_json_node_t *msg_array;
6064   vat_json_node_t *msg;
6065   vat_json_node_t *counter_array;
6066   vat_json_node_t *counter;
6067   interface_counter_t c;
6068   u64 packets;
6069   ip4_fib_counter_t *c4;
6070   ip6_fib_counter_t *c6;
6071   ip4_nbr_counter_t *n4;
6072   ip6_nbr_counter_t *n6;
6073   int i, j;
6074
6075   if (!vam->json_output)
6076     {
6077       clib_warning ("dump_stats_table supported only in JSON format");
6078       return -99;
6079     }
6080
6081   vat_json_init_object (&node);
6082
6083   /* interface counters */
6084   msg_array = vat_json_object_add (&node, "interface_counters");
6085   vat_json_init_array (msg_array);
6086   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6087     {
6088       msg = vat_json_array_add (msg_array);
6089       vat_json_init_object (msg);
6090       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6091                                        (u8 *) counter_type_to_str (i, 0));
6092       vat_json_object_add_int (msg, "is_combined", 0);
6093       counter_array = vat_json_object_add (msg, "data");
6094       vat_json_init_array (counter_array);
6095       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6096         {
6097           packets = vam->simple_interface_counters[i][j];
6098           vat_json_array_add_uint (counter_array, packets);
6099         }
6100     }
6101   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6102     {
6103       msg = vat_json_array_add (msg_array);
6104       vat_json_init_object (msg);
6105       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6106                                        (u8 *) counter_type_to_str (i, 1));
6107       vat_json_object_add_int (msg, "is_combined", 1);
6108       counter_array = vat_json_object_add (msg, "data");
6109       vat_json_init_array (counter_array);
6110       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6111         {
6112           c = vam->combined_interface_counters[i][j];
6113           counter = vat_json_array_add (counter_array);
6114           vat_json_init_object (counter);
6115           vat_json_object_add_uint (counter, "packets", c.packets);
6116           vat_json_object_add_uint (counter, "bytes", c.bytes);
6117         }
6118     }
6119
6120   /* ip4 fib counters */
6121   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6122   vat_json_init_array (msg_array);
6123   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6124     {
6125       msg = vat_json_array_add (msg_array);
6126       vat_json_init_object (msg);
6127       vat_json_object_add_uint (msg, "vrf_id",
6128                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6129       counter_array = vat_json_object_add (msg, "c");
6130       vat_json_init_array (counter_array);
6131       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6132         {
6133           counter = vat_json_array_add (counter_array);
6134           vat_json_init_object (counter);
6135           c4 = &vam->ip4_fib_counters[i][j];
6136           vat_json_object_add_ip4 (counter, "address", c4->address);
6137           vat_json_object_add_uint (counter, "address_length",
6138                                     c4->address_length);
6139           vat_json_object_add_uint (counter, "packets", c4->packets);
6140           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6141         }
6142     }
6143
6144   /* ip6 fib counters */
6145   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6146   vat_json_init_array (msg_array);
6147   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6148     {
6149       msg = vat_json_array_add (msg_array);
6150       vat_json_init_object (msg);
6151       vat_json_object_add_uint (msg, "vrf_id",
6152                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6153       counter_array = vat_json_object_add (msg, "c");
6154       vat_json_init_array (counter_array);
6155       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6156         {
6157           counter = vat_json_array_add (counter_array);
6158           vat_json_init_object (counter);
6159           c6 = &vam->ip6_fib_counters[i][j];
6160           vat_json_object_add_ip6 (counter, "address", c6->address);
6161           vat_json_object_add_uint (counter, "address_length",
6162                                     c6->address_length);
6163           vat_json_object_add_uint (counter, "packets", c6->packets);
6164           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6165         }
6166     }
6167
6168   /* ip4 nbr counters */
6169   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6170   vat_json_init_array (msg_array);
6171   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6172     {
6173       msg = vat_json_array_add (msg_array);
6174       vat_json_init_object (msg);
6175       vat_json_object_add_uint (msg, "sw_if_index", i);
6176       counter_array = vat_json_object_add (msg, "c");
6177       vat_json_init_array (counter_array);
6178       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6179         {
6180           counter = vat_json_array_add (counter_array);
6181           vat_json_init_object (counter);
6182           n4 = &vam->ip4_nbr_counters[i][j];
6183           vat_json_object_add_ip4 (counter, "address", n4->address);
6184           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6185           vat_json_object_add_uint (counter, "packets", n4->packets);
6186           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6187         }
6188     }
6189
6190   /* ip6 nbr counters */
6191   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6192   vat_json_init_array (msg_array);
6193   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6194     {
6195       msg = vat_json_array_add (msg_array);
6196       vat_json_init_object (msg);
6197       vat_json_object_add_uint (msg, "sw_if_index", i);
6198       counter_array = vat_json_object_add (msg, "c");
6199       vat_json_init_array (counter_array);
6200       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6201         {
6202           counter = vat_json_array_add (counter_array);
6203           vat_json_init_object (counter);
6204           n6 = &vam->ip6_nbr_counters[i][j];
6205           vat_json_object_add_ip6 (counter, "address", n6->address);
6206           vat_json_object_add_uint (counter, "packets", n6->packets);
6207           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6208         }
6209     }
6210
6211   vat_json_print (vam->ofp, &node);
6212   vat_json_free (&node);
6213
6214   return 0;
6215 }
6216
6217 /*
6218  * Pass CLI buffers directly in the CLI_INBAND API message,
6219  * instead of an additional shared memory area.
6220  */
6221 static int
6222 exec_inband (vat_main_t * vam)
6223 {
6224   vl_api_cli_inband_t *mp;
6225   unformat_input_t *i = vam->input;
6226   int ret;
6227
6228   if (vec_len (i->buffer) == 0)
6229     return -1;
6230
6231   if (vam->exec_mode == 0 && unformat (i, "mode"))
6232     {
6233       vam->exec_mode = 1;
6234       return 0;
6235     }
6236   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6237     {
6238       vam->exec_mode = 0;
6239       return 0;
6240     }
6241
6242   /*
6243    * In order for the CLI command to work, it
6244    * must be a vector ending in \n, not a C-string ending
6245    * in \n\0.
6246    */
6247   u32 len = vec_len (vam->input->buffer);
6248   M2 (CLI_INBAND, mp, len);
6249   clib_memcpy (mp->cmd, vam->input->buffer, len);
6250   mp->length = htonl (len);
6251
6252   S (mp);
6253   W (ret);
6254   /* json responses may or may not include a useful reply... */
6255   if (vec_len (vam->cmd_reply))
6256     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6257   return ret;
6258 }
6259
6260 int
6261 exec (vat_main_t * vam)
6262 {
6263   return exec_inband (vam);
6264 }
6265
6266 static int
6267 api_create_loopback (vat_main_t * vam)
6268 {
6269   unformat_input_t *i = vam->input;
6270   vl_api_create_loopback_t *mp;
6271   vl_api_create_loopback_instance_t *mp_lbi;
6272   u8 mac_address[6];
6273   u8 mac_set = 0;
6274   u8 is_specified = 0;
6275   u32 user_instance = 0;
6276   int ret;
6277
6278   memset (mac_address, 0, sizeof (mac_address));
6279
6280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6281     {
6282       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6283         mac_set = 1;
6284       if (unformat (i, "instance %d", &user_instance))
6285         is_specified = 1;
6286       else
6287         break;
6288     }
6289
6290   if (is_specified)
6291     {
6292       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6293       mp_lbi->is_specified = is_specified;
6294       if (is_specified)
6295         mp_lbi->user_instance = htonl (user_instance);
6296       if (mac_set)
6297         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6298       S (mp_lbi);
6299     }
6300   else
6301     {
6302       /* Construct the API message */
6303       M (CREATE_LOOPBACK, mp);
6304       if (mac_set)
6305         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6306       S (mp);
6307     }
6308
6309   W (ret);
6310   return ret;
6311 }
6312
6313 static int
6314 api_delete_loopback (vat_main_t * vam)
6315 {
6316   unformat_input_t *i = vam->input;
6317   vl_api_delete_loopback_t *mp;
6318   u32 sw_if_index = ~0;
6319   int ret;
6320
6321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6322     {
6323       if (unformat (i, "sw_if_index %d", &sw_if_index))
6324         ;
6325       else
6326         break;
6327     }
6328
6329   if (sw_if_index == ~0)
6330     {
6331       errmsg ("missing sw_if_index");
6332       return -99;
6333     }
6334
6335   /* Construct the API message */
6336   M (DELETE_LOOPBACK, mp);
6337   mp->sw_if_index = ntohl (sw_if_index);
6338
6339   S (mp);
6340   W (ret);
6341   return ret;
6342 }
6343
6344 static int
6345 api_want_stats (vat_main_t * vam)
6346 {
6347   unformat_input_t *i = vam->input;
6348   vl_api_want_stats_t *mp;
6349   int enable = -1;
6350   int ret;
6351
6352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6353     {
6354       if (unformat (i, "enable"))
6355         enable = 1;
6356       else if (unformat (i, "disable"))
6357         enable = 0;
6358       else
6359         break;
6360     }
6361
6362   if (enable == -1)
6363     {
6364       errmsg ("missing enable|disable");
6365       return -99;
6366     }
6367
6368   M (WANT_STATS, mp);
6369   mp->enable_disable = enable;
6370
6371   S (mp);
6372   W (ret);
6373   return ret;
6374 }
6375
6376 static int
6377 api_want_interface_events (vat_main_t * vam)
6378 {
6379   unformat_input_t *i = vam->input;
6380   vl_api_want_interface_events_t *mp;
6381   int enable = -1;
6382   int ret;
6383
6384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6385     {
6386       if (unformat (i, "enable"))
6387         enable = 1;
6388       else if (unformat (i, "disable"))
6389         enable = 0;
6390       else
6391         break;
6392     }
6393
6394   if (enable == -1)
6395     {
6396       errmsg ("missing enable|disable");
6397       return -99;
6398     }
6399
6400   M (WANT_INTERFACE_EVENTS, mp);
6401   mp->enable_disable = enable;
6402
6403   vam->interface_event_display = enable;
6404
6405   S (mp);
6406   W (ret);
6407   return ret;
6408 }
6409
6410
6411 /* Note: non-static, called once to set up the initial intfc table */
6412 int
6413 api_sw_interface_dump (vat_main_t * vam)
6414 {
6415   vl_api_sw_interface_dump_t *mp;
6416   vl_api_control_ping_t *mp_ping;
6417   hash_pair_t *p;
6418   name_sort_t *nses = 0, *ns;
6419   sw_interface_subif_t *sub = NULL;
6420   int ret;
6421
6422   /* Toss the old name table */
6423   /* *INDENT-OFF* */
6424   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6425   ({
6426     vec_add2 (nses, ns, 1);
6427     ns->name = (u8 *)(p->key);
6428     ns->value = (u32) p->value[0];
6429   }));
6430   /* *INDENT-ON* */
6431
6432   hash_free (vam->sw_if_index_by_interface_name);
6433
6434   vec_foreach (ns, nses) vec_free (ns->name);
6435
6436   vec_free (nses);
6437
6438   vec_foreach (sub, vam->sw_if_subif_table)
6439   {
6440     vec_free (sub->interface_name);
6441   }
6442   vec_free (vam->sw_if_subif_table);
6443
6444   /* recreate the interface name hash table */
6445   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6446
6447   /*
6448    * Ask for all interface names. Otherwise, the epic catalog of
6449    * name filters becomes ridiculously long, and vat ends up needing
6450    * to be taught about new interface types.
6451    */
6452   M (SW_INTERFACE_DUMP, mp);
6453   S (mp);
6454
6455   /* Use a control ping for synchronization */
6456   MPING (CONTROL_PING, mp_ping);
6457   S (mp_ping);
6458
6459   W (ret);
6460   return ret;
6461 }
6462
6463 static int
6464 api_sw_interface_set_flags (vat_main_t * vam)
6465 {
6466   unformat_input_t *i = vam->input;
6467   vl_api_sw_interface_set_flags_t *mp;
6468   u32 sw_if_index;
6469   u8 sw_if_index_set = 0;
6470   u8 admin_up = 0;
6471   int ret;
6472
6473   /* Parse args required to build the message */
6474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6475     {
6476       if (unformat (i, "admin-up"))
6477         admin_up = 1;
6478       else if (unformat (i, "admin-down"))
6479         admin_up = 0;
6480       else
6481         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6482         sw_if_index_set = 1;
6483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6484         sw_if_index_set = 1;
6485       else
6486         break;
6487     }
6488
6489   if (sw_if_index_set == 0)
6490     {
6491       errmsg ("missing interface name or sw_if_index");
6492       return -99;
6493     }
6494
6495   /* Construct the API message */
6496   M (SW_INTERFACE_SET_FLAGS, mp);
6497   mp->sw_if_index = ntohl (sw_if_index);
6498   mp->admin_up_down = admin_up;
6499
6500   /* send it... */
6501   S (mp);
6502
6503   /* Wait for a reply, return the good/bad news... */
6504   W (ret);
6505   return ret;
6506 }
6507
6508 static int
6509 api_sw_interface_set_rx_mode (vat_main_t * vam)
6510 {
6511   unformat_input_t *i = vam->input;
6512   vl_api_sw_interface_set_rx_mode_t *mp;
6513   u32 sw_if_index;
6514   u8 sw_if_index_set = 0;
6515   int ret;
6516   u8 queue_id_valid = 0;
6517   u32 queue_id;
6518   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6519
6520   /* Parse args required to build the message */
6521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6522     {
6523       if (unformat (i, "queue %d", &queue_id))
6524         queue_id_valid = 1;
6525       else if (unformat (i, "polling"))
6526         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6527       else if (unformat (i, "interrupt"))
6528         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6529       else if (unformat (i, "adaptive"))
6530         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6531       else
6532         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6533         sw_if_index_set = 1;
6534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6535         sw_if_index_set = 1;
6536       else
6537         break;
6538     }
6539
6540   if (sw_if_index_set == 0)
6541     {
6542       errmsg ("missing interface name or sw_if_index");
6543       return -99;
6544     }
6545   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6546     {
6547       errmsg ("missing rx-mode");
6548       return -99;
6549     }
6550
6551   /* Construct the API message */
6552   M (SW_INTERFACE_SET_RX_MODE, mp);
6553   mp->sw_if_index = ntohl (sw_if_index);
6554   mp->mode = mode;
6555   mp->queue_id_valid = queue_id_valid;
6556   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6557
6558   /* send it... */
6559   S (mp);
6560
6561   /* Wait for a reply, return the good/bad news... */
6562   W (ret);
6563   return ret;
6564 }
6565
6566 static int
6567 api_sw_interface_set_rx_placement (vat_main_t * vam)
6568 {
6569   unformat_input_t *i = vam->input;
6570   vl_api_sw_interface_set_rx_placement_t *mp;
6571   u32 sw_if_index;
6572   u8 sw_if_index_set = 0;
6573   int ret;
6574   u8 is_main = 0;
6575   u32 queue_id, thread_index;
6576
6577   /* Parse args required to build the message */
6578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6579     {
6580       if (unformat (i, "queue %d", &queue_id))
6581         ;
6582       else if (unformat (i, "main"))
6583         is_main = 1;
6584       else if (unformat (i, "worker %d", &thread_index))
6585         ;
6586       else
6587         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6588         sw_if_index_set = 1;
6589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6590         sw_if_index_set = 1;
6591       else
6592         break;
6593     }
6594
6595   if (sw_if_index_set == 0)
6596     {
6597       errmsg ("missing interface name or sw_if_index");
6598       return -99;
6599     }
6600
6601   if (is_main)
6602     thread_index = 0;
6603   /* Construct the API message */
6604   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6605   mp->sw_if_index = ntohl (sw_if_index);
6606   mp->worker_id = ntohl (thread_index);
6607   mp->queue_id = ntohl (queue_id);
6608   mp->is_main = is_main;
6609
6610   /* send it... */
6611   S (mp);
6612   /* Wait for a reply, return the good/bad news... */
6613   W (ret);
6614   return ret;
6615 }
6616
6617 static int
6618 api_sw_interface_clear_stats (vat_main_t * vam)
6619 {
6620   unformat_input_t *i = vam->input;
6621   vl_api_sw_interface_clear_stats_t *mp;
6622   u32 sw_if_index;
6623   u8 sw_if_index_set = 0;
6624   int ret;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6630         sw_if_index_set = 1;
6631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6632         sw_if_index_set = 1;
6633       else
6634         break;
6635     }
6636
6637   /* Construct the API message */
6638   M (SW_INTERFACE_CLEAR_STATS, mp);
6639
6640   if (sw_if_index_set == 1)
6641     mp->sw_if_index = ntohl (sw_if_index);
6642   else
6643     mp->sw_if_index = ~0;
6644
6645   /* send it... */
6646   S (mp);
6647
6648   /* Wait for a reply, return the good/bad news... */
6649   W (ret);
6650   return ret;
6651 }
6652
6653 static int
6654 api_sw_interface_add_del_address (vat_main_t * vam)
6655 {
6656   unformat_input_t *i = vam->input;
6657   vl_api_sw_interface_add_del_address_t *mp;
6658   u32 sw_if_index;
6659   u8 sw_if_index_set = 0;
6660   u8 is_add = 1, del_all = 0;
6661   u32 address_length = 0;
6662   u8 v4_address_set = 0;
6663   u8 v6_address_set = 0;
6664   ip4_address_t v4address;
6665   ip6_address_t v6address;
6666   int ret;
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "del-all"))
6672         del_all = 1;
6673       else if (unformat (i, "del"))
6674         is_add = 0;
6675       else
6676         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "%U/%d",
6681                          unformat_ip4_address, &v4address, &address_length))
6682         v4_address_set = 1;
6683       else if (unformat (i, "%U/%d",
6684                          unformat_ip6_address, &v6address, &address_length))
6685         v6_address_set = 1;
6686       else
6687         break;
6688     }
6689
6690   if (sw_if_index_set == 0)
6691     {
6692       errmsg ("missing interface name or sw_if_index");
6693       return -99;
6694     }
6695   if (v4_address_set && v6_address_set)
6696     {
6697       errmsg ("both v4 and v6 addresses set");
6698       return -99;
6699     }
6700   if (!v4_address_set && !v6_address_set && !del_all)
6701     {
6702       errmsg ("no addresses set");
6703       return -99;
6704     }
6705
6706   /* Construct the API message */
6707   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6708
6709   mp->sw_if_index = ntohl (sw_if_index);
6710   mp->is_add = is_add;
6711   mp->del_all = del_all;
6712   if (v6_address_set)
6713     {
6714       mp->is_ipv6 = 1;
6715       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6716     }
6717   else
6718     {
6719       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6720     }
6721   mp->address_length = address_length;
6722
6723   /* send it... */
6724   S (mp);
6725
6726   /* Wait for a reply, return good/bad news  */
6727   W (ret);
6728   return ret;
6729 }
6730
6731 static int
6732 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6733 {
6734   unformat_input_t *i = vam->input;
6735   vl_api_sw_interface_set_mpls_enable_t *mp;
6736   u32 sw_if_index;
6737   u8 sw_if_index_set = 0;
6738   u8 enable = 1;
6739   int ret;
6740
6741   /* Parse args required to build the message */
6742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6743     {
6744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6745         sw_if_index_set = 1;
6746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6747         sw_if_index_set = 1;
6748       else if (unformat (i, "disable"))
6749         enable = 0;
6750       else if (unformat (i, "dis"))
6751         enable = 0;
6752       else
6753         break;
6754     }
6755
6756   if (sw_if_index_set == 0)
6757     {
6758       errmsg ("missing interface name or sw_if_index");
6759       return -99;
6760     }
6761
6762   /* Construct the API message */
6763   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6764
6765   mp->sw_if_index = ntohl (sw_if_index);
6766   mp->enable = enable;
6767
6768   /* send it... */
6769   S (mp);
6770
6771   /* Wait for a reply... */
6772   W (ret);
6773   return ret;
6774 }
6775
6776 static int
6777 api_sw_interface_set_table (vat_main_t * vam)
6778 {
6779   unformat_input_t *i = vam->input;
6780   vl_api_sw_interface_set_table_t *mp;
6781   u32 sw_if_index, vrf_id = 0;
6782   u8 sw_if_index_set = 0;
6783   u8 is_ipv6 = 0;
6784   int ret;
6785
6786   /* Parse args required to build the message */
6787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6788     {
6789       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6790         sw_if_index_set = 1;
6791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6792         sw_if_index_set = 1;
6793       else if (unformat (i, "vrf %d", &vrf_id))
6794         ;
6795       else if (unformat (i, "ipv6"))
6796         is_ipv6 = 1;
6797       else
6798         break;
6799     }
6800
6801   if (sw_if_index_set == 0)
6802     {
6803       errmsg ("missing interface name or sw_if_index");
6804       return -99;
6805     }
6806
6807   /* Construct the API message */
6808   M (SW_INTERFACE_SET_TABLE, mp);
6809
6810   mp->sw_if_index = ntohl (sw_if_index);
6811   mp->is_ipv6 = is_ipv6;
6812   mp->vrf_id = ntohl (vrf_id);
6813
6814   /* send it... */
6815   S (mp);
6816
6817   /* Wait for a reply... */
6818   W (ret);
6819   return ret;
6820 }
6821
6822 static void vl_api_sw_interface_get_table_reply_t_handler
6823   (vl_api_sw_interface_get_table_reply_t * mp)
6824 {
6825   vat_main_t *vam = &vat_main;
6826
6827   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6828
6829   vam->retval = ntohl (mp->retval);
6830   vam->result_ready = 1;
6831
6832 }
6833
6834 static void vl_api_sw_interface_get_table_reply_t_handler_json
6835   (vl_api_sw_interface_get_table_reply_t * mp)
6836 {
6837   vat_main_t *vam = &vat_main;
6838   vat_json_node_t node;
6839
6840   vat_json_init_object (&node);
6841   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6842   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6843
6844   vat_json_print (vam->ofp, &node);
6845   vat_json_free (&node);
6846
6847   vam->retval = ntohl (mp->retval);
6848   vam->result_ready = 1;
6849 }
6850
6851 static int
6852 api_sw_interface_get_table (vat_main_t * vam)
6853 {
6854   unformat_input_t *i = vam->input;
6855   vl_api_sw_interface_get_table_t *mp;
6856   u32 sw_if_index;
6857   u8 sw_if_index_set = 0;
6858   u8 is_ipv6 = 0;
6859   int ret;
6860
6861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6862     {
6863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6864         sw_if_index_set = 1;
6865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "ipv6"))
6868         is_ipv6 = 1;
6869       else
6870         break;
6871     }
6872
6873   if (sw_if_index_set == 0)
6874     {
6875       errmsg ("missing interface name or sw_if_index");
6876       return -99;
6877     }
6878
6879   M (SW_INTERFACE_GET_TABLE, mp);
6880   mp->sw_if_index = htonl (sw_if_index);
6881   mp->is_ipv6 = is_ipv6;
6882
6883   S (mp);
6884   W (ret);
6885   return ret;
6886 }
6887
6888 static int
6889 api_sw_interface_set_vpath (vat_main_t * vam)
6890 {
6891   unformat_input_t *i = vam->input;
6892   vl_api_sw_interface_set_vpath_t *mp;
6893   u32 sw_if_index = 0;
6894   u8 sw_if_index_set = 0;
6895   u8 is_enable = 0;
6896   int ret;
6897
6898   /* Parse args required to build the message */
6899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6900     {
6901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6902         sw_if_index_set = 1;
6903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6904         sw_if_index_set = 1;
6905       else if (unformat (i, "enable"))
6906         is_enable = 1;
6907       else if (unformat (i, "disable"))
6908         is_enable = 0;
6909       else
6910         break;
6911     }
6912
6913   if (sw_if_index_set == 0)
6914     {
6915       errmsg ("missing interface name or sw_if_index");
6916       return -99;
6917     }
6918
6919   /* Construct the API message */
6920   M (SW_INTERFACE_SET_VPATH, mp);
6921
6922   mp->sw_if_index = ntohl (sw_if_index);
6923   mp->enable = is_enable;
6924
6925   /* send it... */
6926   S (mp);
6927
6928   /* Wait for a reply... */
6929   W (ret);
6930   return ret;
6931 }
6932
6933 static int
6934 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6935 {
6936   unformat_input_t *i = vam->input;
6937   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6938   u32 sw_if_index = 0;
6939   u8 sw_if_index_set = 0;
6940   u8 is_enable = 1;
6941   u8 is_ipv6 = 0;
6942   int ret;
6943
6944   /* Parse args required to build the message */
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, "enable"))
6952         is_enable = 1;
6953       else if (unformat (i, "disable"))
6954         is_enable = 0;
6955       else if (unformat (i, "ip4"))
6956         is_ipv6 = 0;
6957       else if (unformat (i, "ip6"))
6958         is_ipv6 = 1;
6959       else
6960         break;
6961     }
6962
6963   if (sw_if_index_set == 0)
6964     {
6965       errmsg ("missing interface name or sw_if_index");
6966       return -99;
6967     }
6968
6969   /* Construct the API message */
6970   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6971
6972   mp->sw_if_index = ntohl (sw_if_index);
6973   mp->enable = is_enable;
6974   mp->is_ipv6 = is_ipv6;
6975
6976   /* send it... */
6977   S (mp);
6978
6979   /* Wait for a reply... */
6980   W (ret);
6981   return ret;
6982 }
6983
6984 static int
6985 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6986 {
6987   unformat_input_t *i = vam->input;
6988   vl_api_sw_interface_set_geneve_bypass_t *mp;
6989   u32 sw_if_index = 0;
6990   u8 sw_if_index_set = 0;
6991   u8 is_enable = 1;
6992   u8 is_ipv6 = 0;
6993   int ret;
6994
6995   /* Parse args required to build the message */
6996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6997     {
6998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6999         sw_if_index_set = 1;
7000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7001         sw_if_index_set = 1;
7002       else if (unformat (i, "enable"))
7003         is_enable = 1;
7004       else if (unformat (i, "disable"))
7005         is_enable = 0;
7006       else if (unformat (i, "ip4"))
7007         is_ipv6 = 0;
7008       else if (unformat (i, "ip6"))
7009         is_ipv6 = 1;
7010       else
7011         break;
7012     }
7013
7014   if (sw_if_index_set == 0)
7015     {
7016       errmsg ("missing interface name or sw_if_index");
7017       return -99;
7018     }
7019
7020   /* Construct the API message */
7021   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7022
7023   mp->sw_if_index = ntohl (sw_if_index);
7024   mp->enable = is_enable;
7025   mp->is_ipv6 = is_ipv6;
7026
7027   /* send it... */
7028   S (mp);
7029
7030   /* Wait for a reply... */
7031   W (ret);
7032   return ret;
7033 }
7034
7035 static int
7036 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7037 {
7038   unformat_input_t *i = vam->input;
7039   vl_api_sw_interface_set_l2_xconnect_t *mp;
7040   u32 rx_sw_if_index;
7041   u8 rx_sw_if_index_set = 0;
7042   u32 tx_sw_if_index;
7043   u8 tx_sw_if_index_set = 0;
7044   u8 enable = 1;
7045   int ret;
7046
7047   /* Parse args required to build the message */
7048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7049     {
7050       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7051         rx_sw_if_index_set = 1;
7052       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7053         tx_sw_if_index_set = 1;
7054       else if (unformat (i, "rx"))
7055         {
7056           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7057             {
7058               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7059                             &rx_sw_if_index))
7060                 rx_sw_if_index_set = 1;
7061             }
7062           else
7063             break;
7064         }
7065       else if (unformat (i, "tx"))
7066         {
7067           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068             {
7069               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7070                             &tx_sw_if_index))
7071                 tx_sw_if_index_set = 1;
7072             }
7073           else
7074             break;
7075         }
7076       else if (unformat (i, "enable"))
7077         enable = 1;
7078       else if (unformat (i, "disable"))
7079         enable = 0;
7080       else
7081         break;
7082     }
7083
7084   if (rx_sw_if_index_set == 0)
7085     {
7086       errmsg ("missing rx interface name or rx_sw_if_index");
7087       return -99;
7088     }
7089
7090   if (enable && (tx_sw_if_index_set == 0))
7091     {
7092       errmsg ("missing tx interface name or tx_sw_if_index");
7093       return -99;
7094     }
7095
7096   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7097
7098   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7099   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7100   mp->enable = enable;
7101
7102   S (mp);
7103   W (ret);
7104   return ret;
7105 }
7106
7107 static int
7108 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_sw_interface_set_l2_bridge_t *mp;
7112   u32 rx_sw_if_index;
7113   u8 rx_sw_if_index_set = 0;
7114   u32 bd_id;
7115   u8 bd_id_set = 0;
7116   u8 bvi = 0;
7117   u32 shg = 0;
7118   u8 enable = 1;
7119   int ret;
7120
7121   /* Parse args required to build the message */
7122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7123     {
7124       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7125         rx_sw_if_index_set = 1;
7126       else if (unformat (i, "bd_id %d", &bd_id))
7127         bd_id_set = 1;
7128       else
7129         if (unformat
7130             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7131         rx_sw_if_index_set = 1;
7132       else if (unformat (i, "shg %d", &shg))
7133         ;
7134       else if (unformat (i, "bvi"))
7135         bvi = 1;
7136       else if (unformat (i, "enable"))
7137         enable = 1;
7138       else if (unformat (i, "disable"))
7139         enable = 0;
7140       else
7141         break;
7142     }
7143
7144   if (rx_sw_if_index_set == 0)
7145     {
7146       errmsg ("missing rx interface name or sw_if_index");
7147       return -99;
7148     }
7149
7150   if (enable && (bd_id_set == 0))
7151     {
7152       errmsg ("missing bridge domain");
7153       return -99;
7154     }
7155
7156   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7157
7158   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7159   mp->bd_id = ntohl (bd_id);
7160   mp->shg = (u8) shg;
7161   mp->bvi = bvi;
7162   mp->enable = enable;
7163
7164   S (mp);
7165   W (ret);
7166   return ret;
7167 }
7168
7169 static int
7170 api_bridge_domain_dump (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_bridge_domain_dump_t *mp;
7174   vl_api_control_ping_t *mp_ping;
7175   u32 bd_id = ~0;
7176   int ret;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "bd_id %d", &bd_id))
7182         ;
7183       else
7184         break;
7185     }
7186
7187   M (BRIDGE_DOMAIN_DUMP, mp);
7188   mp->bd_id = ntohl (bd_id);
7189   S (mp);
7190
7191   /* Use a control ping for synchronization */
7192   MPING (CONTROL_PING, mp_ping);
7193   S (mp_ping);
7194
7195   W (ret);
7196   return ret;
7197 }
7198
7199 static int
7200 api_bridge_domain_add_del (vat_main_t * vam)
7201 {
7202   unformat_input_t *i = vam->input;
7203   vl_api_bridge_domain_add_del_t *mp;
7204   u32 bd_id = ~0;
7205   u8 is_add = 1;
7206   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7207   u8 *bd_tag = NULL;
7208   u32 mac_age = 0;
7209   int ret;
7210
7211   /* Parse args required to build the message */
7212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7213     {
7214       if (unformat (i, "bd_id %d", &bd_id))
7215         ;
7216       else if (unformat (i, "flood %d", &flood))
7217         ;
7218       else if (unformat (i, "uu-flood %d", &uu_flood))
7219         ;
7220       else if (unformat (i, "forward %d", &forward))
7221         ;
7222       else if (unformat (i, "learn %d", &learn))
7223         ;
7224       else if (unformat (i, "arp-term %d", &arp_term))
7225         ;
7226       else if (unformat (i, "mac-age %d", &mac_age))
7227         ;
7228       else if (unformat (i, "bd-tag %s", &bd_tag))
7229         ;
7230       else if (unformat (i, "del"))
7231         {
7232           is_add = 0;
7233           flood = uu_flood = forward = learn = 0;
7234         }
7235       else
7236         break;
7237     }
7238
7239   if (bd_id == ~0)
7240     {
7241       errmsg ("missing bridge domain");
7242       ret = -99;
7243       goto done;
7244     }
7245
7246   if (mac_age > 255)
7247     {
7248       errmsg ("mac age must be less than 256 ");
7249       ret = -99;
7250       goto done;
7251     }
7252
7253   if ((bd_tag) && (vec_len (bd_tag) > 63))
7254     {
7255       errmsg ("bd-tag cannot be longer than 63");
7256       ret = -99;
7257       goto done;
7258     }
7259
7260   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7261
7262   mp->bd_id = ntohl (bd_id);
7263   mp->flood = flood;
7264   mp->uu_flood = uu_flood;
7265   mp->forward = forward;
7266   mp->learn = learn;
7267   mp->arp_term = arp_term;
7268   mp->is_add = is_add;
7269   mp->mac_age = (u8) mac_age;
7270   if (bd_tag)
7271     {
7272       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7273       mp->bd_tag[vec_len (bd_tag)] = 0;
7274     }
7275   S (mp);
7276   W (ret);
7277
7278 done:
7279   vec_free (bd_tag);
7280   return ret;
7281 }
7282
7283 static int
7284 api_l2fib_flush_bd (vat_main_t * vam)
7285 {
7286   unformat_input_t *i = vam->input;
7287   vl_api_l2fib_flush_bd_t *mp;
7288   u32 bd_id = ~0;
7289   int ret;
7290
7291   /* Parse args required to build the message */
7292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7293     {
7294       if (unformat (i, "bd_id %d", &bd_id));
7295       else
7296         break;
7297     }
7298
7299   if (bd_id == ~0)
7300     {
7301       errmsg ("missing bridge domain");
7302       return -99;
7303     }
7304
7305   M (L2FIB_FLUSH_BD, mp);
7306
7307   mp->bd_id = htonl (bd_id);
7308
7309   S (mp);
7310   W (ret);
7311   return ret;
7312 }
7313
7314 static int
7315 api_l2fib_flush_int (vat_main_t * vam)
7316 {
7317   unformat_input_t *i = vam->input;
7318   vl_api_l2fib_flush_int_t *mp;
7319   u32 sw_if_index = ~0;
7320   int ret;
7321
7322   /* Parse args required to build the message */
7323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7324     {
7325       if (unformat (i, "sw_if_index %d", &sw_if_index));
7326       else
7327         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7328       else
7329         break;
7330     }
7331
7332   if (sw_if_index == ~0)
7333     {
7334       errmsg ("missing interface name or sw_if_index");
7335       return -99;
7336     }
7337
7338   M (L2FIB_FLUSH_INT, mp);
7339
7340   mp->sw_if_index = ntohl (sw_if_index);
7341
7342   S (mp);
7343   W (ret);
7344   return ret;
7345 }
7346
7347 static int
7348 api_l2fib_add_del (vat_main_t * vam)
7349 {
7350   unformat_input_t *i = vam->input;
7351   vl_api_l2fib_add_del_t *mp;
7352   f64 timeout;
7353   u8 mac[6] = { 0 };
7354   u8 mac_set = 0;
7355   u32 bd_id;
7356   u8 bd_id_set = 0;
7357   u32 sw_if_index = 0;
7358   u8 sw_if_index_set = 0;
7359   u8 is_add = 1;
7360   u8 static_mac = 0;
7361   u8 filter_mac = 0;
7362   u8 bvi_mac = 0;
7363   int count = 1;
7364   f64 before = 0;
7365   int j;
7366
7367   /* Parse args required to build the message */
7368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7369     {
7370       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7371         mac_set = 1;
7372       else if (unformat (i, "bd_id %d", &bd_id))
7373         bd_id_set = 1;
7374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7375         sw_if_index_set = 1;
7376       else if (unformat (i, "sw_if"))
7377         {
7378           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7379             {
7380               if (unformat
7381                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7382                 sw_if_index_set = 1;
7383             }
7384           else
7385             break;
7386         }
7387       else if (unformat (i, "static"))
7388         static_mac = 1;
7389       else if (unformat (i, "filter"))
7390         {
7391           filter_mac = 1;
7392           static_mac = 1;
7393         }
7394       else if (unformat (i, "bvi"))
7395         {
7396           bvi_mac = 1;
7397           static_mac = 1;
7398         }
7399       else if (unformat (i, "del"))
7400         is_add = 0;
7401       else if (unformat (i, "count %d", &count))
7402         ;
7403       else
7404         break;
7405     }
7406
7407   if (mac_set == 0)
7408     {
7409       errmsg ("missing mac address");
7410       return -99;
7411     }
7412
7413   if (bd_id_set == 0)
7414     {
7415       errmsg ("missing bridge domain");
7416       return -99;
7417     }
7418
7419   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7420     {
7421       errmsg ("missing interface name or sw_if_index");
7422       return -99;
7423     }
7424
7425   if (count > 1)
7426     {
7427       /* Turn on async mode */
7428       vam->async_mode = 1;
7429       vam->async_errors = 0;
7430       before = vat_time_now (vam);
7431     }
7432
7433   for (j = 0; j < count; j++)
7434     {
7435       M (L2FIB_ADD_DEL, mp);
7436
7437       clib_memcpy (mp->mac, mac, 6);
7438       mp->bd_id = ntohl (bd_id);
7439       mp->is_add = is_add;
7440       mp->sw_if_index = ntohl (sw_if_index);
7441
7442       if (is_add)
7443         {
7444           mp->static_mac = static_mac;
7445           mp->filter_mac = filter_mac;
7446           mp->bvi_mac = bvi_mac;
7447         }
7448       increment_mac_address (mac);
7449       /* send it... */
7450       S (mp);
7451     }
7452
7453   if (count > 1)
7454     {
7455       vl_api_control_ping_t *mp_ping;
7456       f64 after;
7457
7458       /* Shut off async mode */
7459       vam->async_mode = 0;
7460
7461       MPING (CONTROL_PING, mp_ping);
7462       S (mp_ping);
7463
7464       timeout = vat_time_now (vam) + 1.0;
7465       while (vat_time_now (vam) < timeout)
7466         if (vam->result_ready == 1)
7467           goto out;
7468       vam->retval = -99;
7469
7470     out:
7471       if (vam->retval == -99)
7472         errmsg ("timeout");
7473
7474       if (vam->async_errors > 0)
7475         {
7476           errmsg ("%d asynchronous errors", vam->async_errors);
7477           vam->retval = -98;
7478         }
7479       vam->async_errors = 0;
7480       after = vat_time_now (vam);
7481
7482       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7483              count, after - before, count / (after - before));
7484     }
7485   else
7486     {
7487       int ret;
7488
7489       /* Wait for a reply... */
7490       W (ret);
7491       return ret;
7492     }
7493   /* Return the good/bad news */
7494   return (vam->retval);
7495 }
7496
7497 static int
7498 api_bridge_domain_set_mac_age (vat_main_t * vam)
7499 {
7500   unformat_input_t *i = vam->input;
7501   vl_api_bridge_domain_set_mac_age_t *mp;
7502   u32 bd_id = ~0;
7503   u32 mac_age = 0;
7504   int ret;
7505
7506   /* Parse args required to build the message */
7507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7508     {
7509       if (unformat (i, "bd_id %d", &bd_id));
7510       else if (unformat (i, "mac-age %d", &mac_age));
7511       else
7512         break;
7513     }
7514
7515   if (bd_id == ~0)
7516     {
7517       errmsg ("missing bridge domain");
7518       return -99;
7519     }
7520
7521   if (mac_age > 255)
7522     {
7523       errmsg ("mac age must be less than 256 ");
7524       return -99;
7525     }
7526
7527   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7528
7529   mp->bd_id = htonl (bd_id);
7530   mp->mac_age = (u8) mac_age;
7531
7532   S (mp);
7533   W (ret);
7534   return ret;
7535 }
7536
7537 static int
7538 api_l2_flags (vat_main_t * vam)
7539 {
7540   unformat_input_t *i = vam->input;
7541   vl_api_l2_flags_t *mp;
7542   u32 sw_if_index;
7543   u32 flags = 0;
7544   u8 sw_if_index_set = 0;
7545   u8 is_set = 0;
7546   int ret;
7547
7548   /* Parse args required to build the message */
7549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7550     {
7551       if (unformat (i, "sw_if_index %d", &sw_if_index))
7552         sw_if_index_set = 1;
7553       else if (unformat (i, "sw_if"))
7554         {
7555           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556             {
7557               if (unformat
7558                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7559                 sw_if_index_set = 1;
7560             }
7561           else
7562             break;
7563         }
7564       else if (unformat (i, "learn"))
7565         flags |= L2_LEARN;
7566       else if (unformat (i, "forward"))
7567         flags |= L2_FWD;
7568       else if (unformat (i, "flood"))
7569         flags |= L2_FLOOD;
7570       else if (unformat (i, "uu-flood"))
7571         flags |= L2_UU_FLOOD;
7572       else if (unformat (i, "arp-term"))
7573         flags |= L2_ARP_TERM;
7574       else if (unformat (i, "off"))
7575         is_set = 0;
7576       else if (unformat (i, "disable"))
7577         is_set = 0;
7578       else
7579         break;
7580     }
7581
7582   if (sw_if_index_set == 0)
7583     {
7584       errmsg ("missing interface name or sw_if_index");
7585       return -99;
7586     }
7587
7588   M (L2_FLAGS, mp);
7589
7590   mp->sw_if_index = ntohl (sw_if_index);
7591   mp->feature_bitmap = ntohl (flags);
7592   mp->is_set = is_set;
7593
7594   S (mp);
7595   W (ret);
7596   return ret;
7597 }
7598
7599 static int
7600 api_bridge_flags (vat_main_t * vam)
7601 {
7602   unformat_input_t *i = vam->input;
7603   vl_api_bridge_flags_t *mp;
7604   u32 bd_id;
7605   u8 bd_id_set = 0;
7606   u8 is_set = 1;
7607   u32 flags = 0;
7608   int ret;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "bd_id %d", &bd_id))
7614         bd_id_set = 1;
7615       else if (unformat (i, "learn"))
7616         flags |= L2_LEARN;
7617       else if (unformat (i, "forward"))
7618         flags |= L2_FWD;
7619       else if (unformat (i, "flood"))
7620         flags |= L2_FLOOD;
7621       else if (unformat (i, "uu-flood"))
7622         flags |= L2_UU_FLOOD;
7623       else if (unformat (i, "arp-term"))
7624         flags |= L2_ARP_TERM;
7625       else if (unformat (i, "off"))
7626         is_set = 0;
7627       else if (unformat (i, "disable"))
7628         is_set = 0;
7629       else
7630         break;
7631     }
7632
7633   if (bd_id_set == 0)
7634     {
7635       errmsg ("missing bridge domain");
7636       return -99;
7637     }
7638
7639   M (BRIDGE_FLAGS, mp);
7640
7641   mp->bd_id = ntohl (bd_id);
7642   mp->feature_bitmap = ntohl (flags);
7643   mp->is_set = is_set;
7644
7645   S (mp);
7646   W (ret);
7647   return ret;
7648 }
7649
7650 static int
7651 api_bd_ip_mac_add_del (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_bd_ip_mac_add_del_t *mp;
7655   u32 bd_id;
7656   u8 is_ipv6 = 0;
7657   u8 is_add = 1;
7658   u8 bd_id_set = 0;
7659   u8 ip_set = 0;
7660   u8 mac_set = 0;
7661   ip4_address_t v4addr;
7662   ip6_address_t v6addr;
7663   u8 macaddr[6];
7664   int ret;
7665
7666
7667   /* Parse args required to build the message */
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "bd_id %d", &bd_id))
7671         {
7672           bd_id_set++;
7673         }
7674       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7675         {
7676           ip_set++;
7677         }
7678       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7679         {
7680           ip_set++;
7681           is_ipv6++;
7682         }
7683       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7684         {
7685           mac_set++;
7686         }
7687       else if (unformat (i, "del"))
7688         is_add = 0;
7689       else
7690         break;
7691     }
7692
7693   if (bd_id_set == 0)
7694     {
7695       errmsg ("missing bridge domain");
7696       return -99;
7697     }
7698   else if (ip_set == 0)
7699     {
7700       errmsg ("missing IP address");
7701       return -99;
7702     }
7703   else if (mac_set == 0)
7704     {
7705       errmsg ("missing MAC address");
7706       return -99;
7707     }
7708
7709   M (BD_IP_MAC_ADD_DEL, mp);
7710
7711   mp->bd_id = ntohl (bd_id);
7712   mp->is_ipv6 = is_ipv6;
7713   mp->is_add = is_add;
7714   if (is_ipv6)
7715     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7716   else
7717     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7718   clib_memcpy (mp->mac_address, macaddr, 6);
7719   S (mp);
7720   W (ret);
7721   return ret;
7722 }
7723
7724 static void vl_api_bd_ip_mac_details_t_handler
7725   (vl_api_bd_ip_mac_details_t * mp)
7726 {
7727   vat_main_t *vam = &vat_main;
7728   u8 *ip = 0;
7729
7730   if (!mp->is_ipv6)
7731     ip =
7732       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7733   else
7734     ip =
7735       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7736
7737   print (vam->ofp,
7738          "\n%-5d %-7s %-20U %-30s",
7739          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7740          format_ethernet_address, mp->mac_address, ip);
7741
7742   vec_free (ip);
7743 }
7744
7745 static void vl_api_bd_ip_mac_details_t_handler_json
7746   (vl_api_bd_ip_mac_details_t * mp)
7747 {
7748   vat_main_t *vam = &vat_main;
7749   vat_json_node_t *node = NULL;
7750
7751   if (VAT_JSON_ARRAY != vam->json_tree.type)
7752     {
7753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7754       vat_json_init_array (&vam->json_tree);
7755     }
7756   node = vat_json_array_add (&vam->json_tree);
7757
7758   vat_json_init_object (node);
7759   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7760   vat_json_object_add_uint (node, "is_ipv6", ntohl (mp->is_ipv6));
7761   vat_json_object_add_string_copy (node, "mac_address",
7762                                    format (0, "%U", format_ethernet_address,
7763                                            &mp->mac_address));
7764   u8 *ip = 0;
7765
7766   if (!mp->is_ipv6)
7767     ip =
7768       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7769   else
7770     ip =
7771       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7772   vat_json_object_add_string_copy (node, "ip_address", ip);
7773   vec_free (ip);
7774 }
7775
7776 static int
7777 api_bd_ip_mac_dump (vat_main_t * vam)
7778 {
7779   unformat_input_t *i = vam->input;
7780   vl_api_bd_ip_mac_dump_t *mp;
7781   vl_api_control_ping_t *mp_ping;
7782   int ret;
7783   u32 bd_id;
7784   u8 bd_id_set = 0;
7785
7786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7787     {
7788       if (unformat (i, "bd_id %d", &bd_id))
7789         {
7790           bd_id_set++;
7791         }
7792       else
7793         break;
7794     }
7795
7796   print (vam->ofp,
7797          "\n%-5s %-7s %-20s %-30s",
7798          "bd_id", "is_ipv6", "mac_address", "ip_address");
7799
7800   /* Dump Bridge Domain Ip to Mac entries */
7801   M (BD_IP_MAC_DUMP, mp);
7802
7803   if (bd_id_set)
7804     mp->bd_id = htonl (bd_id);
7805   else
7806     mp->bd_id = ~0;
7807
7808   S (mp);
7809
7810   /* Use a control ping for synchronization */
7811   MPING (CONTROL_PING, mp_ping);
7812   S (mp_ping);
7813
7814   W (ret);
7815   return ret;
7816 }
7817
7818 static int
7819 api_tap_connect (vat_main_t * vam)
7820 {
7821   unformat_input_t *i = vam->input;
7822   vl_api_tap_connect_t *mp;
7823   u8 mac_address[6];
7824   u8 random_mac = 1;
7825   u8 name_set = 0;
7826   u8 *tap_name;
7827   u8 *tag = 0;
7828   ip4_address_t ip4_address;
7829   u32 ip4_mask_width;
7830   int ip4_address_set = 0;
7831   ip6_address_t ip6_address;
7832   u32 ip6_mask_width;
7833   int ip6_address_set = 0;
7834   int ret;
7835
7836   memset (mac_address, 0, sizeof (mac_address));
7837
7838   /* Parse args required to build the message */
7839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7840     {
7841       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7842         {
7843           random_mac = 0;
7844         }
7845       else if (unformat (i, "random-mac"))
7846         random_mac = 1;
7847       else if (unformat (i, "tapname %s", &tap_name))
7848         name_set = 1;
7849       else if (unformat (i, "tag %s", &tag))
7850         ;
7851       else if (unformat (i, "address %U/%d",
7852                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7853         ip4_address_set = 1;
7854       else if (unformat (i, "address %U/%d",
7855                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7856         ip6_address_set = 1;
7857       else
7858         break;
7859     }
7860
7861   if (name_set == 0)
7862     {
7863       errmsg ("missing tap name");
7864       return -99;
7865     }
7866   if (vec_len (tap_name) > 63)
7867     {
7868       errmsg ("tap name too long");
7869       return -99;
7870     }
7871   vec_add1 (tap_name, 0);
7872
7873   if (vec_len (tag) > 63)
7874     {
7875       errmsg ("tag too long");
7876       return -99;
7877     }
7878
7879   /* Construct the API message */
7880   M (TAP_CONNECT, mp);
7881
7882   mp->use_random_mac = random_mac;
7883   clib_memcpy (mp->mac_address, mac_address, 6);
7884   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7885   if (tag)
7886     clib_memcpy (mp->tag, tag, vec_len (tag));
7887
7888   if (ip4_address_set)
7889     {
7890       mp->ip4_address_set = 1;
7891       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7892       mp->ip4_mask_width = ip4_mask_width;
7893     }
7894   if (ip6_address_set)
7895     {
7896       mp->ip6_address_set = 1;
7897       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7898       mp->ip6_mask_width = ip6_mask_width;
7899     }
7900
7901   vec_free (tap_name);
7902   vec_free (tag);
7903
7904   /* send it... */
7905   S (mp);
7906
7907   /* Wait for a reply... */
7908   W (ret);
7909   return ret;
7910 }
7911
7912 static int
7913 api_tap_modify (vat_main_t * vam)
7914 {
7915   unformat_input_t *i = vam->input;
7916   vl_api_tap_modify_t *mp;
7917   u8 mac_address[6];
7918   u8 random_mac = 1;
7919   u8 name_set = 0;
7920   u8 *tap_name;
7921   u32 sw_if_index = ~0;
7922   u8 sw_if_index_set = 0;
7923   int ret;
7924
7925   memset (mac_address, 0, sizeof (mac_address));
7926
7927   /* Parse args required to build the message */
7928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7929     {
7930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7931         sw_if_index_set = 1;
7932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7933         sw_if_index_set = 1;
7934       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7935         {
7936           random_mac = 0;
7937         }
7938       else if (unformat (i, "random-mac"))
7939         random_mac = 1;
7940       else if (unformat (i, "tapname %s", &tap_name))
7941         name_set = 1;
7942       else
7943         break;
7944     }
7945
7946   if (sw_if_index_set == 0)
7947     {
7948       errmsg ("missing vpp interface name");
7949       return -99;
7950     }
7951   if (name_set == 0)
7952     {
7953       errmsg ("missing tap name");
7954       return -99;
7955     }
7956   if (vec_len (tap_name) > 63)
7957     {
7958       errmsg ("tap name too long");
7959     }
7960   vec_add1 (tap_name, 0);
7961
7962   /* Construct the API message */
7963   M (TAP_MODIFY, mp);
7964
7965   mp->use_random_mac = random_mac;
7966   mp->sw_if_index = ntohl (sw_if_index);
7967   clib_memcpy (mp->mac_address, mac_address, 6);
7968   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7969   vec_free (tap_name);
7970
7971   /* send it... */
7972   S (mp);
7973
7974   /* Wait for a reply... */
7975   W (ret);
7976   return ret;
7977 }
7978
7979 static int
7980 api_tap_delete (vat_main_t * vam)
7981 {
7982   unformat_input_t *i = vam->input;
7983   vl_api_tap_delete_t *mp;
7984   u32 sw_if_index = ~0;
7985   u8 sw_if_index_set = 0;
7986   int ret;
7987
7988   /* Parse args required to build the message */
7989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7990     {
7991       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7992         sw_if_index_set = 1;
7993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7994         sw_if_index_set = 1;
7995       else
7996         break;
7997     }
7998
7999   if (sw_if_index_set == 0)
8000     {
8001       errmsg ("missing vpp interface name");
8002       return -99;
8003     }
8004
8005   /* Construct the API message */
8006   M (TAP_DELETE, mp);
8007
8008   mp->sw_if_index = ntohl (sw_if_index);
8009
8010   /* send it... */
8011   S (mp);
8012
8013   /* Wait for a reply... */
8014   W (ret);
8015   return ret;
8016 }
8017
8018 static int
8019 api_tap_create_v2 (vat_main_t * vam)
8020 {
8021   unformat_input_t *i = vam->input;
8022   vl_api_tap_create_v2_t *mp;
8023   u8 mac_address[6];
8024   u8 random_mac = 1;
8025   u32 id = ~0;
8026   u8 *host_if_name = 0;
8027   u8 *host_ns = 0;
8028   u8 host_mac_addr[6];
8029   u8 host_mac_addr_set = 0;
8030   u8 *host_bridge = 0;
8031   ip4_address_t host_ip4_addr;
8032   ip4_address_t host_ip4_gw;
8033   u8 host_ip4_gw_set = 0;
8034   u32 host_ip4_prefix_len = 0;
8035   ip6_address_t host_ip6_addr;
8036   ip6_address_t host_ip6_gw;
8037   u8 host_ip6_gw_set = 0;
8038   u32 host_ip6_prefix_len = 0;
8039   int ret;
8040   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8041
8042   memset (mac_address, 0, sizeof (mac_address));
8043
8044   /* Parse args required to build the message */
8045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8046     {
8047       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8048         {
8049           random_mac = 0;
8050         }
8051       else if (unformat (i, "id %u", &id))
8052         ;
8053       else if (unformat (i, "host-if-name %s", &host_if_name))
8054         ;
8055       else if (unformat (i, "host-ns %s", &host_ns))
8056         ;
8057       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8058                          host_mac_addr))
8059         host_mac_addr_set = 1;
8060       else if (unformat (i, "host-bridge %s", &host_bridge))
8061         ;
8062       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8063                          &host_ip4_addr, &host_ip4_prefix_len))
8064         ;
8065       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8066                          &host_ip6_addr, &host_ip6_prefix_len))
8067         ;
8068       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8069                          &host_ip4_gw))
8070         host_ip4_gw_set = 1;
8071       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8072                          &host_ip6_gw))
8073         host_ip6_gw_set = 1;
8074       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8075         ;
8076       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8077         ;
8078       else
8079         break;
8080     }
8081
8082   if (vec_len (host_if_name) > 63)
8083     {
8084       errmsg ("tap name too long. ");
8085       return -99;
8086     }
8087   if (vec_len (host_ns) > 63)
8088     {
8089       errmsg ("host name space too long. ");
8090       return -99;
8091     }
8092   if (vec_len (host_bridge) > 63)
8093     {
8094       errmsg ("host bridge name too long. ");
8095       return -99;
8096     }
8097   if (host_ip4_prefix_len > 32)
8098     {
8099       errmsg ("host ip4 prefix length not valid. ");
8100       return -99;
8101     }
8102   if (host_ip6_prefix_len > 128)
8103     {
8104       errmsg ("host ip6 prefix length not valid. ");
8105       return -99;
8106     }
8107   if (!is_pow2 (rx_ring_sz))
8108     {
8109       errmsg ("rx ring size must be power of 2. ");
8110       return -99;
8111     }
8112   if (rx_ring_sz > 32768)
8113     {
8114       errmsg ("rx ring size must be 32768 or lower. ");
8115       return -99;
8116     }
8117   if (!is_pow2 (tx_ring_sz))
8118     {
8119       errmsg ("tx ring size must be power of 2. ");
8120       return -99;
8121     }
8122   if (tx_ring_sz > 32768)
8123     {
8124       errmsg ("tx ring size must be 32768 or lower. ");
8125       return -99;
8126     }
8127
8128   /* Construct the API message */
8129   M (TAP_CREATE_V2, mp);
8130
8131   mp->use_random_mac = random_mac;
8132
8133   mp->id = ntohl (id);
8134   mp->host_namespace_set = host_ns != 0;
8135   mp->host_bridge_set = host_bridge != 0;
8136   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8137   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8138   mp->rx_ring_sz = ntohs (rx_ring_sz);
8139   mp->tx_ring_sz = ntohs (tx_ring_sz);
8140
8141   if (random_mac == 0)
8142     clib_memcpy (mp->mac_address, mac_address, 6);
8143   if (host_mac_addr_set)
8144     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8145   if (host_if_name)
8146     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8147   if (host_ns)
8148     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8149   if (host_bridge)
8150     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8151   if (host_ip4_prefix_len)
8152     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8153   if (host_ip4_prefix_len)
8154     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8155   if (host_ip4_gw_set)
8156     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8157   if (host_ip6_gw_set)
8158     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8159
8160   vec_free (host_ns);
8161   vec_free (host_if_name);
8162   vec_free (host_bridge);
8163
8164   /* send it... */
8165   S (mp);
8166
8167   /* Wait for a reply... */
8168   W (ret);
8169   return ret;
8170 }
8171
8172 static int
8173 api_tap_delete_v2 (vat_main_t * vam)
8174 {
8175   unformat_input_t *i = vam->input;
8176   vl_api_tap_delete_v2_t *mp;
8177   u32 sw_if_index = ~0;
8178   u8 sw_if_index_set = 0;
8179   int ret;
8180
8181   /* Parse args required to build the message */
8182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8183     {
8184       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8185         sw_if_index_set = 1;
8186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8187         sw_if_index_set = 1;
8188       else
8189         break;
8190     }
8191
8192   if (sw_if_index_set == 0)
8193     {
8194       errmsg ("missing vpp interface name. ");
8195       return -99;
8196     }
8197
8198   /* Construct the API message */
8199   M (TAP_DELETE_V2, mp);
8200
8201   mp->sw_if_index = ntohl (sw_if_index);
8202
8203   /* send it... */
8204   S (mp);
8205
8206   /* Wait for a reply... */
8207   W (ret);
8208   return ret;
8209 }
8210
8211 static int
8212 api_bond_create (vat_main_t * vam)
8213 {
8214   unformat_input_t *i = vam->input;
8215   vl_api_bond_create_t *mp;
8216   u8 mac_address[6];
8217   u8 custom_mac = 0;
8218   int ret;
8219   u8 mode;
8220   u8 lb;
8221   u8 mode_is_set = 0;
8222
8223   memset (mac_address, 0, sizeof (mac_address));
8224   lb = BOND_LB_L2;
8225
8226   /* Parse args required to build the message */
8227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8228     {
8229       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8230         mode_is_set = 1;
8231       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8232                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8233         ;
8234       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8235                          mac_address))
8236         custom_mac = 1;
8237       else
8238         break;
8239     }
8240
8241   if (mode_is_set == 0)
8242     {
8243       errmsg ("Missing bond mode. ");
8244       return -99;
8245     }
8246
8247   /* Construct the API message */
8248   M (BOND_CREATE, mp);
8249
8250   mp->use_custom_mac = custom_mac;
8251
8252   mp->mode = mode;
8253   mp->lb = lb;
8254
8255   if (custom_mac)
8256     clib_memcpy (mp->mac_address, mac_address, 6);
8257
8258   /* send it... */
8259   S (mp);
8260
8261   /* Wait for a reply... */
8262   W (ret);
8263   return ret;
8264 }
8265
8266 static int
8267 api_bond_delete (vat_main_t * vam)
8268 {
8269   unformat_input_t *i = vam->input;
8270   vl_api_bond_delete_t *mp;
8271   u32 sw_if_index = ~0;
8272   u8 sw_if_index_set = 0;
8273   int ret;
8274
8275   /* Parse args required to build the message */
8276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8277     {
8278       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8279         sw_if_index_set = 1;
8280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8281         sw_if_index_set = 1;
8282       else
8283         break;
8284     }
8285
8286   if (sw_if_index_set == 0)
8287     {
8288       errmsg ("missing vpp interface name. ");
8289       return -99;
8290     }
8291
8292   /* Construct the API message */
8293   M (BOND_DELETE, mp);
8294
8295   mp->sw_if_index = ntohl (sw_if_index);
8296
8297   /* send it... */
8298   S (mp);
8299
8300   /* Wait for a reply... */
8301   W (ret);
8302   return ret;
8303 }
8304
8305 static int
8306 api_bond_enslave (vat_main_t * vam)
8307 {
8308   unformat_input_t *i = vam->input;
8309   vl_api_bond_enslave_t *mp;
8310   u32 bond_sw_if_index;
8311   int ret;
8312   u8 is_passive;
8313   u8 is_long_timeout;
8314   u32 bond_sw_if_index_is_set = 0;
8315   u32 sw_if_index;
8316   u8 sw_if_index_is_set = 0;
8317
8318   /* Parse args required to build the message */
8319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8320     {
8321       if (unformat (i, "sw_if_index %d", &sw_if_index))
8322         sw_if_index_is_set = 1;
8323       else if (unformat (i, "bond %u", &bond_sw_if_index))
8324         bond_sw_if_index_is_set = 1;
8325       else if (unformat (i, "passive %d", &is_passive))
8326         ;
8327       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8328         ;
8329       else
8330         break;
8331     }
8332
8333   if (bond_sw_if_index_is_set == 0)
8334     {
8335       errmsg ("Missing bond sw_if_index. ");
8336       return -99;
8337     }
8338   if (sw_if_index_is_set == 0)
8339     {
8340       errmsg ("Missing slave sw_if_index. ");
8341       return -99;
8342     }
8343
8344   /* Construct the API message */
8345   M (BOND_ENSLAVE, mp);
8346
8347   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8348   mp->sw_if_index = ntohl (sw_if_index);
8349   mp->is_long_timeout = is_long_timeout;
8350   mp->is_passive = is_passive;
8351
8352   /* send it... */
8353   S (mp);
8354
8355   /* Wait for a reply... */
8356   W (ret);
8357   return ret;
8358 }
8359
8360 static int
8361 api_bond_detach_slave (vat_main_t * vam)
8362 {
8363   unformat_input_t *i = vam->input;
8364   vl_api_bond_detach_slave_t *mp;
8365   u32 sw_if_index = ~0;
8366   u8 sw_if_index_set = 0;
8367   int ret;
8368
8369   /* Parse args required to build the message */
8370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8371     {
8372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8373         sw_if_index_set = 1;
8374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8375         sw_if_index_set = 1;
8376       else
8377         break;
8378     }
8379
8380   if (sw_if_index_set == 0)
8381     {
8382       errmsg ("missing vpp interface name. ");
8383       return -99;
8384     }
8385
8386   /* Construct the API message */
8387   M (BOND_DETACH_SLAVE, mp);
8388
8389   mp->sw_if_index = ntohl (sw_if_index);
8390
8391   /* send it... */
8392   S (mp);
8393
8394   /* Wait for a reply... */
8395   W (ret);
8396   return ret;
8397 }
8398
8399 static int
8400 api_ip_table_add_del (vat_main_t * vam)
8401 {
8402   unformat_input_t *i = vam->input;
8403   vl_api_ip_table_add_del_t *mp;
8404   u32 table_id = ~0;
8405   u8 is_ipv6 = 0;
8406   u8 is_add = 1;
8407   int ret = 0;
8408
8409   /* Parse args required to build the message */
8410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8411     {
8412       if (unformat (i, "ipv6"))
8413         is_ipv6 = 1;
8414       else if (unformat (i, "del"))
8415         is_add = 0;
8416       else if (unformat (i, "add"))
8417         is_add = 1;
8418       else if (unformat (i, "table %d", &table_id))
8419         ;
8420       else
8421         {
8422           clib_warning ("parse error '%U'", format_unformat_error, i);
8423           return -99;
8424         }
8425     }
8426
8427   if (~0 == table_id)
8428     {
8429       errmsg ("missing table-ID");
8430       return -99;
8431     }
8432
8433   /* Construct the API message */
8434   M (IP_TABLE_ADD_DEL, mp);
8435
8436   mp->table_id = ntohl (table_id);
8437   mp->is_ipv6 = is_ipv6;
8438   mp->is_add = is_add;
8439
8440   /* send it... */
8441   S (mp);
8442
8443   /* Wait for a reply... */
8444   W (ret);
8445
8446   return ret;
8447 }
8448
8449 static int
8450 api_ip_add_del_route (vat_main_t * vam)
8451 {
8452   unformat_input_t *i = vam->input;
8453   vl_api_ip_add_del_route_t *mp;
8454   u32 sw_if_index = ~0, vrf_id = 0;
8455   u8 is_ipv6 = 0;
8456   u8 is_local = 0, is_drop = 0;
8457   u8 is_unreach = 0, is_prohibit = 0;
8458   u8 is_add = 1;
8459   u32 next_hop_weight = 1;
8460   u8 is_multipath = 0;
8461   u8 address_set = 0;
8462   u8 address_length_set = 0;
8463   u32 next_hop_table_id = 0;
8464   u32 resolve_attempts = 0;
8465   u32 dst_address_length = 0;
8466   u8 next_hop_set = 0;
8467   ip4_address_t v4_dst_address, v4_next_hop_address;
8468   ip6_address_t v6_dst_address, v6_next_hop_address;
8469   int count = 1;
8470   int j;
8471   f64 before = 0;
8472   u32 random_add_del = 0;
8473   u32 *random_vector = 0;
8474   uword *random_hash;
8475   u32 random_seed = 0xdeaddabe;
8476   u32 classify_table_index = ~0;
8477   u8 is_classify = 0;
8478   u8 resolve_host = 0, resolve_attached = 0;
8479   mpls_label_t *next_hop_out_label_stack = NULL;
8480   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8481   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8482
8483   /* Parse args required to build the message */
8484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8485     {
8486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8487         ;
8488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8489         ;
8490       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8491         {
8492           address_set = 1;
8493           is_ipv6 = 0;
8494         }
8495       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8496         {
8497           address_set = 1;
8498           is_ipv6 = 1;
8499         }
8500       else if (unformat (i, "/%d", &dst_address_length))
8501         {
8502           address_length_set = 1;
8503         }
8504
8505       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8506                                          &v4_next_hop_address))
8507         {
8508           next_hop_set = 1;
8509         }
8510       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8511                                          &v6_next_hop_address))
8512         {
8513           next_hop_set = 1;
8514         }
8515       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8516         ;
8517       else if (unformat (i, "weight %d", &next_hop_weight))
8518         ;
8519       else if (unformat (i, "drop"))
8520         {
8521           is_drop = 1;
8522         }
8523       else if (unformat (i, "null-send-unreach"))
8524         {
8525           is_unreach = 1;
8526         }
8527       else if (unformat (i, "null-send-prohibit"))
8528         {
8529           is_prohibit = 1;
8530         }
8531       else if (unformat (i, "local"))
8532         {
8533           is_local = 1;
8534         }
8535       else if (unformat (i, "classify %d", &classify_table_index))
8536         {
8537           is_classify = 1;
8538         }
8539       else if (unformat (i, "del"))
8540         is_add = 0;
8541       else if (unformat (i, "add"))
8542         is_add = 1;
8543       else if (unformat (i, "resolve-via-host"))
8544         resolve_host = 1;
8545       else if (unformat (i, "resolve-via-attached"))
8546         resolve_attached = 1;
8547       else if (unformat (i, "multipath"))
8548         is_multipath = 1;
8549       else if (unformat (i, "vrf %d", &vrf_id))
8550         ;
8551       else if (unformat (i, "count %d", &count))
8552         ;
8553       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8554         ;
8555       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8556         ;
8557       else if (unformat (i, "out-label %d", &next_hop_out_label))
8558         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8559       else if (unformat (i, "via-label %d", &next_hop_via_label))
8560         ;
8561       else if (unformat (i, "random"))
8562         random_add_del = 1;
8563       else if (unformat (i, "seed %d", &random_seed))
8564         ;
8565       else
8566         {
8567           clib_warning ("parse error '%U'", format_unformat_error, i);
8568           return -99;
8569         }
8570     }
8571
8572   if (!next_hop_set && !is_drop && !is_local &&
8573       !is_classify && !is_unreach && !is_prohibit &&
8574       MPLS_LABEL_INVALID == next_hop_via_label)
8575     {
8576       errmsg
8577         ("next hop / local / drop / unreach / prohibit / classify not set");
8578       return -99;
8579     }
8580
8581   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8582     {
8583       errmsg ("next hop and next-hop via label set");
8584       return -99;
8585     }
8586   if (address_set == 0)
8587     {
8588       errmsg ("missing addresses");
8589       return -99;
8590     }
8591
8592   if (address_length_set == 0)
8593     {
8594       errmsg ("missing address length");
8595       return -99;
8596     }
8597
8598   /* Generate a pile of unique, random routes */
8599   if (random_add_del)
8600     {
8601       u32 this_random_address;
8602       random_hash = hash_create (count, sizeof (uword));
8603
8604       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8605       for (j = 0; j <= count; j++)
8606         {
8607           do
8608             {
8609               this_random_address = random_u32 (&random_seed);
8610               this_random_address =
8611                 clib_host_to_net_u32 (this_random_address);
8612             }
8613           while (hash_get (random_hash, this_random_address));
8614           vec_add1 (random_vector, this_random_address);
8615           hash_set (random_hash, this_random_address, 1);
8616         }
8617       hash_free (random_hash);
8618       v4_dst_address.as_u32 = random_vector[0];
8619     }
8620
8621   if (count > 1)
8622     {
8623       /* Turn on async mode */
8624       vam->async_mode = 1;
8625       vam->async_errors = 0;
8626       before = vat_time_now (vam);
8627     }
8628
8629   for (j = 0; j < count; j++)
8630     {
8631       /* Construct the API message */
8632       M2 (IP_ADD_DEL_ROUTE, mp,
8633           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8634
8635       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8636       mp->table_id = ntohl (vrf_id);
8637
8638       mp->is_add = is_add;
8639       mp->is_drop = is_drop;
8640       mp->is_unreach = is_unreach;
8641       mp->is_prohibit = is_prohibit;
8642       mp->is_ipv6 = is_ipv6;
8643       mp->is_local = is_local;
8644       mp->is_classify = is_classify;
8645       mp->is_multipath = is_multipath;
8646       mp->is_resolve_host = resolve_host;
8647       mp->is_resolve_attached = resolve_attached;
8648       mp->next_hop_weight = next_hop_weight;
8649       mp->dst_address_length = dst_address_length;
8650       mp->next_hop_table_id = ntohl (next_hop_table_id);
8651       mp->classify_table_index = ntohl (classify_table_index);
8652       mp->next_hop_via_label = ntohl (next_hop_via_label);
8653       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8654       if (0 != mp->next_hop_n_out_labels)
8655         {
8656           memcpy (mp->next_hop_out_label_stack,
8657                   next_hop_out_label_stack,
8658                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8659           vec_free (next_hop_out_label_stack);
8660         }
8661
8662       if (is_ipv6)
8663         {
8664           clib_memcpy (mp->dst_address, &v6_dst_address,
8665                        sizeof (v6_dst_address));
8666           if (next_hop_set)
8667             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8668                          sizeof (v6_next_hop_address));
8669           increment_v6_address (&v6_dst_address);
8670         }
8671       else
8672         {
8673           clib_memcpy (mp->dst_address, &v4_dst_address,
8674                        sizeof (v4_dst_address));
8675           if (next_hop_set)
8676             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8677                          sizeof (v4_next_hop_address));
8678           if (random_add_del)
8679             v4_dst_address.as_u32 = random_vector[j + 1];
8680           else
8681             increment_v4_address (&v4_dst_address);
8682         }
8683       /* send it... */
8684       S (mp);
8685       /* If we receive SIGTERM, stop now... */
8686       if (vam->do_exit)
8687         break;
8688     }
8689
8690   /* When testing multiple add/del ops, use a control-ping to sync */
8691   if (count > 1)
8692     {
8693       vl_api_control_ping_t *mp_ping;
8694       f64 after;
8695       f64 timeout;
8696
8697       /* Shut off async mode */
8698       vam->async_mode = 0;
8699
8700       MPING (CONTROL_PING, mp_ping);
8701       S (mp_ping);
8702
8703       timeout = vat_time_now (vam) + 1.0;
8704       while (vat_time_now (vam) < timeout)
8705         if (vam->result_ready == 1)
8706           goto out;
8707       vam->retval = -99;
8708
8709     out:
8710       if (vam->retval == -99)
8711         errmsg ("timeout");
8712
8713       if (vam->async_errors > 0)
8714         {
8715           errmsg ("%d asynchronous errors", vam->async_errors);
8716           vam->retval = -98;
8717         }
8718       vam->async_errors = 0;
8719       after = vat_time_now (vam);
8720
8721       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8722       if (j > 0)
8723         count = j;
8724
8725       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8726              count, after - before, count / (after - before));
8727     }
8728   else
8729     {
8730       int ret;
8731
8732       /* Wait for a reply... */
8733       W (ret);
8734       return ret;
8735     }
8736
8737   /* Return the good/bad news */
8738   return (vam->retval);
8739 }
8740
8741 static int
8742 api_ip_mroute_add_del (vat_main_t * vam)
8743 {
8744   unformat_input_t *i = vam->input;
8745   vl_api_ip_mroute_add_del_t *mp;
8746   u32 sw_if_index = ~0, vrf_id = 0;
8747   u8 is_ipv6 = 0;
8748   u8 is_local = 0;
8749   u8 is_add = 1;
8750   u8 address_set = 0;
8751   u32 grp_address_length = 0;
8752   ip4_address_t v4_grp_address, v4_src_address;
8753   ip6_address_t v6_grp_address, v6_src_address;
8754   mfib_itf_flags_t iflags = 0;
8755   mfib_entry_flags_t eflags = 0;
8756   int ret;
8757
8758   /* Parse args required to build the message */
8759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8760     {
8761       if (unformat (i, "sw_if_index %d", &sw_if_index))
8762         ;
8763       else if (unformat (i, "%U %U",
8764                          unformat_ip4_address, &v4_src_address,
8765                          unformat_ip4_address, &v4_grp_address))
8766         {
8767           grp_address_length = 64;
8768           address_set = 1;
8769           is_ipv6 = 0;
8770         }
8771       else if (unformat (i, "%U %U",
8772                          unformat_ip6_address, &v6_src_address,
8773                          unformat_ip6_address, &v6_grp_address))
8774         {
8775           grp_address_length = 256;
8776           address_set = 1;
8777           is_ipv6 = 1;
8778         }
8779       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8780         {
8781           memset (&v4_src_address, 0, sizeof (v4_src_address));
8782           grp_address_length = 32;
8783           address_set = 1;
8784           is_ipv6 = 0;
8785         }
8786       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8787         {
8788           memset (&v6_src_address, 0, sizeof (v6_src_address));
8789           grp_address_length = 128;
8790           address_set = 1;
8791           is_ipv6 = 1;
8792         }
8793       else if (unformat (i, "/%d", &grp_address_length))
8794         ;
8795       else if (unformat (i, "local"))
8796         {
8797           is_local = 1;
8798         }
8799       else if (unformat (i, "del"))
8800         is_add = 0;
8801       else if (unformat (i, "add"))
8802         is_add = 1;
8803       else if (unformat (i, "vrf %d", &vrf_id))
8804         ;
8805       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8806         ;
8807       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8808         ;
8809       else
8810         {
8811           clib_warning ("parse error '%U'", format_unformat_error, i);
8812           return -99;
8813         }
8814     }
8815
8816   if (address_set == 0)
8817     {
8818       errmsg ("missing addresses\n");
8819       return -99;
8820     }
8821
8822   /* Construct the API message */
8823   M (IP_MROUTE_ADD_DEL, mp);
8824
8825   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8826   mp->table_id = ntohl (vrf_id);
8827
8828   mp->is_add = is_add;
8829   mp->is_ipv6 = is_ipv6;
8830   mp->is_local = is_local;
8831   mp->itf_flags = ntohl (iflags);
8832   mp->entry_flags = ntohl (eflags);
8833   mp->grp_address_length = grp_address_length;
8834   mp->grp_address_length = ntohs (mp->grp_address_length);
8835
8836   if (is_ipv6)
8837     {
8838       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8839       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8840     }
8841   else
8842     {
8843       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8844       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8845
8846     }
8847
8848   /* send it... */
8849   S (mp);
8850   /* Wait for a reply... */
8851   W (ret);
8852   return ret;
8853 }
8854
8855 static int
8856 api_mpls_table_add_del (vat_main_t * vam)
8857 {
8858   unformat_input_t *i = vam->input;
8859   vl_api_mpls_table_add_del_t *mp;
8860   u32 table_id = ~0;
8861   u8 is_add = 1;
8862   int ret = 0;
8863
8864   /* Parse args required to build the message */
8865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8866     {
8867       if (unformat (i, "table %d", &table_id))
8868         ;
8869       else if (unformat (i, "del"))
8870         is_add = 0;
8871       else if (unformat (i, "add"))
8872         is_add = 1;
8873       else
8874         {
8875           clib_warning ("parse error '%U'", format_unformat_error, i);
8876           return -99;
8877         }
8878     }
8879
8880   if (~0 == table_id)
8881     {
8882       errmsg ("missing table-ID");
8883       return -99;
8884     }
8885
8886   /* Construct the API message */
8887   M (MPLS_TABLE_ADD_DEL, mp);
8888
8889   mp->mt_table_id = ntohl (table_id);
8890   mp->mt_is_add = is_add;
8891
8892   /* send it... */
8893   S (mp);
8894
8895   /* Wait for a reply... */
8896   W (ret);
8897
8898   return ret;
8899 }
8900
8901 static int
8902 api_mpls_route_add_del (vat_main_t * vam)
8903 {
8904   unformat_input_t *i = vam->input;
8905   vl_api_mpls_route_add_del_t *mp;
8906   u32 sw_if_index = ~0, table_id = 0;
8907   u8 is_add = 1;
8908   u32 next_hop_weight = 1;
8909   u8 is_multipath = 0;
8910   u32 next_hop_table_id = 0;
8911   u8 next_hop_set = 0;
8912   ip4_address_t v4_next_hop_address = {
8913     .as_u32 = 0,
8914   };
8915   ip6_address_t v6_next_hop_address = { {0} };
8916   int count = 1;
8917   int j;
8918   f64 before = 0;
8919   u32 classify_table_index = ~0;
8920   u8 is_classify = 0;
8921   u8 resolve_host = 0, resolve_attached = 0;
8922   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8923   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8924   mpls_label_t *next_hop_out_label_stack = NULL;
8925   mpls_label_t local_label = MPLS_LABEL_INVALID;
8926   u8 is_eos = 0;
8927   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8928
8929   /* Parse args required to build the message */
8930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8931     {
8932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8933         ;
8934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8935         ;
8936       else if (unformat (i, "%d", &local_label))
8937         ;
8938       else if (unformat (i, "eos"))
8939         is_eos = 1;
8940       else if (unformat (i, "non-eos"))
8941         is_eos = 0;
8942       else if (unformat (i, "via %U", unformat_ip4_address,
8943                          &v4_next_hop_address))
8944         {
8945           next_hop_set = 1;
8946           next_hop_proto = DPO_PROTO_IP4;
8947         }
8948       else if (unformat (i, "via %U", unformat_ip6_address,
8949                          &v6_next_hop_address))
8950         {
8951           next_hop_set = 1;
8952           next_hop_proto = DPO_PROTO_IP6;
8953         }
8954       else if (unformat (i, "weight %d", &next_hop_weight))
8955         ;
8956       else if (unformat (i, "classify %d", &classify_table_index))
8957         {
8958           is_classify = 1;
8959         }
8960       else if (unformat (i, "del"))
8961         is_add = 0;
8962       else if (unformat (i, "add"))
8963         is_add = 1;
8964       else if (unformat (i, "resolve-via-host"))
8965         resolve_host = 1;
8966       else if (unformat (i, "resolve-via-attached"))
8967         resolve_attached = 1;
8968       else if (unformat (i, "multipath"))
8969         is_multipath = 1;
8970       else if (unformat (i, "count %d", &count))
8971         ;
8972       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8973         {
8974           next_hop_set = 1;
8975           next_hop_proto = DPO_PROTO_IP4;
8976         }
8977       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8978         {
8979           next_hop_set = 1;
8980           next_hop_proto = DPO_PROTO_IP6;
8981         }
8982       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8983         ;
8984       else if (unformat (i, "via-label %d", &next_hop_via_label))
8985         ;
8986       else if (unformat (i, "out-label %d", &next_hop_out_label))
8987         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8988       else
8989         {
8990           clib_warning ("parse error '%U'", format_unformat_error, i);
8991           return -99;
8992         }
8993     }
8994
8995   if (!next_hop_set && !is_classify)
8996     {
8997       errmsg ("next hop / classify not set");
8998       return -99;
8999     }
9000
9001   if (MPLS_LABEL_INVALID == local_label)
9002     {
9003       errmsg ("missing label");
9004       return -99;
9005     }
9006
9007   if (count > 1)
9008     {
9009       /* Turn on async mode */
9010       vam->async_mode = 1;
9011       vam->async_errors = 0;
9012       before = vat_time_now (vam);
9013     }
9014
9015   for (j = 0; j < count; j++)
9016     {
9017       /* Construct the API message */
9018       M2 (MPLS_ROUTE_ADD_DEL, mp,
9019           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
9020
9021       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9022       mp->mr_table_id = ntohl (table_id);
9023
9024       mp->mr_is_add = is_add;
9025       mp->mr_next_hop_proto = next_hop_proto;
9026       mp->mr_is_classify = is_classify;
9027       mp->mr_is_multipath = is_multipath;
9028       mp->mr_is_resolve_host = resolve_host;
9029       mp->mr_is_resolve_attached = resolve_attached;
9030       mp->mr_next_hop_weight = next_hop_weight;
9031       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9032       mp->mr_classify_table_index = ntohl (classify_table_index);
9033       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9034       mp->mr_label = ntohl (local_label);
9035       mp->mr_eos = is_eos;
9036
9037       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9038       if (0 != mp->mr_next_hop_n_out_labels)
9039         {
9040           memcpy (mp->mr_next_hop_out_label_stack,
9041                   next_hop_out_label_stack,
9042                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
9043           vec_free (next_hop_out_label_stack);
9044         }
9045
9046       if (next_hop_set)
9047         {
9048           if (DPO_PROTO_IP4 == next_hop_proto)
9049             {
9050               clib_memcpy (mp->mr_next_hop,
9051                            &v4_next_hop_address,
9052                            sizeof (v4_next_hop_address));
9053             }
9054           else if (DPO_PROTO_IP6 == next_hop_proto)
9055
9056             {
9057               clib_memcpy (mp->mr_next_hop,
9058                            &v6_next_hop_address,
9059                            sizeof (v6_next_hop_address));
9060             }
9061         }
9062       local_label++;
9063
9064       /* send it... */
9065       S (mp);
9066       /* If we receive SIGTERM, stop now... */
9067       if (vam->do_exit)
9068         break;
9069     }
9070
9071   /* When testing multiple add/del ops, use a control-ping to sync */
9072   if (count > 1)
9073     {
9074       vl_api_control_ping_t *mp_ping;
9075       f64 after;
9076       f64 timeout;
9077
9078       /* Shut off async mode */
9079       vam->async_mode = 0;
9080
9081       MPING (CONTROL_PING, mp_ping);
9082       S (mp_ping);
9083
9084       timeout = vat_time_now (vam) + 1.0;
9085       while (vat_time_now (vam) < timeout)
9086         if (vam->result_ready == 1)
9087           goto out;
9088       vam->retval = -99;
9089
9090     out:
9091       if (vam->retval == -99)
9092         errmsg ("timeout");
9093
9094       if (vam->async_errors > 0)
9095         {
9096           errmsg ("%d asynchronous errors", vam->async_errors);
9097           vam->retval = -98;
9098         }
9099       vam->async_errors = 0;
9100       after = vat_time_now (vam);
9101
9102       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9103       if (j > 0)
9104         count = j;
9105
9106       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9107              count, after - before, count / (after - before));
9108     }
9109   else
9110     {
9111       int ret;
9112
9113       /* Wait for a reply... */
9114       W (ret);
9115       return ret;
9116     }
9117
9118   /* Return the good/bad news */
9119   return (vam->retval);
9120 }
9121
9122 static int
9123 api_mpls_ip_bind_unbind (vat_main_t * vam)
9124 {
9125   unformat_input_t *i = vam->input;
9126   vl_api_mpls_ip_bind_unbind_t *mp;
9127   u32 ip_table_id = 0;
9128   u8 is_bind = 1;
9129   u8 is_ip4 = 1;
9130   ip4_address_t v4_address;
9131   ip6_address_t v6_address;
9132   u32 address_length;
9133   u8 address_set = 0;
9134   mpls_label_t local_label = MPLS_LABEL_INVALID;
9135   int ret;
9136
9137   /* Parse args required to build the message */
9138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9139     {
9140       if (unformat (i, "%U/%d", unformat_ip4_address,
9141                     &v4_address, &address_length))
9142         {
9143           is_ip4 = 1;
9144           address_set = 1;
9145         }
9146       else if (unformat (i, "%U/%d", unformat_ip6_address,
9147                          &v6_address, &address_length))
9148         {
9149           is_ip4 = 0;
9150           address_set = 1;
9151         }
9152       else if (unformat (i, "%d", &local_label))
9153         ;
9154       else if (unformat (i, "table-id %d", &ip_table_id))
9155         ;
9156       else if (unformat (i, "unbind"))
9157         is_bind = 0;
9158       else if (unformat (i, "bind"))
9159         is_bind = 1;
9160       else
9161         {
9162           clib_warning ("parse error '%U'", format_unformat_error, i);
9163           return -99;
9164         }
9165     }
9166
9167   if (!address_set)
9168     {
9169       errmsg ("IP addres not set");
9170       return -99;
9171     }
9172
9173   if (MPLS_LABEL_INVALID == local_label)
9174     {
9175       errmsg ("missing label");
9176       return -99;
9177     }
9178
9179   /* Construct the API message */
9180   M (MPLS_IP_BIND_UNBIND, mp);
9181
9182   mp->mb_is_bind = is_bind;
9183   mp->mb_is_ip4 = is_ip4;
9184   mp->mb_ip_table_id = ntohl (ip_table_id);
9185   mp->mb_mpls_table_id = 0;
9186   mp->mb_label = ntohl (local_label);
9187   mp->mb_address_length = address_length;
9188
9189   if (is_ip4)
9190     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9191   else
9192     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9193
9194   /* send it... */
9195   S (mp);
9196
9197   /* Wait for a reply... */
9198   W (ret);
9199   return ret;
9200 }
9201
9202 static int
9203 api_bier_table_add_del (vat_main_t * vam)
9204 {
9205   unformat_input_t *i = vam->input;
9206   vl_api_bier_table_add_del_t *mp;
9207   u8 is_add = 1;
9208   u32 set = 0, sub_domain = 0, hdr_len = 3;
9209   mpls_label_t local_label = MPLS_LABEL_INVALID;
9210   int ret;
9211
9212   /* Parse args required to build the message */
9213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9214     {
9215       if (unformat (i, "sub-domain %d", &sub_domain))
9216         ;
9217       else if (unformat (i, "set %d", &set))
9218         ;
9219       else if (unformat (i, "label %d", &local_label))
9220         ;
9221       else if (unformat (i, "hdr-len %d", &hdr_len))
9222         ;
9223       else if (unformat (i, "add"))
9224         is_add = 1;
9225       else if (unformat (i, "del"))
9226         is_add = 0;
9227       else
9228         {
9229           clib_warning ("parse error '%U'", format_unformat_error, i);
9230           return -99;
9231         }
9232     }
9233
9234   if (MPLS_LABEL_INVALID == local_label)
9235     {
9236       errmsg ("missing label\n");
9237       return -99;
9238     }
9239
9240   /* Construct the API message */
9241   M (BIER_TABLE_ADD_DEL, mp);
9242
9243   mp->bt_is_add = is_add;
9244   mp->bt_label = ntohl (local_label);
9245   mp->bt_tbl_id.bt_set = set;
9246   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9247   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9248
9249   /* send it... */
9250   S (mp);
9251
9252   /* Wait for a reply... */
9253   W (ret);
9254
9255   return (ret);
9256 }
9257
9258 static int
9259 api_bier_route_add_del (vat_main_t * vam)
9260 {
9261   unformat_input_t *i = vam->input;
9262   vl_api_bier_route_add_del_t *mp;
9263   u8 is_add = 1;
9264   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9265   ip4_address_t v4_next_hop_address;
9266   ip6_address_t v6_next_hop_address;
9267   u8 next_hop_set = 0;
9268   u8 next_hop_proto_is_ip4 = 1;
9269   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9270   int ret;
9271
9272   /* Parse args required to build the message */
9273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9274     {
9275       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9276         {
9277           next_hop_proto_is_ip4 = 1;
9278           next_hop_set = 1;
9279         }
9280       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9281         {
9282           next_hop_proto_is_ip4 = 0;
9283           next_hop_set = 1;
9284         }
9285       if (unformat (i, "sub-domain %d", &sub_domain))
9286         ;
9287       else if (unformat (i, "set %d", &set))
9288         ;
9289       else if (unformat (i, "hdr-len %d", &hdr_len))
9290         ;
9291       else if (unformat (i, "bp %d", &bp))
9292         ;
9293       else if (unformat (i, "add"))
9294         is_add = 1;
9295       else if (unformat (i, "del"))
9296         is_add = 0;
9297       else if (unformat (i, "out-label %d", &next_hop_out_label))
9298         ;
9299       else
9300         {
9301           clib_warning ("parse error '%U'", format_unformat_error, i);
9302           return -99;
9303         }
9304     }
9305
9306   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9307     {
9308       errmsg ("next hop / label set\n");
9309       return -99;
9310     }
9311   if (0 == bp)
9312     {
9313       errmsg ("bit=position not set\n");
9314       return -99;
9315     }
9316
9317   /* Construct the API message */
9318   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9319
9320   mp->br_is_add = is_add;
9321   mp->br_tbl_id.bt_set = set;
9322   mp->br_tbl_id.bt_sub_domain = sub_domain;
9323   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9324   mp->br_bp = ntohs (bp);
9325   mp->br_n_paths = 1;
9326   mp->br_paths[0].n_labels = 1;
9327   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9328   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9329
9330   if (next_hop_proto_is_ip4)
9331     {
9332       clib_memcpy (mp->br_paths[0].next_hop,
9333                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9334     }
9335   else
9336     {
9337       clib_memcpy (mp->br_paths[0].next_hop,
9338                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9339     }
9340
9341   /* send it... */
9342   S (mp);
9343
9344   /* Wait for a reply... */
9345   W (ret);
9346
9347   return (ret);
9348 }
9349
9350 static int
9351 api_proxy_arp_add_del (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_proxy_arp_add_del_t *mp;
9355   u32 vrf_id = 0;
9356   u8 is_add = 1;
9357   ip4_address_t lo, hi;
9358   u8 range_set = 0;
9359   int ret;
9360
9361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9362     {
9363       if (unformat (i, "vrf %d", &vrf_id))
9364         ;
9365       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9366                          unformat_ip4_address, &hi))
9367         range_set = 1;
9368       else if (unformat (i, "del"))
9369         is_add = 0;
9370       else
9371         {
9372           clib_warning ("parse error '%U'", format_unformat_error, i);
9373           return -99;
9374         }
9375     }
9376
9377   if (range_set == 0)
9378     {
9379       errmsg ("address range not set");
9380       return -99;
9381     }
9382
9383   M (PROXY_ARP_ADD_DEL, mp);
9384
9385   mp->proxy.vrf_id = ntohl (vrf_id);
9386   mp->is_add = is_add;
9387   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9388   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9389
9390   S (mp);
9391   W (ret);
9392   return ret;
9393 }
9394
9395 static int
9396 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9397 {
9398   unformat_input_t *i = vam->input;
9399   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9400   u32 sw_if_index;
9401   u8 enable = 1;
9402   u8 sw_if_index_set = 0;
9403   int ret;
9404
9405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9406     {
9407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9408         sw_if_index_set = 1;
9409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9410         sw_if_index_set = 1;
9411       else if (unformat (i, "enable"))
9412         enable = 1;
9413       else if (unformat (i, "disable"))
9414         enable = 0;
9415       else
9416         {
9417           clib_warning ("parse error '%U'", format_unformat_error, i);
9418           return -99;
9419         }
9420     }
9421
9422   if (sw_if_index_set == 0)
9423     {
9424       errmsg ("missing interface name or sw_if_index");
9425       return -99;
9426     }
9427
9428   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9429
9430   mp->sw_if_index = ntohl (sw_if_index);
9431   mp->enable_disable = enable;
9432
9433   S (mp);
9434   W (ret);
9435   return ret;
9436 }
9437
9438 static int
9439 api_mpls_tunnel_add_del (vat_main_t * vam)
9440 {
9441   unformat_input_t *i = vam->input;
9442   vl_api_mpls_tunnel_add_del_t *mp;
9443
9444   u8 is_add = 1;
9445   u8 l2_only = 0;
9446   u32 sw_if_index = ~0;
9447   u32 next_hop_sw_if_index = ~0;
9448   u32 next_hop_proto_is_ip4 = 1;
9449
9450   u32 next_hop_table_id = 0;
9451   ip4_address_t v4_next_hop_address = {
9452     .as_u32 = 0,
9453   };
9454   ip6_address_t v6_next_hop_address = { {0} };
9455   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9456   int ret;
9457
9458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9459     {
9460       if (unformat (i, "add"))
9461         is_add = 1;
9462       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9463         is_add = 0;
9464       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9465         ;
9466       else if (unformat (i, "via %U",
9467                          unformat_ip4_address, &v4_next_hop_address))
9468         {
9469           next_hop_proto_is_ip4 = 1;
9470         }
9471       else if (unformat (i, "via %U",
9472                          unformat_ip6_address, &v6_next_hop_address))
9473         {
9474           next_hop_proto_is_ip4 = 0;
9475         }
9476       else if (unformat (i, "l2-only"))
9477         l2_only = 1;
9478       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9479         ;
9480       else if (unformat (i, "out-label %d", &next_hop_out_label))
9481         vec_add1 (labels, ntohl (next_hop_out_label));
9482       else
9483         {
9484           clib_warning ("parse error '%U'", format_unformat_error, i);
9485           return -99;
9486         }
9487     }
9488
9489   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9490
9491   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9492   mp->mt_sw_if_index = ntohl (sw_if_index);
9493   mp->mt_is_add = is_add;
9494   mp->mt_l2_only = l2_only;
9495   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9496   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9497
9498   mp->mt_next_hop_n_out_labels = vec_len (labels);
9499
9500   if (0 != mp->mt_next_hop_n_out_labels)
9501     {
9502       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9503                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9504       vec_free (labels);
9505     }
9506
9507   if (next_hop_proto_is_ip4)
9508     {
9509       clib_memcpy (mp->mt_next_hop,
9510                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9511     }
9512   else
9513     {
9514       clib_memcpy (mp->mt_next_hop,
9515                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9516     }
9517
9518   S (mp);
9519   W (ret);
9520   return ret;
9521 }
9522
9523 static int
9524 api_sw_interface_set_unnumbered (vat_main_t * vam)
9525 {
9526   unformat_input_t *i = vam->input;
9527   vl_api_sw_interface_set_unnumbered_t *mp;
9528   u32 sw_if_index;
9529   u32 unnum_sw_index = ~0;
9530   u8 is_add = 1;
9531   u8 sw_if_index_set = 0;
9532   int ret;
9533
9534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9535     {
9536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9537         sw_if_index_set = 1;
9538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9539         sw_if_index_set = 1;
9540       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9541         ;
9542       else if (unformat (i, "del"))
9543         is_add = 0;
9544       else
9545         {
9546           clib_warning ("parse error '%U'", format_unformat_error, i);
9547           return -99;
9548         }
9549     }
9550
9551   if (sw_if_index_set == 0)
9552     {
9553       errmsg ("missing interface name or sw_if_index");
9554       return -99;
9555     }
9556
9557   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9558
9559   mp->sw_if_index = ntohl (sw_if_index);
9560   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9561   mp->is_add = is_add;
9562
9563   S (mp);
9564   W (ret);
9565   return ret;
9566 }
9567
9568 static int
9569 api_ip_neighbor_add_del (vat_main_t * vam)
9570 {
9571   unformat_input_t *i = vam->input;
9572   vl_api_ip_neighbor_add_del_t *mp;
9573   u32 sw_if_index;
9574   u8 sw_if_index_set = 0;
9575   u8 is_add = 1;
9576   u8 is_static = 0;
9577   u8 is_no_fib_entry = 0;
9578   u8 mac_address[6];
9579   u8 mac_set = 0;
9580   u8 v4_address_set = 0;
9581   u8 v6_address_set = 0;
9582   ip4_address_t v4address;
9583   ip6_address_t v6address;
9584   int ret;
9585
9586   memset (mac_address, 0, sizeof (mac_address));
9587
9588   /* Parse args required to build the message */
9589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9590     {
9591       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9592         {
9593           mac_set = 1;
9594         }
9595       else if (unformat (i, "del"))
9596         is_add = 0;
9597       else
9598         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9599         sw_if_index_set = 1;
9600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9601         sw_if_index_set = 1;
9602       else if (unformat (i, "is_static"))
9603         is_static = 1;
9604       else if (unformat (i, "no-fib-entry"))
9605         is_no_fib_entry = 1;
9606       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9607         v4_address_set = 1;
9608       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9609         v6_address_set = 1;
9610       else
9611         {
9612           clib_warning ("parse error '%U'", format_unformat_error, i);
9613           return -99;
9614         }
9615     }
9616
9617   if (sw_if_index_set == 0)
9618     {
9619       errmsg ("missing interface name or sw_if_index");
9620       return -99;
9621     }
9622   if (v4_address_set && v6_address_set)
9623     {
9624       errmsg ("both v4 and v6 addresses set");
9625       return -99;
9626     }
9627   if (!v4_address_set && !v6_address_set)
9628     {
9629       errmsg ("no address set");
9630       return -99;
9631     }
9632
9633   /* Construct the API message */
9634   M (IP_NEIGHBOR_ADD_DEL, mp);
9635
9636   mp->sw_if_index = ntohl (sw_if_index);
9637   mp->is_add = is_add;
9638   mp->is_static = is_static;
9639   mp->is_no_adj_fib = is_no_fib_entry;
9640   if (mac_set)
9641     clib_memcpy (mp->mac_address, mac_address, 6);
9642   if (v6_address_set)
9643     {
9644       mp->is_ipv6 = 1;
9645       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9646     }
9647   else
9648     {
9649       /* mp->is_ipv6 = 0; via memset in M macro above */
9650       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9651     }
9652
9653   /* send it... */
9654   S (mp);
9655
9656   /* Wait for a reply, return good/bad news  */
9657   W (ret);
9658   return ret;
9659 }
9660
9661 static int
9662 api_create_vlan_subif (vat_main_t * vam)
9663 {
9664   unformat_input_t *i = vam->input;
9665   vl_api_create_vlan_subif_t *mp;
9666   u32 sw_if_index;
9667   u8 sw_if_index_set = 0;
9668   u32 vlan_id;
9669   u8 vlan_id_set = 0;
9670   int ret;
9671
9672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9673     {
9674       if (unformat (i, "sw_if_index %d", &sw_if_index))
9675         sw_if_index_set = 1;
9676       else
9677         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9678         sw_if_index_set = 1;
9679       else if (unformat (i, "vlan %d", &vlan_id))
9680         vlan_id_set = 1;
9681       else
9682         {
9683           clib_warning ("parse error '%U'", format_unformat_error, i);
9684           return -99;
9685         }
9686     }
9687
9688   if (sw_if_index_set == 0)
9689     {
9690       errmsg ("missing interface name or sw_if_index");
9691       return -99;
9692     }
9693
9694   if (vlan_id_set == 0)
9695     {
9696       errmsg ("missing vlan_id");
9697       return -99;
9698     }
9699   M (CREATE_VLAN_SUBIF, mp);
9700
9701   mp->sw_if_index = ntohl (sw_if_index);
9702   mp->vlan_id = ntohl (vlan_id);
9703
9704   S (mp);
9705   W (ret);
9706   return ret;
9707 }
9708
9709 #define foreach_create_subif_bit                \
9710 _(no_tags)                                      \
9711 _(one_tag)                                      \
9712 _(two_tags)                                     \
9713 _(dot1ad)                                       \
9714 _(exact_match)                                  \
9715 _(default_sub)                                  \
9716 _(outer_vlan_id_any)                            \
9717 _(inner_vlan_id_any)
9718
9719 static int
9720 api_create_subif (vat_main_t * vam)
9721 {
9722   unformat_input_t *i = vam->input;
9723   vl_api_create_subif_t *mp;
9724   u32 sw_if_index;
9725   u8 sw_if_index_set = 0;
9726   u32 sub_id;
9727   u8 sub_id_set = 0;
9728   u32 no_tags = 0;
9729   u32 one_tag = 0;
9730   u32 two_tags = 0;
9731   u32 dot1ad = 0;
9732   u32 exact_match = 0;
9733   u32 default_sub = 0;
9734   u32 outer_vlan_id_any = 0;
9735   u32 inner_vlan_id_any = 0;
9736   u32 tmp;
9737   u16 outer_vlan_id = 0;
9738   u16 inner_vlan_id = 0;
9739   int ret;
9740
9741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9742     {
9743       if (unformat (i, "sw_if_index %d", &sw_if_index))
9744         sw_if_index_set = 1;
9745       else
9746         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9747         sw_if_index_set = 1;
9748       else if (unformat (i, "sub_id %d", &sub_id))
9749         sub_id_set = 1;
9750       else if (unformat (i, "outer_vlan_id %d", &tmp))
9751         outer_vlan_id = tmp;
9752       else if (unformat (i, "inner_vlan_id %d", &tmp))
9753         inner_vlan_id = tmp;
9754
9755 #define _(a) else if (unformat (i, #a)) a = 1 ;
9756       foreach_create_subif_bit
9757 #undef _
9758         else
9759         {
9760           clib_warning ("parse error '%U'", format_unformat_error, i);
9761           return -99;
9762         }
9763     }
9764
9765   if (sw_if_index_set == 0)
9766     {
9767       errmsg ("missing interface name or sw_if_index");
9768       return -99;
9769     }
9770
9771   if (sub_id_set == 0)
9772     {
9773       errmsg ("missing sub_id");
9774       return -99;
9775     }
9776   M (CREATE_SUBIF, mp);
9777
9778   mp->sw_if_index = ntohl (sw_if_index);
9779   mp->sub_id = ntohl (sub_id);
9780
9781 #define _(a) mp->a = a;
9782   foreach_create_subif_bit;
9783 #undef _
9784
9785   mp->outer_vlan_id = ntohs (outer_vlan_id);
9786   mp->inner_vlan_id = ntohs (inner_vlan_id);
9787
9788   S (mp);
9789   W (ret);
9790   return ret;
9791 }
9792
9793 static int
9794 api_oam_add_del (vat_main_t * vam)
9795 {
9796   unformat_input_t *i = vam->input;
9797   vl_api_oam_add_del_t *mp;
9798   u32 vrf_id = 0;
9799   u8 is_add = 1;
9800   ip4_address_t src, dst;
9801   u8 src_set = 0;
9802   u8 dst_set = 0;
9803   int ret;
9804
9805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9806     {
9807       if (unformat (i, "vrf %d", &vrf_id))
9808         ;
9809       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9810         src_set = 1;
9811       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9812         dst_set = 1;
9813       else if (unformat (i, "del"))
9814         is_add = 0;
9815       else
9816         {
9817           clib_warning ("parse error '%U'", format_unformat_error, i);
9818           return -99;
9819         }
9820     }
9821
9822   if (src_set == 0)
9823     {
9824       errmsg ("missing src addr");
9825       return -99;
9826     }
9827
9828   if (dst_set == 0)
9829     {
9830       errmsg ("missing dst addr");
9831       return -99;
9832     }
9833
9834   M (OAM_ADD_DEL, mp);
9835
9836   mp->vrf_id = ntohl (vrf_id);
9837   mp->is_add = is_add;
9838   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9839   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9840
9841   S (mp);
9842   W (ret);
9843   return ret;
9844 }
9845
9846 static int
9847 api_reset_fib (vat_main_t * vam)
9848 {
9849   unformat_input_t *i = vam->input;
9850   vl_api_reset_fib_t *mp;
9851   u32 vrf_id = 0;
9852   u8 is_ipv6 = 0;
9853   u8 vrf_id_set = 0;
9854
9855   int ret;
9856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9857     {
9858       if (unformat (i, "vrf %d", &vrf_id))
9859         vrf_id_set = 1;
9860       else if (unformat (i, "ipv6"))
9861         is_ipv6 = 1;
9862       else
9863         {
9864           clib_warning ("parse error '%U'", format_unformat_error, i);
9865           return -99;
9866         }
9867     }
9868
9869   if (vrf_id_set == 0)
9870     {
9871       errmsg ("missing vrf id");
9872       return -99;
9873     }
9874
9875   M (RESET_FIB, mp);
9876
9877   mp->vrf_id = ntohl (vrf_id);
9878   mp->is_ipv6 = is_ipv6;
9879
9880   S (mp);
9881   W (ret);
9882   return ret;
9883 }
9884
9885 static int
9886 api_dhcp_proxy_config (vat_main_t * vam)
9887 {
9888   unformat_input_t *i = vam->input;
9889   vl_api_dhcp_proxy_config_t *mp;
9890   u32 rx_vrf_id = 0;
9891   u32 server_vrf_id = 0;
9892   u8 is_add = 1;
9893   u8 v4_address_set = 0;
9894   u8 v6_address_set = 0;
9895   ip4_address_t v4address;
9896   ip6_address_t v6address;
9897   u8 v4_src_address_set = 0;
9898   u8 v6_src_address_set = 0;
9899   ip4_address_t v4srcaddress;
9900   ip6_address_t v6srcaddress;
9901   int ret;
9902
9903   /* Parse args required to build the message */
9904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9905     {
9906       if (unformat (i, "del"))
9907         is_add = 0;
9908       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9909         ;
9910       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9911         ;
9912       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9913         v4_address_set = 1;
9914       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9915         v6_address_set = 1;
9916       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9917         v4_src_address_set = 1;
9918       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9919         v6_src_address_set = 1;
9920       else
9921         break;
9922     }
9923
9924   if (v4_address_set && v6_address_set)
9925     {
9926       errmsg ("both v4 and v6 server addresses set");
9927       return -99;
9928     }
9929   if (!v4_address_set && !v6_address_set)
9930     {
9931       errmsg ("no server addresses set");
9932       return -99;
9933     }
9934
9935   if (v4_src_address_set && v6_src_address_set)
9936     {
9937       errmsg ("both v4 and v6  src addresses set");
9938       return -99;
9939     }
9940   if (!v4_src_address_set && !v6_src_address_set)
9941     {
9942       errmsg ("no src addresses set");
9943       return -99;
9944     }
9945
9946   if (!(v4_src_address_set && v4_address_set) &&
9947       !(v6_src_address_set && v6_address_set))
9948     {
9949       errmsg ("no matching server and src addresses set");
9950       return -99;
9951     }
9952
9953   /* Construct the API message */
9954   M (DHCP_PROXY_CONFIG, mp);
9955
9956   mp->is_add = is_add;
9957   mp->rx_vrf_id = ntohl (rx_vrf_id);
9958   mp->server_vrf_id = ntohl (server_vrf_id);
9959   if (v6_address_set)
9960     {
9961       mp->is_ipv6 = 1;
9962       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9963       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9964     }
9965   else
9966     {
9967       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9968       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9969     }
9970
9971   /* send it... */
9972   S (mp);
9973
9974   /* Wait for a reply, return good/bad news  */
9975   W (ret);
9976   return ret;
9977 }
9978
9979 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9980 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9981
9982 static void
9983 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9984 {
9985   vat_main_t *vam = &vat_main;
9986   u32 i, count = mp->count;
9987   vl_api_dhcp_server_t *s;
9988
9989   if (mp->is_ipv6)
9990     print (vam->ofp,
9991            "RX Table-ID %d, Source Address %U, VSS Type %d, "
9992            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
9993            ntohl (mp->rx_vrf_id),
9994            format_ip6_address, mp->dhcp_src_address,
9995            mp->vss_type, mp->vss_vpn_ascii_id,
9996            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9997   else
9998     print (vam->ofp,
9999            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10000            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10001            ntohl (mp->rx_vrf_id),
10002            format_ip4_address, mp->dhcp_src_address,
10003            mp->vss_type, mp->vss_vpn_ascii_id,
10004            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10005
10006   for (i = 0; i < count; i++)
10007     {
10008       s = &mp->servers[i];
10009
10010       if (mp->is_ipv6)
10011         print (vam->ofp,
10012                " Server Table-ID %d, Server Address %U",
10013                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10014       else
10015         print (vam->ofp,
10016                " Server Table-ID %d, Server Address %U",
10017                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10018     }
10019 }
10020
10021 static void vl_api_dhcp_proxy_details_t_handler_json
10022   (vl_api_dhcp_proxy_details_t * mp)
10023 {
10024   vat_main_t *vam = &vat_main;
10025   vat_json_node_t *node = NULL;
10026   u32 i, count = mp->count;
10027   struct in_addr ip4;
10028   struct in6_addr ip6;
10029   vl_api_dhcp_server_t *s;
10030
10031   if (VAT_JSON_ARRAY != vam->json_tree.type)
10032     {
10033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10034       vat_json_init_array (&vam->json_tree);
10035     }
10036   node = vat_json_array_add (&vam->json_tree);
10037
10038   vat_json_init_object (node);
10039   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10040   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10041                              sizeof (mp->vss_type));
10042   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10043                                    mp->vss_vpn_ascii_id);
10044   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10045   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10046
10047   if (mp->is_ipv6)
10048     {
10049       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10050       vat_json_object_add_ip6 (node, "src_address", ip6);
10051     }
10052   else
10053     {
10054       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10055       vat_json_object_add_ip4 (node, "src_address", ip4);
10056     }
10057
10058   for (i = 0; i < count; i++)
10059     {
10060       s = &mp->servers[i];
10061
10062       vat_json_object_add_uint (node, "server-table-id",
10063                                 ntohl (s->server_vrf_id));
10064
10065       if (mp->is_ipv6)
10066         {
10067           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10068           vat_json_object_add_ip4 (node, "src_address", ip4);
10069         }
10070       else
10071         {
10072           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10073           vat_json_object_add_ip6 (node, "server_address", ip6);
10074         }
10075     }
10076 }
10077
10078 static int
10079 api_dhcp_proxy_dump (vat_main_t * vam)
10080 {
10081   unformat_input_t *i = vam->input;
10082   vl_api_control_ping_t *mp_ping;
10083   vl_api_dhcp_proxy_dump_t *mp;
10084   u8 is_ipv6 = 0;
10085   int ret;
10086
10087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10088     {
10089       if (unformat (i, "ipv6"))
10090         is_ipv6 = 1;
10091       else
10092         {
10093           clib_warning ("parse error '%U'", format_unformat_error, i);
10094           return -99;
10095         }
10096     }
10097
10098   M (DHCP_PROXY_DUMP, mp);
10099
10100   mp->is_ip6 = is_ipv6;
10101   S (mp);
10102
10103   /* Use a control ping for synchronization */
10104   MPING (CONTROL_PING, mp_ping);
10105   S (mp_ping);
10106
10107   W (ret);
10108   return ret;
10109 }
10110
10111 static int
10112 api_dhcp_proxy_set_vss (vat_main_t * vam)
10113 {
10114   unformat_input_t *i = vam->input;
10115   vl_api_dhcp_proxy_set_vss_t *mp;
10116   u8 is_ipv6 = 0;
10117   u8 is_add = 1;
10118   u32 tbl_id = ~0;
10119   u8 vss_type = VSS_TYPE_DEFAULT;
10120   u8 *vpn_ascii_id = 0;
10121   u32 oui = 0;
10122   u32 fib_id = 0;
10123   int ret;
10124
10125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10126     {
10127       if (unformat (i, "tbl_id %d", &tbl_id))
10128         ;
10129       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10130         vss_type = VSS_TYPE_ASCII;
10131       else if (unformat (i, "fib_id %d", &fib_id))
10132         vss_type = VSS_TYPE_VPN_ID;
10133       else if (unformat (i, "oui %d", &oui))
10134         vss_type = VSS_TYPE_VPN_ID;
10135       else if (unformat (i, "ipv6"))
10136         is_ipv6 = 1;
10137       else if (unformat (i, "del"))
10138         is_add = 0;
10139       else
10140         break;
10141     }
10142
10143   if (tbl_id == ~0)
10144     {
10145       errmsg ("missing tbl_id ");
10146       vec_free (vpn_ascii_id);
10147       return -99;
10148     }
10149
10150   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10151     {
10152       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10153       vec_free (vpn_ascii_id);
10154       return -99;
10155     }
10156
10157   M (DHCP_PROXY_SET_VSS, mp);
10158   mp->tbl_id = ntohl (tbl_id);
10159   mp->vss_type = vss_type;
10160   if (vpn_ascii_id)
10161     {
10162       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10163       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10164     }
10165   mp->vpn_index = ntohl (fib_id);
10166   mp->oui = ntohl (oui);
10167   mp->is_ipv6 = is_ipv6;
10168   mp->is_add = is_add;
10169
10170   S (mp);
10171   W (ret);
10172
10173   vec_free (vpn_ascii_id);
10174   return ret;
10175 }
10176
10177 static int
10178 api_dhcp_client_config (vat_main_t * vam)
10179 {
10180   unformat_input_t *i = vam->input;
10181   vl_api_dhcp_client_config_t *mp;
10182   u32 sw_if_index;
10183   u8 sw_if_index_set = 0;
10184   u8 is_add = 1;
10185   u8 *hostname = 0;
10186   u8 disable_event = 0;
10187   int ret;
10188
10189   /* Parse args required to build the message */
10190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10191     {
10192       if (unformat (i, "del"))
10193         is_add = 0;
10194       else
10195         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10196         sw_if_index_set = 1;
10197       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10198         sw_if_index_set = 1;
10199       else if (unformat (i, "hostname %s", &hostname))
10200         ;
10201       else if (unformat (i, "disable_event"))
10202         disable_event = 1;
10203       else
10204         break;
10205     }
10206
10207   if (sw_if_index_set == 0)
10208     {
10209       errmsg ("missing interface name or sw_if_index");
10210       return -99;
10211     }
10212
10213   if (vec_len (hostname) > 63)
10214     {
10215       errmsg ("hostname too long");
10216     }
10217   vec_add1 (hostname, 0);
10218
10219   /* Construct the API message */
10220   M (DHCP_CLIENT_CONFIG, mp);
10221
10222   mp->is_add = is_add;
10223   mp->client.sw_if_index = htonl (sw_if_index);
10224   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10225   vec_free (hostname);
10226   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10227   mp->client.pid = htonl (getpid ());
10228
10229   /* send it... */
10230   S (mp);
10231
10232   /* Wait for a reply, return good/bad news  */
10233   W (ret);
10234   return ret;
10235 }
10236
10237 static int
10238 api_set_ip_flow_hash (vat_main_t * vam)
10239 {
10240   unformat_input_t *i = vam->input;
10241   vl_api_set_ip_flow_hash_t *mp;
10242   u32 vrf_id = 0;
10243   u8 is_ipv6 = 0;
10244   u8 vrf_id_set = 0;
10245   u8 src = 0;
10246   u8 dst = 0;
10247   u8 sport = 0;
10248   u8 dport = 0;
10249   u8 proto = 0;
10250   u8 reverse = 0;
10251   int ret;
10252
10253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10254     {
10255       if (unformat (i, "vrf %d", &vrf_id))
10256         vrf_id_set = 1;
10257       else if (unformat (i, "ipv6"))
10258         is_ipv6 = 1;
10259       else if (unformat (i, "src"))
10260         src = 1;
10261       else if (unformat (i, "dst"))
10262         dst = 1;
10263       else if (unformat (i, "sport"))
10264         sport = 1;
10265       else if (unformat (i, "dport"))
10266         dport = 1;
10267       else if (unformat (i, "proto"))
10268         proto = 1;
10269       else if (unformat (i, "reverse"))
10270         reverse = 1;
10271
10272       else
10273         {
10274           clib_warning ("parse error '%U'", format_unformat_error, i);
10275           return -99;
10276         }
10277     }
10278
10279   if (vrf_id_set == 0)
10280     {
10281       errmsg ("missing vrf id");
10282       return -99;
10283     }
10284
10285   M (SET_IP_FLOW_HASH, mp);
10286   mp->src = src;
10287   mp->dst = dst;
10288   mp->sport = sport;
10289   mp->dport = dport;
10290   mp->proto = proto;
10291   mp->reverse = reverse;
10292   mp->vrf_id = ntohl (vrf_id);
10293   mp->is_ipv6 = is_ipv6;
10294
10295   S (mp);
10296   W (ret);
10297   return ret;
10298 }
10299
10300 static int
10301 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10302 {
10303   unformat_input_t *i = vam->input;
10304   vl_api_sw_interface_ip6_enable_disable_t *mp;
10305   u32 sw_if_index;
10306   u8 sw_if_index_set = 0;
10307   u8 enable = 0;
10308   int ret;
10309
10310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10313         sw_if_index_set = 1;
10314       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10315         sw_if_index_set = 1;
10316       else if (unformat (i, "enable"))
10317         enable = 1;
10318       else if (unformat (i, "disable"))
10319         enable = 0;
10320       else
10321         {
10322           clib_warning ("parse error '%U'", format_unformat_error, i);
10323           return -99;
10324         }
10325     }
10326
10327   if (sw_if_index_set == 0)
10328     {
10329       errmsg ("missing interface name or sw_if_index");
10330       return -99;
10331     }
10332
10333   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10334
10335   mp->sw_if_index = ntohl (sw_if_index);
10336   mp->enable = enable;
10337
10338   S (mp);
10339   W (ret);
10340   return ret;
10341 }
10342
10343 static int
10344 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10345 {
10346   unformat_input_t *i = vam->input;
10347   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10348   u32 sw_if_index;
10349   u8 sw_if_index_set = 0;
10350   u8 v6_address_set = 0;
10351   ip6_address_t v6address;
10352   int ret;
10353
10354   /* Parse args required to build the message */
10355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10356     {
10357       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10358         sw_if_index_set = 1;
10359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10360         sw_if_index_set = 1;
10361       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10362         v6_address_set = 1;
10363       else
10364         break;
10365     }
10366
10367   if (sw_if_index_set == 0)
10368     {
10369       errmsg ("missing interface name or sw_if_index");
10370       return -99;
10371     }
10372   if (!v6_address_set)
10373     {
10374       errmsg ("no address set");
10375       return -99;
10376     }
10377
10378   /* Construct the API message */
10379   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10380
10381   mp->sw_if_index = ntohl (sw_if_index);
10382   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10383
10384   /* send it... */
10385   S (mp);
10386
10387   /* Wait for a reply, return good/bad news  */
10388   W (ret);
10389   return ret;
10390 }
10391
10392 static int
10393 api_ip6nd_proxy_add_del (vat_main_t * vam)
10394 {
10395   unformat_input_t *i = vam->input;
10396   vl_api_ip6nd_proxy_add_del_t *mp;
10397   u32 sw_if_index = ~0;
10398   u8 v6_address_set = 0;
10399   ip6_address_t v6address;
10400   u8 is_del = 0;
10401   int ret;
10402
10403   /* Parse args required to build the message */
10404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10407         ;
10408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10409         ;
10410       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10411         v6_address_set = 1;
10412       if (unformat (i, "del"))
10413         is_del = 1;
10414       else
10415         {
10416           clib_warning ("parse error '%U'", format_unformat_error, i);
10417           return -99;
10418         }
10419     }
10420
10421   if (sw_if_index == ~0)
10422     {
10423       errmsg ("missing interface name or sw_if_index");
10424       return -99;
10425     }
10426   if (!v6_address_set)
10427     {
10428       errmsg ("no address set");
10429       return -99;
10430     }
10431
10432   /* Construct the API message */
10433   M (IP6ND_PROXY_ADD_DEL, mp);
10434
10435   mp->is_del = is_del;
10436   mp->sw_if_index = ntohl (sw_if_index);
10437   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10438
10439   /* send it... */
10440   S (mp);
10441
10442   /* Wait for a reply, return good/bad news  */
10443   W (ret);
10444   return ret;
10445 }
10446
10447 static int
10448 api_ip6nd_proxy_dump (vat_main_t * vam)
10449 {
10450   vl_api_ip6nd_proxy_dump_t *mp;
10451   vl_api_control_ping_t *mp_ping;
10452   int ret;
10453
10454   M (IP6ND_PROXY_DUMP, mp);
10455
10456   S (mp);
10457
10458   /* Use a control ping for synchronization */
10459   MPING (CONTROL_PING, mp_ping);
10460   S (mp_ping);
10461
10462   W (ret);
10463   return ret;
10464 }
10465
10466 static void vl_api_ip6nd_proxy_details_t_handler
10467   (vl_api_ip6nd_proxy_details_t * mp)
10468 {
10469   vat_main_t *vam = &vat_main;
10470
10471   print (vam->ofp, "host %U sw_if_index %d",
10472          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10473 }
10474
10475 static void vl_api_ip6nd_proxy_details_t_handler_json
10476   (vl_api_ip6nd_proxy_details_t * mp)
10477 {
10478   vat_main_t *vam = &vat_main;
10479   struct in6_addr ip6;
10480   vat_json_node_t *node = NULL;
10481
10482   if (VAT_JSON_ARRAY != vam->json_tree.type)
10483     {
10484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10485       vat_json_init_array (&vam->json_tree);
10486     }
10487   node = vat_json_array_add (&vam->json_tree);
10488
10489   vat_json_init_object (node);
10490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10491
10492   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10493   vat_json_object_add_ip6 (node, "host", ip6);
10494 }
10495
10496 static int
10497 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10498 {
10499   unformat_input_t *i = vam->input;
10500   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10501   u32 sw_if_index;
10502   u8 sw_if_index_set = 0;
10503   u32 address_length = 0;
10504   u8 v6_address_set = 0;
10505   ip6_address_t v6address;
10506   u8 use_default = 0;
10507   u8 no_advertise = 0;
10508   u8 off_link = 0;
10509   u8 no_autoconfig = 0;
10510   u8 no_onlink = 0;
10511   u8 is_no = 0;
10512   u32 val_lifetime = 0;
10513   u32 pref_lifetime = 0;
10514   int ret;
10515
10516   /* Parse args required to build the message */
10517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10518     {
10519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10520         sw_if_index_set = 1;
10521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10522         sw_if_index_set = 1;
10523       else if (unformat (i, "%U/%d",
10524                          unformat_ip6_address, &v6address, &address_length))
10525         v6_address_set = 1;
10526       else if (unformat (i, "val_life %d", &val_lifetime))
10527         ;
10528       else if (unformat (i, "pref_life %d", &pref_lifetime))
10529         ;
10530       else if (unformat (i, "def"))
10531         use_default = 1;
10532       else if (unformat (i, "noadv"))
10533         no_advertise = 1;
10534       else if (unformat (i, "offl"))
10535         off_link = 1;
10536       else if (unformat (i, "noauto"))
10537         no_autoconfig = 1;
10538       else if (unformat (i, "nolink"))
10539         no_onlink = 1;
10540       else if (unformat (i, "isno"))
10541         is_no = 1;
10542       else
10543         {
10544           clib_warning ("parse error '%U'", format_unformat_error, i);
10545           return -99;
10546         }
10547     }
10548
10549   if (sw_if_index_set == 0)
10550     {
10551       errmsg ("missing interface name or sw_if_index");
10552       return -99;
10553     }
10554   if (!v6_address_set)
10555     {
10556       errmsg ("no address set");
10557       return -99;
10558     }
10559
10560   /* Construct the API message */
10561   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10562
10563   mp->sw_if_index = ntohl (sw_if_index);
10564   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10565   mp->address_length = address_length;
10566   mp->use_default = use_default;
10567   mp->no_advertise = no_advertise;
10568   mp->off_link = off_link;
10569   mp->no_autoconfig = no_autoconfig;
10570   mp->no_onlink = no_onlink;
10571   mp->is_no = is_no;
10572   mp->val_lifetime = ntohl (val_lifetime);
10573   mp->pref_lifetime = ntohl (pref_lifetime);
10574
10575   /* send it... */
10576   S (mp);
10577
10578   /* Wait for a reply, return good/bad news  */
10579   W (ret);
10580   return ret;
10581 }
10582
10583 static int
10584 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10585 {
10586   unformat_input_t *i = vam->input;
10587   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10588   u32 sw_if_index;
10589   u8 sw_if_index_set = 0;
10590   u8 suppress = 0;
10591   u8 managed = 0;
10592   u8 other = 0;
10593   u8 ll_option = 0;
10594   u8 send_unicast = 0;
10595   u8 cease = 0;
10596   u8 is_no = 0;
10597   u8 default_router = 0;
10598   u32 max_interval = 0;
10599   u32 min_interval = 0;
10600   u32 lifetime = 0;
10601   u32 initial_count = 0;
10602   u32 initial_interval = 0;
10603   int ret;
10604
10605
10606   /* Parse args required to build the message */
10607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10608     {
10609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10610         sw_if_index_set = 1;
10611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10612         sw_if_index_set = 1;
10613       else if (unformat (i, "maxint %d", &max_interval))
10614         ;
10615       else if (unformat (i, "minint %d", &min_interval))
10616         ;
10617       else if (unformat (i, "life %d", &lifetime))
10618         ;
10619       else if (unformat (i, "count %d", &initial_count))
10620         ;
10621       else if (unformat (i, "interval %d", &initial_interval))
10622         ;
10623       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10624         suppress = 1;
10625       else if (unformat (i, "managed"))
10626         managed = 1;
10627       else if (unformat (i, "other"))
10628         other = 1;
10629       else if (unformat (i, "ll"))
10630         ll_option = 1;
10631       else if (unformat (i, "send"))
10632         send_unicast = 1;
10633       else if (unformat (i, "cease"))
10634         cease = 1;
10635       else if (unformat (i, "isno"))
10636         is_no = 1;
10637       else if (unformat (i, "def"))
10638         default_router = 1;
10639       else
10640         {
10641           clib_warning ("parse error '%U'", format_unformat_error, i);
10642           return -99;
10643         }
10644     }
10645
10646   if (sw_if_index_set == 0)
10647     {
10648       errmsg ("missing interface name or sw_if_index");
10649       return -99;
10650     }
10651
10652   /* Construct the API message */
10653   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10654
10655   mp->sw_if_index = ntohl (sw_if_index);
10656   mp->max_interval = ntohl (max_interval);
10657   mp->min_interval = ntohl (min_interval);
10658   mp->lifetime = ntohl (lifetime);
10659   mp->initial_count = ntohl (initial_count);
10660   mp->initial_interval = ntohl (initial_interval);
10661   mp->suppress = suppress;
10662   mp->managed = managed;
10663   mp->other = other;
10664   mp->ll_option = ll_option;
10665   mp->send_unicast = send_unicast;
10666   mp->cease = cease;
10667   mp->is_no = is_no;
10668   mp->default_router = default_router;
10669
10670   /* send it... */
10671   S (mp);
10672
10673   /* Wait for a reply, return good/bad news  */
10674   W (ret);
10675   return ret;
10676 }
10677
10678 static int
10679 api_set_arp_neighbor_limit (vat_main_t * vam)
10680 {
10681   unformat_input_t *i = vam->input;
10682   vl_api_set_arp_neighbor_limit_t *mp;
10683   u32 arp_nbr_limit;
10684   u8 limit_set = 0;
10685   u8 is_ipv6 = 0;
10686   int ret;
10687
10688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10689     {
10690       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10691         limit_set = 1;
10692       else if (unformat (i, "ipv6"))
10693         is_ipv6 = 1;
10694       else
10695         {
10696           clib_warning ("parse error '%U'", format_unformat_error, i);
10697           return -99;
10698         }
10699     }
10700
10701   if (limit_set == 0)
10702     {
10703       errmsg ("missing limit value");
10704       return -99;
10705     }
10706
10707   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10708
10709   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10710   mp->is_ipv6 = is_ipv6;
10711
10712   S (mp);
10713   W (ret);
10714   return ret;
10715 }
10716
10717 static int
10718 api_l2_patch_add_del (vat_main_t * vam)
10719 {
10720   unformat_input_t *i = vam->input;
10721   vl_api_l2_patch_add_del_t *mp;
10722   u32 rx_sw_if_index;
10723   u8 rx_sw_if_index_set = 0;
10724   u32 tx_sw_if_index;
10725   u8 tx_sw_if_index_set = 0;
10726   u8 is_add = 1;
10727   int ret;
10728
10729   /* Parse args required to build the message */
10730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10731     {
10732       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10733         rx_sw_if_index_set = 1;
10734       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10735         tx_sw_if_index_set = 1;
10736       else if (unformat (i, "rx"))
10737         {
10738           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10739             {
10740               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10741                             &rx_sw_if_index))
10742                 rx_sw_if_index_set = 1;
10743             }
10744           else
10745             break;
10746         }
10747       else if (unformat (i, "tx"))
10748         {
10749           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10750             {
10751               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10752                             &tx_sw_if_index))
10753                 tx_sw_if_index_set = 1;
10754             }
10755           else
10756             break;
10757         }
10758       else if (unformat (i, "del"))
10759         is_add = 0;
10760       else
10761         break;
10762     }
10763
10764   if (rx_sw_if_index_set == 0)
10765     {
10766       errmsg ("missing rx interface name or rx_sw_if_index");
10767       return -99;
10768     }
10769
10770   if (tx_sw_if_index_set == 0)
10771     {
10772       errmsg ("missing tx interface name or tx_sw_if_index");
10773       return -99;
10774     }
10775
10776   M (L2_PATCH_ADD_DEL, mp);
10777
10778   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10779   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10780   mp->is_add = is_add;
10781
10782   S (mp);
10783   W (ret);
10784   return ret;
10785 }
10786
10787 u8 is_del;
10788 u8 localsid_addr[16];
10789 u8 end_psp;
10790 u8 behavior;
10791 u32 sw_if_index;
10792 u32 vlan_index;
10793 u32 fib_table;
10794 u8 nh_addr[16];
10795
10796 static int
10797 api_sr_localsid_add_del (vat_main_t * vam)
10798 {
10799   unformat_input_t *i = vam->input;
10800   vl_api_sr_localsid_add_del_t *mp;
10801
10802   u8 is_del;
10803   ip6_address_t localsid;
10804   u8 end_psp = 0;
10805   u8 behavior = ~0;
10806   u32 sw_if_index;
10807   u32 fib_table = ~(u32) 0;
10808   ip6_address_t nh_addr6;
10809   ip4_address_t nh_addr4;
10810   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10811   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10812
10813   bool nexthop_set = 0;
10814
10815   int ret;
10816
10817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10818     {
10819       if (unformat (i, "del"))
10820         is_del = 1;
10821       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10822       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10823         nexthop_set = 1;
10824       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10825         nexthop_set = 1;
10826       else if (unformat (i, "behavior %u", &behavior));
10827       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10828       else if (unformat (i, "fib-table %u", &fib_table));
10829       else if (unformat (i, "end.psp %u", &behavior));
10830       else
10831         break;
10832     }
10833
10834   M (SR_LOCALSID_ADD_DEL, mp);
10835
10836   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10837   if (nexthop_set)
10838     {
10839       clib_memcpy (mp->nh_addr6, &nh_addr4, sizeof (mp->nh_addr6));
10840       clib_memcpy (mp->nh_addr4, &nh_addr6, sizeof (mp->nh_addr4));
10841     }
10842   mp->behavior = behavior;
10843   mp->sw_if_index = ntohl (sw_if_index);
10844   mp->fib_table = ntohl (fib_table);
10845   mp->end_psp = end_psp;
10846   mp->is_del = is_del;
10847
10848   S (mp);
10849   W (ret);
10850   return ret;
10851 }
10852
10853 static int
10854 api_ioam_enable (vat_main_t * vam)
10855 {
10856   unformat_input_t *input = vam->input;
10857   vl_api_ioam_enable_t *mp;
10858   u32 id = 0;
10859   int has_trace_option = 0;
10860   int has_pot_option = 0;
10861   int has_seqno_option = 0;
10862   int has_analyse_option = 0;
10863   int ret;
10864
10865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10866     {
10867       if (unformat (input, "trace"))
10868         has_trace_option = 1;
10869       else if (unformat (input, "pot"))
10870         has_pot_option = 1;
10871       else if (unformat (input, "seqno"))
10872         has_seqno_option = 1;
10873       else if (unformat (input, "analyse"))
10874         has_analyse_option = 1;
10875       else
10876         break;
10877     }
10878   M (IOAM_ENABLE, mp);
10879   mp->id = htons (id);
10880   mp->seqno = has_seqno_option;
10881   mp->analyse = has_analyse_option;
10882   mp->pot_enable = has_pot_option;
10883   mp->trace_enable = has_trace_option;
10884
10885   S (mp);
10886   W (ret);
10887   return ret;
10888 }
10889
10890
10891 static int
10892 api_ioam_disable (vat_main_t * vam)
10893 {
10894   vl_api_ioam_disable_t *mp;
10895   int ret;
10896
10897   M (IOAM_DISABLE, mp);
10898   S (mp);
10899   W (ret);
10900   return ret;
10901 }
10902
10903 #define foreach_tcp_proto_field                 \
10904 _(src_port)                                     \
10905 _(dst_port)
10906
10907 #define foreach_udp_proto_field                 \
10908 _(src_port)                                     \
10909 _(dst_port)
10910
10911 #define foreach_ip4_proto_field                 \
10912 _(src_address)                                  \
10913 _(dst_address)                                  \
10914 _(tos)                                          \
10915 _(length)                                       \
10916 _(fragment_id)                                  \
10917 _(ttl)                                          \
10918 _(protocol)                                     \
10919 _(checksum)
10920
10921 typedef struct
10922 {
10923   u16 src_port, dst_port;
10924 } tcpudp_header_t;
10925
10926 #if VPP_API_TEST_BUILTIN == 0
10927 uword
10928 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10929 {
10930   u8 **maskp = va_arg (*args, u8 **);
10931   u8 *mask = 0;
10932   u8 found_something = 0;
10933   tcp_header_t *tcp;
10934
10935 #define _(a) u8 a=0;
10936   foreach_tcp_proto_field;
10937 #undef _
10938
10939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10940     {
10941       if (0);
10942 #define _(a) else if (unformat (input, #a)) a=1;
10943       foreach_tcp_proto_field
10944 #undef _
10945         else
10946         break;
10947     }
10948
10949 #define _(a) found_something += a;
10950   foreach_tcp_proto_field;
10951 #undef _
10952
10953   if (found_something == 0)
10954     return 0;
10955
10956   vec_validate (mask, sizeof (*tcp) - 1);
10957
10958   tcp = (tcp_header_t *) mask;
10959
10960 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10961   foreach_tcp_proto_field;
10962 #undef _
10963
10964   *maskp = mask;
10965   return 1;
10966 }
10967
10968 uword
10969 unformat_udp_mask (unformat_input_t * input, va_list * args)
10970 {
10971   u8 **maskp = va_arg (*args, u8 **);
10972   u8 *mask = 0;
10973   u8 found_something = 0;
10974   udp_header_t *udp;
10975
10976 #define _(a) u8 a=0;
10977   foreach_udp_proto_field;
10978 #undef _
10979
10980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10981     {
10982       if (0);
10983 #define _(a) else if (unformat (input, #a)) a=1;
10984       foreach_udp_proto_field
10985 #undef _
10986         else
10987         break;
10988     }
10989
10990 #define _(a) found_something += a;
10991   foreach_udp_proto_field;
10992 #undef _
10993
10994   if (found_something == 0)
10995     return 0;
10996
10997   vec_validate (mask, sizeof (*udp) - 1);
10998
10999   udp = (udp_header_t *) mask;
11000
11001 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11002   foreach_udp_proto_field;
11003 #undef _
11004
11005   *maskp = mask;
11006   return 1;
11007 }
11008
11009 uword
11010 unformat_l4_mask (unformat_input_t * input, va_list * args)
11011 {
11012   u8 **maskp = va_arg (*args, u8 **);
11013   u16 src_port = 0, dst_port = 0;
11014   tcpudp_header_t *tcpudp;
11015
11016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11017     {
11018       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11019         return 1;
11020       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11021         return 1;
11022       else if (unformat (input, "src_port"))
11023         src_port = 0xFFFF;
11024       else if (unformat (input, "dst_port"))
11025         dst_port = 0xFFFF;
11026       else
11027         return 0;
11028     }
11029
11030   if (!src_port && !dst_port)
11031     return 0;
11032
11033   u8 *mask = 0;
11034   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11035
11036   tcpudp = (tcpudp_header_t *) mask;
11037   tcpudp->src_port = src_port;
11038   tcpudp->dst_port = dst_port;
11039
11040   *maskp = mask;
11041
11042   return 1;
11043 }
11044
11045 uword
11046 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11047 {
11048   u8 **maskp = va_arg (*args, u8 **);
11049   u8 *mask = 0;
11050   u8 found_something = 0;
11051   ip4_header_t *ip;
11052
11053 #define _(a) u8 a=0;
11054   foreach_ip4_proto_field;
11055 #undef _
11056   u8 version = 0;
11057   u8 hdr_length = 0;
11058
11059
11060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11061     {
11062       if (unformat (input, "version"))
11063         version = 1;
11064       else if (unformat (input, "hdr_length"))
11065         hdr_length = 1;
11066       else if (unformat (input, "src"))
11067         src_address = 1;
11068       else if (unformat (input, "dst"))
11069         dst_address = 1;
11070       else if (unformat (input, "proto"))
11071         protocol = 1;
11072
11073 #define _(a) else if (unformat (input, #a)) a=1;
11074       foreach_ip4_proto_field
11075 #undef _
11076         else
11077         break;
11078     }
11079
11080 #define _(a) found_something += a;
11081   foreach_ip4_proto_field;
11082 #undef _
11083
11084   if (found_something == 0)
11085     return 0;
11086
11087   vec_validate (mask, sizeof (*ip) - 1);
11088
11089   ip = (ip4_header_t *) mask;
11090
11091 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11092   foreach_ip4_proto_field;
11093 #undef _
11094
11095   ip->ip_version_and_header_length = 0;
11096
11097   if (version)
11098     ip->ip_version_and_header_length |= 0xF0;
11099
11100   if (hdr_length)
11101     ip->ip_version_and_header_length |= 0x0F;
11102
11103   *maskp = mask;
11104   return 1;
11105 }
11106
11107 #define foreach_ip6_proto_field                 \
11108 _(src_address)                                  \
11109 _(dst_address)                                  \
11110 _(payload_length)                               \
11111 _(hop_limit)                                    \
11112 _(protocol)
11113
11114 uword
11115 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11116 {
11117   u8 **maskp = va_arg (*args, u8 **);
11118   u8 *mask = 0;
11119   u8 found_something = 0;
11120   ip6_header_t *ip;
11121   u32 ip_version_traffic_class_and_flow_label;
11122
11123 #define _(a) u8 a=0;
11124   foreach_ip6_proto_field;
11125 #undef _
11126   u8 version = 0;
11127   u8 traffic_class = 0;
11128   u8 flow_label = 0;
11129
11130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11131     {
11132       if (unformat (input, "version"))
11133         version = 1;
11134       else if (unformat (input, "traffic-class"))
11135         traffic_class = 1;
11136       else if (unformat (input, "flow-label"))
11137         flow_label = 1;
11138       else if (unformat (input, "src"))
11139         src_address = 1;
11140       else if (unformat (input, "dst"))
11141         dst_address = 1;
11142       else if (unformat (input, "proto"))
11143         protocol = 1;
11144
11145 #define _(a) else if (unformat (input, #a)) a=1;
11146       foreach_ip6_proto_field
11147 #undef _
11148         else
11149         break;
11150     }
11151
11152 #define _(a) found_something += a;
11153   foreach_ip6_proto_field;
11154 #undef _
11155
11156   if (found_something == 0)
11157     return 0;
11158
11159   vec_validate (mask, sizeof (*ip) - 1);
11160
11161   ip = (ip6_header_t *) mask;
11162
11163 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11164   foreach_ip6_proto_field;
11165 #undef _
11166
11167   ip_version_traffic_class_and_flow_label = 0;
11168
11169   if (version)
11170     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11171
11172   if (traffic_class)
11173     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11174
11175   if (flow_label)
11176     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11177
11178   ip->ip_version_traffic_class_and_flow_label =
11179     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11180
11181   *maskp = mask;
11182   return 1;
11183 }
11184
11185 uword
11186 unformat_l3_mask (unformat_input_t * input, va_list * args)
11187 {
11188   u8 **maskp = va_arg (*args, u8 **);
11189
11190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11191     {
11192       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11193         return 1;
11194       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11195         return 1;
11196       else
11197         break;
11198     }
11199   return 0;
11200 }
11201
11202 uword
11203 unformat_l2_mask (unformat_input_t * input, va_list * args)
11204 {
11205   u8 **maskp = va_arg (*args, u8 **);
11206   u8 *mask = 0;
11207   u8 src = 0;
11208   u8 dst = 0;
11209   u8 proto = 0;
11210   u8 tag1 = 0;
11211   u8 tag2 = 0;
11212   u8 ignore_tag1 = 0;
11213   u8 ignore_tag2 = 0;
11214   u8 cos1 = 0;
11215   u8 cos2 = 0;
11216   u8 dot1q = 0;
11217   u8 dot1ad = 0;
11218   int len = 14;
11219
11220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11221     {
11222       if (unformat (input, "src"))
11223         src = 1;
11224       else if (unformat (input, "dst"))
11225         dst = 1;
11226       else if (unformat (input, "proto"))
11227         proto = 1;
11228       else if (unformat (input, "tag1"))
11229         tag1 = 1;
11230       else if (unformat (input, "tag2"))
11231         tag2 = 1;
11232       else if (unformat (input, "ignore-tag1"))
11233         ignore_tag1 = 1;
11234       else if (unformat (input, "ignore-tag2"))
11235         ignore_tag2 = 1;
11236       else if (unformat (input, "cos1"))
11237         cos1 = 1;
11238       else if (unformat (input, "cos2"))
11239         cos2 = 1;
11240       else if (unformat (input, "dot1q"))
11241         dot1q = 1;
11242       else if (unformat (input, "dot1ad"))
11243         dot1ad = 1;
11244       else
11245         break;
11246     }
11247   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11248        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11249     return 0;
11250
11251   if (tag1 || ignore_tag1 || cos1 || dot1q)
11252     len = 18;
11253   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11254     len = 22;
11255
11256   vec_validate (mask, len - 1);
11257
11258   if (dst)
11259     memset (mask, 0xff, 6);
11260
11261   if (src)
11262     memset (mask + 6, 0xff, 6);
11263
11264   if (tag2 || dot1ad)
11265     {
11266       /* inner vlan tag */
11267       if (tag2)
11268         {
11269           mask[19] = 0xff;
11270           mask[18] = 0x0f;
11271         }
11272       if (cos2)
11273         mask[18] |= 0xe0;
11274       if (proto)
11275         mask[21] = mask[20] = 0xff;
11276       if (tag1)
11277         {
11278           mask[15] = 0xff;
11279           mask[14] = 0x0f;
11280         }
11281       if (cos1)
11282         mask[14] |= 0xe0;
11283       *maskp = mask;
11284       return 1;
11285     }
11286   if (tag1 | dot1q)
11287     {
11288       if (tag1)
11289         {
11290           mask[15] = 0xff;
11291           mask[14] = 0x0f;
11292         }
11293       if (cos1)
11294         mask[14] |= 0xe0;
11295       if (proto)
11296         mask[16] = mask[17] = 0xff;
11297
11298       *maskp = mask;
11299       return 1;
11300     }
11301   if (cos2)
11302     mask[18] |= 0xe0;
11303   if (cos1)
11304     mask[14] |= 0xe0;
11305   if (proto)
11306     mask[12] = mask[13] = 0xff;
11307
11308   *maskp = mask;
11309   return 1;
11310 }
11311
11312 uword
11313 unformat_classify_mask (unformat_input_t * input, va_list * args)
11314 {
11315   u8 **maskp = va_arg (*args, u8 **);
11316   u32 *skipp = va_arg (*args, u32 *);
11317   u32 *matchp = va_arg (*args, u32 *);
11318   u32 match;
11319   u8 *mask = 0;
11320   u8 *l2 = 0;
11321   u8 *l3 = 0;
11322   u8 *l4 = 0;
11323   int i;
11324
11325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11326     {
11327       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11328         ;
11329       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11330         ;
11331       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11332         ;
11333       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11334         ;
11335       else
11336         break;
11337     }
11338
11339   if (l4 && !l3)
11340     {
11341       vec_free (mask);
11342       vec_free (l2);
11343       vec_free (l4);
11344       return 0;
11345     }
11346
11347   if (mask || l2 || l3 || l4)
11348     {
11349       if (l2 || l3 || l4)
11350         {
11351           /* "With a free Ethernet header in every package" */
11352           if (l2 == 0)
11353             vec_validate (l2, 13);
11354           mask = l2;
11355           if (vec_len (l3))
11356             {
11357               vec_append (mask, l3);
11358               vec_free (l3);
11359             }
11360           if (vec_len (l4))
11361             {
11362               vec_append (mask, l4);
11363               vec_free (l4);
11364             }
11365         }
11366
11367       /* Scan forward looking for the first significant mask octet */
11368       for (i = 0; i < vec_len (mask); i++)
11369         if (mask[i])
11370           break;
11371
11372       /* compute (skip, match) params */
11373       *skipp = i / sizeof (u32x4);
11374       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11375
11376       /* Pad mask to an even multiple of the vector size */
11377       while (vec_len (mask) % sizeof (u32x4))
11378         vec_add1 (mask, 0);
11379
11380       match = vec_len (mask) / sizeof (u32x4);
11381
11382       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11383         {
11384           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11385           if (*tmp || *(tmp + 1))
11386             break;
11387           match--;
11388         }
11389       if (match == 0)
11390         clib_warning ("BUG: match 0");
11391
11392       _vec_len (mask) = match * sizeof (u32x4);
11393
11394       *matchp = match;
11395       *maskp = mask;
11396
11397       return 1;
11398     }
11399
11400   return 0;
11401 }
11402 #endif /* VPP_API_TEST_BUILTIN */
11403
11404 #define foreach_l2_next                         \
11405 _(drop, DROP)                                   \
11406 _(ethernet, ETHERNET_INPUT)                     \
11407 _(ip4, IP4_INPUT)                               \
11408 _(ip6, IP6_INPUT)
11409
11410 uword
11411 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11412 {
11413   u32 *miss_next_indexp = va_arg (*args, u32 *);
11414   u32 next_index = 0;
11415   u32 tmp;
11416
11417 #define _(n,N) \
11418   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11419   foreach_l2_next;
11420 #undef _
11421
11422   if (unformat (input, "%d", &tmp))
11423     {
11424       next_index = tmp;
11425       goto out;
11426     }
11427
11428   return 0;
11429
11430 out:
11431   *miss_next_indexp = next_index;
11432   return 1;
11433 }
11434
11435 #define foreach_ip_next                         \
11436 _(drop, DROP)                                   \
11437 _(local, LOCAL)                                 \
11438 _(rewrite, REWRITE)
11439
11440 uword
11441 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11442 {
11443   u32 *miss_next_indexp = va_arg (*args, u32 *);
11444   u32 next_index = 0;
11445   u32 tmp;
11446
11447 #define _(n,N) \
11448   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11449   foreach_ip_next;
11450 #undef _
11451
11452   if (unformat (input, "%d", &tmp))
11453     {
11454       next_index = tmp;
11455       goto out;
11456     }
11457
11458   return 0;
11459
11460 out:
11461   *miss_next_indexp = next_index;
11462   return 1;
11463 }
11464
11465 #define foreach_acl_next                        \
11466 _(deny, DENY)
11467
11468 uword
11469 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11470 {
11471   u32 *miss_next_indexp = va_arg (*args, u32 *);
11472   u32 next_index = 0;
11473   u32 tmp;
11474
11475 #define _(n,N) \
11476   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11477   foreach_acl_next;
11478 #undef _
11479
11480   if (unformat (input, "permit"))
11481     {
11482       next_index = ~0;
11483       goto out;
11484     }
11485   else if (unformat (input, "%d", &tmp))
11486     {
11487       next_index = tmp;
11488       goto out;
11489     }
11490
11491   return 0;
11492
11493 out:
11494   *miss_next_indexp = next_index;
11495   return 1;
11496 }
11497
11498 uword
11499 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11500 {
11501   u32 *r = va_arg (*args, u32 *);
11502
11503   if (unformat (input, "conform-color"))
11504     *r = POLICE_CONFORM;
11505   else if (unformat (input, "exceed-color"))
11506     *r = POLICE_EXCEED;
11507   else
11508     return 0;
11509
11510   return 1;
11511 }
11512
11513 static int
11514 api_classify_add_del_table (vat_main_t * vam)
11515 {
11516   unformat_input_t *i = vam->input;
11517   vl_api_classify_add_del_table_t *mp;
11518
11519   u32 nbuckets = 2;
11520   u32 skip = ~0;
11521   u32 match = ~0;
11522   int is_add = 1;
11523   int del_chain = 0;
11524   u32 table_index = ~0;
11525   u32 next_table_index = ~0;
11526   u32 miss_next_index = ~0;
11527   u32 memory_size = 32 << 20;
11528   u8 *mask = 0;
11529   u32 current_data_flag = 0;
11530   int current_data_offset = 0;
11531   int ret;
11532
11533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (i, "del"))
11536         is_add = 0;
11537       else if (unformat (i, "del-chain"))
11538         {
11539           is_add = 0;
11540           del_chain = 1;
11541         }
11542       else if (unformat (i, "buckets %d", &nbuckets))
11543         ;
11544       else if (unformat (i, "memory_size %d", &memory_size))
11545         ;
11546       else if (unformat (i, "skip %d", &skip))
11547         ;
11548       else if (unformat (i, "match %d", &match))
11549         ;
11550       else if (unformat (i, "table %d", &table_index))
11551         ;
11552       else if (unformat (i, "mask %U", unformat_classify_mask,
11553                          &mask, &skip, &match))
11554         ;
11555       else if (unformat (i, "next-table %d", &next_table_index))
11556         ;
11557       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11558                          &miss_next_index))
11559         ;
11560       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11561                          &miss_next_index))
11562         ;
11563       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11564                          &miss_next_index))
11565         ;
11566       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11567         ;
11568       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11569         ;
11570       else
11571         break;
11572     }
11573
11574   if (is_add && mask == 0)
11575     {
11576       errmsg ("Mask required");
11577       return -99;
11578     }
11579
11580   if (is_add && skip == ~0)
11581     {
11582       errmsg ("skip count required");
11583       return -99;
11584     }
11585
11586   if (is_add && match == ~0)
11587     {
11588       errmsg ("match count required");
11589       return -99;
11590     }
11591
11592   if (!is_add && table_index == ~0)
11593     {
11594       errmsg ("table index required for delete");
11595       return -99;
11596     }
11597
11598   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11599
11600   mp->is_add = is_add;
11601   mp->del_chain = del_chain;
11602   mp->table_index = ntohl (table_index);
11603   mp->nbuckets = ntohl (nbuckets);
11604   mp->memory_size = ntohl (memory_size);
11605   mp->skip_n_vectors = ntohl (skip);
11606   mp->match_n_vectors = ntohl (match);
11607   mp->next_table_index = ntohl (next_table_index);
11608   mp->miss_next_index = ntohl (miss_next_index);
11609   mp->current_data_flag = ntohl (current_data_flag);
11610   mp->current_data_offset = ntohl (current_data_offset);
11611   mp->mask_len = ntohl (vec_len (mask));
11612   clib_memcpy (mp->mask, mask, vec_len (mask));
11613
11614   vec_free (mask);
11615
11616   S (mp);
11617   W (ret);
11618   return ret;
11619 }
11620
11621 #if VPP_API_TEST_BUILTIN == 0
11622 uword
11623 unformat_l4_match (unformat_input_t * input, va_list * args)
11624 {
11625   u8 **matchp = va_arg (*args, u8 **);
11626
11627   u8 *proto_header = 0;
11628   int src_port = 0;
11629   int dst_port = 0;
11630
11631   tcpudp_header_t h;
11632
11633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11634     {
11635       if (unformat (input, "src_port %d", &src_port))
11636         ;
11637       else if (unformat (input, "dst_port %d", &dst_port))
11638         ;
11639       else
11640         return 0;
11641     }
11642
11643   h.src_port = clib_host_to_net_u16 (src_port);
11644   h.dst_port = clib_host_to_net_u16 (dst_port);
11645   vec_validate (proto_header, sizeof (h) - 1);
11646   memcpy (proto_header, &h, sizeof (h));
11647
11648   *matchp = proto_header;
11649
11650   return 1;
11651 }
11652
11653 uword
11654 unformat_ip4_match (unformat_input_t * input, va_list * args)
11655 {
11656   u8 **matchp = va_arg (*args, u8 **);
11657   u8 *match = 0;
11658   ip4_header_t *ip;
11659   int version = 0;
11660   u32 version_val;
11661   int hdr_length = 0;
11662   u32 hdr_length_val;
11663   int src = 0, dst = 0;
11664   ip4_address_t src_val, dst_val;
11665   int proto = 0;
11666   u32 proto_val;
11667   int tos = 0;
11668   u32 tos_val;
11669   int length = 0;
11670   u32 length_val;
11671   int fragment_id = 0;
11672   u32 fragment_id_val;
11673   int ttl = 0;
11674   int ttl_val;
11675   int checksum = 0;
11676   u32 checksum_val;
11677
11678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (input, "version %d", &version_val))
11681         version = 1;
11682       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11683         hdr_length = 1;
11684       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11685         src = 1;
11686       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11687         dst = 1;
11688       else if (unformat (input, "proto %d", &proto_val))
11689         proto = 1;
11690       else if (unformat (input, "tos %d", &tos_val))
11691         tos = 1;
11692       else if (unformat (input, "length %d", &length_val))
11693         length = 1;
11694       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11695         fragment_id = 1;
11696       else if (unformat (input, "ttl %d", &ttl_val))
11697         ttl = 1;
11698       else if (unformat (input, "checksum %d", &checksum_val))
11699         checksum = 1;
11700       else
11701         break;
11702     }
11703
11704   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11705       + ttl + checksum == 0)
11706     return 0;
11707
11708   /*
11709    * Aligned because we use the real comparison functions
11710    */
11711   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11712
11713   ip = (ip4_header_t *) match;
11714
11715   /* These are realistically matched in practice */
11716   if (src)
11717     ip->src_address.as_u32 = src_val.as_u32;
11718
11719   if (dst)
11720     ip->dst_address.as_u32 = dst_val.as_u32;
11721
11722   if (proto)
11723     ip->protocol = proto_val;
11724
11725
11726   /* These are not, but they're included for completeness */
11727   if (version)
11728     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11729
11730   if (hdr_length)
11731     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11732
11733   if (tos)
11734     ip->tos = tos_val;
11735
11736   if (length)
11737     ip->length = clib_host_to_net_u16 (length_val);
11738
11739   if (ttl)
11740     ip->ttl = ttl_val;
11741
11742   if (checksum)
11743     ip->checksum = clib_host_to_net_u16 (checksum_val);
11744
11745   *matchp = match;
11746   return 1;
11747 }
11748
11749 uword
11750 unformat_ip6_match (unformat_input_t * input, va_list * args)
11751 {
11752   u8 **matchp = va_arg (*args, u8 **);
11753   u8 *match = 0;
11754   ip6_header_t *ip;
11755   int version = 0;
11756   u32 version_val;
11757   u8 traffic_class = 0;
11758   u32 traffic_class_val = 0;
11759   u8 flow_label = 0;
11760   u8 flow_label_val;
11761   int src = 0, dst = 0;
11762   ip6_address_t src_val, dst_val;
11763   int proto = 0;
11764   u32 proto_val;
11765   int payload_length = 0;
11766   u32 payload_length_val;
11767   int hop_limit = 0;
11768   int hop_limit_val;
11769   u32 ip_version_traffic_class_and_flow_label;
11770
11771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11772     {
11773       if (unformat (input, "version %d", &version_val))
11774         version = 1;
11775       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11776         traffic_class = 1;
11777       else if (unformat (input, "flow_label %d", &flow_label_val))
11778         flow_label = 1;
11779       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11780         src = 1;
11781       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11782         dst = 1;
11783       else if (unformat (input, "proto %d", &proto_val))
11784         proto = 1;
11785       else if (unformat (input, "payload_length %d", &payload_length_val))
11786         payload_length = 1;
11787       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11788         hop_limit = 1;
11789       else
11790         break;
11791     }
11792
11793   if (version + traffic_class + flow_label + src + dst + proto +
11794       payload_length + hop_limit == 0)
11795     return 0;
11796
11797   /*
11798    * Aligned because we use the real comparison functions
11799    */
11800   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11801
11802   ip = (ip6_header_t *) match;
11803
11804   if (src)
11805     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11806
11807   if (dst)
11808     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11809
11810   if (proto)
11811     ip->protocol = proto_val;
11812
11813   ip_version_traffic_class_and_flow_label = 0;
11814
11815   if (version)
11816     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11817
11818   if (traffic_class)
11819     ip_version_traffic_class_and_flow_label |=
11820       (traffic_class_val & 0xFF) << 20;
11821
11822   if (flow_label)
11823     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11824
11825   ip->ip_version_traffic_class_and_flow_label =
11826     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11827
11828   if (payload_length)
11829     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11830
11831   if (hop_limit)
11832     ip->hop_limit = hop_limit_val;
11833
11834   *matchp = match;
11835   return 1;
11836 }
11837
11838 uword
11839 unformat_l3_match (unformat_input_t * input, va_list * args)
11840 {
11841   u8 **matchp = va_arg (*args, u8 **);
11842
11843   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11844     {
11845       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11846         return 1;
11847       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11848         return 1;
11849       else
11850         break;
11851     }
11852   return 0;
11853 }
11854
11855 uword
11856 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11857 {
11858   u8 *tagp = va_arg (*args, u8 *);
11859   u32 tag;
11860
11861   if (unformat (input, "%d", &tag))
11862     {
11863       tagp[0] = (tag >> 8) & 0x0F;
11864       tagp[1] = tag & 0xFF;
11865       return 1;
11866     }
11867
11868   return 0;
11869 }
11870
11871 uword
11872 unformat_l2_match (unformat_input_t * input, va_list * args)
11873 {
11874   u8 **matchp = va_arg (*args, u8 **);
11875   u8 *match = 0;
11876   u8 src = 0;
11877   u8 src_val[6];
11878   u8 dst = 0;
11879   u8 dst_val[6];
11880   u8 proto = 0;
11881   u16 proto_val;
11882   u8 tag1 = 0;
11883   u8 tag1_val[2];
11884   u8 tag2 = 0;
11885   u8 tag2_val[2];
11886   int len = 14;
11887   u8 ignore_tag1 = 0;
11888   u8 ignore_tag2 = 0;
11889   u8 cos1 = 0;
11890   u8 cos2 = 0;
11891   u32 cos1_val = 0;
11892   u32 cos2_val = 0;
11893
11894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11895     {
11896       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11897         src = 1;
11898       else
11899         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11900         dst = 1;
11901       else if (unformat (input, "proto %U",
11902                          unformat_ethernet_type_host_byte_order, &proto_val))
11903         proto = 1;
11904       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11905         tag1 = 1;
11906       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11907         tag2 = 1;
11908       else if (unformat (input, "ignore-tag1"))
11909         ignore_tag1 = 1;
11910       else if (unformat (input, "ignore-tag2"))
11911         ignore_tag2 = 1;
11912       else if (unformat (input, "cos1 %d", &cos1_val))
11913         cos1 = 1;
11914       else if (unformat (input, "cos2 %d", &cos2_val))
11915         cos2 = 1;
11916       else
11917         break;
11918     }
11919   if ((src + dst + proto + tag1 + tag2 +
11920        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11921     return 0;
11922
11923   if (tag1 || ignore_tag1 || cos1)
11924     len = 18;
11925   if (tag2 || ignore_tag2 || cos2)
11926     len = 22;
11927
11928   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11929
11930   if (dst)
11931     clib_memcpy (match, dst_val, 6);
11932
11933   if (src)
11934     clib_memcpy (match + 6, src_val, 6);
11935
11936   if (tag2)
11937     {
11938       /* inner vlan tag */
11939       match[19] = tag2_val[1];
11940       match[18] = tag2_val[0];
11941       if (cos2)
11942         match[18] |= (cos2_val & 0x7) << 5;
11943       if (proto)
11944         {
11945           match[21] = proto_val & 0xff;
11946           match[20] = proto_val >> 8;
11947         }
11948       if (tag1)
11949         {
11950           match[15] = tag1_val[1];
11951           match[14] = tag1_val[0];
11952         }
11953       if (cos1)
11954         match[14] |= (cos1_val & 0x7) << 5;
11955       *matchp = match;
11956       return 1;
11957     }
11958   if (tag1)
11959     {
11960       match[15] = tag1_val[1];
11961       match[14] = tag1_val[0];
11962       if (proto)
11963         {
11964           match[17] = proto_val & 0xff;
11965           match[16] = proto_val >> 8;
11966         }
11967       if (cos1)
11968         match[14] |= (cos1_val & 0x7) << 5;
11969
11970       *matchp = match;
11971       return 1;
11972     }
11973   if (cos2)
11974     match[18] |= (cos2_val & 0x7) << 5;
11975   if (cos1)
11976     match[14] |= (cos1_val & 0x7) << 5;
11977   if (proto)
11978     {
11979       match[13] = proto_val & 0xff;
11980       match[12] = proto_val >> 8;
11981     }
11982
11983   *matchp = match;
11984   return 1;
11985 }
11986
11987 uword
11988 unformat_qos_source (unformat_input_t * input, va_list * args)
11989 {
11990   int *qs = va_arg (*args, int *);
11991
11992   if (unformat (input, "ip"))
11993     *qs = QOS_SOURCE_IP;
11994   else if (unformat (input, "mpls"))
11995     *qs = QOS_SOURCE_MPLS;
11996   else if (unformat (input, "ext"))
11997     *qs = QOS_SOURCE_EXT;
11998   else if (unformat (input, "vlan"))
11999     *qs = QOS_SOURCE_VLAN;
12000   else
12001     return 0;
12002
12003   return 1;
12004 }
12005 #endif
12006
12007 uword
12008 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12009 {
12010   u8 **matchp = va_arg (*args, u8 **);
12011   u32 skip_n_vectors = va_arg (*args, u32);
12012   u32 match_n_vectors = va_arg (*args, u32);
12013
12014   u8 *match = 0;
12015   u8 *l2 = 0;
12016   u8 *l3 = 0;
12017   u8 *l4 = 0;
12018
12019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12020     {
12021       if (unformat (input, "hex %U", unformat_hex_string, &match))
12022         ;
12023       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12024         ;
12025       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12026         ;
12027       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12028         ;
12029       else
12030         break;
12031     }
12032
12033   if (l4 && !l3)
12034     {
12035       vec_free (match);
12036       vec_free (l2);
12037       vec_free (l4);
12038       return 0;
12039     }
12040
12041   if (match || l2 || l3 || l4)
12042     {
12043       if (l2 || l3 || l4)
12044         {
12045           /* "Win a free Ethernet header in every packet" */
12046           if (l2 == 0)
12047             vec_validate_aligned (l2, 13, sizeof (u32x4));
12048           match = l2;
12049           if (vec_len (l3))
12050             {
12051               vec_append_aligned (match, l3, sizeof (u32x4));
12052               vec_free (l3);
12053             }
12054           if (vec_len (l4))
12055             {
12056               vec_append_aligned (match, l4, sizeof (u32x4));
12057               vec_free (l4);
12058             }
12059         }
12060
12061       /* Make sure the vector is big enough even if key is all 0's */
12062       vec_validate_aligned
12063         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12064          sizeof (u32x4));
12065
12066       /* Set size, include skipped vectors */
12067       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12068
12069       *matchp = match;
12070
12071       return 1;
12072     }
12073
12074   return 0;
12075 }
12076
12077 static int
12078 api_classify_add_del_session (vat_main_t * vam)
12079 {
12080   unformat_input_t *i = vam->input;
12081   vl_api_classify_add_del_session_t *mp;
12082   int is_add = 1;
12083   u32 table_index = ~0;
12084   u32 hit_next_index = ~0;
12085   u32 opaque_index = ~0;
12086   u8 *match = 0;
12087   i32 advance = 0;
12088   u32 skip_n_vectors = 0;
12089   u32 match_n_vectors = 0;
12090   u32 action = 0;
12091   u32 metadata = 0;
12092   int ret;
12093
12094   /*
12095    * Warning: you have to supply skip_n and match_n
12096    * because the API client cant simply look at the classify
12097    * table object.
12098    */
12099
12100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12101     {
12102       if (unformat (i, "del"))
12103         is_add = 0;
12104       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12105                          &hit_next_index))
12106         ;
12107       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12108                          &hit_next_index))
12109         ;
12110       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12111                          &hit_next_index))
12112         ;
12113       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12114         ;
12115       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12116         ;
12117       else if (unformat (i, "opaque-index %d", &opaque_index))
12118         ;
12119       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12120         ;
12121       else if (unformat (i, "match_n %d", &match_n_vectors))
12122         ;
12123       else if (unformat (i, "match %U", api_unformat_classify_match,
12124                          &match, skip_n_vectors, match_n_vectors))
12125         ;
12126       else if (unformat (i, "advance %d", &advance))
12127         ;
12128       else if (unformat (i, "table-index %d", &table_index))
12129         ;
12130       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12131         action = 1;
12132       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12133         action = 2;
12134       else if (unformat (i, "action %d", &action))
12135         ;
12136       else if (unformat (i, "metadata %d", &metadata))
12137         ;
12138       else
12139         break;
12140     }
12141
12142   if (table_index == ~0)
12143     {
12144       errmsg ("Table index required");
12145       return -99;
12146     }
12147
12148   if (is_add && match == 0)
12149     {
12150       errmsg ("Match value required");
12151       return -99;
12152     }
12153
12154   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12155
12156   mp->is_add = is_add;
12157   mp->table_index = ntohl (table_index);
12158   mp->hit_next_index = ntohl (hit_next_index);
12159   mp->opaque_index = ntohl (opaque_index);
12160   mp->advance = ntohl (advance);
12161   mp->action = action;
12162   mp->metadata = ntohl (metadata);
12163   mp->match_len = ntohl (vec_len (match));
12164   clib_memcpy (mp->match, match, vec_len (match));
12165   vec_free (match);
12166
12167   S (mp);
12168   W (ret);
12169   return ret;
12170 }
12171
12172 static int
12173 api_classify_set_interface_ip_table (vat_main_t * vam)
12174 {
12175   unformat_input_t *i = vam->input;
12176   vl_api_classify_set_interface_ip_table_t *mp;
12177   u32 sw_if_index;
12178   int sw_if_index_set;
12179   u32 table_index = ~0;
12180   u8 is_ipv6 = 0;
12181   int ret;
12182
12183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12184     {
12185       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12186         sw_if_index_set = 1;
12187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12188         sw_if_index_set = 1;
12189       else if (unformat (i, "table %d", &table_index))
12190         ;
12191       else
12192         {
12193           clib_warning ("parse error '%U'", format_unformat_error, i);
12194           return -99;
12195         }
12196     }
12197
12198   if (sw_if_index_set == 0)
12199     {
12200       errmsg ("missing interface name or sw_if_index");
12201       return -99;
12202     }
12203
12204
12205   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12206
12207   mp->sw_if_index = ntohl (sw_if_index);
12208   mp->table_index = ntohl (table_index);
12209   mp->is_ipv6 = is_ipv6;
12210
12211   S (mp);
12212   W (ret);
12213   return ret;
12214 }
12215
12216 static int
12217 api_classify_set_interface_l2_tables (vat_main_t * vam)
12218 {
12219   unformat_input_t *i = vam->input;
12220   vl_api_classify_set_interface_l2_tables_t *mp;
12221   u32 sw_if_index;
12222   int sw_if_index_set;
12223   u32 ip4_table_index = ~0;
12224   u32 ip6_table_index = ~0;
12225   u32 other_table_index = ~0;
12226   u32 is_input = 1;
12227   int ret;
12228
12229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12230     {
12231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12232         sw_if_index_set = 1;
12233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12234         sw_if_index_set = 1;
12235       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12236         ;
12237       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12238         ;
12239       else if (unformat (i, "other-table %d", &other_table_index))
12240         ;
12241       else if (unformat (i, "is-input %d", &is_input))
12242         ;
12243       else
12244         {
12245           clib_warning ("parse error '%U'", format_unformat_error, i);
12246           return -99;
12247         }
12248     }
12249
12250   if (sw_if_index_set == 0)
12251     {
12252       errmsg ("missing interface name or sw_if_index");
12253       return -99;
12254     }
12255
12256
12257   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12258
12259   mp->sw_if_index = ntohl (sw_if_index);
12260   mp->ip4_table_index = ntohl (ip4_table_index);
12261   mp->ip6_table_index = ntohl (ip6_table_index);
12262   mp->other_table_index = ntohl (other_table_index);
12263   mp->is_input = (u8) is_input;
12264
12265   S (mp);
12266   W (ret);
12267   return ret;
12268 }
12269
12270 static int
12271 api_set_ipfix_exporter (vat_main_t * vam)
12272 {
12273   unformat_input_t *i = vam->input;
12274   vl_api_set_ipfix_exporter_t *mp;
12275   ip4_address_t collector_address;
12276   u8 collector_address_set = 0;
12277   u32 collector_port = ~0;
12278   ip4_address_t src_address;
12279   u8 src_address_set = 0;
12280   u32 vrf_id = ~0;
12281   u32 path_mtu = ~0;
12282   u32 template_interval = ~0;
12283   u8 udp_checksum = 0;
12284   int ret;
12285
12286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12287     {
12288       if (unformat (i, "collector_address %U", unformat_ip4_address,
12289                     &collector_address))
12290         collector_address_set = 1;
12291       else if (unformat (i, "collector_port %d", &collector_port))
12292         ;
12293       else if (unformat (i, "src_address %U", unformat_ip4_address,
12294                          &src_address))
12295         src_address_set = 1;
12296       else if (unformat (i, "vrf_id %d", &vrf_id))
12297         ;
12298       else if (unformat (i, "path_mtu %d", &path_mtu))
12299         ;
12300       else if (unformat (i, "template_interval %d", &template_interval))
12301         ;
12302       else if (unformat (i, "udp_checksum"))
12303         udp_checksum = 1;
12304       else
12305         break;
12306     }
12307
12308   if (collector_address_set == 0)
12309     {
12310       errmsg ("collector_address required");
12311       return -99;
12312     }
12313
12314   if (src_address_set == 0)
12315     {
12316       errmsg ("src_address required");
12317       return -99;
12318     }
12319
12320   M (SET_IPFIX_EXPORTER, mp);
12321
12322   memcpy (mp->collector_address, collector_address.data,
12323           sizeof (collector_address.data));
12324   mp->collector_port = htons ((u16) collector_port);
12325   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12326   mp->vrf_id = htonl (vrf_id);
12327   mp->path_mtu = htonl (path_mtu);
12328   mp->template_interval = htonl (template_interval);
12329   mp->udp_checksum = udp_checksum;
12330
12331   S (mp);
12332   W (ret);
12333   return ret;
12334 }
12335
12336 static int
12337 api_set_ipfix_classify_stream (vat_main_t * vam)
12338 {
12339   unformat_input_t *i = vam->input;
12340   vl_api_set_ipfix_classify_stream_t *mp;
12341   u32 domain_id = 0;
12342   u32 src_port = UDP_DST_PORT_ipfix;
12343   int ret;
12344
12345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12346     {
12347       if (unformat (i, "domain %d", &domain_id))
12348         ;
12349       else if (unformat (i, "src_port %d", &src_port))
12350         ;
12351       else
12352         {
12353           errmsg ("unknown input `%U'", format_unformat_error, i);
12354           return -99;
12355         }
12356     }
12357
12358   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12359
12360   mp->domain_id = htonl (domain_id);
12361   mp->src_port = htons ((u16) src_port);
12362
12363   S (mp);
12364   W (ret);
12365   return ret;
12366 }
12367
12368 static int
12369 api_ipfix_classify_table_add_del (vat_main_t * vam)
12370 {
12371   unformat_input_t *i = vam->input;
12372   vl_api_ipfix_classify_table_add_del_t *mp;
12373   int is_add = -1;
12374   u32 classify_table_index = ~0;
12375   u8 ip_version = 0;
12376   u8 transport_protocol = 255;
12377   int ret;
12378
12379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12380     {
12381       if (unformat (i, "add"))
12382         is_add = 1;
12383       else if (unformat (i, "del"))
12384         is_add = 0;
12385       else if (unformat (i, "table %d", &classify_table_index))
12386         ;
12387       else if (unformat (i, "ip4"))
12388         ip_version = 4;
12389       else if (unformat (i, "ip6"))
12390         ip_version = 6;
12391       else if (unformat (i, "tcp"))
12392         transport_protocol = 6;
12393       else if (unformat (i, "udp"))
12394         transport_protocol = 17;
12395       else
12396         {
12397           errmsg ("unknown input `%U'", format_unformat_error, i);
12398           return -99;
12399         }
12400     }
12401
12402   if (is_add == -1)
12403     {
12404       errmsg ("expecting: add|del");
12405       return -99;
12406     }
12407   if (classify_table_index == ~0)
12408     {
12409       errmsg ("classifier table not specified");
12410       return -99;
12411     }
12412   if (ip_version == 0)
12413     {
12414       errmsg ("IP version not specified");
12415       return -99;
12416     }
12417
12418   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12419
12420   mp->is_add = is_add;
12421   mp->table_id = htonl (classify_table_index);
12422   mp->ip_version = ip_version;
12423   mp->transport_protocol = transport_protocol;
12424
12425   S (mp);
12426   W (ret);
12427   return ret;
12428 }
12429
12430 static int
12431 api_get_node_index (vat_main_t * vam)
12432 {
12433   unformat_input_t *i = vam->input;
12434   vl_api_get_node_index_t *mp;
12435   u8 *name = 0;
12436   int ret;
12437
12438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12439     {
12440       if (unformat (i, "node %s", &name))
12441         ;
12442       else
12443         break;
12444     }
12445   if (name == 0)
12446     {
12447       errmsg ("node name required");
12448       return -99;
12449     }
12450   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12451     {
12452       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12453       return -99;
12454     }
12455
12456   M (GET_NODE_INDEX, mp);
12457   clib_memcpy (mp->node_name, name, vec_len (name));
12458   vec_free (name);
12459
12460   S (mp);
12461   W (ret);
12462   return ret;
12463 }
12464
12465 static int
12466 api_get_next_index (vat_main_t * vam)
12467 {
12468   unformat_input_t *i = vam->input;
12469   vl_api_get_next_index_t *mp;
12470   u8 *node_name = 0, *next_node_name = 0;
12471   int ret;
12472
12473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12474     {
12475       if (unformat (i, "node-name %s", &node_name))
12476         ;
12477       else if (unformat (i, "next-node-name %s", &next_node_name))
12478         break;
12479     }
12480
12481   if (node_name == 0)
12482     {
12483       errmsg ("node name required");
12484       return -99;
12485     }
12486   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12487     {
12488       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12489       return -99;
12490     }
12491
12492   if (next_node_name == 0)
12493     {
12494       errmsg ("next node name required");
12495       return -99;
12496     }
12497   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12498     {
12499       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12500       return -99;
12501     }
12502
12503   M (GET_NEXT_INDEX, mp);
12504   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12505   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12506   vec_free (node_name);
12507   vec_free (next_node_name);
12508
12509   S (mp);
12510   W (ret);
12511   return ret;
12512 }
12513
12514 static int
12515 api_add_node_next (vat_main_t * vam)
12516 {
12517   unformat_input_t *i = vam->input;
12518   vl_api_add_node_next_t *mp;
12519   u8 *name = 0;
12520   u8 *next = 0;
12521   int ret;
12522
12523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12524     {
12525       if (unformat (i, "node %s", &name))
12526         ;
12527       else if (unformat (i, "next %s", &next))
12528         ;
12529       else
12530         break;
12531     }
12532   if (name == 0)
12533     {
12534       errmsg ("node name required");
12535       return -99;
12536     }
12537   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12538     {
12539       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12540       return -99;
12541     }
12542   if (next == 0)
12543     {
12544       errmsg ("next node required");
12545       return -99;
12546     }
12547   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12548     {
12549       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12550       return -99;
12551     }
12552
12553   M (ADD_NODE_NEXT, mp);
12554   clib_memcpy (mp->node_name, name, vec_len (name));
12555   clib_memcpy (mp->next_name, next, vec_len (next));
12556   vec_free (name);
12557   vec_free (next);
12558
12559   S (mp);
12560   W (ret);
12561   return ret;
12562 }
12563
12564 static int
12565 api_l2tpv3_create_tunnel (vat_main_t * vam)
12566 {
12567   unformat_input_t *i = vam->input;
12568   ip6_address_t client_address, our_address;
12569   int client_address_set = 0;
12570   int our_address_set = 0;
12571   u32 local_session_id = 0;
12572   u32 remote_session_id = 0;
12573   u64 local_cookie = 0;
12574   u64 remote_cookie = 0;
12575   u8 l2_sublayer_present = 0;
12576   vl_api_l2tpv3_create_tunnel_t *mp;
12577   int ret;
12578
12579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12580     {
12581       if (unformat (i, "client_address %U", unformat_ip6_address,
12582                     &client_address))
12583         client_address_set = 1;
12584       else if (unformat (i, "our_address %U", unformat_ip6_address,
12585                          &our_address))
12586         our_address_set = 1;
12587       else if (unformat (i, "local_session_id %d", &local_session_id))
12588         ;
12589       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12590         ;
12591       else if (unformat (i, "local_cookie %lld", &local_cookie))
12592         ;
12593       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12594         ;
12595       else if (unformat (i, "l2-sublayer-present"))
12596         l2_sublayer_present = 1;
12597       else
12598         break;
12599     }
12600
12601   if (client_address_set == 0)
12602     {
12603       errmsg ("client_address required");
12604       return -99;
12605     }
12606
12607   if (our_address_set == 0)
12608     {
12609       errmsg ("our_address required");
12610       return -99;
12611     }
12612
12613   M (L2TPV3_CREATE_TUNNEL, mp);
12614
12615   clib_memcpy (mp->client_address, client_address.as_u8,
12616                sizeof (mp->client_address));
12617
12618   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12619
12620   mp->local_session_id = ntohl (local_session_id);
12621   mp->remote_session_id = ntohl (remote_session_id);
12622   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12623   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12624   mp->l2_sublayer_present = l2_sublayer_present;
12625   mp->is_ipv6 = 1;
12626
12627   S (mp);
12628   W (ret);
12629   return ret;
12630 }
12631
12632 static int
12633 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12634 {
12635   unformat_input_t *i = vam->input;
12636   u32 sw_if_index;
12637   u8 sw_if_index_set = 0;
12638   u64 new_local_cookie = 0;
12639   u64 new_remote_cookie = 0;
12640   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12641   int ret;
12642
12643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12644     {
12645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12646         sw_if_index_set = 1;
12647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12648         sw_if_index_set = 1;
12649       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12650         ;
12651       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12652         ;
12653       else
12654         break;
12655     }
12656
12657   if (sw_if_index_set == 0)
12658     {
12659       errmsg ("missing interface name or sw_if_index");
12660       return -99;
12661     }
12662
12663   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12664
12665   mp->sw_if_index = ntohl (sw_if_index);
12666   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12667   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12668
12669   S (mp);
12670   W (ret);
12671   return ret;
12672 }
12673
12674 static int
12675 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12676 {
12677   unformat_input_t *i = vam->input;
12678   vl_api_l2tpv3_interface_enable_disable_t *mp;
12679   u32 sw_if_index;
12680   u8 sw_if_index_set = 0;
12681   u8 enable_disable = 1;
12682   int ret;
12683
12684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12685     {
12686       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12687         sw_if_index_set = 1;
12688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12689         sw_if_index_set = 1;
12690       else if (unformat (i, "enable"))
12691         enable_disable = 1;
12692       else if (unformat (i, "disable"))
12693         enable_disable = 0;
12694       else
12695         break;
12696     }
12697
12698   if (sw_if_index_set == 0)
12699     {
12700       errmsg ("missing interface name or sw_if_index");
12701       return -99;
12702     }
12703
12704   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12705
12706   mp->sw_if_index = ntohl (sw_if_index);
12707   mp->enable_disable = enable_disable;
12708
12709   S (mp);
12710   W (ret);
12711   return ret;
12712 }
12713
12714 static int
12715 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12716 {
12717   unformat_input_t *i = vam->input;
12718   vl_api_l2tpv3_set_lookup_key_t *mp;
12719   u8 key = ~0;
12720   int ret;
12721
12722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12723     {
12724       if (unformat (i, "lookup_v6_src"))
12725         key = L2T_LOOKUP_SRC_ADDRESS;
12726       else if (unformat (i, "lookup_v6_dst"))
12727         key = L2T_LOOKUP_DST_ADDRESS;
12728       else if (unformat (i, "lookup_session_id"))
12729         key = L2T_LOOKUP_SESSION_ID;
12730       else
12731         break;
12732     }
12733
12734   if (key == (u8) ~ 0)
12735     {
12736       errmsg ("l2tp session lookup key unset");
12737       return -99;
12738     }
12739
12740   M (L2TPV3_SET_LOOKUP_KEY, mp);
12741
12742   mp->key = key;
12743
12744   S (mp);
12745   W (ret);
12746   return ret;
12747 }
12748
12749 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12750   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12751 {
12752   vat_main_t *vam = &vat_main;
12753
12754   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12755          format_ip6_address, mp->our_address,
12756          format_ip6_address, mp->client_address,
12757          clib_net_to_host_u32 (mp->sw_if_index));
12758
12759   print (vam->ofp,
12760          "   local cookies %016llx %016llx remote cookie %016llx",
12761          clib_net_to_host_u64 (mp->local_cookie[0]),
12762          clib_net_to_host_u64 (mp->local_cookie[1]),
12763          clib_net_to_host_u64 (mp->remote_cookie));
12764
12765   print (vam->ofp, "   local session-id %d remote session-id %d",
12766          clib_net_to_host_u32 (mp->local_session_id),
12767          clib_net_to_host_u32 (mp->remote_session_id));
12768
12769   print (vam->ofp, "   l2 specific sublayer %s\n",
12770          mp->l2_sublayer_present ? "preset" : "absent");
12771
12772 }
12773
12774 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12775   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12776 {
12777   vat_main_t *vam = &vat_main;
12778   vat_json_node_t *node = NULL;
12779   struct in6_addr addr;
12780
12781   if (VAT_JSON_ARRAY != vam->json_tree.type)
12782     {
12783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12784       vat_json_init_array (&vam->json_tree);
12785     }
12786   node = vat_json_array_add (&vam->json_tree);
12787
12788   vat_json_init_object (node);
12789
12790   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12791   vat_json_object_add_ip6 (node, "our_address", addr);
12792   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12793   vat_json_object_add_ip6 (node, "client_address", addr);
12794
12795   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12796   vat_json_init_array (lc);
12797   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12798   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12799   vat_json_object_add_uint (node, "remote_cookie",
12800                             clib_net_to_host_u64 (mp->remote_cookie));
12801
12802   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12803   vat_json_object_add_uint (node, "local_session_id",
12804                             clib_net_to_host_u32 (mp->local_session_id));
12805   vat_json_object_add_uint (node, "remote_session_id",
12806                             clib_net_to_host_u32 (mp->remote_session_id));
12807   vat_json_object_add_string_copy (node, "l2_sublayer",
12808                                    mp->l2_sublayer_present ? (u8 *) "present"
12809                                    : (u8 *) "absent");
12810 }
12811
12812 static int
12813 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12814 {
12815   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12816   vl_api_control_ping_t *mp_ping;
12817   int ret;
12818
12819   /* Get list of l2tpv3-tunnel interfaces */
12820   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12821   S (mp);
12822
12823   /* Use a control ping for synchronization */
12824   MPING (CONTROL_PING, mp_ping);
12825   S (mp_ping);
12826
12827   W (ret);
12828   return ret;
12829 }
12830
12831
12832 static void vl_api_sw_interface_tap_details_t_handler
12833   (vl_api_sw_interface_tap_details_t * mp)
12834 {
12835   vat_main_t *vam = &vat_main;
12836
12837   print (vam->ofp, "%-16s %d",
12838          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12839 }
12840
12841 static void vl_api_sw_interface_tap_details_t_handler_json
12842   (vl_api_sw_interface_tap_details_t * mp)
12843 {
12844   vat_main_t *vam = &vat_main;
12845   vat_json_node_t *node = NULL;
12846
12847   if (VAT_JSON_ARRAY != vam->json_tree.type)
12848     {
12849       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12850       vat_json_init_array (&vam->json_tree);
12851     }
12852   node = vat_json_array_add (&vam->json_tree);
12853
12854   vat_json_init_object (node);
12855   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12856   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12857 }
12858
12859 static int
12860 api_sw_interface_tap_dump (vat_main_t * vam)
12861 {
12862   vl_api_sw_interface_tap_dump_t *mp;
12863   vl_api_control_ping_t *mp_ping;
12864   int ret;
12865
12866   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12867   /* Get list of tap interfaces */
12868   M (SW_INTERFACE_TAP_DUMP, mp);
12869   S (mp);
12870
12871   /* Use a control ping for synchronization */
12872   MPING (CONTROL_PING, mp_ping);
12873   S (mp_ping);
12874
12875   W (ret);
12876   return ret;
12877 }
12878
12879 static void vl_api_sw_interface_tap_v2_details_t_handler
12880   (vl_api_sw_interface_tap_v2_details_t * mp)
12881 {
12882   vat_main_t *vam = &vat_main;
12883
12884   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
12885                     mp->host_ip4_prefix_len);
12886   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
12887                     mp->host_ip6_prefix_len);
12888
12889   print (vam->ofp,
12890          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
12891          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
12892          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
12893          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
12894          mp->host_bridge, ip4, ip6);
12895
12896   vec_free (ip4);
12897   vec_free (ip6);
12898 }
12899
12900 static void vl_api_sw_interface_tap_v2_details_t_handler_json
12901   (vl_api_sw_interface_tap_v2_details_t * mp)
12902 {
12903   vat_main_t *vam = &vat_main;
12904   vat_json_node_t *node = NULL;
12905
12906   if (VAT_JSON_ARRAY != vam->json_tree.type)
12907     {
12908       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12909       vat_json_init_array (&vam->json_tree);
12910     }
12911   node = vat_json_array_add (&vam->json_tree);
12912
12913   vat_json_init_object (node);
12914   vat_json_object_add_uint (node, "id", ntohl (mp->id));
12915   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12916   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12917   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
12918   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
12919   vat_json_object_add_string_copy (node, "host_mac_addr",
12920                                    format (0, "%U", format_ethernet_address,
12921                                            &mp->host_mac_addr));
12922   vat_json_object_add_string_copy (node, "host_namespace",
12923                                    mp->host_namespace);
12924   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
12925   vat_json_object_add_string_copy (node, "host_ip4_addr",
12926                                    format (0, "%U/%d", format_ip4_address,
12927                                            mp->host_ip4_addr,
12928                                            mp->host_ip4_prefix_len));
12929   vat_json_object_add_string_copy (node, "host_ip6_addr",
12930                                    format (0, "%U/%d", format_ip6_address,
12931                                            mp->host_ip6_addr,
12932                                            mp->host_ip6_prefix_len));
12933
12934 }
12935
12936 static int
12937 api_sw_interface_tap_v2_dump (vat_main_t * vam)
12938 {
12939   vl_api_sw_interface_tap_v2_dump_t *mp;
12940   vl_api_control_ping_t *mp_ping;
12941   int ret;
12942
12943   print (vam->ofp,
12944          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
12945          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
12946          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
12947          "host_ip6_addr");
12948
12949   /* Get list of tap interfaces */
12950   M (SW_INTERFACE_TAP_V2_DUMP, mp);
12951   S (mp);
12952
12953   /* Use a control ping for synchronization */
12954   MPING (CONTROL_PING, mp_ping);
12955   S (mp_ping);
12956
12957   W (ret);
12958   return ret;
12959 }
12960
12961 static int
12962 api_vxlan_offload_rx (vat_main_t * vam)
12963 {
12964   unformat_input_t *line_input = vam->input;
12965   vl_api_vxlan_offload_rx_t *mp;
12966   u32 hw_if_index = ~0, rx_if_index = ~0;
12967   u8 is_add = 1;
12968   int ret;
12969
12970   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12971     {
12972       if (unformat (line_input, "del"))
12973         is_add = 0;
12974       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12975                          &hw_if_index))
12976         ;
12977       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12978         ;
12979       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12980                          &rx_if_index))
12981         ;
12982       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12983         ;
12984       else
12985         {
12986           errmsg ("parse error '%U'", format_unformat_error, line_input);
12987           return -99;
12988         }
12989     }
12990
12991   if (hw_if_index == ~0)
12992     {
12993       errmsg ("no hw interface");
12994       return -99;
12995     }
12996
12997   if (rx_if_index == ~0)
12998     {
12999       errmsg ("no rx tunnel");
13000       return -99;
13001     }
13002
13003   M (VXLAN_OFFLOAD_RX, mp);
13004
13005   mp->hw_if_index = ntohl (hw_if_index);
13006   mp->sw_if_index = ntohl (rx_if_index);
13007   mp->enable = is_add;
13008
13009   S (mp);
13010   W (ret);
13011   return ret;
13012 }
13013
13014 static uword unformat_vxlan_decap_next
13015   (unformat_input_t * input, va_list * args)
13016 {
13017   u32 *result = va_arg (*args, u32 *);
13018   u32 tmp;
13019
13020   if (unformat (input, "l2"))
13021     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13022   else if (unformat (input, "%d", &tmp))
13023     *result = tmp;
13024   else
13025     return 0;
13026   return 1;
13027 }
13028
13029 static int
13030 api_vxlan_add_del_tunnel (vat_main_t * vam)
13031 {
13032   unformat_input_t *line_input = vam->input;
13033   vl_api_vxlan_add_del_tunnel_t *mp;
13034   ip46_address_t src, dst;
13035   u8 is_add = 1;
13036   u8 ipv4_set = 0, ipv6_set = 0;
13037   u8 src_set = 0;
13038   u8 dst_set = 0;
13039   u8 grp_set = 0;
13040   u32 instance = ~0;
13041   u32 mcast_sw_if_index = ~0;
13042   u32 encap_vrf_id = 0;
13043   u32 decap_next_index = ~0;
13044   u32 vni = 0;
13045   int ret;
13046
13047   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13048   memset (&src, 0, sizeof src);
13049   memset (&dst, 0, sizeof dst);
13050
13051   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13052     {
13053       if (unformat (line_input, "del"))
13054         is_add = 0;
13055       else if (unformat (line_input, "instance %d", &instance))
13056         ;
13057       else
13058         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13059         {
13060           ipv4_set = 1;
13061           src_set = 1;
13062         }
13063       else
13064         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13065         {
13066           ipv4_set = 1;
13067           dst_set = 1;
13068         }
13069       else
13070         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13071         {
13072           ipv6_set = 1;
13073           src_set = 1;
13074         }
13075       else
13076         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13077         {
13078           ipv6_set = 1;
13079           dst_set = 1;
13080         }
13081       else if (unformat (line_input, "group %U %U",
13082                          unformat_ip4_address, &dst.ip4,
13083                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13084         {
13085           grp_set = dst_set = 1;
13086           ipv4_set = 1;
13087         }
13088       else if (unformat (line_input, "group %U",
13089                          unformat_ip4_address, &dst.ip4))
13090         {
13091           grp_set = dst_set = 1;
13092           ipv4_set = 1;
13093         }
13094       else if (unformat (line_input, "group %U %U",
13095                          unformat_ip6_address, &dst.ip6,
13096                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13097         {
13098           grp_set = dst_set = 1;
13099           ipv6_set = 1;
13100         }
13101       else if (unformat (line_input, "group %U",
13102                          unformat_ip6_address, &dst.ip6))
13103         {
13104           grp_set = dst_set = 1;
13105           ipv6_set = 1;
13106         }
13107       else
13108         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13109         ;
13110       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13111         ;
13112       else if (unformat (line_input, "decap-next %U",
13113                          unformat_vxlan_decap_next, &decap_next_index))
13114         ;
13115       else if (unformat (line_input, "vni %d", &vni))
13116         ;
13117       else
13118         {
13119           errmsg ("parse error '%U'", format_unformat_error, line_input);
13120           return -99;
13121         }
13122     }
13123
13124   if (src_set == 0)
13125     {
13126       errmsg ("tunnel src address not specified");
13127       return -99;
13128     }
13129   if (dst_set == 0)
13130     {
13131       errmsg ("tunnel dst address not specified");
13132       return -99;
13133     }
13134
13135   if (grp_set && !ip46_address_is_multicast (&dst))
13136     {
13137       errmsg ("tunnel group address not multicast");
13138       return -99;
13139     }
13140   if (grp_set && mcast_sw_if_index == ~0)
13141     {
13142       errmsg ("tunnel nonexistent multicast device");
13143       return -99;
13144     }
13145   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13146     {
13147       errmsg ("tunnel dst address must be unicast");
13148       return -99;
13149     }
13150
13151
13152   if (ipv4_set && ipv6_set)
13153     {
13154       errmsg ("both IPv4 and IPv6 addresses specified");
13155       return -99;
13156     }
13157
13158   if ((vni == 0) || (vni >> 24))
13159     {
13160       errmsg ("vni not specified or out of range");
13161       return -99;
13162     }
13163
13164   M (VXLAN_ADD_DEL_TUNNEL, mp);
13165
13166   if (ipv6_set)
13167     {
13168       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13169       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13170     }
13171   else
13172     {
13173       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13174       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13175     }
13176
13177   mp->instance = htonl (instance);
13178   mp->encap_vrf_id = ntohl (encap_vrf_id);
13179   mp->decap_next_index = ntohl (decap_next_index);
13180   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13181   mp->vni = ntohl (vni);
13182   mp->is_add = is_add;
13183   mp->is_ipv6 = ipv6_set;
13184
13185   S (mp);
13186   W (ret);
13187   return ret;
13188 }
13189
13190 static void vl_api_vxlan_tunnel_details_t_handler
13191   (vl_api_vxlan_tunnel_details_t * mp)
13192 {
13193   vat_main_t *vam = &vat_main;
13194   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13195   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13196
13197   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13198          ntohl (mp->sw_if_index),
13199          ntohl (mp->instance),
13200          format_ip46_address, &src, IP46_TYPE_ANY,
13201          format_ip46_address, &dst, IP46_TYPE_ANY,
13202          ntohl (mp->encap_vrf_id),
13203          ntohl (mp->decap_next_index), ntohl (mp->vni),
13204          ntohl (mp->mcast_sw_if_index));
13205 }
13206
13207 static void vl_api_vxlan_tunnel_details_t_handler_json
13208   (vl_api_vxlan_tunnel_details_t * mp)
13209 {
13210   vat_main_t *vam = &vat_main;
13211   vat_json_node_t *node = NULL;
13212
13213   if (VAT_JSON_ARRAY != vam->json_tree.type)
13214     {
13215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13216       vat_json_init_array (&vam->json_tree);
13217     }
13218   node = vat_json_array_add (&vam->json_tree);
13219
13220   vat_json_init_object (node);
13221   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13222
13223   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13224
13225   if (mp->is_ipv6)
13226     {
13227       struct in6_addr ip6;
13228
13229       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13230       vat_json_object_add_ip6 (node, "src_address", ip6);
13231       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13232       vat_json_object_add_ip6 (node, "dst_address", ip6);
13233     }
13234   else
13235     {
13236       struct in_addr ip4;
13237
13238       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13239       vat_json_object_add_ip4 (node, "src_address", ip4);
13240       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13241       vat_json_object_add_ip4 (node, "dst_address", ip4);
13242     }
13243   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13244   vat_json_object_add_uint (node, "decap_next_index",
13245                             ntohl (mp->decap_next_index));
13246   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13247   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13248   vat_json_object_add_uint (node, "mcast_sw_if_index",
13249                             ntohl (mp->mcast_sw_if_index));
13250 }
13251
13252 static int
13253 api_vxlan_tunnel_dump (vat_main_t * vam)
13254 {
13255   unformat_input_t *i = vam->input;
13256   vl_api_vxlan_tunnel_dump_t *mp;
13257   vl_api_control_ping_t *mp_ping;
13258   u32 sw_if_index;
13259   u8 sw_if_index_set = 0;
13260   int ret;
13261
13262   /* Parse args required to build the message */
13263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13264     {
13265       if (unformat (i, "sw_if_index %d", &sw_if_index))
13266         sw_if_index_set = 1;
13267       else
13268         break;
13269     }
13270
13271   if (sw_if_index_set == 0)
13272     {
13273       sw_if_index = ~0;
13274     }
13275
13276   if (!vam->json_output)
13277     {
13278       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13279              "sw_if_index", "instance", "src_address", "dst_address",
13280              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13281     }
13282
13283   /* Get list of vxlan-tunnel interfaces */
13284   M (VXLAN_TUNNEL_DUMP, mp);
13285
13286   mp->sw_if_index = htonl (sw_if_index);
13287
13288   S (mp);
13289
13290   /* Use a control ping for synchronization */
13291   MPING (CONTROL_PING, mp_ping);
13292   S (mp_ping);
13293
13294   W (ret);
13295   return ret;
13296 }
13297
13298 static uword unformat_geneve_decap_next
13299   (unformat_input_t * input, va_list * args)
13300 {
13301   u32 *result = va_arg (*args, u32 *);
13302   u32 tmp;
13303
13304   if (unformat (input, "l2"))
13305     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13306   else if (unformat (input, "%d", &tmp))
13307     *result = tmp;
13308   else
13309     return 0;
13310   return 1;
13311 }
13312
13313 static int
13314 api_geneve_add_del_tunnel (vat_main_t * vam)
13315 {
13316   unformat_input_t *line_input = vam->input;
13317   vl_api_geneve_add_del_tunnel_t *mp;
13318   ip46_address_t src, dst;
13319   u8 is_add = 1;
13320   u8 ipv4_set = 0, ipv6_set = 0;
13321   u8 src_set = 0;
13322   u8 dst_set = 0;
13323   u8 grp_set = 0;
13324   u32 mcast_sw_if_index = ~0;
13325   u32 encap_vrf_id = 0;
13326   u32 decap_next_index = ~0;
13327   u32 vni = 0;
13328   int ret;
13329
13330   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13331   memset (&src, 0, sizeof src);
13332   memset (&dst, 0, sizeof dst);
13333
13334   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13335     {
13336       if (unformat (line_input, "del"))
13337         is_add = 0;
13338       else
13339         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13340         {
13341           ipv4_set = 1;
13342           src_set = 1;
13343         }
13344       else
13345         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13346         {
13347           ipv4_set = 1;
13348           dst_set = 1;
13349         }
13350       else
13351         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13352         {
13353           ipv6_set = 1;
13354           src_set = 1;
13355         }
13356       else
13357         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13358         {
13359           ipv6_set = 1;
13360           dst_set = 1;
13361         }
13362       else if (unformat (line_input, "group %U %U",
13363                          unformat_ip4_address, &dst.ip4,
13364                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13365         {
13366           grp_set = dst_set = 1;
13367           ipv4_set = 1;
13368         }
13369       else if (unformat (line_input, "group %U",
13370                          unformat_ip4_address, &dst.ip4))
13371         {
13372           grp_set = dst_set = 1;
13373           ipv4_set = 1;
13374         }
13375       else if (unformat (line_input, "group %U %U",
13376                          unformat_ip6_address, &dst.ip6,
13377                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13378         {
13379           grp_set = dst_set = 1;
13380           ipv6_set = 1;
13381         }
13382       else if (unformat (line_input, "group %U",
13383                          unformat_ip6_address, &dst.ip6))
13384         {
13385           grp_set = dst_set = 1;
13386           ipv6_set = 1;
13387         }
13388       else
13389         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13390         ;
13391       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13392         ;
13393       else if (unformat (line_input, "decap-next %U",
13394                          unformat_geneve_decap_next, &decap_next_index))
13395         ;
13396       else if (unformat (line_input, "vni %d", &vni))
13397         ;
13398       else
13399         {
13400           errmsg ("parse error '%U'", format_unformat_error, line_input);
13401           return -99;
13402         }
13403     }
13404
13405   if (src_set == 0)
13406     {
13407       errmsg ("tunnel src address not specified");
13408       return -99;
13409     }
13410   if (dst_set == 0)
13411     {
13412       errmsg ("tunnel dst address not specified");
13413       return -99;
13414     }
13415
13416   if (grp_set && !ip46_address_is_multicast (&dst))
13417     {
13418       errmsg ("tunnel group address not multicast");
13419       return -99;
13420     }
13421   if (grp_set && mcast_sw_if_index == ~0)
13422     {
13423       errmsg ("tunnel nonexistent multicast device");
13424       return -99;
13425     }
13426   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13427     {
13428       errmsg ("tunnel dst address must be unicast");
13429       return -99;
13430     }
13431
13432
13433   if (ipv4_set && ipv6_set)
13434     {
13435       errmsg ("both IPv4 and IPv6 addresses specified");
13436       return -99;
13437     }
13438
13439   if ((vni == 0) || (vni >> 24))
13440     {
13441       errmsg ("vni not specified or out of range");
13442       return -99;
13443     }
13444
13445   M (GENEVE_ADD_DEL_TUNNEL, mp);
13446
13447   if (ipv6_set)
13448     {
13449       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13450       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13451     }
13452   else
13453     {
13454       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13455       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13456     }
13457   mp->encap_vrf_id = ntohl (encap_vrf_id);
13458   mp->decap_next_index = ntohl (decap_next_index);
13459   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13460   mp->vni = ntohl (vni);
13461   mp->is_add = is_add;
13462   mp->is_ipv6 = ipv6_set;
13463
13464   S (mp);
13465   W (ret);
13466   return ret;
13467 }
13468
13469 static void vl_api_geneve_tunnel_details_t_handler
13470   (vl_api_geneve_tunnel_details_t * mp)
13471 {
13472   vat_main_t *vam = &vat_main;
13473   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13474   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13475
13476   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13477          ntohl (mp->sw_if_index),
13478          format_ip46_address, &src, IP46_TYPE_ANY,
13479          format_ip46_address, &dst, IP46_TYPE_ANY,
13480          ntohl (mp->encap_vrf_id),
13481          ntohl (mp->decap_next_index), ntohl (mp->vni),
13482          ntohl (mp->mcast_sw_if_index));
13483 }
13484
13485 static void vl_api_geneve_tunnel_details_t_handler_json
13486   (vl_api_geneve_tunnel_details_t * mp)
13487 {
13488   vat_main_t *vam = &vat_main;
13489   vat_json_node_t *node = NULL;
13490
13491   if (VAT_JSON_ARRAY != vam->json_tree.type)
13492     {
13493       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13494       vat_json_init_array (&vam->json_tree);
13495     }
13496   node = vat_json_array_add (&vam->json_tree);
13497
13498   vat_json_init_object (node);
13499   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13500   if (mp->is_ipv6)
13501     {
13502       struct in6_addr ip6;
13503
13504       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13505       vat_json_object_add_ip6 (node, "src_address", ip6);
13506       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13507       vat_json_object_add_ip6 (node, "dst_address", ip6);
13508     }
13509   else
13510     {
13511       struct in_addr ip4;
13512
13513       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13514       vat_json_object_add_ip4 (node, "src_address", ip4);
13515       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13516       vat_json_object_add_ip4 (node, "dst_address", ip4);
13517     }
13518   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13519   vat_json_object_add_uint (node, "decap_next_index",
13520                             ntohl (mp->decap_next_index));
13521   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13522   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13523   vat_json_object_add_uint (node, "mcast_sw_if_index",
13524                             ntohl (mp->mcast_sw_if_index));
13525 }
13526
13527 static int
13528 api_geneve_tunnel_dump (vat_main_t * vam)
13529 {
13530   unformat_input_t *i = vam->input;
13531   vl_api_geneve_tunnel_dump_t *mp;
13532   vl_api_control_ping_t *mp_ping;
13533   u32 sw_if_index;
13534   u8 sw_if_index_set = 0;
13535   int ret;
13536
13537   /* Parse args required to build the message */
13538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13539     {
13540       if (unformat (i, "sw_if_index %d", &sw_if_index))
13541         sw_if_index_set = 1;
13542       else
13543         break;
13544     }
13545
13546   if (sw_if_index_set == 0)
13547     {
13548       sw_if_index = ~0;
13549     }
13550
13551   if (!vam->json_output)
13552     {
13553       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13554              "sw_if_index", "local_address", "remote_address",
13555              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13556     }
13557
13558   /* Get list of geneve-tunnel interfaces */
13559   M (GENEVE_TUNNEL_DUMP, mp);
13560
13561   mp->sw_if_index = htonl (sw_if_index);
13562
13563   S (mp);
13564
13565   /* Use a control ping for synchronization */
13566   M (CONTROL_PING, mp_ping);
13567   S (mp_ping);
13568
13569   W (ret);
13570   return ret;
13571 }
13572
13573 static int
13574 api_gre_add_del_tunnel (vat_main_t * vam)
13575 {
13576   unformat_input_t *line_input = vam->input;
13577   vl_api_gre_add_del_tunnel_t *mp;
13578   ip4_address_t src4, dst4;
13579   ip6_address_t src6, dst6;
13580   u8 is_add = 1;
13581   u8 ipv4_set = 0;
13582   u8 ipv6_set = 0;
13583   u8 t_type = GRE_TUNNEL_TYPE_L3;
13584   u8 src_set = 0;
13585   u8 dst_set = 0;
13586   u32 outer_fib_id = 0;
13587   u32 session_id = 0;
13588   u32 instance = ~0;
13589   int ret;
13590
13591   memset (&src4, 0, sizeof src4);
13592   memset (&dst4, 0, sizeof dst4);
13593   memset (&src6, 0, sizeof src6);
13594   memset (&dst6, 0, sizeof dst6);
13595
13596   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13597     {
13598       if (unformat (line_input, "del"))
13599         is_add = 0;
13600       else if (unformat (line_input, "instance %d", &instance))
13601         ;
13602       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13603         {
13604           src_set = 1;
13605           ipv4_set = 1;
13606         }
13607       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13608         {
13609           dst_set = 1;
13610           ipv4_set = 1;
13611         }
13612       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13613         {
13614           src_set = 1;
13615           ipv6_set = 1;
13616         }
13617       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13618         {
13619           dst_set = 1;
13620           ipv6_set = 1;
13621         }
13622       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13623         ;
13624       else if (unformat (line_input, "teb"))
13625         t_type = GRE_TUNNEL_TYPE_TEB;
13626       else if (unformat (line_input, "erspan %d", &session_id))
13627         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13628       else
13629         {
13630           errmsg ("parse error '%U'", format_unformat_error, line_input);
13631           return -99;
13632         }
13633     }
13634
13635   if (src_set == 0)
13636     {
13637       errmsg ("tunnel src address not specified");
13638       return -99;
13639     }
13640   if (dst_set == 0)
13641     {
13642       errmsg ("tunnel dst address not specified");
13643       return -99;
13644     }
13645   if (ipv4_set && ipv6_set)
13646     {
13647       errmsg ("both IPv4 and IPv6 addresses specified");
13648       return -99;
13649     }
13650
13651
13652   M (GRE_ADD_DEL_TUNNEL, mp);
13653
13654   if (ipv4_set)
13655     {
13656       clib_memcpy (&mp->src_address, &src4, 4);
13657       clib_memcpy (&mp->dst_address, &dst4, 4);
13658     }
13659   else
13660     {
13661       clib_memcpy (&mp->src_address, &src6, 16);
13662       clib_memcpy (&mp->dst_address, &dst6, 16);
13663     }
13664   mp->instance = htonl (instance);
13665   mp->outer_fib_id = htonl (outer_fib_id);
13666   mp->is_add = is_add;
13667   mp->session_id = htons ((u16) session_id);
13668   mp->tunnel_type = t_type;
13669   mp->is_ipv6 = ipv6_set;
13670
13671   S (mp);
13672   W (ret);
13673   return ret;
13674 }
13675
13676 static void vl_api_gre_tunnel_details_t_handler
13677   (vl_api_gre_tunnel_details_t * mp)
13678 {
13679   vat_main_t *vam = &vat_main;
13680   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13681   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13682
13683   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13684          ntohl (mp->sw_if_index),
13685          ntohl (mp->instance),
13686          format_ip46_address, &src, IP46_TYPE_ANY,
13687          format_ip46_address, &dst, IP46_TYPE_ANY,
13688          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13689 }
13690
13691 static void vl_api_gre_tunnel_details_t_handler_json
13692   (vl_api_gre_tunnel_details_t * mp)
13693 {
13694   vat_main_t *vam = &vat_main;
13695   vat_json_node_t *node = NULL;
13696   struct in_addr ip4;
13697   struct in6_addr ip6;
13698
13699   if (VAT_JSON_ARRAY != vam->json_tree.type)
13700     {
13701       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13702       vat_json_init_array (&vam->json_tree);
13703     }
13704   node = vat_json_array_add (&vam->json_tree);
13705
13706   vat_json_init_object (node);
13707   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13708   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13709   if (!mp->is_ipv6)
13710     {
13711       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13712       vat_json_object_add_ip4 (node, "src_address", ip4);
13713       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13714       vat_json_object_add_ip4 (node, "dst_address", ip4);
13715     }
13716   else
13717     {
13718       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13719       vat_json_object_add_ip6 (node, "src_address", ip6);
13720       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13721       vat_json_object_add_ip6 (node, "dst_address", ip6);
13722     }
13723   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13724   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13725   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13726   vat_json_object_add_uint (node, "session_id", mp->session_id);
13727 }
13728
13729 static int
13730 api_gre_tunnel_dump (vat_main_t * vam)
13731 {
13732   unformat_input_t *i = vam->input;
13733   vl_api_gre_tunnel_dump_t *mp;
13734   vl_api_control_ping_t *mp_ping;
13735   u32 sw_if_index;
13736   u8 sw_if_index_set = 0;
13737   int ret;
13738
13739   /* Parse args required to build the message */
13740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13741     {
13742       if (unformat (i, "sw_if_index %d", &sw_if_index))
13743         sw_if_index_set = 1;
13744       else
13745         break;
13746     }
13747
13748   if (sw_if_index_set == 0)
13749     {
13750       sw_if_index = ~0;
13751     }
13752
13753   if (!vam->json_output)
13754     {
13755       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13756              "sw_if_index", "instance", "src_address", "dst_address",
13757              "tunnel_type", "outer_fib_id", "session_id");
13758     }
13759
13760   /* Get list of gre-tunnel interfaces */
13761   M (GRE_TUNNEL_DUMP, mp);
13762
13763   mp->sw_if_index = htonl (sw_if_index);
13764
13765   S (mp);
13766
13767   /* Use a control ping for synchronization */
13768   MPING (CONTROL_PING, mp_ping);
13769   S (mp_ping);
13770
13771   W (ret);
13772   return ret;
13773 }
13774
13775 static int
13776 api_l2_fib_clear_table (vat_main_t * vam)
13777 {
13778 //  unformat_input_t * i = vam->input;
13779   vl_api_l2_fib_clear_table_t *mp;
13780   int ret;
13781
13782   M (L2_FIB_CLEAR_TABLE, mp);
13783
13784   S (mp);
13785   W (ret);
13786   return ret;
13787 }
13788
13789 static int
13790 api_l2_interface_efp_filter (vat_main_t * vam)
13791 {
13792   unformat_input_t *i = vam->input;
13793   vl_api_l2_interface_efp_filter_t *mp;
13794   u32 sw_if_index;
13795   u8 enable = 1;
13796   u8 sw_if_index_set = 0;
13797   int ret;
13798
13799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13800     {
13801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13802         sw_if_index_set = 1;
13803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13804         sw_if_index_set = 1;
13805       else if (unformat (i, "enable"))
13806         enable = 1;
13807       else if (unformat (i, "disable"))
13808         enable = 0;
13809       else
13810         {
13811           clib_warning ("parse error '%U'", format_unformat_error, i);
13812           return -99;
13813         }
13814     }
13815
13816   if (sw_if_index_set == 0)
13817     {
13818       errmsg ("missing sw_if_index");
13819       return -99;
13820     }
13821
13822   M (L2_INTERFACE_EFP_FILTER, mp);
13823
13824   mp->sw_if_index = ntohl (sw_if_index);
13825   mp->enable_disable = enable;
13826
13827   S (mp);
13828   W (ret);
13829   return ret;
13830 }
13831
13832 #define foreach_vtr_op                          \
13833 _("disable",  L2_VTR_DISABLED)                  \
13834 _("push-1",  L2_VTR_PUSH_1)                     \
13835 _("push-2",  L2_VTR_PUSH_2)                     \
13836 _("pop-1",  L2_VTR_POP_1)                       \
13837 _("pop-2",  L2_VTR_POP_2)                       \
13838 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13839 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13840 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13841 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13842
13843 static int
13844 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13845 {
13846   unformat_input_t *i = vam->input;
13847   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13848   u32 sw_if_index;
13849   u8 sw_if_index_set = 0;
13850   u8 vtr_op_set = 0;
13851   u32 vtr_op = 0;
13852   u32 push_dot1q = 1;
13853   u32 tag1 = ~0;
13854   u32 tag2 = ~0;
13855   int ret;
13856
13857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13858     {
13859       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13860         sw_if_index_set = 1;
13861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13862         sw_if_index_set = 1;
13863       else if (unformat (i, "vtr_op %d", &vtr_op))
13864         vtr_op_set = 1;
13865 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13866       foreach_vtr_op
13867 #undef _
13868         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13869         ;
13870       else if (unformat (i, "tag1 %d", &tag1))
13871         ;
13872       else if (unformat (i, "tag2 %d", &tag2))
13873         ;
13874       else
13875         {
13876           clib_warning ("parse error '%U'", format_unformat_error, i);
13877           return -99;
13878         }
13879     }
13880
13881   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13882     {
13883       errmsg ("missing vtr operation or sw_if_index");
13884       return -99;
13885     }
13886
13887   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13888   mp->sw_if_index = ntohl (sw_if_index);
13889   mp->vtr_op = ntohl (vtr_op);
13890   mp->push_dot1q = ntohl (push_dot1q);
13891   mp->tag1 = ntohl (tag1);
13892   mp->tag2 = ntohl (tag2);
13893
13894   S (mp);
13895   W (ret);
13896   return ret;
13897 }
13898
13899 static int
13900 api_create_vhost_user_if (vat_main_t * vam)
13901 {
13902   unformat_input_t *i = vam->input;
13903   vl_api_create_vhost_user_if_t *mp;
13904   u8 *file_name;
13905   u8 is_server = 0;
13906   u8 file_name_set = 0;
13907   u32 custom_dev_instance = ~0;
13908   u8 hwaddr[6];
13909   u8 use_custom_mac = 0;
13910   u8 *tag = 0;
13911   int ret;
13912
13913   /* Shut up coverity */
13914   memset (hwaddr, 0, sizeof (hwaddr));
13915
13916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13917     {
13918       if (unformat (i, "socket %s", &file_name))
13919         {
13920           file_name_set = 1;
13921         }
13922       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13923         ;
13924       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13925         use_custom_mac = 1;
13926       else if (unformat (i, "server"))
13927         is_server = 1;
13928       else if (unformat (i, "tag %s", &tag))
13929         ;
13930       else
13931         break;
13932     }
13933
13934   if (file_name_set == 0)
13935     {
13936       errmsg ("missing socket file name");
13937       return -99;
13938     }
13939
13940   if (vec_len (file_name) > 255)
13941     {
13942       errmsg ("socket file name too long");
13943       return -99;
13944     }
13945   vec_add1 (file_name, 0);
13946
13947   M (CREATE_VHOST_USER_IF, mp);
13948
13949   mp->is_server = is_server;
13950   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13951   vec_free (file_name);
13952   if (custom_dev_instance != ~0)
13953     {
13954       mp->renumber = 1;
13955       mp->custom_dev_instance = ntohl (custom_dev_instance);
13956     }
13957   mp->use_custom_mac = use_custom_mac;
13958   clib_memcpy (mp->mac_address, hwaddr, 6);
13959   if (tag)
13960     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13961   vec_free (tag);
13962
13963   S (mp);
13964   W (ret);
13965   return ret;
13966 }
13967
13968 static int
13969 api_modify_vhost_user_if (vat_main_t * vam)
13970 {
13971   unformat_input_t *i = vam->input;
13972   vl_api_modify_vhost_user_if_t *mp;
13973   u8 *file_name;
13974   u8 is_server = 0;
13975   u8 file_name_set = 0;
13976   u32 custom_dev_instance = ~0;
13977   u8 sw_if_index_set = 0;
13978   u32 sw_if_index = (u32) ~ 0;
13979   int ret;
13980
13981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13982     {
13983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13984         sw_if_index_set = 1;
13985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13986         sw_if_index_set = 1;
13987       else if (unformat (i, "socket %s", &file_name))
13988         {
13989           file_name_set = 1;
13990         }
13991       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13992         ;
13993       else if (unformat (i, "server"))
13994         is_server = 1;
13995       else
13996         break;
13997     }
13998
13999   if (sw_if_index_set == 0)
14000     {
14001       errmsg ("missing sw_if_index or interface name");
14002       return -99;
14003     }
14004
14005   if (file_name_set == 0)
14006     {
14007       errmsg ("missing socket file name");
14008       return -99;
14009     }
14010
14011   if (vec_len (file_name) > 255)
14012     {
14013       errmsg ("socket file name too long");
14014       return -99;
14015     }
14016   vec_add1 (file_name, 0);
14017
14018   M (MODIFY_VHOST_USER_IF, mp);
14019
14020   mp->sw_if_index = ntohl (sw_if_index);
14021   mp->is_server = is_server;
14022   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14023   vec_free (file_name);
14024   if (custom_dev_instance != ~0)
14025     {
14026       mp->renumber = 1;
14027       mp->custom_dev_instance = ntohl (custom_dev_instance);
14028     }
14029
14030   S (mp);
14031   W (ret);
14032   return ret;
14033 }
14034
14035 static int
14036 api_delete_vhost_user_if (vat_main_t * vam)
14037 {
14038   unformat_input_t *i = vam->input;
14039   vl_api_delete_vhost_user_if_t *mp;
14040   u32 sw_if_index = ~0;
14041   u8 sw_if_index_set = 0;
14042   int ret;
14043
14044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14045     {
14046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14047         sw_if_index_set = 1;
14048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14049         sw_if_index_set = 1;
14050       else
14051         break;
14052     }
14053
14054   if (sw_if_index_set == 0)
14055     {
14056       errmsg ("missing sw_if_index or interface name");
14057       return -99;
14058     }
14059
14060
14061   M (DELETE_VHOST_USER_IF, mp);
14062
14063   mp->sw_if_index = ntohl (sw_if_index);
14064
14065   S (mp);
14066   W (ret);
14067   return ret;
14068 }
14069
14070 static void vl_api_sw_interface_vhost_user_details_t_handler
14071   (vl_api_sw_interface_vhost_user_details_t * mp)
14072 {
14073   vat_main_t *vam = &vat_main;
14074
14075   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14076          (char *) mp->interface_name,
14077          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14078          clib_net_to_host_u64 (mp->features), mp->is_server,
14079          ntohl (mp->num_regions), (char *) mp->sock_filename);
14080   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14081 }
14082
14083 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14084   (vl_api_sw_interface_vhost_user_details_t * mp)
14085 {
14086   vat_main_t *vam = &vat_main;
14087   vat_json_node_t *node = NULL;
14088
14089   if (VAT_JSON_ARRAY != vam->json_tree.type)
14090     {
14091       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14092       vat_json_init_array (&vam->json_tree);
14093     }
14094   node = vat_json_array_add (&vam->json_tree);
14095
14096   vat_json_init_object (node);
14097   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14098   vat_json_object_add_string_copy (node, "interface_name",
14099                                    mp->interface_name);
14100   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14101                             ntohl (mp->virtio_net_hdr_sz));
14102   vat_json_object_add_uint (node, "features",
14103                             clib_net_to_host_u64 (mp->features));
14104   vat_json_object_add_uint (node, "is_server", mp->is_server);
14105   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14106   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14107   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14108 }
14109
14110 static int
14111 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14112 {
14113   vl_api_sw_interface_vhost_user_dump_t *mp;
14114   vl_api_control_ping_t *mp_ping;
14115   int ret;
14116   print (vam->ofp,
14117          "Interface name            idx hdr_sz features server regions filename");
14118
14119   /* Get list of vhost-user interfaces */
14120   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14121   S (mp);
14122
14123   /* Use a control ping for synchronization */
14124   MPING (CONTROL_PING, mp_ping);
14125   S (mp_ping);
14126
14127   W (ret);
14128   return ret;
14129 }
14130
14131 static int
14132 api_show_version (vat_main_t * vam)
14133 {
14134   vl_api_show_version_t *mp;
14135   int ret;
14136
14137   M (SHOW_VERSION, mp);
14138
14139   S (mp);
14140   W (ret);
14141   return ret;
14142 }
14143
14144
14145 static int
14146 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14147 {
14148   unformat_input_t *line_input = vam->input;
14149   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14150   ip4_address_t local4, remote4;
14151   ip6_address_t local6, remote6;
14152   u8 is_add = 1;
14153   u8 ipv4_set = 0, ipv6_set = 0;
14154   u8 local_set = 0;
14155   u8 remote_set = 0;
14156   u8 grp_set = 0;
14157   u32 mcast_sw_if_index = ~0;
14158   u32 encap_vrf_id = 0;
14159   u32 decap_vrf_id = 0;
14160   u8 protocol = ~0;
14161   u32 vni;
14162   u8 vni_set = 0;
14163   int ret;
14164
14165   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14166   memset (&local4, 0, sizeof local4);
14167   memset (&remote4, 0, sizeof remote4);
14168   memset (&local6, 0, sizeof local6);
14169   memset (&remote6, 0, sizeof remote6);
14170
14171   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14172     {
14173       if (unformat (line_input, "del"))
14174         is_add = 0;
14175       else if (unformat (line_input, "local %U",
14176                          unformat_ip4_address, &local4))
14177         {
14178           local_set = 1;
14179           ipv4_set = 1;
14180         }
14181       else if (unformat (line_input, "remote %U",
14182                          unformat_ip4_address, &remote4))
14183         {
14184           remote_set = 1;
14185           ipv4_set = 1;
14186         }
14187       else if (unformat (line_input, "local %U",
14188                          unformat_ip6_address, &local6))
14189         {
14190           local_set = 1;
14191           ipv6_set = 1;
14192         }
14193       else if (unformat (line_input, "remote %U",
14194                          unformat_ip6_address, &remote6))
14195         {
14196           remote_set = 1;
14197           ipv6_set = 1;
14198         }
14199       else if (unformat (line_input, "group %U %U",
14200                          unformat_ip4_address, &remote4,
14201                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14202         {
14203           grp_set = remote_set = 1;
14204           ipv4_set = 1;
14205         }
14206       else if (unformat (line_input, "group %U",
14207                          unformat_ip4_address, &remote4))
14208         {
14209           grp_set = remote_set = 1;
14210           ipv4_set = 1;
14211         }
14212       else if (unformat (line_input, "group %U %U",
14213                          unformat_ip6_address, &remote6,
14214                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14215         {
14216           grp_set = remote_set = 1;
14217           ipv6_set = 1;
14218         }
14219       else if (unformat (line_input, "group %U",
14220                          unformat_ip6_address, &remote6))
14221         {
14222           grp_set = remote_set = 1;
14223           ipv6_set = 1;
14224         }
14225       else
14226         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14227         ;
14228       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14229         ;
14230       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14231         ;
14232       else if (unformat (line_input, "vni %d", &vni))
14233         vni_set = 1;
14234       else if (unformat (line_input, "next-ip4"))
14235         protocol = 1;
14236       else if (unformat (line_input, "next-ip6"))
14237         protocol = 2;
14238       else if (unformat (line_input, "next-ethernet"))
14239         protocol = 3;
14240       else if (unformat (line_input, "next-nsh"))
14241         protocol = 4;
14242       else
14243         {
14244           errmsg ("parse error '%U'", format_unformat_error, line_input);
14245           return -99;
14246         }
14247     }
14248
14249   if (local_set == 0)
14250     {
14251       errmsg ("tunnel local address not specified");
14252       return -99;
14253     }
14254   if (remote_set == 0)
14255     {
14256       errmsg ("tunnel remote address not specified");
14257       return -99;
14258     }
14259   if (grp_set && mcast_sw_if_index == ~0)
14260     {
14261       errmsg ("tunnel nonexistent multicast device");
14262       return -99;
14263     }
14264   if (ipv4_set && ipv6_set)
14265     {
14266       errmsg ("both IPv4 and IPv6 addresses specified");
14267       return -99;
14268     }
14269
14270   if (vni_set == 0)
14271     {
14272       errmsg ("vni not specified");
14273       return -99;
14274     }
14275
14276   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14277
14278
14279   if (ipv6_set)
14280     {
14281       clib_memcpy (&mp->local, &local6, sizeof (local6));
14282       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14283     }
14284   else
14285     {
14286       clib_memcpy (&mp->local, &local4, sizeof (local4));
14287       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14288     }
14289
14290   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14291   mp->encap_vrf_id = ntohl (encap_vrf_id);
14292   mp->decap_vrf_id = ntohl (decap_vrf_id);
14293   mp->protocol = protocol;
14294   mp->vni = ntohl (vni);
14295   mp->is_add = is_add;
14296   mp->is_ipv6 = ipv6_set;
14297
14298   S (mp);
14299   W (ret);
14300   return ret;
14301 }
14302
14303 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14304   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14305 {
14306   vat_main_t *vam = &vat_main;
14307   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14308   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14309
14310   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14311          ntohl (mp->sw_if_index),
14312          format_ip46_address, &local, IP46_TYPE_ANY,
14313          format_ip46_address, &remote, IP46_TYPE_ANY,
14314          ntohl (mp->vni), mp->protocol,
14315          ntohl (mp->mcast_sw_if_index),
14316          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14317 }
14318
14319
14320 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14321   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14322 {
14323   vat_main_t *vam = &vat_main;
14324   vat_json_node_t *node = NULL;
14325   struct in_addr ip4;
14326   struct in6_addr ip6;
14327
14328   if (VAT_JSON_ARRAY != vam->json_tree.type)
14329     {
14330       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14331       vat_json_init_array (&vam->json_tree);
14332     }
14333   node = vat_json_array_add (&vam->json_tree);
14334
14335   vat_json_init_object (node);
14336   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14337   if (mp->is_ipv6)
14338     {
14339       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14340       vat_json_object_add_ip6 (node, "local", ip6);
14341       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14342       vat_json_object_add_ip6 (node, "remote", ip6);
14343     }
14344   else
14345     {
14346       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14347       vat_json_object_add_ip4 (node, "local", ip4);
14348       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14349       vat_json_object_add_ip4 (node, "remote", ip4);
14350     }
14351   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14352   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14353   vat_json_object_add_uint (node, "mcast_sw_if_index",
14354                             ntohl (mp->mcast_sw_if_index));
14355   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14356   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14357   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14358 }
14359
14360 static int
14361 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14362 {
14363   unformat_input_t *i = vam->input;
14364   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14365   vl_api_control_ping_t *mp_ping;
14366   u32 sw_if_index;
14367   u8 sw_if_index_set = 0;
14368   int ret;
14369
14370   /* Parse args required to build the message */
14371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14372     {
14373       if (unformat (i, "sw_if_index %d", &sw_if_index))
14374         sw_if_index_set = 1;
14375       else
14376         break;
14377     }
14378
14379   if (sw_if_index_set == 0)
14380     {
14381       sw_if_index = ~0;
14382     }
14383
14384   if (!vam->json_output)
14385     {
14386       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14387              "sw_if_index", "local", "remote", "vni",
14388              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14389     }
14390
14391   /* Get list of vxlan-tunnel interfaces */
14392   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14393
14394   mp->sw_if_index = htonl (sw_if_index);
14395
14396   S (mp);
14397
14398   /* Use a control ping for synchronization */
14399   MPING (CONTROL_PING, mp_ping);
14400   S (mp_ping);
14401
14402   W (ret);
14403   return ret;
14404 }
14405
14406 static void vl_api_l2_fib_table_details_t_handler
14407   (vl_api_l2_fib_table_details_t * mp)
14408 {
14409   vat_main_t *vam = &vat_main;
14410
14411   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14412          "       %d       %d     %d",
14413          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14414          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14415          mp->bvi_mac);
14416 }
14417
14418 static void vl_api_l2_fib_table_details_t_handler_json
14419   (vl_api_l2_fib_table_details_t * mp)
14420 {
14421   vat_main_t *vam = &vat_main;
14422   vat_json_node_t *node = NULL;
14423
14424   if (VAT_JSON_ARRAY != vam->json_tree.type)
14425     {
14426       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14427       vat_json_init_array (&vam->json_tree);
14428     }
14429   node = vat_json_array_add (&vam->json_tree);
14430
14431   vat_json_init_object (node);
14432   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14433   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14434   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14435   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14436   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14437   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14438 }
14439
14440 static int
14441 api_l2_fib_table_dump (vat_main_t * vam)
14442 {
14443   unformat_input_t *i = vam->input;
14444   vl_api_l2_fib_table_dump_t *mp;
14445   vl_api_control_ping_t *mp_ping;
14446   u32 bd_id;
14447   u8 bd_id_set = 0;
14448   int ret;
14449
14450   /* Parse args required to build the message */
14451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14452     {
14453       if (unformat (i, "bd_id %d", &bd_id))
14454         bd_id_set = 1;
14455       else
14456         break;
14457     }
14458
14459   if (bd_id_set == 0)
14460     {
14461       errmsg ("missing bridge domain");
14462       return -99;
14463     }
14464
14465   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14466
14467   /* Get list of l2 fib entries */
14468   M (L2_FIB_TABLE_DUMP, mp);
14469
14470   mp->bd_id = ntohl (bd_id);
14471   S (mp);
14472
14473   /* Use a control ping for synchronization */
14474   MPING (CONTROL_PING, mp_ping);
14475   S (mp_ping);
14476
14477   W (ret);
14478   return ret;
14479 }
14480
14481
14482 static int
14483 api_interface_name_renumber (vat_main_t * vam)
14484 {
14485   unformat_input_t *line_input = vam->input;
14486   vl_api_interface_name_renumber_t *mp;
14487   u32 sw_if_index = ~0;
14488   u32 new_show_dev_instance = ~0;
14489   int ret;
14490
14491   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14492     {
14493       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14494                     &sw_if_index))
14495         ;
14496       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14497         ;
14498       else if (unformat (line_input, "new_show_dev_instance %d",
14499                          &new_show_dev_instance))
14500         ;
14501       else
14502         break;
14503     }
14504
14505   if (sw_if_index == ~0)
14506     {
14507       errmsg ("missing interface name or sw_if_index");
14508       return -99;
14509     }
14510
14511   if (new_show_dev_instance == ~0)
14512     {
14513       errmsg ("missing new_show_dev_instance");
14514       return -99;
14515     }
14516
14517   M (INTERFACE_NAME_RENUMBER, mp);
14518
14519   mp->sw_if_index = ntohl (sw_if_index);
14520   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14521
14522   S (mp);
14523   W (ret);
14524   return ret;
14525 }
14526
14527 static int
14528 api_ip_probe_neighbor (vat_main_t * vam)
14529 {
14530   unformat_input_t *i = vam->input;
14531   vl_api_ip_probe_neighbor_t *mp;
14532   u8 int_set = 0;
14533   u8 adr_set = 0;
14534   u8 is_ipv6 = 0;
14535   u8 dst_adr[16];
14536   u32 sw_if_index;
14537   int ret;
14538
14539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14542         int_set = 1;
14543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14544         int_set = 1;
14545       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14546         adr_set = 1;
14547       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14548         {
14549           adr_set = 1;
14550           is_ipv6 = 1;
14551         }
14552       else
14553         break;
14554     }
14555
14556   if (int_set == 0)
14557     {
14558       errmsg ("missing interface");
14559       return -99;
14560     }
14561
14562   if (adr_set == 0)
14563     {
14564       errmsg ("missing addresses");
14565       return -99;
14566     }
14567
14568   M (IP_PROBE_NEIGHBOR, mp);
14569
14570   mp->sw_if_index = ntohl (sw_if_index);
14571   mp->is_ipv6 = is_ipv6;
14572   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14573
14574   S (mp);
14575   W (ret);
14576   return ret;
14577 }
14578
14579 static int
14580 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14581 {
14582   unformat_input_t *i = vam->input;
14583   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14584   u8 mode = IP_SCAN_V46_NEIGHBORS;
14585   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14586   int ret;
14587
14588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14589     {
14590       if (unformat (i, "ip4"))
14591         mode = IP_SCAN_V4_NEIGHBORS;
14592       else if (unformat (i, "ip6"))
14593         mode = IP_SCAN_V6_NEIGHBORS;
14594       if (unformat (i, "both"))
14595         mode = IP_SCAN_V46_NEIGHBORS;
14596       else if (unformat (i, "disable"))
14597         mode = IP_SCAN_DISABLED;
14598       else if (unformat (i, "interval %d", &interval))
14599         ;
14600       else if (unformat (i, "max-time %d", &time))
14601         ;
14602       else if (unformat (i, "max-update %d", &update))
14603         ;
14604       else if (unformat (i, "delay %d", &delay))
14605         ;
14606       else if (unformat (i, "stale %d", &stale))
14607         ;
14608       else
14609         break;
14610     }
14611
14612   if (interval > 255)
14613     {
14614       errmsg ("interval cannot exceed 255 minutes.");
14615       return -99;
14616     }
14617   if (time > 255)
14618     {
14619       errmsg ("max-time cannot exceed 255 usec.");
14620       return -99;
14621     }
14622   if (update > 255)
14623     {
14624       errmsg ("max-update cannot exceed 255.");
14625       return -99;
14626     }
14627   if (delay > 255)
14628     {
14629       errmsg ("delay cannot exceed 255 msec.");
14630       return -99;
14631     }
14632   if (stale > 255)
14633     {
14634       errmsg ("stale cannot exceed 255 minutes.");
14635       return -99;
14636     }
14637
14638   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14639   mp->mode = mode;
14640   mp->scan_interval = interval;
14641   mp->max_proc_time = time;
14642   mp->max_update = update;
14643   mp->scan_int_delay = delay;
14644   mp->stale_threshold = stale;
14645
14646   S (mp);
14647   W (ret);
14648   return ret;
14649 }
14650
14651 static int
14652 api_want_ip4_arp_events (vat_main_t * vam)
14653 {
14654   unformat_input_t *line_input = vam->input;
14655   vl_api_want_ip4_arp_events_t *mp;
14656   ip4_address_t address;
14657   int address_set = 0;
14658   u32 enable_disable = 1;
14659   int ret;
14660
14661   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14662     {
14663       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14664         address_set = 1;
14665       else if (unformat (line_input, "del"))
14666         enable_disable = 0;
14667       else
14668         break;
14669     }
14670
14671   if (address_set == 0)
14672     {
14673       errmsg ("missing addresses");
14674       return -99;
14675     }
14676
14677   M (WANT_IP4_ARP_EVENTS, mp);
14678   mp->enable_disable = enable_disable;
14679   mp->pid = htonl (getpid ());
14680   mp->address = address.as_u32;
14681
14682   S (mp);
14683   W (ret);
14684   return ret;
14685 }
14686
14687 static int
14688 api_want_ip6_nd_events (vat_main_t * vam)
14689 {
14690   unformat_input_t *line_input = vam->input;
14691   vl_api_want_ip6_nd_events_t *mp;
14692   ip6_address_t address;
14693   int address_set = 0;
14694   u32 enable_disable = 1;
14695   int ret;
14696
14697   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14698     {
14699       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14700         address_set = 1;
14701       else if (unformat (line_input, "del"))
14702         enable_disable = 0;
14703       else
14704         break;
14705     }
14706
14707   if (address_set == 0)
14708     {
14709       errmsg ("missing addresses");
14710       return -99;
14711     }
14712
14713   M (WANT_IP6_ND_EVENTS, mp);
14714   mp->enable_disable = enable_disable;
14715   mp->pid = htonl (getpid ());
14716   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14717
14718   S (mp);
14719   W (ret);
14720   return ret;
14721 }
14722
14723 static int
14724 api_want_l2_macs_events (vat_main_t * vam)
14725 {
14726   unformat_input_t *line_input = vam->input;
14727   vl_api_want_l2_macs_events_t *mp;
14728   u8 enable_disable = 1;
14729   u32 scan_delay = 0;
14730   u32 max_macs_in_event = 0;
14731   u32 learn_limit = 0;
14732   int ret;
14733
14734   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14735     {
14736       if (unformat (line_input, "learn-limit %d", &learn_limit))
14737         ;
14738       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14739         ;
14740       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14741         ;
14742       else if (unformat (line_input, "disable"))
14743         enable_disable = 0;
14744       else
14745         break;
14746     }
14747
14748   M (WANT_L2_MACS_EVENTS, mp);
14749   mp->enable_disable = enable_disable;
14750   mp->pid = htonl (getpid ());
14751   mp->learn_limit = htonl (learn_limit);
14752   mp->scan_delay = (u8) scan_delay;
14753   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14754   S (mp);
14755   W (ret);
14756   return ret;
14757 }
14758
14759 static int
14760 api_input_acl_set_interface (vat_main_t * vam)
14761 {
14762   unformat_input_t *i = vam->input;
14763   vl_api_input_acl_set_interface_t *mp;
14764   u32 sw_if_index;
14765   int sw_if_index_set;
14766   u32 ip4_table_index = ~0;
14767   u32 ip6_table_index = ~0;
14768   u32 l2_table_index = ~0;
14769   u8 is_add = 1;
14770   int ret;
14771
14772   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14773     {
14774       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14775         sw_if_index_set = 1;
14776       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14777         sw_if_index_set = 1;
14778       else if (unformat (i, "del"))
14779         is_add = 0;
14780       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14781         ;
14782       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14783         ;
14784       else if (unformat (i, "l2-table %d", &l2_table_index))
14785         ;
14786       else
14787         {
14788           clib_warning ("parse error '%U'", format_unformat_error, i);
14789           return -99;
14790         }
14791     }
14792
14793   if (sw_if_index_set == 0)
14794     {
14795       errmsg ("missing interface name or sw_if_index");
14796       return -99;
14797     }
14798
14799   M (INPUT_ACL_SET_INTERFACE, mp);
14800
14801   mp->sw_if_index = ntohl (sw_if_index);
14802   mp->ip4_table_index = ntohl (ip4_table_index);
14803   mp->ip6_table_index = ntohl (ip6_table_index);
14804   mp->l2_table_index = ntohl (l2_table_index);
14805   mp->is_add = is_add;
14806
14807   S (mp);
14808   W (ret);
14809   return ret;
14810 }
14811
14812 static int
14813 api_output_acl_set_interface (vat_main_t * vam)
14814 {
14815   unformat_input_t *i = vam->input;
14816   vl_api_output_acl_set_interface_t *mp;
14817   u32 sw_if_index;
14818   int sw_if_index_set;
14819   u32 ip4_table_index = ~0;
14820   u32 ip6_table_index = ~0;
14821   u32 l2_table_index = ~0;
14822   u8 is_add = 1;
14823   int ret;
14824
14825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14826     {
14827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14828         sw_if_index_set = 1;
14829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14830         sw_if_index_set = 1;
14831       else if (unformat (i, "del"))
14832         is_add = 0;
14833       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14834         ;
14835       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14836         ;
14837       else if (unformat (i, "l2-table %d", &l2_table_index))
14838         ;
14839       else
14840         {
14841           clib_warning ("parse error '%U'", format_unformat_error, i);
14842           return -99;
14843         }
14844     }
14845
14846   if (sw_if_index_set == 0)
14847     {
14848       errmsg ("missing interface name or sw_if_index");
14849       return -99;
14850     }
14851
14852   M (OUTPUT_ACL_SET_INTERFACE, mp);
14853
14854   mp->sw_if_index = ntohl (sw_if_index);
14855   mp->ip4_table_index = ntohl (ip4_table_index);
14856   mp->ip6_table_index = ntohl (ip6_table_index);
14857   mp->l2_table_index = ntohl (l2_table_index);
14858   mp->is_add = is_add;
14859
14860   S (mp);
14861   W (ret);
14862   return ret;
14863 }
14864
14865 static int
14866 api_ip_address_dump (vat_main_t * vam)
14867 {
14868   unformat_input_t *i = vam->input;
14869   vl_api_ip_address_dump_t *mp;
14870   vl_api_control_ping_t *mp_ping;
14871   u32 sw_if_index = ~0;
14872   u8 sw_if_index_set = 0;
14873   u8 ipv4_set = 0;
14874   u8 ipv6_set = 0;
14875   int ret;
14876
14877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14878     {
14879       if (unformat (i, "sw_if_index %d", &sw_if_index))
14880         sw_if_index_set = 1;
14881       else
14882         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14883         sw_if_index_set = 1;
14884       else if (unformat (i, "ipv4"))
14885         ipv4_set = 1;
14886       else if (unformat (i, "ipv6"))
14887         ipv6_set = 1;
14888       else
14889         break;
14890     }
14891
14892   if (ipv4_set && ipv6_set)
14893     {
14894       errmsg ("ipv4 and ipv6 flags cannot be both set");
14895       return -99;
14896     }
14897
14898   if ((!ipv4_set) && (!ipv6_set))
14899     {
14900       errmsg ("no ipv4 nor ipv6 flag set");
14901       return -99;
14902     }
14903
14904   if (sw_if_index_set == 0)
14905     {
14906       errmsg ("missing interface name or sw_if_index");
14907       return -99;
14908     }
14909
14910   vam->current_sw_if_index = sw_if_index;
14911   vam->is_ipv6 = ipv6_set;
14912
14913   M (IP_ADDRESS_DUMP, mp);
14914   mp->sw_if_index = ntohl (sw_if_index);
14915   mp->is_ipv6 = ipv6_set;
14916   S (mp);
14917
14918   /* Use a control ping for synchronization */
14919   MPING (CONTROL_PING, mp_ping);
14920   S (mp_ping);
14921
14922   W (ret);
14923   return ret;
14924 }
14925
14926 static int
14927 api_ip_dump (vat_main_t * vam)
14928 {
14929   vl_api_ip_dump_t *mp;
14930   vl_api_control_ping_t *mp_ping;
14931   unformat_input_t *in = vam->input;
14932   int ipv4_set = 0;
14933   int ipv6_set = 0;
14934   int is_ipv6;
14935   int i;
14936   int ret;
14937
14938   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
14939     {
14940       if (unformat (in, "ipv4"))
14941         ipv4_set = 1;
14942       else if (unformat (in, "ipv6"))
14943         ipv6_set = 1;
14944       else
14945         break;
14946     }
14947
14948   if (ipv4_set && ipv6_set)
14949     {
14950       errmsg ("ipv4 and ipv6 flags cannot be both set");
14951       return -99;
14952     }
14953
14954   if ((!ipv4_set) && (!ipv6_set))
14955     {
14956       errmsg ("no ipv4 nor ipv6 flag set");
14957       return -99;
14958     }
14959
14960   is_ipv6 = ipv6_set;
14961   vam->is_ipv6 = is_ipv6;
14962
14963   /* free old data */
14964   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14965     {
14966       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14967     }
14968   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14969
14970   M (IP_DUMP, mp);
14971   mp->is_ipv6 = ipv6_set;
14972   S (mp);
14973
14974   /* Use a control ping for synchronization */
14975   MPING (CONTROL_PING, mp_ping);
14976   S (mp_ping);
14977
14978   W (ret);
14979   return ret;
14980 }
14981
14982 static int
14983 api_ipsec_spd_add_del (vat_main_t * vam)
14984 {
14985   unformat_input_t *i = vam->input;
14986   vl_api_ipsec_spd_add_del_t *mp;
14987   u32 spd_id = ~0;
14988   u8 is_add = 1;
14989   int ret;
14990
14991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14992     {
14993       if (unformat (i, "spd_id %d", &spd_id))
14994         ;
14995       else if (unformat (i, "del"))
14996         is_add = 0;
14997       else
14998         {
14999           clib_warning ("parse error '%U'", format_unformat_error, i);
15000           return -99;
15001         }
15002     }
15003   if (spd_id == ~0)
15004     {
15005       errmsg ("spd_id must be set");
15006       return -99;
15007     }
15008
15009   M (IPSEC_SPD_ADD_DEL, mp);
15010
15011   mp->spd_id = ntohl (spd_id);
15012   mp->is_add = is_add;
15013
15014   S (mp);
15015   W (ret);
15016   return ret;
15017 }
15018
15019 static int
15020 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15021 {
15022   unformat_input_t *i = vam->input;
15023   vl_api_ipsec_interface_add_del_spd_t *mp;
15024   u32 sw_if_index;
15025   u8 sw_if_index_set = 0;
15026   u32 spd_id = (u32) ~ 0;
15027   u8 is_add = 1;
15028   int ret;
15029
15030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15031     {
15032       if (unformat (i, "del"))
15033         is_add = 0;
15034       else if (unformat (i, "spd_id %d", &spd_id))
15035         ;
15036       else
15037         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15038         sw_if_index_set = 1;
15039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15040         sw_if_index_set = 1;
15041       else
15042         {
15043           clib_warning ("parse error '%U'", format_unformat_error, i);
15044           return -99;
15045         }
15046
15047     }
15048
15049   if (spd_id == (u32) ~ 0)
15050     {
15051       errmsg ("spd_id must be set");
15052       return -99;
15053     }
15054
15055   if (sw_if_index_set == 0)
15056     {
15057       errmsg ("missing interface name or sw_if_index");
15058       return -99;
15059     }
15060
15061   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15062
15063   mp->spd_id = ntohl (spd_id);
15064   mp->sw_if_index = ntohl (sw_if_index);
15065   mp->is_add = is_add;
15066
15067   S (mp);
15068   W (ret);
15069   return ret;
15070 }
15071
15072 static int
15073 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15074 {
15075   unformat_input_t *i = vam->input;
15076   vl_api_ipsec_spd_add_del_entry_t *mp;
15077   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15078   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15079   i32 priority = 0;
15080   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15081   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15082   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15083   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15084   int ret;
15085
15086   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15087   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15088   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15089   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15090   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15091   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15092
15093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15094     {
15095       if (unformat (i, "del"))
15096         is_add = 0;
15097       if (unformat (i, "outbound"))
15098         is_outbound = 1;
15099       if (unformat (i, "inbound"))
15100         is_outbound = 0;
15101       else if (unformat (i, "spd_id %d", &spd_id))
15102         ;
15103       else if (unformat (i, "sa_id %d", &sa_id))
15104         ;
15105       else if (unformat (i, "priority %d", &priority))
15106         ;
15107       else if (unformat (i, "protocol %d", &protocol))
15108         ;
15109       else if (unformat (i, "lport_start %d", &lport_start))
15110         ;
15111       else if (unformat (i, "lport_stop %d", &lport_stop))
15112         ;
15113       else if (unformat (i, "rport_start %d", &rport_start))
15114         ;
15115       else if (unformat (i, "rport_stop %d", &rport_stop))
15116         ;
15117       else
15118         if (unformat
15119             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15120         {
15121           is_ipv6 = 0;
15122           is_ip_any = 0;
15123         }
15124       else
15125         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15126         {
15127           is_ipv6 = 0;
15128           is_ip_any = 0;
15129         }
15130       else
15131         if (unformat
15132             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15133         {
15134           is_ipv6 = 0;
15135           is_ip_any = 0;
15136         }
15137       else
15138         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15139         {
15140           is_ipv6 = 0;
15141           is_ip_any = 0;
15142         }
15143       else
15144         if (unformat
15145             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15146         {
15147           is_ipv6 = 1;
15148           is_ip_any = 0;
15149         }
15150       else
15151         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15152         {
15153           is_ipv6 = 1;
15154           is_ip_any = 0;
15155         }
15156       else
15157         if (unformat
15158             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15159         {
15160           is_ipv6 = 1;
15161           is_ip_any = 0;
15162         }
15163       else
15164         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15165         {
15166           is_ipv6 = 1;
15167           is_ip_any = 0;
15168         }
15169       else
15170         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15171         {
15172           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15173             {
15174               clib_warning ("unsupported action: 'resolve'");
15175               return -99;
15176             }
15177         }
15178       else
15179         {
15180           clib_warning ("parse error '%U'", format_unformat_error, i);
15181           return -99;
15182         }
15183
15184     }
15185
15186   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15187
15188   mp->spd_id = ntohl (spd_id);
15189   mp->priority = ntohl (priority);
15190   mp->is_outbound = is_outbound;
15191
15192   mp->is_ipv6 = is_ipv6;
15193   if (is_ipv6 || is_ip_any)
15194     {
15195       clib_memcpy (mp->remote_address_start, &raddr6_start,
15196                    sizeof (ip6_address_t));
15197       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15198                    sizeof (ip6_address_t));
15199       clib_memcpy (mp->local_address_start, &laddr6_start,
15200                    sizeof (ip6_address_t));
15201       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15202                    sizeof (ip6_address_t));
15203     }
15204   else
15205     {
15206       clib_memcpy (mp->remote_address_start, &raddr4_start,
15207                    sizeof (ip4_address_t));
15208       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15209                    sizeof (ip4_address_t));
15210       clib_memcpy (mp->local_address_start, &laddr4_start,
15211                    sizeof (ip4_address_t));
15212       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15213                    sizeof (ip4_address_t));
15214     }
15215   mp->protocol = (u8) protocol;
15216   mp->local_port_start = ntohs ((u16) lport_start);
15217   mp->local_port_stop = ntohs ((u16) lport_stop);
15218   mp->remote_port_start = ntohs ((u16) rport_start);
15219   mp->remote_port_stop = ntohs ((u16) rport_stop);
15220   mp->policy = (u8) policy;
15221   mp->sa_id = ntohl (sa_id);
15222   mp->is_add = is_add;
15223   mp->is_ip_any = is_ip_any;
15224   S (mp);
15225   W (ret);
15226   return ret;
15227 }
15228
15229 static int
15230 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15231 {
15232   unformat_input_t *i = vam->input;
15233   vl_api_ipsec_sad_add_del_entry_t *mp;
15234   u32 sad_id = 0, spi = 0;
15235   u8 *ck = 0, *ik = 0;
15236   u8 is_add = 1;
15237
15238   u8 protocol = IPSEC_PROTOCOL_AH;
15239   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15240   u32 crypto_alg = 0, integ_alg = 0;
15241   ip4_address_t tun_src4;
15242   ip4_address_t tun_dst4;
15243   ip6_address_t tun_src6;
15244   ip6_address_t tun_dst6;
15245   int ret;
15246
15247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15248     {
15249       if (unformat (i, "del"))
15250         is_add = 0;
15251       else if (unformat (i, "sad_id %d", &sad_id))
15252         ;
15253       else if (unformat (i, "spi %d", &spi))
15254         ;
15255       else if (unformat (i, "esp"))
15256         protocol = IPSEC_PROTOCOL_ESP;
15257       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15258         {
15259           is_tunnel = 1;
15260           is_tunnel_ipv6 = 0;
15261         }
15262       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15263         {
15264           is_tunnel = 1;
15265           is_tunnel_ipv6 = 0;
15266         }
15267       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15268         {
15269           is_tunnel = 1;
15270           is_tunnel_ipv6 = 1;
15271         }
15272       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15273         {
15274           is_tunnel = 1;
15275           is_tunnel_ipv6 = 1;
15276         }
15277       else
15278         if (unformat
15279             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15280         {
15281           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15282             {
15283               clib_warning ("unsupported crypto-alg: '%U'",
15284                             format_ipsec_crypto_alg, crypto_alg);
15285               return -99;
15286             }
15287         }
15288       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15289         ;
15290       else
15291         if (unformat
15292             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15293         {
15294           if (integ_alg >= IPSEC_INTEG_N_ALG)
15295             {
15296               clib_warning ("unsupported integ-alg: '%U'",
15297                             format_ipsec_integ_alg, integ_alg);
15298               return -99;
15299             }
15300         }
15301       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15302         ;
15303       else
15304         {
15305           clib_warning ("parse error '%U'", format_unformat_error, i);
15306           return -99;
15307         }
15308
15309     }
15310
15311   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15312
15313   mp->sad_id = ntohl (sad_id);
15314   mp->is_add = is_add;
15315   mp->protocol = protocol;
15316   mp->spi = ntohl (spi);
15317   mp->is_tunnel = is_tunnel;
15318   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15319   mp->crypto_algorithm = crypto_alg;
15320   mp->integrity_algorithm = integ_alg;
15321   mp->crypto_key_length = vec_len (ck);
15322   mp->integrity_key_length = vec_len (ik);
15323
15324   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15325     mp->crypto_key_length = sizeof (mp->crypto_key);
15326
15327   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15328     mp->integrity_key_length = sizeof (mp->integrity_key);
15329
15330   if (ck)
15331     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15332   if (ik)
15333     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15334
15335   if (is_tunnel)
15336     {
15337       if (is_tunnel_ipv6)
15338         {
15339           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15340                        sizeof (ip6_address_t));
15341           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15342                        sizeof (ip6_address_t));
15343         }
15344       else
15345         {
15346           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15347                        sizeof (ip4_address_t));
15348           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15349                        sizeof (ip4_address_t));
15350         }
15351     }
15352
15353   S (mp);
15354   W (ret);
15355   return ret;
15356 }
15357
15358 static int
15359 api_ipsec_sa_set_key (vat_main_t * vam)
15360 {
15361   unformat_input_t *i = vam->input;
15362   vl_api_ipsec_sa_set_key_t *mp;
15363   u32 sa_id;
15364   u8 *ck = 0, *ik = 0;
15365   int ret;
15366
15367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (i, "sa_id %d", &sa_id))
15370         ;
15371       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15372         ;
15373       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15374         ;
15375       else
15376         {
15377           clib_warning ("parse error '%U'", format_unformat_error, i);
15378           return -99;
15379         }
15380     }
15381
15382   M (IPSEC_SA_SET_KEY, mp);
15383
15384   mp->sa_id = ntohl (sa_id);
15385   mp->crypto_key_length = vec_len (ck);
15386   mp->integrity_key_length = vec_len (ik);
15387
15388   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15389     mp->crypto_key_length = sizeof (mp->crypto_key);
15390
15391   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15392     mp->integrity_key_length = sizeof (mp->integrity_key);
15393
15394   if (ck)
15395     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15396   if (ik)
15397     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15398
15399   S (mp);
15400   W (ret);
15401   return ret;
15402 }
15403
15404 static int
15405 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15406 {
15407   unformat_input_t *i = vam->input;
15408   vl_api_ipsec_tunnel_if_add_del_t *mp;
15409   u32 local_spi = 0, remote_spi = 0;
15410   u32 crypto_alg = 0, integ_alg = 0;
15411   u8 *lck = NULL, *rck = NULL;
15412   u8 *lik = NULL, *rik = NULL;
15413   ip4_address_t local_ip = { {0} };
15414   ip4_address_t remote_ip = { {0} };
15415   u8 is_add = 1;
15416   u8 esn = 0;
15417   u8 anti_replay = 0;
15418   u8 renumber = 0;
15419   u32 instance = ~0;
15420   int ret;
15421
15422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15423     {
15424       if (unformat (i, "del"))
15425         is_add = 0;
15426       else if (unformat (i, "esn"))
15427         esn = 1;
15428       else if (unformat (i, "anti_replay"))
15429         anti_replay = 1;
15430       else if (unformat (i, "local_spi %d", &local_spi))
15431         ;
15432       else if (unformat (i, "remote_spi %d", &remote_spi))
15433         ;
15434       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15435         ;
15436       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15437         ;
15438       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15439         ;
15440       else
15441         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15442         ;
15443       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15444         ;
15445       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15446         ;
15447       else
15448         if (unformat
15449             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15450         {
15451           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15452             {
15453               errmsg ("unsupported crypto-alg: '%U'\n",
15454                       format_ipsec_crypto_alg, crypto_alg);
15455               return -99;
15456             }
15457         }
15458       else
15459         if (unformat
15460             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15461         {
15462           if (integ_alg >= IPSEC_INTEG_N_ALG)
15463             {
15464               errmsg ("unsupported integ-alg: '%U'\n",
15465                       format_ipsec_integ_alg, integ_alg);
15466               return -99;
15467             }
15468         }
15469       else if (unformat (i, "instance %u", &instance))
15470         renumber = 1;
15471       else
15472         {
15473           errmsg ("parse error '%U'\n", format_unformat_error, i);
15474           return -99;
15475         }
15476     }
15477
15478   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15479
15480   mp->is_add = is_add;
15481   mp->esn = esn;
15482   mp->anti_replay = anti_replay;
15483
15484   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15485   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15486
15487   mp->local_spi = htonl (local_spi);
15488   mp->remote_spi = htonl (remote_spi);
15489   mp->crypto_alg = (u8) crypto_alg;
15490
15491   mp->local_crypto_key_len = 0;
15492   if (lck)
15493     {
15494       mp->local_crypto_key_len = vec_len (lck);
15495       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15496         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15497       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15498     }
15499
15500   mp->remote_crypto_key_len = 0;
15501   if (rck)
15502     {
15503       mp->remote_crypto_key_len = vec_len (rck);
15504       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15505         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15506       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15507     }
15508
15509   mp->integ_alg = (u8) integ_alg;
15510
15511   mp->local_integ_key_len = 0;
15512   if (lik)
15513     {
15514       mp->local_integ_key_len = vec_len (lik);
15515       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15516         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15517       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15518     }
15519
15520   mp->remote_integ_key_len = 0;
15521   if (rik)
15522     {
15523       mp->remote_integ_key_len = vec_len (rik);
15524       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15525         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15526       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15527     }
15528
15529   if (renumber)
15530     {
15531       mp->renumber = renumber;
15532       mp->show_instance = ntohl (instance);
15533     }
15534
15535   S (mp);
15536   W (ret);
15537   return ret;
15538 }
15539
15540 static void
15541 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15542 {
15543   vat_main_t *vam = &vat_main;
15544
15545   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15546          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15547          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15548          "tunnel_src_addr %U tunnel_dst_addr %U "
15549          "salt %u seq_outbound %lu last_seq_inbound %lu "
15550          "replay_window %lu total_data_size %lu\n",
15551          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15552          mp->protocol,
15553          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15554          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15555          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15556          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15557          mp->tunnel_src_addr,
15558          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15559          mp->tunnel_dst_addr,
15560          ntohl (mp->salt),
15561          clib_net_to_host_u64 (mp->seq_outbound),
15562          clib_net_to_host_u64 (mp->last_seq_inbound),
15563          clib_net_to_host_u64 (mp->replay_window),
15564          clib_net_to_host_u64 (mp->total_data_size));
15565 }
15566
15567 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15568 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15569
15570 static void vl_api_ipsec_sa_details_t_handler_json
15571   (vl_api_ipsec_sa_details_t * mp)
15572 {
15573   vat_main_t *vam = &vat_main;
15574   vat_json_node_t *node = NULL;
15575   struct in_addr src_ip4, dst_ip4;
15576   struct in6_addr src_ip6, dst_ip6;
15577
15578   if (VAT_JSON_ARRAY != vam->json_tree.type)
15579     {
15580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15581       vat_json_init_array (&vam->json_tree);
15582     }
15583   node = vat_json_array_add (&vam->json_tree);
15584
15585   vat_json_init_object (node);
15586   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15587   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15588   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15589   vat_json_object_add_uint (node, "proto", mp->protocol);
15590   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15591   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15592   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15593   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15594   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15595   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15596   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15597                              mp->crypto_key_len);
15598   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15599                              mp->integ_key_len);
15600   if (mp->is_tunnel_ip6)
15601     {
15602       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15603       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15604       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15605       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15606     }
15607   else
15608     {
15609       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15610       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15611       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15612       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15613     }
15614   vat_json_object_add_uint (node, "replay_window",
15615                             clib_net_to_host_u64 (mp->replay_window));
15616   vat_json_object_add_uint (node, "total_data_size",
15617                             clib_net_to_host_u64 (mp->total_data_size));
15618
15619 }
15620
15621 static int
15622 api_ipsec_sa_dump (vat_main_t * vam)
15623 {
15624   unformat_input_t *i = vam->input;
15625   vl_api_ipsec_sa_dump_t *mp;
15626   vl_api_control_ping_t *mp_ping;
15627   u32 sa_id = ~0;
15628   int ret;
15629
15630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15631     {
15632       if (unformat (i, "sa_id %d", &sa_id))
15633         ;
15634       else
15635         {
15636           clib_warning ("parse error '%U'", format_unformat_error, i);
15637           return -99;
15638         }
15639     }
15640
15641   M (IPSEC_SA_DUMP, mp);
15642
15643   mp->sa_id = ntohl (sa_id);
15644
15645   S (mp);
15646
15647   /* Use a control ping for synchronization */
15648   M (CONTROL_PING, mp_ping);
15649   S (mp_ping);
15650
15651   W (ret);
15652   return ret;
15653 }
15654
15655 static int
15656 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15657 {
15658   unformat_input_t *i = vam->input;
15659   vl_api_ipsec_tunnel_if_set_key_t *mp;
15660   u32 sw_if_index = ~0;
15661   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15662   u8 *key = 0;
15663   u32 alg = ~0;
15664   int ret;
15665
15666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15667     {
15668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15669         ;
15670       else
15671         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15672         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15673       else
15674         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15675         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15676       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15677         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15678       else
15679         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15680         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15681       else if (unformat (i, "%U", unformat_hex_string, &key))
15682         ;
15683       else
15684         {
15685           clib_warning ("parse error '%U'", format_unformat_error, i);
15686           return -99;
15687         }
15688     }
15689
15690   if (sw_if_index == ~0)
15691     {
15692       errmsg ("interface must be specified");
15693       return -99;
15694     }
15695
15696   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15697     {
15698       errmsg ("key type must be specified");
15699       return -99;
15700     }
15701
15702   if (alg == ~0)
15703     {
15704       errmsg ("algorithm must be specified");
15705       return -99;
15706     }
15707
15708   if (vec_len (key) == 0)
15709     {
15710       errmsg ("key must be specified");
15711       return -99;
15712     }
15713
15714   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15715
15716   mp->sw_if_index = htonl (sw_if_index);
15717   mp->alg = alg;
15718   mp->key_type = key_type;
15719   mp->key_len = vec_len (key);
15720   clib_memcpy (mp->key, key, vec_len (key));
15721
15722   S (mp);
15723   W (ret);
15724
15725   return ret;
15726 }
15727
15728 static int
15729 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15730 {
15731   unformat_input_t *i = vam->input;
15732   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15733   u32 sw_if_index = ~0;
15734   u32 sa_id = ~0;
15735   u8 is_outbound = (u8) ~ 0;
15736   int ret;
15737
15738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15739     {
15740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15741         ;
15742       else if (unformat (i, "sa_id %d", &sa_id))
15743         ;
15744       else if (unformat (i, "outbound"))
15745         is_outbound = 1;
15746       else if (unformat (i, "inbound"))
15747         is_outbound = 0;
15748       else
15749         {
15750           clib_warning ("parse error '%U'", format_unformat_error, i);
15751           return -99;
15752         }
15753     }
15754
15755   if (sw_if_index == ~0)
15756     {
15757       errmsg ("interface must be specified");
15758       return -99;
15759     }
15760
15761   if (sa_id == ~0)
15762     {
15763       errmsg ("SA ID must be specified");
15764       return -99;
15765     }
15766
15767   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15768
15769   mp->sw_if_index = htonl (sw_if_index);
15770   mp->sa_id = htonl (sa_id);
15771   mp->is_outbound = is_outbound;
15772
15773   S (mp);
15774   W (ret);
15775
15776   return ret;
15777 }
15778
15779 static int
15780 api_ikev2_profile_add_del (vat_main_t * vam)
15781 {
15782   unformat_input_t *i = vam->input;
15783   vl_api_ikev2_profile_add_del_t *mp;
15784   u8 is_add = 1;
15785   u8 *name = 0;
15786   int ret;
15787
15788   const char *valid_chars = "a-zA-Z0-9_";
15789
15790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15791     {
15792       if (unformat (i, "del"))
15793         is_add = 0;
15794       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15795         vec_add1 (name, 0);
15796       else
15797         {
15798           errmsg ("parse error '%U'", format_unformat_error, i);
15799           return -99;
15800         }
15801     }
15802
15803   if (!vec_len (name))
15804     {
15805       errmsg ("profile name must be specified");
15806       return -99;
15807     }
15808
15809   if (vec_len (name) > 64)
15810     {
15811       errmsg ("profile name too long");
15812       return -99;
15813     }
15814
15815   M (IKEV2_PROFILE_ADD_DEL, mp);
15816
15817   clib_memcpy (mp->name, name, vec_len (name));
15818   mp->is_add = is_add;
15819   vec_free (name);
15820
15821   S (mp);
15822   W (ret);
15823   return ret;
15824 }
15825
15826 static int
15827 api_ikev2_profile_set_auth (vat_main_t * vam)
15828 {
15829   unformat_input_t *i = vam->input;
15830   vl_api_ikev2_profile_set_auth_t *mp;
15831   u8 *name = 0;
15832   u8 *data = 0;
15833   u32 auth_method = 0;
15834   u8 is_hex = 0;
15835   int ret;
15836
15837   const char *valid_chars = "a-zA-Z0-9_";
15838
15839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15840     {
15841       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15842         vec_add1 (name, 0);
15843       else if (unformat (i, "auth_method %U",
15844                          unformat_ikev2_auth_method, &auth_method))
15845         ;
15846       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15847         is_hex = 1;
15848       else if (unformat (i, "auth_data %v", &data))
15849         ;
15850       else
15851         {
15852           errmsg ("parse error '%U'", format_unformat_error, i);
15853           return -99;
15854         }
15855     }
15856
15857   if (!vec_len (name))
15858     {
15859       errmsg ("profile name must be specified");
15860       return -99;
15861     }
15862
15863   if (vec_len (name) > 64)
15864     {
15865       errmsg ("profile name too long");
15866       return -99;
15867     }
15868
15869   if (!vec_len (data))
15870     {
15871       errmsg ("auth_data must be specified");
15872       return -99;
15873     }
15874
15875   if (!auth_method)
15876     {
15877       errmsg ("auth_method must be specified");
15878       return -99;
15879     }
15880
15881   M (IKEV2_PROFILE_SET_AUTH, mp);
15882
15883   mp->is_hex = is_hex;
15884   mp->auth_method = (u8) auth_method;
15885   mp->data_len = vec_len (data);
15886   clib_memcpy (mp->name, name, vec_len (name));
15887   clib_memcpy (mp->data, data, vec_len (data));
15888   vec_free (name);
15889   vec_free (data);
15890
15891   S (mp);
15892   W (ret);
15893   return ret;
15894 }
15895
15896 static int
15897 api_ikev2_profile_set_id (vat_main_t * vam)
15898 {
15899   unformat_input_t *i = vam->input;
15900   vl_api_ikev2_profile_set_id_t *mp;
15901   u8 *name = 0;
15902   u8 *data = 0;
15903   u8 is_local = 0;
15904   u32 id_type = 0;
15905   ip4_address_t ip4;
15906   int ret;
15907
15908   const char *valid_chars = "a-zA-Z0-9_";
15909
15910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15911     {
15912       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15913         vec_add1 (name, 0);
15914       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
15915         ;
15916       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
15917         {
15918           data = vec_new (u8, 4);
15919           clib_memcpy (data, ip4.as_u8, 4);
15920         }
15921       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
15922         ;
15923       else if (unformat (i, "id_data %v", &data))
15924         ;
15925       else if (unformat (i, "local"))
15926         is_local = 1;
15927       else if (unformat (i, "remote"))
15928         is_local = 0;
15929       else
15930         {
15931           errmsg ("parse error '%U'", format_unformat_error, i);
15932           return -99;
15933         }
15934     }
15935
15936   if (!vec_len (name))
15937     {
15938       errmsg ("profile name must be specified");
15939       return -99;
15940     }
15941
15942   if (vec_len (name) > 64)
15943     {
15944       errmsg ("profile name too long");
15945       return -99;
15946     }
15947
15948   if (!vec_len (data))
15949     {
15950       errmsg ("id_data must be specified");
15951       return -99;
15952     }
15953
15954   if (!id_type)
15955     {
15956       errmsg ("id_type must be specified");
15957       return -99;
15958     }
15959
15960   M (IKEV2_PROFILE_SET_ID, mp);
15961
15962   mp->is_local = is_local;
15963   mp->id_type = (u8) id_type;
15964   mp->data_len = vec_len (data);
15965   clib_memcpy (mp->name, name, vec_len (name));
15966   clib_memcpy (mp->data, data, vec_len (data));
15967   vec_free (name);
15968   vec_free (data);
15969
15970   S (mp);
15971   W (ret);
15972   return ret;
15973 }
15974
15975 static int
15976 api_ikev2_profile_set_ts (vat_main_t * vam)
15977 {
15978   unformat_input_t *i = vam->input;
15979   vl_api_ikev2_profile_set_ts_t *mp;
15980   u8 *name = 0;
15981   u8 is_local = 0;
15982   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
15983   ip4_address_t start_addr, end_addr;
15984
15985   const char *valid_chars = "a-zA-Z0-9_";
15986   int ret;
15987
15988   start_addr.as_u32 = 0;
15989   end_addr.as_u32 = (u32) ~ 0;
15990
15991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15992     {
15993       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15994         vec_add1 (name, 0);
15995       else if (unformat (i, "protocol %d", &proto))
15996         ;
15997       else if (unformat (i, "start_port %d", &start_port))
15998         ;
15999       else if (unformat (i, "end_port %d", &end_port))
16000         ;
16001       else
16002         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16003         ;
16004       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16005         ;
16006       else if (unformat (i, "local"))
16007         is_local = 1;
16008       else if (unformat (i, "remote"))
16009         is_local = 0;
16010       else
16011         {
16012           errmsg ("parse error '%U'", format_unformat_error, i);
16013           return -99;
16014         }
16015     }
16016
16017   if (!vec_len (name))
16018     {
16019       errmsg ("profile name must be specified");
16020       return -99;
16021     }
16022
16023   if (vec_len (name) > 64)
16024     {
16025       errmsg ("profile name too long");
16026       return -99;
16027     }
16028
16029   M (IKEV2_PROFILE_SET_TS, mp);
16030
16031   mp->is_local = is_local;
16032   mp->proto = (u8) proto;
16033   mp->start_port = (u16) start_port;
16034   mp->end_port = (u16) end_port;
16035   mp->start_addr = start_addr.as_u32;
16036   mp->end_addr = end_addr.as_u32;
16037   clib_memcpy (mp->name, name, vec_len (name));
16038   vec_free (name);
16039
16040   S (mp);
16041   W (ret);
16042   return ret;
16043 }
16044
16045 static int
16046 api_ikev2_set_local_key (vat_main_t * vam)
16047 {
16048   unformat_input_t *i = vam->input;
16049   vl_api_ikev2_set_local_key_t *mp;
16050   u8 *file = 0;
16051   int ret;
16052
16053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16054     {
16055       if (unformat (i, "file %v", &file))
16056         vec_add1 (file, 0);
16057       else
16058         {
16059           errmsg ("parse error '%U'", format_unformat_error, i);
16060           return -99;
16061         }
16062     }
16063
16064   if (!vec_len (file))
16065     {
16066       errmsg ("RSA key file must be specified");
16067       return -99;
16068     }
16069
16070   if (vec_len (file) > 256)
16071     {
16072       errmsg ("file name too long");
16073       return -99;
16074     }
16075
16076   M (IKEV2_SET_LOCAL_KEY, mp);
16077
16078   clib_memcpy (mp->key_file, file, vec_len (file));
16079   vec_free (file);
16080
16081   S (mp);
16082   W (ret);
16083   return ret;
16084 }
16085
16086 static int
16087 api_ikev2_set_responder (vat_main_t * vam)
16088 {
16089   unformat_input_t *i = vam->input;
16090   vl_api_ikev2_set_responder_t *mp;
16091   int ret;
16092   u8 *name = 0;
16093   u32 sw_if_index = ~0;
16094   ip4_address_t address;
16095
16096   const char *valid_chars = "a-zA-Z0-9_";
16097
16098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat
16101           (i, "%U interface %d address %U", unformat_token, valid_chars,
16102            &name, &sw_if_index, unformat_ip4_address, &address))
16103         vec_add1 (name, 0);
16104       else
16105         {
16106           errmsg ("parse error '%U'", format_unformat_error, i);
16107           return -99;
16108         }
16109     }
16110
16111   if (!vec_len (name))
16112     {
16113       errmsg ("profile name must be specified");
16114       return -99;
16115     }
16116
16117   if (vec_len (name) > 64)
16118     {
16119       errmsg ("profile name too long");
16120       return -99;
16121     }
16122
16123   M (IKEV2_SET_RESPONDER, mp);
16124
16125   clib_memcpy (mp->name, name, vec_len (name));
16126   vec_free (name);
16127
16128   mp->sw_if_index = sw_if_index;
16129   clib_memcpy (mp->address, &address, sizeof (address));
16130
16131   S (mp);
16132   W (ret);
16133   return ret;
16134 }
16135
16136 static int
16137 api_ikev2_set_ike_transforms (vat_main_t * vam)
16138 {
16139   unformat_input_t *i = vam->input;
16140   vl_api_ikev2_set_ike_transforms_t *mp;
16141   int ret;
16142   u8 *name = 0;
16143   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16144
16145   const char *valid_chars = "a-zA-Z0-9_";
16146
16147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16148     {
16149       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16150                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16151         vec_add1 (name, 0);
16152       else
16153         {
16154           errmsg ("parse error '%U'", format_unformat_error, i);
16155           return -99;
16156         }
16157     }
16158
16159   if (!vec_len (name))
16160     {
16161       errmsg ("profile name must be specified");
16162       return -99;
16163     }
16164
16165   if (vec_len (name) > 64)
16166     {
16167       errmsg ("profile name too long");
16168       return -99;
16169     }
16170
16171   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16172
16173   clib_memcpy (mp->name, name, vec_len (name));
16174   vec_free (name);
16175   mp->crypto_alg = crypto_alg;
16176   mp->crypto_key_size = crypto_key_size;
16177   mp->integ_alg = integ_alg;
16178   mp->dh_group = dh_group;
16179
16180   S (mp);
16181   W (ret);
16182   return ret;
16183 }
16184
16185
16186 static int
16187 api_ikev2_set_esp_transforms (vat_main_t * vam)
16188 {
16189   unformat_input_t *i = vam->input;
16190   vl_api_ikev2_set_esp_transforms_t *mp;
16191   int ret;
16192   u8 *name = 0;
16193   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16194
16195   const char *valid_chars = "a-zA-Z0-9_";
16196
16197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16198     {
16199       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16200                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16201         vec_add1 (name, 0);
16202       else
16203         {
16204           errmsg ("parse error '%U'", format_unformat_error, i);
16205           return -99;
16206         }
16207     }
16208
16209   if (!vec_len (name))
16210     {
16211       errmsg ("profile name must be specified");
16212       return -99;
16213     }
16214
16215   if (vec_len (name) > 64)
16216     {
16217       errmsg ("profile name too long");
16218       return -99;
16219     }
16220
16221   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16222
16223   clib_memcpy (mp->name, name, vec_len (name));
16224   vec_free (name);
16225   mp->crypto_alg = crypto_alg;
16226   mp->crypto_key_size = crypto_key_size;
16227   mp->integ_alg = integ_alg;
16228   mp->dh_group = dh_group;
16229
16230   S (mp);
16231   W (ret);
16232   return ret;
16233 }
16234
16235 static int
16236 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16237 {
16238   unformat_input_t *i = vam->input;
16239   vl_api_ikev2_set_sa_lifetime_t *mp;
16240   int ret;
16241   u8 *name = 0;
16242   u64 lifetime, lifetime_maxdata;
16243   u32 lifetime_jitter, handover;
16244
16245   const char *valid_chars = "a-zA-Z0-9_";
16246
16247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16248     {
16249       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16250                     &lifetime, &lifetime_jitter, &handover,
16251                     &lifetime_maxdata))
16252         vec_add1 (name, 0);
16253       else
16254         {
16255           errmsg ("parse error '%U'", format_unformat_error, i);
16256           return -99;
16257         }
16258     }
16259
16260   if (!vec_len (name))
16261     {
16262       errmsg ("profile name must be specified");
16263       return -99;
16264     }
16265
16266   if (vec_len (name) > 64)
16267     {
16268       errmsg ("profile name too long");
16269       return -99;
16270     }
16271
16272   M (IKEV2_SET_SA_LIFETIME, mp);
16273
16274   clib_memcpy (mp->name, name, vec_len (name));
16275   vec_free (name);
16276   mp->lifetime = lifetime;
16277   mp->lifetime_jitter = lifetime_jitter;
16278   mp->handover = handover;
16279   mp->lifetime_maxdata = lifetime_maxdata;
16280
16281   S (mp);
16282   W (ret);
16283   return ret;
16284 }
16285
16286 static int
16287 api_ikev2_initiate_sa_init (vat_main_t * vam)
16288 {
16289   unformat_input_t *i = vam->input;
16290   vl_api_ikev2_initiate_sa_init_t *mp;
16291   int ret;
16292   u8 *name = 0;
16293
16294   const char *valid_chars = "a-zA-Z0-9_";
16295
16296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16297     {
16298       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16299         vec_add1 (name, 0);
16300       else
16301         {
16302           errmsg ("parse error '%U'", format_unformat_error, i);
16303           return -99;
16304         }
16305     }
16306
16307   if (!vec_len (name))
16308     {
16309       errmsg ("profile name must be specified");
16310       return -99;
16311     }
16312
16313   if (vec_len (name) > 64)
16314     {
16315       errmsg ("profile name too long");
16316       return -99;
16317     }
16318
16319   M (IKEV2_INITIATE_SA_INIT, mp);
16320
16321   clib_memcpy (mp->name, name, vec_len (name));
16322   vec_free (name);
16323
16324   S (mp);
16325   W (ret);
16326   return ret;
16327 }
16328
16329 static int
16330 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16331 {
16332   unformat_input_t *i = vam->input;
16333   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16334   int ret;
16335   u64 ispi;
16336
16337
16338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16339     {
16340       if (unformat (i, "%lx", &ispi))
16341         ;
16342       else
16343         {
16344           errmsg ("parse error '%U'", format_unformat_error, i);
16345           return -99;
16346         }
16347     }
16348
16349   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16350
16351   mp->ispi = ispi;
16352
16353   S (mp);
16354   W (ret);
16355   return ret;
16356 }
16357
16358 static int
16359 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16360 {
16361   unformat_input_t *i = vam->input;
16362   vl_api_ikev2_initiate_del_child_sa_t *mp;
16363   int ret;
16364   u32 ispi;
16365
16366
16367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16368     {
16369       if (unformat (i, "%x", &ispi))
16370         ;
16371       else
16372         {
16373           errmsg ("parse error '%U'", format_unformat_error, i);
16374           return -99;
16375         }
16376     }
16377
16378   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16379
16380   mp->ispi = ispi;
16381
16382   S (mp);
16383   W (ret);
16384   return ret;
16385 }
16386
16387 static int
16388 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16389 {
16390   unformat_input_t *i = vam->input;
16391   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16392   int ret;
16393   u32 ispi;
16394
16395
16396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16397     {
16398       if (unformat (i, "%x", &ispi))
16399         ;
16400       else
16401         {
16402           errmsg ("parse error '%U'", format_unformat_error, i);
16403           return -99;
16404         }
16405     }
16406
16407   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16408
16409   mp->ispi = ispi;
16410
16411   S (mp);
16412   W (ret);
16413   return ret;
16414 }
16415
16416 static int
16417 api_get_first_msg_id (vat_main_t * vam)
16418 {
16419   vl_api_get_first_msg_id_t *mp;
16420   unformat_input_t *i = vam->input;
16421   u8 *name;
16422   u8 name_set = 0;
16423   int ret;
16424
16425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16426     {
16427       if (unformat (i, "client %s", &name))
16428         name_set = 1;
16429       else
16430         break;
16431     }
16432
16433   if (name_set == 0)
16434     {
16435       errmsg ("missing client name");
16436       return -99;
16437     }
16438   vec_add1 (name, 0);
16439
16440   if (vec_len (name) > 63)
16441     {
16442       errmsg ("client name too long");
16443       return -99;
16444     }
16445
16446   M (GET_FIRST_MSG_ID, mp);
16447   clib_memcpy (mp->name, name, vec_len (name));
16448   S (mp);
16449   W (ret);
16450   return ret;
16451 }
16452
16453 static int
16454 api_cop_interface_enable_disable (vat_main_t * vam)
16455 {
16456   unformat_input_t *line_input = vam->input;
16457   vl_api_cop_interface_enable_disable_t *mp;
16458   u32 sw_if_index = ~0;
16459   u8 enable_disable = 1;
16460   int ret;
16461
16462   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16463     {
16464       if (unformat (line_input, "disable"))
16465         enable_disable = 0;
16466       if (unformat (line_input, "enable"))
16467         enable_disable = 1;
16468       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16469                          vam, &sw_if_index))
16470         ;
16471       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16472         ;
16473       else
16474         break;
16475     }
16476
16477   if (sw_if_index == ~0)
16478     {
16479       errmsg ("missing interface name or sw_if_index");
16480       return -99;
16481     }
16482
16483   /* Construct the API message */
16484   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16485   mp->sw_if_index = ntohl (sw_if_index);
16486   mp->enable_disable = enable_disable;
16487
16488   /* send it... */
16489   S (mp);
16490   /* Wait for the reply */
16491   W (ret);
16492   return ret;
16493 }
16494
16495 static int
16496 api_cop_whitelist_enable_disable (vat_main_t * vam)
16497 {
16498   unformat_input_t *line_input = vam->input;
16499   vl_api_cop_whitelist_enable_disable_t *mp;
16500   u32 sw_if_index = ~0;
16501   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16502   u32 fib_id = 0;
16503   int ret;
16504
16505   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16506     {
16507       if (unformat (line_input, "ip4"))
16508         ip4 = 1;
16509       else if (unformat (line_input, "ip6"))
16510         ip6 = 1;
16511       else if (unformat (line_input, "default"))
16512         default_cop = 1;
16513       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16514                          vam, &sw_if_index))
16515         ;
16516       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16517         ;
16518       else if (unformat (line_input, "fib-id %d", &fib_id))
16519         ;
16520       else
16521         break;
16522     }
16523
16524   if (sw_if_index == ~0)
16525     {
16526       errmsg ("missing interface name or sw_if_index");
16527       return -99;
16528     }
16529
16530   /* Construct the API message */
16531   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16532   mp->sw_if_index = ntohl (sw_if_index);
16533   mp->fib_id = ntohl (fib_id);
16534   mp->ip4 = ip4;
16535   mp->ip6 = ip6;
16536   mp->default_cop = default_cop;
16537
16538   /* send it... */
16539   S (mp);
16540   /* Wait for the reply */
16541   W (ret);
16542   return ret;
16543 }
16544
16545 static int
16546 api_get_node_graph (vat_main_t * vam)
16547 {
16548   vl_api_get_node_graph_t *mp;
16549   int ret;
16550
16551   M (GET_NODE_GRAPH, mp);
16552
16553   /* send it... */
16554   S (mp);
16555   /* Wait for the reply */
16556   W (ret);
16557   return ret;
16558 }
16559
16560 /* *INDENT-OFF* */
16561 /** Used for parsing LISP eids */
16562 typedef CLIB_PACKED(struct{
16563   u8 addr[16];   /**< eid address */
16564   u32 len;       /**< prefix length if IP */
16565   u8 type;      /**< type of eid */
16566 }) lisp_eid_vat_t;
16567 /* *INDENT-ON* */
16568
16569 static uword
16570 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16571 {
16572   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16573
16574   memset (a, 0, sizeof (a[0]));
16575
16576   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16577     {
16578       a->type = 0;              /* ipv4 type */
16579     }
16580   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16581     {
16582       a->type = 1;              /* ipv6 type */
16583     }
16584   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16585     {
16586       a->type = 2;              /* mac type */
16587     }
16588   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16589     {
16590       a->type = 3;              /* NSH type */
16591       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16592       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16593     }
16594   else
16595     {
16596       return 0;
16597     }
16598
16599   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16600     {
16601       return 0;
16602     }
16603
16604   return 1;
16605 }
16606
16607 static int
16608 lisp_eid_size_vat (u8 type)
16609 {
16610   switch (type)
16611     {
16612     case 0:
16613       return 4;
16614     case 1:
16615       return 16;
16616     case 2:
16617       return 6;
16618     case 3:
16619       return 5;
16620     }
16621   return 0;
16622 }
16623
16624 static void
16625 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16626 {
16627   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16628 }
16629
16630 static int
16631 api_one_add_del_locator_set (vat_main_t * vam)
16632 {
16633   unformat_input_t *input = vam->input;
16634   vl_api_one_add_del_locator_set_t *mp;
16635   u8 is_add = 1;
16636   u8 *locator_set_name = NULL;
16637   u8 locator_set_name_set = 0;
16638   vl_api_local_locator_t locator, *locators = 0;
16639   u32 sw_if_index, priority, weight;
16640   u32 data_len = 0;
16641
16642   int ret;
16643   /* Parse args required to build the message */
16644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16645     {
16646       if (unformat (input, "del"))
16647         {
16648           is_add = 0;
16649         }
16650       else if (unformat (input, "locator-set %s", &locator_set_name))
16651         {
16652           locator_set_name_set = 1;
16653         }
16654       else if (unformat (input, "sw_if_index %u p %u w %u",
16655                          &sw_if_index, &priority, &weight))
16656         {
16657           locator.sw_if_index = htonl (sw_if_index);
16658           locator.priority = priority;
16659           locator.weight = weight;
16660           vec_add1 (locators, locator);
16661         }
16662       else
16663         if (unformat
16664             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16665              &sw_if_index, &priority, &weight))
16666         {
16667           locator.sw_if_index = htonl (sw_if_index);
16668           locator.priority = priority;
16669           locator.weight = weight;
16670           vec_add1 (locators, locator);
16671         }
16672       else
16673         break;
16674     }
16675
16676   if (locator_set_name_set == 0)
16677     {
16678       errmsg ("missing locator-set name");
16679       vec_free (locators);
16680       return -99;
16681     }
16682
16683   if (vec_len (locator_set_name) > 64)
16684     {
16685       errmsg ("locator-set name too long");
16686       vec_free (locator_set_name);
16687       vec_free (locators);
16688       return -99;
16689     }
16690   vec_add1 (locator_set_name, 0);
16691
16692   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16693
16694   /* Construct the API message */
16695   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16696
16697   mp->is_add = is_add;
16698   clib_memcpy (mp->locator_set_name, locator_set_name,
16699                vec_len (locator_set_name));
16700   vec_free (locator_set_name);
16701
16702   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16703   if (locators)
16704     clib_memcpy (mp->locators, locators, data_len);
16705   vec_free (locators);
16706
16707   /* send it... */
16708   S (mp);
16709
16710   /* Wait for a reply... */
16711   W (ret);
16712   return ret;
16713 }
16714
16715 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16716
16717 static int
16718 api_one_add_del_locator (vat_main_t * vam)
16719 {
16720   unformat_input_t *input = vam->input;
16721   vl_api_one_add_del_locator_t *mp;
16722   u32 tmp_if_index = ~0;
16723   u32 sw_if_index = ~0;
16724   u8 sw_if_index_set = 0;
16725   u8 sw_if_index_if_name_set = 0;
16726   u32 priority = ~0;
16727   u8 priority_set = 0;
16728   u32 weight = ~0;
16729   u8 weight_set = 0;
16730   u8 is_add = 1;
16731   u8 *locator_set_name = NULL;
16732   u8 locator_set_name_set = 0;
16733   int ret;
16734
16735   /* Parse args required to build the message */
16736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16737     {
16738       if (unformat (input, "del"))
16739         {
16740           is_add = 0;
16741         }
16742       else if (unformat (input, "locator-set %s", &locator_set_name))
16743         {
16744           locator_set_name_set = 1;
16745         }
16746       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16747                          &tmp_if_index))
16748         {
16749           sw_if_index_if_name_set = 1;
16750           sw_if_index = tmp_if_index;
16751         }
16752       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16753         {
16754           sw_if_index_set = 1;
16755           sw_if_index = tmp_if_index;
16756         }
16757       else if (unformat (input, "p %d", &priority))
16758         {
16759           priority_set = 1;
16760         }
16761       else if (unformat (input, "w %d", &weight))
16762         {
16763           weight_set = 1;
16764         }
16765       else
16766         break;
16767     }
16768
16769   if (locator_set_name_set == 0)
16770     {
16771       errmsg ("missing locator-set name");
16772       return -99;
16773     }
16774
16775   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16776     {
16777       errmsg ("missing sw_if_index");
16778       vec_free (locator_set_name);
16779       return -99;
16780     }
16781
16782   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16783     {
16784       errmsg ("cannot use both params interface name and sw_if_index");
16785       vec_free (locator_set_name);
16786       return -99;
16787     }
16788
16789   if (priority_set == 0)
16790     {
16791       errmsg ("missing locator-set priority");
16792       vec_free (locator_set_name);
16793       return -99;
16794     }
16795
16796   if (weight_set == 0)
16797     {
16798       errmsg ("missing locator-set weight");
16799       vec_free (locator_set_name);
16800       return -99;
16801     }
16802
16803   if (vec_len (locator_set_name) > 64)
16804     {
16805       errmsg ("locator-set name too long");
16806       vec_free (locator_set_name);
16807       return -99;
16808     }
16809   vec_add1 (locator_set_name, 0);
16810
16811   /* Construct the API message */
16812   M (ONE_ADD_DEL_LOCATOR, mp);
16813
16814   mp->is_add = is_add;
16815   mp->sw_if_index = ntohl (sw_if_index);
16816   mp->priority = priority;
16817   mp->weight = weight;
16818   clib_memcpy (mp->locator_set_name, locator_set_name,
16819                vec_len (locator_set_name));
16820   vec_free (locator_set_name);
16821
16822   /* send it... */
16823   S (mp);
16824
16825   /* Wait for a reply... */
16826   W (ret);
16827   return ret;
16828 }
16829
16830 #define api_lisp_add_del_locator api_one_add_del_locator
16831
16832 uword
16833 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16834 {
16835   u32 *key_id = va_arg (*args, u32 *);
16836   u8 *s = 0;
16837
16838   if (unformat (input, "%s", &s))
16839     {
16840       if (!strcmp ((char *) s, "sha1"))
16841         key_id[0] = HMAC_SHA_1_96;
16842       else if (!strcmp ((char *) s, "sha256"))
16843         key_id[0] = HMAC_SHA_256_128;
16844       else
16845         {
16846           clib_warning ("invalid key_id: '%s'", s);
16847           key_id[0] = HMAC_NO_KEY;
16848         }
16849     }
16850   else
16851     return 0;
16852
16853   vec_free (s);
16854   return 1;
16855 }
16856
16857 static int
16858 api_one_add_del_local_eid (vat_main_t * vam)
16859 {
16860   unformat_input_t *input = vam->input;
16861   vl_api_one_add_del_local_eid_t *mp;
16862   u8 is_add = 1;
16863   u8 eid_set = 0;
16864   lisp_eid_vat_t _eid, *eid = &_eid;
16865   u8 *locator_set_name = 0;
16866   u8 locator_set_name_set = 0;
16867   u32 vni = 0;
16868   u16 key_id = 0;
16869   u8 *key = 0;
16870   int ret;
16871
16872   /* Parse args required to build the message */
16873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16874     {
16875       if (unformat (input, "del"))
16876         {
16877           is_add = 0;
16878         }
16879       else if (unformat (input, "vni %d", &vni))
16880         {
16881           ;
16882         }
16883       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16884         {
16885           eid_set = 1;
16886         }
16887       else if (unformat (input, "locator-set %s", &locator_set_name))
16888         {
16889           locator_set_name_set = 1;
16890         }
16891       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16892         ;
16893       else if (unformat (input, "secret-key %_%v%_", &key))
16894         ;
16895       else
16896         break;
16897     }
16898
16899   if (locator_set_name_set == 0)
16900     {
16901       errmsg ("missing locator-set name");
16902       return -99;
16903     }
16904
16905   if (0 == eid_set)
16906     {
16907       errmsg ("EID address not set!");
16908       vec_free (locator_set_name);
16909       return -99;
16910     }
16911
16912   if (key && (0 == key_id))
16913     {
16914       errmsg ("invalid key_id!");
16915       return -99;
16916     }
16917
16918   if (vec_len (key) > 64)
16919     {
16920       errmsg ("key too long");
16921       vec_free (key);
16922       return -99;
16923     }
16924
16925   if (vec_len (locator_set_name) > 64)
16926     {
16927       errmsg ("locator-set name too long");
16928       vec_free (locator_set_name);
16929       return -99;
16930     }
16931   vec_add1 (locator_set_name, 0);
16932
16933   /* Construct the API message */
16934   M (ONE_ADD_DEL_LOCAL_EID, mp);
16935
16936   mp->is_add = is_add;
16937   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16938   mp->eid_type = eid->type;
16939   mp->prefix_len = eid->len;
16940   mp->vni = clib_host_to_net_u32 (vni);
16941   mp->key_id = clib_host_to_net_u16 (key_id);
16942   clib_memcpy (mp->locator_set_name, locator_set_name,
16943                vec_len (locator_set_name));
16944   clib_memcpy (mp->key, key, vec_len (key));
16945
16946   vec_free (locator_set_name);
16947   vec_free (key);
16948
16949   /* send it... */
16950   S (mp);
16951
16952   /* Wait for a reply... */
16953   W (ret);
16954   return ret;
16955 }
16956
16957 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16958
16959 static int
16960 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16961 {
16962   u32 dp_table = 0, vni = 0;;
16963   unformat_input_t *input = vam->input;
16964   vl_api_gpe_add_del_fwd_entry_t *mp;
16965   u8 is_add = 1;
16966   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16967   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16968   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16969   u32 action = ~0, w;
16970   ip4_address_t rmt_rloc4, lcl_rloc4;
16971   ip6_address_t rmt_rloc6, lcl_rloc6;
16972   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16973   int ret;
16974
16975   memset (&rloc, 0, sizeof (rloc));
16976
16977   /* Parse args required to build the message */
16978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16979     {
16980       if (unformat (input, "del"))
16981         is_add = 0;
16982       else if (unformat (input, "add"))
16983         is_add = 1;
16984       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16985         {
16986           rmt_eid_set = 1;
16987         }
16988       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16989         {
16990           lcl_eid_set = 1;
16991         }
16992       else if (unformat (input, "vrf %d", &dp_table))
16993         ;
16994       else if (unformat (input, "bd %d", &dp_table))
16995         ;
16996       else if (unformat (input, "vni %d", &vni))
16997         ;
16998       else if (unformat (input, "w %d", &w))
16999         {
17000           if (!curr_rloc)
17001             {
17002               errmsg ("No RLOC configured for setting priority/weight!");
17003               return -99;
17004             }
17005           curr_rloc->weight = w;
17006         }
17007       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17008                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17009         {
17010           rloc.is_ip4 = 1;
17011
17012           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17013           rloc.weight = 0;
17014           vec_add1 (lcl_locs, rloc);
17015
17016           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17017           vec_add1 (rmt_locs, rloc);
17018           /* weight saved in rmt loc */
17019           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17020         }
17021       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17022                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17023         {
17024           rloc.is_ip4 = 0;
17025           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17026           rloc.weight = 0;
17027           vec_add1 (lcl_locs, rloc);
17028
17029           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17030           vec_add1 (rmt_locs, rloc);
17031           /* weight saved in rmt loc */
17032           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17033         }
17034       else if (unformat (input, "action %d", &action))
17035         {
17036           ;
17037         }
17038       else
17039         {
17040           clib_warning ("parse error '%U'", format_unformat_error, input);
17041           return -99;
17042         }
17043     }
17044
17045   if (!rmt_eid_set)
17046     {
17047       errmsg ("remote eid addresses not set");
17048       return -99;
17049     }
17050
17051   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17052     {
17053       errmsg ("eid types don't match");
17054       return -99;
17055     }
17056
17057   if (0 == rmt_locs && (u32) ~ 0 == action)
17058     {
17059       errmsg ("action not set for negative mapping");
17060       return -99;
17061     }
17062
17063   /* Construct the API message */
17064   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17065       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17066
17067   mp->is_add = is_add;
17068   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17069   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17070   mp->eid_type = rmt_eid->type;
17071   mp->dp_table = clib_host_to_net_u32 (dp_table);
17072   mp->vni = clib_host_to_net_u32 (vni);
17073   mp->rmt_len = rmt_eid->len;
17074   mp->lcl_len = lcl_eid->len;
17075   mp->action = action;
17076
17077   if (0 != rmt_locs && 0 != lcl_locs)
17078     {
17079       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17080       clib_memcpy (mp->locs, lcl_locs,
17081                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17082
17083       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17084       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17085                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17086     }
17087   vec_free (lcl_locs);
17088   vec_free (rmt_locs);
17089
17090   /* send it... */
17091   S (mp);
17092
17093   /* Wait for a reply... */
17094   W (ret);
17095   return ret;
17096 }
17097
17098 static int
17099 api_one_add_del_map_server (vat_main_t * vam)
17100 {
17101   unformat_input_t *input = vam->input;
17102   vl_api_one_add_del_map_server_t *mp;
17103   u8 is_add = 1;
17104   u8 ipv4_set = 0;
17105   u8 ipv6_set = 0;
17106   ip4_address_t ipv4;
17107   ip6_address_t ipv6;
17108   int ret;
17109
17110   /* Parse args required to build the message */
17111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17112     {
17113       if (unformat (input, "del"))
17114         {
17115           is_add = 0;
17116         }
17117       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17118         {
17119           ipv4_set = 1;
17120         }
17121       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17122         {
17123           ipv6_set = 1;
17124         }
17125       else
17126         break;
17127     }
17128
17129   if (ipv4_set && ipv6_set)
17130     {
17131       errmsg ("both eid v4 and v6 addresses set");
17132       return -99;
17133     }
17134
17135   if (!ipv4_set && !ipv6_set)
17136     {
17137       errmsg ("eid addresses not set");
17138       return -99;
17139     }
17140
17141   /* Construct the API message */
17142   M (ONE_ADD_DEL_MAP_SERVER, mp);
17143
17144   mp->is_add = is_add;
17145   if (ipv6_set)
17146     {
17147       mp->is_ipv6 = 1;
17148       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17149     }
17150   else
17151     {
17152       mp->is_ipv6 = 0;
17153       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17154     }
17155
17156   /* send it... */
17157   S (mp);
17158
17159   /* Wait for a reply... */
17160   W (ret);
17161   return ret;
17162 }
17163
17164 #define api_lisp_add_del_map_server api_one_add_del_map_server
17165
17166 static int
17167 api_one_add_del_map_resolver (vat_main_t * vam)
17168 {
17169   unformat_input_t *input = vam->input;
17170   vl_api_one_add_del_map_resolver_t *mp;
17171   u8 is_add = 1;
17172   u8 ipv4_set = 0;
17173   u8 ipv6_set = 0;
17174   ip4_address_t ipv4;
17175   ip6_address_t ipv6;
17176   int ret;
17177
17178   /* Parse args required to build the message */
17179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17180     {
17181       if (unformat (input, "del"))
17182         {
17183           is_add = 0;
17184         }
17185       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17186         {
17187           ipv4_set = 1;
17188         }
17189       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17190         {
17191           ipv6_set = 1;
17192         }
17193       else
17194         break;
17195     }
17196
17197   if (ipv4_set && ipv6_set)
17198     {
17199       errmsg ("both eid v4 and v6 addresses set");
17200       return -99;
17201     }
17202
17203   if (!ipv4_set && !ipv6_set)
17204     {
17205       errmsg ("eid addresses not set");
17206       return -99;
17207     }
17208
17209   /* Construct the API message */
17210   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17211
17212   mp->is_add = is_add;
17213   if (ipv6_set)
17214     {
17215       mp->is_ipv6 = 1;
17216       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17217     }
17218   else
17219     {
17220       mp->is_ipv6 = 0;
17221       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17222     }
17223
17224   /* send it... */
17225   S (mp);
17226
17227   /* Wait for a reply... */
17228   W (ret);
17229   return ret;
17230 }
17231
17232 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17233
17234 static int
17235 api_lisp_gpe_enable_disable (vat_main_t * vam)
17236 {
17237   unformat_input_t *input = vam->input;
17238   vl_api_gpe_enable_disable_t *mp;
17239   u8 is_set = 0;
17240   u8 is_en = 1;
17241   int ret;
17242
17243   /* Parse args required to build the message */
17244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17245     {
17246       if (unformat (input, "enable"))
17247         {
17248           is_set = 1;
17249           is_en = 1;
17250         }
17251       else if (unformat (input, "disable"))
17252         {
17253           is_set = 1;
17254           is_en = 0;
17255         }
17256       else
17257         break;
17258     }
17259
17260   if (is_set == 0)
17261     {
17262       errmsg ("Value not set");
17263       return -99;
17264     }
17265
17266   /* Construct the API message */
17267   M (GPE_ENABLE_DISABLE, mp);
17268
17269   mp->is_en = is_en;
17270
17271   /* send it... */
17272   S (mp);
17273
17274   /* Wait for a reply... */
17275   W (ret);
17276   return ret;
17277 }
17278
17279 static int
17280 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17281 {
17282   unformat_input_t *input = vam->input;
17283   vl_api_one_rloc_probe_enable_disable_t *mp;
17284   u8 is_set = 0;
17285   u8 is_en = 0;
17286   int ret;
17287
17288   /* Parse args required to build the message */
17289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17290     {
17291       if (unformat (input, "enable"))
17292         {
17293           is_set = 1;
17294           is_en = 1;
17295         }
17296       else if (unformat (input, "disable"))
17297         is_set = 1;
17298       else
17299         break;
17300     }
17301
17302   if (!is_set)
17303     {
17304       errmsg ("Value not set");
17305       return -99;
17306     }
17307
17308   /* Construct the API message */
17309   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17310
17311   mp->is_enabled = is_en;
17312
17313   /* send it... */
17314   S (mp);
17315
17316   /* Wait for a reply... */
17317   W (ret);
17318   return ret;
17319 }
17320
17321 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17322
17323 static int
17324 api_one_map_register_enable_disable (vat_main_t * vam)
17325 {
17326   unformat_input_t *input = vam->input;
17327   vl_api_one_map_register_enable_disable_t *mp;
17328   u8 is_set = 0;
17329   u8 is_en = 0;
17330   int ret;
17331
17332   /* Parse args required to build the message */
17333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17334     {
17335       if (unformat (input, "enable"))
17336         {
17337           is_set = 1;
17338           is_en = 1;
17339         }
17340       else if (unformat (input, "disable"))
17341         is_set = 1;
17342       else
17343         break;
17344     }
17345
17346   if (!is_set)
17347     {
17348       errmsg ("Value not set");
17349       return -99;
17350     }
17351
17352   /* Construct the API message */
17353   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17354
17355   mp->is_enabled = is_en;
17356
17357   /* send it... */
17358   S (mp);
17359
17360   /* Wait for a reply... */
17361   W (ret);
17362   return ret;
17363 }
17364
17365 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17366
17367 static int
17368 api_one_enable_disable (vat_main_t * vam)
17369 {
17370   unformat_input_t *input = vam->input;
17371   vl_api_one_enable_disable_t *mp;
17372   u8 is_set = 0;
17373   u8 is_en = 0;
17374   int ret;
17375
17376   /* Parse args required to build the message */
17377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17378     {
17379       if (unformat (input, "enable"))
17380         {
17381           is_set = 1;
17382           is_en = 1;
17383         }
17384       else if (unformat (input, "disable"))
17385         {
17386           is_set = 1;
17387         }
17388       else
17389         break;
17390     }
17391
17392   if (!is_set)
17393     {
17394       errmsg ("Value not set");
17395       return -99;
17396     }
17397
17398   /* Construct the API message */
17399   M (ONE_ENABLE_DISABLE, mp);
17400
17401   mp->is_en = is_en;
17402
17403   /* send it... */
17404   S (mp);
17405
17406   /* Wait for a reply... */
17407   W (ret);
17408   return ret;
17409 }
17410
17411 #define api_lisp_enable_disable api_one_enable_disable
17412
17413 static int
17414 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17415 {
17416   unformat_input_t *input = vam->input;
17417   vl_api_one_enable_disable_xtr_mode_t *mp;
17418   u8 is_set = 0;
17419   u8 is_en = 0;
17420   int ret;
17421
17422   /* Parse args required to build the message */
17423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17424     {
17425       if (unformat (input, "enable"))
17426         {
17427           is_set = 1;
17428           is_en = 1;
17429         }
17430       else if (unformat (input, "disable"))
17431         {
17432           is_set = 1;
17433         }
17434       else
17435         break;
17436     }
17437
17438   if (!is_set)
17439     {
17440       errmsg ("Value not set");
17441       return -99;
17442     }
17443
17444   /* Construct the API message */
17445   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17446
17447   mp->is_en = is_en;
17448
17449   /* send it... */
17450   S (mp);
17451
17452   /* Wait for a reply... */
17453   W (ret);
17454   return ret;
17455 }
17456
17457 static int
17458 api_one_show_xtr_mode (vat_main_t * vam)
17459 {
17460   vl_api_one_show_xtr_mode_t *mp;
17461   int ret;
17462
17463   /* Construct the API message */
17464   M (ONE_SHOW_XTR_MODE, mp);
17465
17466   /* send it... */
17467   S (mp);
17468
17469   /* Wait for a reply... */
17470   W (ret);
17471   return ret;
17472 }
17473
17474 static int
17475 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17476 {
17477   unformat_input_t *input = vam->input;
17478   vl_api_one_enable_disable_pitr_mode_t *mp;
17479   u8 is_set = 0;
17480   u8 is_en = 0;
17481   int ret;
17482
17483   /* Parse args required to build the message */
17484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17485     {
17486       if (unformat (input, "enable"))
17487         {
17488           is_set = 1;
17489           is_en = 1;
17490         }
17491       else if (unformat (input, "disable"))
17492         {
17493           is_set = 1;
17494         }
17495       else
17496         break;
17497     }
17498
17499   if (!is_set)
17500     {
17501       errmsg ("Value not set");
17502       return -99;
17503     }
17504
17505   /* Construct the API message */
17506   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17507
17508   mp->is_en = is_en;
17509
17510   /* send it... */
17511   S (mp);
17512
17513   /* Wait for a reply... */
17514   W (ret);
17515   return ret;
17516 }
17517
17518 static int
17519 api_one_show_pitr_mode (vat_main_t * vam)
17520 {
17521   vl_api_one_show_pitr_mode_t *mp;
17522   int ret;
17523
17524   /* Construct the API message */
17525   M (ONE_SHOW_PITR_MODE, mp);
17526
17527   /* send it... */
17528   S (mp);
17529
17530   /* Wait for a reply... */
17531   W (ret);
17532   return ret;
17533 }
17534
17535 static int
17536 api_one_enable_disable_petr_mode (vat_main_t * vam)
17537 {
17538   unformat_input_t *input = vam->input;
17539   vl_api_one_enable_disable_petr_mode_t *mp;
17540   u8 is_set = 0;
17541   u8 is_en = 0;
17542   int ret;
17543
17544   /* Parse args required to build the message */
17545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17546     {
17547       if (unformat (input, "enable"))
17548         {
17549           is_set = 1;
17550           is_en = 1;
17551         }
17552       else if (unformat (input, "disable"))
17553         {
17554           is_set = 1;
17555         }
17556       else
17557         break;
17558     }
17559
17560   if (!is_set)
17561     {
17562       errmsg ("Value not set");
17563       return -99;
17564     }
17565
17566   /* Construct the API message */
17567   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17568
17569   mp->is_en = is_en;
17570
17571   /* send it... */
17572   S (mp);
17573
17574   /* Wait for a reply... */
17575   W (ret);
17576   return ret;
17577 }
17578
17579 static int
17580 api_one_show_petr_mode (vat_main_t * vam)
17581 {
17582   vl_api_one_show_petr_mode_t *mp;
17583   int ret;
17584
17585   /* Construct the API message */
17586   M (ONE_SHOW_PETR_MODE, mp);
17587
17588   /* send it... */
17589   S (mp);
17590
17591   /* Wait for a reply... */
17592   W (ret);
17593   return ret;
17594 }
17595
17596 static int
17597 api_show_one_map_register_state (vat_main_t * vam)
17598 {
17599   vl_api_show_one_map_register_state_t *mp;
17600   int ret;
17601
17602   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17603
17604   /* send */
17605   S (mp);
17606
17607   /* wait for reply */
17608   W (ret);
17609   return ret;
17610 }
17611
17612 #define api_show_lisp_map_register_state api_show_one_map_register_state
17613
17614 static int
17615 api_show_one_rloc_probe_state (vat_main_t * vam)
17616 {
17617   vl_api_show_one_rloc_probe_state_t *mp;
17618   int ret;
17619
17620   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17621
17622   /* send */
17623   S (mp);
17624
17625   /* wait for reply */
17626   W (ret);
17627   return ret;
17628 }
17629
17630 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17631
17632 static int
17633 api_one_add_del_ndp_entry (vat_main_t * vam)
17634 {
17635   vl_api_one_add_del_ndp_entry_t *mp;
17636   unformat_input_t *input = vam->input;
17637   u8 is_add = 1;
17638   u8 mac_set = 0;
17639   u8 bd_set = 0;
17640   u8 ip_set = 0;
17641   u8 mac[6] = { 0, };
17642   u8 ip6[16] = { 0, };
17643   u32 bd = ~0;
17644   int ret;
17645
17646   /* Parse args required to build the message */
17647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17648     {
17649       if (unformat (input, "del"))
17650         is_add = 0;
17651       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17652         mac_set = 1;
17653       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17654         ip_set = 1;
17655       else if (unformat (input, "bd %d", &bd))
17656         bd_set = 1;
17657       else
17658         {
17659           errmsg ("parse error '%U'", format_unformat_error, input);
17660           return -99;
17661         }
17662     }
17663
17664   if (!bd_set || !ip_set || (!mac_set && is_add))
17665     {
17666       errmsg ("Missing BD, IP or MAC!");
17667       return -99;
17668     }
17669
17670   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17671   mp->is_add = is_add;
17672   clib_memcpy (mp->mac, mac, 6);
17673   mp->bd = clib_host_to_net_u32 (bd);
17674   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17675
17676   /* send */
17677   S (mp);
17678
17679   /* wait for reply */
17680   W (ret);
17681   return ret;
17682 }
17683
17684 static int
17685 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17686 {
17687   vl_api_one_add_del_l2_arp_entry_t *mp;
17688   unformat_input_t *input = vam->input;
17689   u8 is_add = 1;
17690   u8 mac_set = 0;
17691   u8 bd_set = 0;
17692   u8 ip_set = 0;
17693   u8 mac[6] = { 0, };
17694   u32 ip4 = 0, bd = ~0;
17695   int ret;
17696
17697   /* Parse args required to build the message */
17698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17699     {
17700       if (unformat (input, "del"))
17701         is_add = 0;
17702       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17703         mac_set = 1;
17704       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17705         ip_set = 1;
17706       else if (unformat (input, "bd %d", &bd))
17707         bd_set = 1;
17708       else
17709         {
17710           errmsg ("parse error '%U'", format_unformat_error, input);
17711           return -99;
17712         }
17713     }
17714
17715   if (!bd_set || !ip_set || (!mac_set && is_add))
17716     {
17717       errmsg ("Missing BD, IP or MAC!");
17718       return -99;
17719     }
17720
17721   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17722   mp->is_add = is_add;
17723   clib_memcpy (mp->mac, mac, 6);
17724   mp->bd = clib_host_to_net_u32 (bd);
17725   mp->ip4 = ip4;
17726
17727   /* send */
17728   S (mp);
17729
17730   /* wait for reply */
17731   W (ret);
17732   return ret;
17733 }
17734
17735 static int
17736 api_one_ndp_bd_get (vat_main_t * vam)
17737 {
17738   vl_api_one_ndp_bd_get_t *mp;
17739   int ret;
17740
17741   M (ONE_NDP_BD_GET, mp);
17742
17743   /* send */
17744   S (mp);
17745
17746   /* wait for reply */
17747   W (ret);
17748   return ret;
17749 }
17750
17751 static int
17752 api_one_ndp_entries_get (vat_main_t * vam)
17753 {
17754   vl_api_one_ndp_entries_get_t *mp;
17755   unformat_input_t *input = vam->input;
17756   u8 bd_set = 0;
17757   u32 bd = ~0;
17758   int ret;
17759
17760   /* Parse args required to build the message */
17761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17762     {
17763       if (unformat (input, "bd %d", &bd))
17764         bd_set = 1;
17765       else
17766         {
17767           errmsg ("parse error '%U'", format_unformat_error, input);
17768           return -99;
17769         }
17770     }
17771
17772   if (!bd_set)
17773     {
17774       errmsg ("Expected bridge domain!");
17775       return -99;
17776     }
17777
17778   M (ONE_NDP_ENTRIES_GET, mp);
17779   mp->bd = clib_host_to_net_u32 (bd);
17780
17781   /* send */
17782   S (mp);
17783
17784   /* wait for reply */
17785   W (ret);
17786   return ret;
17787 }
17788
17789 static int
17790 api_one_l2_arp_bd_get (vat_main_t * vam)
17791 {
17792   vl_api_one_l2_arp_bd_get_t *mp;
17793   int ret;
17794
17795   M (ONE_L2_ARP_BD_GET, mp);
17796
17797   /* send */
17798   S (mp);
17799
17800   /* wait for reply */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 static int
17806 api_one_l2_arp_entries_get (vat_main_t * vam)
17807 {
17808   vl_api_one_l2_arp_entries_get_t *mp;
17809   unformat_input_t *input = vam->input;
17810   u8 bd_set = 0;
17811   u32 bd = ~0;
17812   int ret;
17813
17814   /* Parse args required to build the message */
17815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17816     {
17817       if (unformat (input, "bd %d", &bd))
17818         bd_set = 1;
17819       else
17820         {
17821           errmsg ("parse error '%U'", format_unformat_error, input);
17822           return -99;
17823         }
17824     }
17825
17826   if (!bd_set)
17827     {
17828       errmsg ("Expected bridge domain!");
17829       return -99;
17830     }
17831
17832   M (ONE_L2_ARP_ENTRIES_GET, mp);
17833   mp->bd = clib_host_to_net_u32 (bd);
17834
17835   /* send */
17836   S (mp);
17837
17838   /* wait for reply */
17839   W (ret);
17840   return ret;
17841 }
17842
17843 static int
17844 api_one_stats_enable_disable (vat_main_t * vam)
17845 {
17846   vl_api_one_stats_enable_disable_t *mp;
17847   unformat_input_t *input = vam->input;
17848   u8 is_set = 0;
17849   u8 is_en = 0;
17850   int ret;
17851
17852   /* Parse args required to build the message */
17853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17854     {
17855       if (unformat (input, "enable"))
17856         {
17857           is_set = 1;
17858           is_en = 1;
17859         }
17860       else if (unformat (input, "disable"))
17861         {
17862           is_set = 1;
17863         }
17864       else
17865         break;
17866     }
17867
17868   if (!is_set)
17869     {
17870       errmsg ("Value not set");
17871       return -99;
17872     }
17873
17874   M (ONE_STATS_ENABLE_DISABLE, mp);
17875   mp->is_en = is_en;
17876
17877   /* send */
17878   S (mp);
17879
17880   /* wait for reply */
17881   W (ret);
17882   return ret;
17883 }
17884
17885 static int
17886 api_show_one_stats_enable_disable (vat_main_t * vam)
17887 {
17888   vl_api_show_one_stats_enable_disable_t *mp;
17889   int ret;
17890
17891   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17892
17893   /* send */
17894   S (mp);
17895
17896   /* wait for reply */
17897   W (ret);
17898   return ret;
17899 }
17900
17901 static int
17902 api_show_one_map_request_mode (vat_main_t * vam)
17903 {
17904   vl_api_show_one_map_request_mode_t *mp;
17905   int ret;
17906
17907   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17908
17909   /* send */
17910   S (mp);
17911
17912   /* wait for reply */
17913   W (ret);
17914   return ret;
17915 }
17916
17917 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17918
17919 static int
17920 api_one_map_request_mode (vat_main_t * vam)
17921 {
17922   unformat_input_t *input = vam->input;
17923   vl_api_one_map_request_mode_t *mp;
17924   u8 mode = 0;
17925   int ret;
17926
17927   /* Parse args required to build the message */
17928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17929     {
17930       if (unformat (input, "dst-only"))
17931         mode = 0;
17932       else if (unformat (input, "src-dst"))
17933         mode = 1;
17934       else
17935         {
17936           errmsg ("parse error '%U'", format_unformat_error, input);
17937           return -99;
17938         }
17939     }
17940
17941   M (ONE_MAP_REQUEST_MODE, mp);
17942
17943   mp->mode = mode;
17944
17945   /* send */
17946   S (mp);
17947
17948   /* wait for reply */
17949   W (ret);
17950   return ret;
17951 }
17952
17953 #define api_lisp_map_request_mode api_one_map_request_mode
17954
17955 /**
17956  * Enable/disable ONE proxy ITR.
17957  *
17958  * @param vam vpp API test context
17959  * @return return code
17960  */
17961 static int
17962 api_one_pitr_set_locator_set (vat_main_t * vam)
17963 {
17964   u8 ls_name_set = 0;
17965   unformat_input_t *input = vam->input;
17966   vl_api_one_pitr_set_locator_set_t *mp;
17967   u8 is_add = 1;
17968   u8 *ls_name = 0;
17969   int ret;
17970
17971   /* Parse args required to build the message */
17972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17973     {
17974       if (unformat (input, "del"))
17975         is_add = 0;
17976       else if (unformat (input, "locator-set %s", &ls_name))
17977         ls_name_set = 1;
17978       else
17979         {
17980           errmsg ("parse error '%U'", format_unformat_error, input);
17981           return -99;
17982         }
17983     }
17984
17985   if (!ls_name_set)
17986     {
17987       errmsg ("locator-set name not set!");
17988       return -99;
17989     }
17990
17991   M (ONE_PITR_SET_LOCATOR_SET, mp);
17992
17993   mp->is_add = is_add;
17994   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17995   vec_free (ls_name);
17996
17997   /* send */
17998   S (mp);
17999
18000   /* wait for reply */
18001   W (ret);
18002   return ret;
18003 }
18004
18005 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18006
18007 static int
18008 api_one_nsh_set_locator_set (vat_main_t * vam)
18009 {
18010   u8 ls_name_set = 0;
18011   unformat_input_t *input = vam->input;
18012   vl_api_one_nsh_set_locator_set_t *mp;
18013   u8 is_add = 1;
18014   u8 *ls_name = 0;
18015   int ret;
18016
18017   /* Parse args required to build the message */
18018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18019     {
18020       if (unformat (input, "del"))
18021         is_add = 0;
18022       else if (unformat (input, "ls %s", &ls_name))
18023         ls_name_set = 1;
18024       else
18025         {
18026           errmsg ("parse error '%U'", format_unformat_error, input);
18027           return -99;
18028         }
18029     }
18030
18031   if (!ls_name_set && is_add)
18032     {
18033       errmsg ("locator-set name not set!");
18034       return -99;
18035     }
18036
18037   M (ONE_NSH_SET_LOCATOR_SET, mp);
18038
18039   mp->is_add = is_add;
18040   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18041   vec_free (ls_name);
18042
18043   /* send */
18044   S (mp);
18045
18046   /* wait for reply */
18047   W (ret);
18048   return ret;
18049 }
18050
18051 static int
18052 api_show_one_pitr (vat_main_t * vam)
18053 {
18054   vl_api_show_one_pitr_t *mp;
18055   int ret;
18056
18057   if (!vam->json_output)
18058     {
18059       print (vam->ofp, "%=20s", "lisp status:");
18060     }
18061
18062   M (SHOW_ONE_PITR, mp);
18063   /* send it... */
18064   S (mp);
18065
18066   /* Wait for a reply... */
18067   W (ret);
18068   return ret;
18069 }
18070
18071 #define api_show_lisp_pitr api_show_one_pitr
18072
18073 static int
18074 api_one_use_petr (vat_main_t * vam)
18075 {
18076   unformat_input_t *input = vam->input;
18077   vl_api_one_use_petr_t *mp;
18078   u8 is_add = 0;
18079   ip_address_t ip;
18080   int ret;
18081
18082   memset (&ip, 0, sizeof (ip));
18083
18084   /* Parse args required to build the message */
18085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (input, "disable"))
18088         is_add = 0;
18089       else
18090         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18091         {
18092           is_add = 1;
18093           ip_addr_version (&ip) = IP4;
18094         }
18095       else
18096         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18097         {
18098           is_add = 1;
18099           ip_addr_version (&ip) = IP6;
18100         }
18101       else
18102         {
18103           errmsg ("parse error '%U'", format_unformat_error, input);
18104           return -99;
18105         }
18106     }
18107
18108   M (ONE_USE_PETR, mp);
18109
18110   mp->is_add = is_add;
18111   if (is_add)
18112     {
18113       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18114       if (mp->is_ip4)
18115         clib_memcpy (mp->address, &ip, 4);
18116       else
18117         clib_memcpy (mp->address, &ip, 16);
18118     }
18119
18120   /* send */
18121   S (mp);
18122
18123   /* wait for reply */
18124   W (ret);
18125   return ret;
18126 }
18127
18128 #define api_lisp_use_petr api_one_use_petr
18129
18130 static int
18131 api_show_one_nsh_mapping (vat_main_t * vam)
18132 {
18133   vl_api_show_one_use_petr_t *mp;
18134   int ret;
18135
18136   if (!vam->json_output)
18137     {
18138       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18139     }
18140
18141   M (SHOW_ONE_NSH_MAPPING, mp);
18142   /* send it... */
18143   S (mp);
18144
18145   /* Wait for a reply... */
18146   W (ret);
18147   return ret;
18148 }
18149
18150 static int
18151 api_show_one_use_petr (vat_main_t * vam)
18152 {
18153   vl_api_show_one_use_petr_t *mp;
18154   int ret;
18155
18156   if (!vam->json_output)
18157     {
18158       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18159     }
18160
18161   M (SHOW_ONE_USE_PETR, mp);
18162   /* send it... */
18163   S (mp);
18164
18165   /* Wait for a reply... */
18166   W (ret);
18167   return ret;
18168 }
18169
18170 #define api_show_lisp_use_petr api_show_one_use_petr
18171
18172 /**
18173  * Add/delete mapping between vni and vrf
18174  */
18175 static int
18176 api_one_eid_table_add_del_map (vat_main_t * vam)
18177 {
18178   unformat_input_t *input = vam->input;
18179   vl_api_one_eid_table_add_del_map_t *mp;
18180   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18181   u32 vni, vrf, bd_index;
18182   int ret;
18183
18184   /* Parse args required to build the message */
18185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18186     {
18187       if (unformat (input, "del"))
18188         is_add = 0;
18189       else if (unformat (input, "vrf %d", &vrf))
18190         vrf_set = 1;
18191       else if (unformat (input, "bd_index %d", &bd_index))
18192         bd_index_set = 1;
18193       else if (unformat (input, "vni %d", &vni))
18194         vni_set = 1;
18195       else
18196         break;
18197     }
18198
18199   if (!vni_set || (!vrf_set && !bd_index_set))
18200     {
18201       errmsg ("missing arguments!");
18202       return -99;
18203     }
18204
18205   if (vrf_set && bd_index_set)
18206     {
18207       errmsg ("error: both vrf and bd entered!");
18208       return -99;
18209     }
18210
18211   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18212
18213   mp->is_add = is_add;
18214   mp->vni = htonl (vni);
18215   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18216   mp->is_l2 = bd_index_set;
18217
18218   /* send */
18219   S (mp);
18220
18221   /* wait for reply */
18222   W (ret);
18223   return ret;
18224 }
18225
18226 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18227
18228 uword
18229 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18230 {
18231   u32 *action = va_arg (*args, u32 *);
18232   u8 *s = 0;
18233
18234   if (unformat (input, "%s", &s))
18235     {
18236       if (!strcmp ((char *) s, "no-action"))
18237         action[0] = 0;
18238       else if (!strcmp ((char *) s, "natively-forward"))
18239         action[0] = 1;
18240       else if (!strcmp ((char *) s, "send-map-request"))
18241         action[0] = 2;
18242       else if (!strcmp ((char *) s, "drop"))
18243         action[0] = 3;
18244       else
18245         {
18246           clib_warning ("invalid action: '%s'", s);
18247           action[0] = 3;
18248         }
18249     }
18250   else
18251     return 0;
18252
18253   vec_free (s);
18254   return 1;
18255 }
18256
18257 /**
18258  * Add/del remote mapping to/from ONE control plane
18259  *
18260  * @param vam vpp API test context
18261  * @return return code
18262  */
18263 static int
18264 api_one_add_del_remote_mapping (vat_main_t * vam)
18265 {
18266   unformat_input_t *input = vam->input;
18267   vl_api_one_add_del_remote_mapping_t *mp;
18268   u32 vni = 0;
18269   lisp_eid_vat_t _eid, *eid = &_eid;
18270   lisp_eid_vat_t _seid, *seid = &_seid;
18271   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18272   u32 action = ~0, p, w, data_len;
18273   ip4_address_t rloc4;
18274   ip6_address_t rloc6;
18275   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18276   int ret;
18277
18278   memset (&rloc, 0, sizeof (rloc));
18279
18280   /* Parse args required to build the message */
18281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18282     {
18283       if (unformat (input, "del-all"))
18284         {
18285           del_all = 1;
18286         }
18287       else if (unformat (input, "del"))
18288         {
18289           is_add = 0;
18290         }
18291       else if (unformat (input, "add"))
18292         {
18293           is_add = 1;
18294         }
18295       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18296         {
18297           eid_set = 1;
18298         }
18299       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18300         {
18301           seid_set = 1;
18302         }
18303       else if (unformat (input, "vni %d", &vni))
18304         {
18305           ;
18306         }
18307       else if (unformat (input, "p %d w %d", &p, &w))
18308         {
18309           if (!curr_rloc)
18310             {
18311               errmsg ("No RLOC configured for setting priority/weight!");
18312               return -99;
18313             }
18314           curr_rloc->priority = p;
18315           curr_rloc->weight = w;
18316         }
18317       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18318         {
18319           rloc.is_ip4 = 1;
18320           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18321           vec_add1 (rlocs, rloc);
18322           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18323         }
18324       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18325         {
18326           rloc.is_ip4 = 0;
18327           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18328           vec_add1 (rlocs, rloc);
18329           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18330         }
18331       else if (unformat (input, "action %U",
18332                          unformat_negative_mapping_action, &action))
18333         {
18334           ;
18335         }
18336       else
18337         {
18338           clib_warning ("parse error '%U'", format_unformat_error, input);
18339           return -99;
18340         }
18341     }
18342
18343   if (0 == eid_set)
18344     {
18345       errmsg ("missing params!");
18346       return -99;
18347     }
18348
18349   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18350     {
18351       errmsg ("no action set for negative map-reply!");
18352       return -99;
18353     }
18354
18355   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18356
18357   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18358   mp->is_add = is_add;
18359   mp->vni = htonl (vni);
18360   mp->action = (u8) action;
18361   mp->is_src_dst = seid_set;
18362   mp->eid_len = eid->len;
18363   mp->seid_len = seid->len;
18364   mp->del_all = del_all;
18365   mp->eid_type = eid->type;
18366   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18367   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18368
18369   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18370   clib_memcpy (mp->rlocs, rlocs, data_len);
18371   vec_free (rlocs);
18372
18373   /* send it... */
18374   S (mp);
18375
18376   /* Wait for a reply... */
18377   W (ret);
18378   return ret;
18379 }
18380
18381 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18382
18383 /**
18384  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18385  * forwarding entries in data-plane accordingly.
18386  *
18387  * @param vam vpp API test context
18388  * @return return code
18389  */
18390 static int
18391 api_one_add_del_adjacency (vat_main_t * vam)
18392 {
18393   unformat_input_t *input = vam->input;
18394   vl_api_one_add_del_adjacency_t *mp;
18395   u32 vni = 0;
18396   ip4_address_t leid4, reid4;
18397   ip6_address_t leid6, reid6;
18398   u8 reid_mac[6] = { 0 };
18399   u8 leid_mac[6] = { 0 };
18400   u8 reid_type, leid_type;
18401   u32 leid_len = 0, reid_len = 0, len;
18402   u8 is_add = 1;
18403   int ret;
18404
18405   leid_type = reid_type = (u8) ~ 0;
18406
18407   /* Parse args required to build the message */
18408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18409     {
18410       if (unformat (input, "del"))
18411         {
18412           is_add = 0;
18413         }
18414       else if (unformat (input, "add"))
18415         {
18416           is_add = 1;
18417         }
18418       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18419                          &reid4, &len))
18420         {
18421           reid_type = 0;        /* ipv4 */
18422           reid_len = len;
18423         }
18424       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18425                          &reid6, &len))
18426         {
18427           reid_type = 1;        /* ipv6 */
18428           reid_len = len;
18429         }
18430       else if (unformat (input, "reid %U", unformat_ethernet_address,
18431                          reid_mac))
18432         {
18433           reid_type = 2;        /* mac */
18434         }
18435       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18436                          &leid4, &len))
18437         {
18438           leid_type = 0;        /* ipv4 */
18439           leid_len = len;
18440         }
18441       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18442                          &leid6, &len))
18443         {
18444           leid_type = 1;        /* ipv6 */
18445           leid_len = len;
18446         }
18447       else if (unformat (input, "leid %U", unformat_ethernet_address,
18448                          leid_mac))
18449         {
18450           leid_type = 2;        /* mac */
18451         }
18452       else if (unformat (input, "vni %d", &vni))
18453         {
18454           ;
18455         }
18456       else
18457         {
18458           errmsg ("parse error '%U'", format_unformat_error, input);
18459           return -99;
18460         }
18461     }
18462
18463   if ((u8) ~ 0 == reid_type)
18464     {
18465       errmsg ("missing params!");
18466       return -99;
18467     }
18468
18469   if (leid_type != reid_type)
18470     {
18471       errmsg ("remote and local EIDs are of different types!");
18472       return -99;
18473     }
18474
18475   M (ONE_ADD_DEL_ADJACENCY, mp);
18476   mp->is_add = is_add;
18477   mp->vni = htonl (vni);
18478   mp->leid_len = leid_len;
18479   mp->reid_len = reid_len;
18480   mp->eid_type = reid_type;
18481
18482   switch (mp->eid_type)
18483     {
18484     case 0:
18485       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18486       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18487       break;
18488     case 1:
18489       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18490       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18491       break;
18492     case 2:
18493       clib_memcpy (mp->leid, leid_mac, 6);
18494       clib_memcpy (mp->reid, reid_mac, 6);
18495       break;
18496     default:
18497       errmsg ("unknown EID type %d!", mp->eid_type);
18498       return 0;
18499     }
18500
18501   /* send it... */
18502   S (mp);
18503
18504   /* Wait for a reply... */
18505   W (ret);
18506   return ret;
18507 }
18508
18509 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18510
18511 uword
18512 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18513 {
18514   u32 *mode = va_arg (*args, u32 *);
18515
18516   if (unformat (input, "lisp"))
18517     *mode = 0;
18518   else if (unformat (input, "vxlan"))
18519     *mode = 1;
18520   else
18521     return 0;
18522
18523   return 1;
18524 }
18525
18526 static int
18527 api_gpe_get_encap_mode (vat_main_t * vam)
18528 {
18529   vl_api_gpe_get_encap_mode_t *mp;
18530   int ret;
18531
18532   /* Construct the API message */
18533   M (GPE_GET_ENCAP_MODE, mp);
18534
18535   /* send it... */
18536   S (mp);
18537
18538   /* Wait for a reply... */
18539   W (ret);
18540   return ret;
18541 }
18542
18543 static int
18544 api_gpe_set_encap_mode (vat_main_t * vam)
18545 {
18546   unformat_input_t *input = vam->input;
18547   vl_api_gpe_set_encap_mode_t *mp;
18548   int ret;
18549   u32 mode = 0;
18550
18551   /* Parse args required to build the message */
18552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18553     {
18554       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18555         ;
18556       else
18557         break;
18558     }
18559
18560   /* Construct the API message */
18561   M (GPE_SET_ENCAP_MODE, mp);
18562
18563   mp->mode = mode;
18564
18565   /* send it... */
18566   S (mp);
18567
18568   /* Wait for a reply... */
18569   W (ret);
18570   return ret;
18571 }
18572
18573 static int
18574 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18575 {
18576   unformat_input_t *input = vam->input;
18577   vl_api_gpe_add_del_iface_t *mp;
18578   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18579   u32 dp_table = 0, vni = 0;
18580   int ret;
18581
18582   /* Parse args required to build the message */
18583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18584     {
18585       if (unformat (input, "up"))
18586         {
18587           action_set = 1;
18588           is_add = 1;
18589         }
18590       else if (unformat (input, "down"))
18591         {
18592           action_set = 1;
18593           is_add = 0;
18594         }
18595       else if (unformat (input, "table_id %d", &dp_table))
18596         {
18597           dp_table_set = 1;
18598         }
18599       else if (unformat (input, "bd_id %d", &dp_table))
18600         {
18601           dp_table_set = 1;
18602           is_l2 = 1;
18603         }
18604       else if (unformat (input, "vni %d", &vni))
18605         {
18606           vni_set = 1;
18607         }
18608       else
18609         break;
18610     }
18611
18612   if (action_set == 0)
18613     {
18614       errmsg ("Action not set");
18615       return -99;
18616     }
18617   if (dp_table_set == 0 || vni_set == 0)
18618     {
18619       errmsg ("vni and dp_table must be set");
18620       return -99;
18621     }
18622
18623   /* Construct the API message */
18624   M (GPE_ADD_DEL_IFACE, mp);
18625
18626   mp->is_add = is_add;
18627   mp->dp_table = clib_host_to_net_u32 (dp_table);
18628   mp->is_l2 = is_l2;
18629   mp->vni = clib_host_to_net_u32 (vni);
18630
18631   /* send it... */
18632   S (mp);
18633
18634   /* Wait for a reply... */
18635   W (ret);
18636   return ret;
18637 }
18638
18639 static int
18640 api_one_map_register_fallback_threshold (vat_main_t * vam)
18641 {
18642   unformat_input_t *input = vam->input;
18643   vl_api_one_map_register_fallback_threshold_t *mp;
18644   u32 value = 0;
18645   u8 is_set = 0;
18646   int ret;
18647
18648   /* Parse args required to build the message */
18649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18650     {
18651       if (unformat (input, "%u", &value))
18652         is_set = 1;
18653       else
18654         {
18655           clib_warning ("parse error '%U'", format_unformat_error, input);
18656           return -99;
18657         }
18658     }
18659
18660   if (!is_set)
18661     {
18662       errmsg ("fallback threshold value is missing!");
18663       return -99;
18664     }
18665
18666   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18667   mp->value = clib_host_to_net_u32 (value);
18668
18669   /* send it... */
18670   S (mp);
18671
18672   /* Wait for a reply... */
18673   W (ret);
18674   return ret;
18675 }
18676
18677 static int
18678 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18679 {
18680   vl_api_show_one_map_register_fallback_threshold_t *mp;
18681   int ret;
18682
18683   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18684
18685   /* send it... */
18686   S (mp);
18687
18688   /* Wait for a reply... */
18689   W (ret);
18690   return ret;
18691 }
18692
18693 uword
18694 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18695 {
18696   u32 *proto = va_arg (*args, u32 *);
18697
18698   if (unformat (input, "udp"))
18699     *proto = 1;
18700   else if (unformat (input, "api"))
18701     *proto = 2;
18702   else
18703     return 0;
18704
18705   return 1;
18706 }
18707
18708 static int
18709 api_one_set_transport_protocol (vat_main_t * vam)
18710 {
18711   unformat_input_t *input = vam->input;
18712   vl_api_one_set_transport_protocol_t *mp;
18713   u8 is_set = 0;
18714   u32 protocol = 0;
18715   int ret;
18716
18717   /* Parse args required to build the message */
18718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18719     {
18720       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18721         is_set = 1;
18722       else
18723         {
18724           clib_warning ("parse error '%U'", format_unformat_error, input);
18725           return -99;
18726         }
18727     }
18728
18729   if (!is_set)
18730     {
18731       errmsg ("Transport protocol missing!");
18732       return -99;
18733     }
18734
18735   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18736   mp->protocol = (u8) protocol;
18737
18738   /* send it... */
18739   S (mp);
18740
18741   /* Wait for a reply... */
18742   W (ret);
18743   return ret;
18744 }
18745
18746 static int
18747 api_one_get_transport_protocol (vat_main_t * vam)
18748 {
18749   vl_api_one_get_transport_protocol_t *mp;
18750   int ret;
18751
18752   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18753
18754   /* send it... */
18755   S (mp);
18756
18757   /* Wait for a reply... */
18758   W (ret);
18759   return ret;
18760 }
18761
18762 static int
18763 api_one_map_register_set_ttl (vat_main_t * vam)
18764 {
18765   unformat_input_t *input = vam->input;
18766   vl_api_one_map_register_set_ttl_t *mp;
18767   u32 ttl = 0;
18768   u8 is_set = 0;
18769   int ret;
18770
18771   /* Parse args required to build the message */
18772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18773     {
18774       if (unformat (input, "%u", &ttl))
18775         is_set = 1;
18776       else
18777         {
18778           clib_warning ("parse error '%U'", format_unformat_error, input);
18779           return -99;
18780         }
18781     }
18782
18783   if (!is_set)
18784     {
18785       errmsg ("TTL value missing!");
18786       return -99;
18787     }
18788
18789   M (ONE_MAP_REGISTER_SET_TTL, mp);
18790   mp->ttl = clib_host_to_net_u32 (ttl);
18791
18792   /* send it... */
18793   S (mp);
18794
18795   /* Wait for a reply... */
18796   W (ret);
18797   return ret;
18798 }
18799
18800 static int
18801 api_show_one_map_register_ttl (vat_main_t * vam)
18802 {
18803   vl_api_show_one_map_register_ttl_t *mp;
18804   int ret;
18805
18806   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18807
18808   /* send it... */
18809   S (mp);
18810
18811   /* Wait for a reply... */
18812   W (ret);
18813   return ret;
18814 }
18815
18816 /**
18817  * Add/del map request itr rlocs from ONE control plane and updates
18818  *
18819  * @param vam vpp API test context
18820  * @return return code
18821  */
18822 static int
18823 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18824 {
18825   unformat_input_t *input = vam->input;
18826   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18827   u8 *locator_set_name = 0;
18828   u8 locator_set_name_set = 0;
18829   u8 is_add = 1;
18830   int ret;
18831
18832   /* Parse args required to build the message */
18833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18834     {
18835       if (unformat (input, "del"))
18836         {
18837           is_add = 0;
18838         }
18839       else if (unformat (input, "%_%v%_", &locator_set_name))
18840         {
18841           locator_set_name_set = 1;
18842         }
18843       else
18844         {
18845           clib_warning ("parse error '%U'", format_unformat_error, input);
18846           return -99;
18847         }
18848     }
18849
18850   if (is_add && !locator_set_name_set)
18851     {
18852       errmsg ("itr-rloc is not set!");
18853       return -99;
18854     }
18855
18856   if (is_add && vec_len (locator_set_name) > 64)
18857     {
18858       errmsg ("itr-rloc locator-set name too long");
18859       vec_free (locator_set_name);
18860       return -99;
18861     }
18862
18863   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18864   mp->is_add = is_add;
18865   if (is_add)
18866     {
18867       clib_memcpy (mp->locator_set_name, locator_set_name,
18868                    vec_len (locator_set_name));
18869     }
18870   else
18871     {
18872       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18873     }
18874   vec_free (locator_set_name);
18875
18876   /* send it... */
18877   S (mp);
18878
18879   /* Wait for a reply... */
18880   W (ret);
18881   return ret;
18882 }
18883
18884 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18885
18886 static int
18887 api_one_locator_dump (vat_main_t * vam)
18888 {
18889   unformat_input_t *input = vam->input;
18890   vl_api_one_locator_dump_t *mp;
18891   vl_api_control_ping_t *mp_ping;
18892   u8 is_index_set = 0, is_name_set = 0;
18893   u8 *ls_name = 0;
18894   u32 ls_index = ~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, "ls_name %_%v%_", &ls_name))
18901         {
18902           is_name_set = 1;
18903         }
18904       else if (unformat (input, "ls_index %d", &ls_index))
18905         {
18906           is_index_set = 1;
18907         }
18908       else
18909         {
18910           errmsg ("parse error '%U'", format_unformat_error, input);
18911           return -99;
18912         }
18913     }
18914
18915   if (!is_index_set && !is_name_set)
18916     {
18917       errmsg ("error: expected one of index or name!");
18918       return -99;
18919     }
18920
18921   if (is_index_set && is_name_set)
18922     {
18923       errmsg ("error: only one param expected!");
18924       return -99;
18925     }
18926
18927   if (vec_len (ls_name) > 62)
18928     {
18929       errmsg ("error: locator set name too long!");
18930       return -99;
18931     }
18932
18933   if (!vam->json_output)
18934     {
18935       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18936     }
18937
18938   M (ONE_LOCATOR_DUMP, mp);
18939   mp->is_index_set = is_index_set;
18940
18941   if (is_index_set)
18942     mp->ls_index = clib_host_to_net_u32 (ls_index);
18943   else
18944     {
18945       vec_add1 (ls_name, 0);
18946       strncpy ((char *) mp->ls_name, (char *) ls_name,
18947                sizeof (mp->ls_name) - 1);
18948     }
18949
18950   /* send it... */
18951   S (mp);
18952
18953   /* Use a control ping for synchronization */
18954   MPING (CONTROL_PING, mp_ping);
18955   S (mp_ping);
18956
18957   /* Wait for a reply... */
18958   W (ret);
18959   return ret;
18960 }
18961
18962 #define api_lisp_locator_dump api_one_locator_dump
18963
18964 static int
18965 api_one_locator_set_dump (vat_main_t * vam)
18966 {
18967   vl_api_one_locator_set_dump_t *mp;
18968   vl_api_control_ping_t *mp_ping;
18969   unformat_input_t *input = vam->input;
18970   u8 filter = 0;
18971   int ret;
18972
18973   /* Parse args required to build the message */
18974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18975     {
18976       if (unformat (input, "local"))
18977         {
18978           filter = 1;
18979         }
18980       else if (unformat (input, "remote"))
18981         {
18982           filter = 2;
18983         }
18984       else
18985         {
18986           errmsg ("parse error '%U'", format_unformat_error, input);
18987           return -99;
18988         }
18989     }
18990
18991   if (!vam->json_output)
18992     {
18993       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18994     }
18995
18996   M (ONE_LOCATOR_SET_DUMP, mp);
18997
18998   mp->filter = filter;
18999
19000   /* send it... */
19001   S (mp);
19002
19003   /* Use a control ping for synchronization */
19004   MPING (CONTROL_PING, mp_ping);
19005   S (mp_ping);
19006
19007   /* Wait for a reply... */
19008   W (ret);
19009   return ret;
19010 }
19011
19012 #define api_lisp_locator_set_dump api_one_locator_set_dump
19013
19014 static int
19015 api_one_eid_table_map_dump (vat_main_t * vam)
19016 {
19017   u8 is_l2 = 0;
19018   u8 mode_set = 0;
19019   unformat_input_t *input = vam->input;
19020   vl_api_one_eid_table_map_dump_t *mp;
19021   vl_api_control_ping_t *mp_ping;
19022   int ret;
19023
19024   /* Parse args required to build the message */
19025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19026     {
19027       if (unformat (input, "l2"))
19028         {
19029           is_l2 = 1;
19030           mode_set = 1;
19031         }
19032       else if (unformat (input, "l3"))
19033         {
19034           is_l2 = 0;
19035           mode_set = 1;
19036         }
19037       else
19038         {
19039           errmsg ("parse error '%U'", format_unformat_error, input);
19040           return -99;
19041         }
19042     }
19043
19044   if (!mode_set)
19045     {
19046       errmsg ("expected one of 'l2' or 'l3' parameter!");
19047       return -99;
19048     }
19049
19050   if (!vam->json_output)
19051     {
19052       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19053     }
19054
19055   M (ONE_EID_TABLE_MAP_DUMP, mp);
19056   mp->is_l2 = is_l2;
19057
19058   /* send it... */
19059   S (mp);
19060
19061   /* Use a control ping for synchronization */
19062   MPING (CONTROL_PING, mp_ping);
19063   S (mp_ping);
19064
19065   /* Wait for a reply... */
19066   W (ret);
19067   return ret;
19068 }
19069
19070 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19071
19072 static int
19073 api_one_eid_table_vni_dump (vat_main_t * vam)
19074 {
19075   vl_api_one_eid_table_vni_dump_t *mp;
19076   vl_api_control_ping_t *mp_ping;
19077   int ret;
19078
19079   if (!vam->json_output)
19080     {
19081       print (vam->ofp, "VNI");
19082     }
19083
19084   M (ONE_EID_TABLE_VNI_DUMP, mp);
19085
19086   /* send it... */
19087   S (mp);
19088
19089   /* Use a control ping for synchronization */
19090   MPING (CONTROL_PING, mp_ping);
19091   S (mp_ping);
19092
19093   /* Wait for a reply... */
19094   W (ret);
19095   return ret;
19096 }
19097
19098 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19099
19100 static int
19101 api_one_eid_table_dump (vat_main_t * vam)
19102 {
19103   unformat_input_t *i = vam->input;
19104   vl_api_one_eid_table_dump_t *mp;
19105   vl_api_control_ping_t *mp_ping;
19106   struct in_addr ip4;
19107   struct in6_addr ip6;
19108   u8 mac[6];
19109   u8 eid_type = ~0, eid_set = 0;
19110   u32 prefix_length = ~0, t, vni = 0;
19111   u8 filter = 0;
19112   int ret;
19113   lisp_nsh_api_t nsh;
19114
19115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19116     {
19117       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19118         {
19119           eid_set = 1;
19120           eid_type = 0;
19121           prefix_length = t;
19122         }
19123       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19124         {
19125           eid_set = 1;
19126           eid_type = 1;
19127           prefix_length = t;
19128         }
19129       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19130         {
19131           eid_set = 1;
19132           eid_type = 2;
19133         }
19134       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19135         {
19136           eid_set = 1;
19137           eid_type = 3;
19138         }
19139       else if (unformat (i, "vni %d", &t))
19140         {
19141           vni = t;
19142         }
19143       else if (unformat (i, "local"))
19144         {
19145           filter = 1;
19146         }
19147       else if (unformat (i, "remote"))
19148         {
19149           filter = 2;
19150         }
19151       else
19152         {
19153           errmsg ("parse error '%U'", format_unformat_error, i);
19154           return -99;
19155         }
19156     }
19157
19158   if (!vam->json_output)
19159     {
19160       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19161              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19162     }
19163
19164   M (ONE_EID_TABLE_DUMP, mp);
19165
19166   mp->filter = filter;
19167   if (eid_set)
19168     {
19169       mp->eid_set = 1;
19170       mp->vni = htonl (vni);
19171       mp->eid_type = eid_type;
19172       switch (eid_type)
19173         {
19174         case 0:
19175           mp->prefix_length = prefix_length;
19176           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19177           break;
19178         case 1:
19179           mp->prefix_length = prefix_length;
19180           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19181           break;
19182         case 2:
19183           clib_memcpy (mp->eid, mac, sizeof (mac));
19184           break;
19185         case 3:
19186           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19187           break;
19188         default:
19189           errmsg ("unknown EID type %d!", eid_type);
19190           return -99;
19191         }
19192     }
19193
19194   /* send it... */
19195   S (mp);
19196
19197   /* Use a control ping for synchronization */
19198   MPING (CONTROL_PING, mp_ping);
19199   S (mp_ping);
19200
19201   /* Wait for a reply... */
19202   W (ret);
19203   return ret;
19204 }
19205
19206 #define api_lisp_eid_table_dump api_one_eid_table_dump
19207
19208 static int
19209 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19210 {
19211   unformat_input_t *i = vam->input;
19212   vl_api_gpe_fwd_entries_get_t *mp;
19213   u8 vni_set = 0;
19214   u32 vni = ~0;
19215   int ret;
19216
19217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19218     {
19219       if (unformat (i, "vni %d", &vni))
19220         {
19221           vni_set = 1;
19222         }
19223       else
19224         {
19225           errmsg ("parse error '%U'", format_unformat_error, i);
19226           return -99;
19227         }
19228     }
19229
19230   if (!vni_set)
19231     {
19232       errmsg ("vni not set!");
19233       return -99;
19234     }
19235
19236   if (!vam->json_output)
19237     {
19238       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19239              "leid", "reid");
19240     }
19241
19242   M (GPE_FWD_ENTRIES_GET, mp);
19243   mp->vni = clib_host_to_net_u32 (vni);
19244
19245   /* send it... */
19246   S (mp);
19247
19248   /* Wait for a reply... */
19249   W (ret);
19250   return ret;
19251 }
19252
19253 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19254 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19255 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19256 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19257 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19258 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19259 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19260 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19261
19262 static int
19263 api_one_adjacencies_get (vat_main_t * vam)
19264 {
19265   unformat_input_t *i = vam->input;
19266   vl_api_one_adjacencies_get_t *mp;
19267   u8 vni_set = 0;
19268   u32 vni = ~0;
19269   int ret;
19270
19271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19272     {
19273       if (unformat (i, "vni %d", &vni))
19274         {
19275           vni_set = 1;
19276         }
19277       else
19278         {
19279           errmsg ("parse error '%U'", format_unformat_error, i);
19280           return -99;
19281         }
19282     }
19283
19284   if (!vni_set)
19285     {
19286       errmsg ("vni not set!");
19287       return -99;
19288     }
19289
19290   if (!vam->json_output)
19291     {
19292       print (vam->ofp, "%s %40s", "leid", "reid");
19293     }
19294
19295   M (ONE_ADJACENCIES_GET, mp);
19296   mp->vni = clib_host_to_net_u32 (vni);
19297
19298   /* send it... */
19299   S (mp);
19300
19301   /* Wait for a reply... */
19302   W (ret);
19303   return ret;
19304 }
19305
19306 #define api_lisp_adjacencies_get api_one_adjacencies_get
19307
19308 static int
19309 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19310 {
19311   unformat_input_t *i = vam->input;
19312   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19313   int ret;
19314   u8 ip_family_set = 0, is_ip4 = 1;
19315
19316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19317     {
19318       if (unformat (i, "ip4"))
19319         {
19320           ip_family_set = 1;
19321           is_ip4 = 1;
19322         }
19323       else if (unformat (i, "ip6"))
19324         {
19325           ip_family_set = 1;
19326           is_ip4 = 0;
19327         }
19328       else
19329         {
19330           errmsg ("parse error '%U'", format_unformat_error, i);
19331           return -99;
19332         }
19333     }
19334
19335   if (!ip_family_set)
19336     {
19337       errmsg ("ip family not set!");
19338       return -99;
19339     }
19340
19341   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19342   mp->is_ip4 = is_ip4;
19343
19344   /* send it... */
19345   S (mp);
19346
19347   /* Wait for a reply... */
19348   W (ret);
19349   return ret;
19350 }
19351
19352 static int
19353 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19354 {
19355   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19356   int ret;
19357
19358   if (!vam->json_output)
19359     {
19360       print (vam->ofp, "VNIs");
19361     }
19362
19363   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19364
19365   /* send it... */
19366   S (mp);
19367
19368   /* Wait for a reply... */
19369   W (ret);
19370   return ret;
19371 }
19372
19373 static int
19374 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19375 {
19376   unformat_input_t *i = vam->input;
19377   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19378   int ret = 0;
19379   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19380   struct in_addr ip4;
19381   struct in6_addr ip6;
19382   u32 table_id = 0, nh_sw_if_index = ~0;
19383
19384   memset (&ip4, 0, sizeof (ip4));
19385   memset (&ip6, 0, sizeof (ip6));
19386
19387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19388     {
19389       if (unformat (i, "del"))
19390         is_add = 0;
19391       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19392                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19393         {
19394           ip_set = 1;
19395           is_ip4 = 1;
19396         }
19397       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19398                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19399         {
19400           ip_set = 1;
19401           is_ip4 = 0;
19402         }
19403       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19404         {
19405           ip_set = 1;
19406           is_ip4 = 1;
19407           nh_sw_if_index = ~0;
19408         }
19409       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19410         {
19411           ip_set = 1;
19412           is_ip4 = 0;
19413           nh_sw_if_index = ~0;
19414         }
19415       else if (unformat (i, "table %d", &table_id))
19416         ;
19417       else
19418         {
19419           errmsg ("parse error '%U'", format_unformat_error, i);
19420           return -99;
19421         }
19422     }
19423
19424   if (!ip_set)
19425     {
19426       errmsg ("nh addr not set!");
19427       return -99;
19428     }
19429
19430   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19431   mp->is_add = is_add;
19432   mp->table_id = clib_host_to_net_u32 (table_id);
19433   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19434   mp->is_ip4 = is_ip4;
19435   if (is_ip4)
19436     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19437   else
19438     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19439
19440   /* send it... */
19441   S (mp);
19442
19443   /* Wait for a reply... */
19444   W (ret);
19445   return ret;
19446 }
19447
19448 static int
19449 api_one_map_server_dump (vat_main_t * vam)
19450 {
19451   vl_api_one_map_server_dump_t *mp;
19452   vl_api_control_ping_t *mp_ping;
19453   int ret;
19454
19455   if (!vam->json_output)
19456     {
19457       print (vam->ofp, "%=20s", "Map server");
19458     }
19459
19460   M (ONE_MAP_SERVER_DUMP, mp);
19461   /* send it... */
19462   S (mp);
19463
19464   /* Use a control ping for synchronization */
19465   MPING (CONTROL_PING, mp_ping);
19466   S (mp_ping);
19467
19468   /* Wait for a reply... */
19469   W (ret);
19470   return ret;
19471 }
19472
19473 #define api_lisp_map_server_dump api_one_map_server_dump
19474
19475 static int
19476 api_one_map_resolver_dump (vat_main_t * vam)
19477 {
19478   vl_api_one_map_resolver_dump_t *mp;
19479   vl_api_control_ping_t *mp_ping;
19480   int ret;
19481
19482   if (!vam->json_output)
19483     {
19484       print (vam->ofp, "%=20s", "Map resolver");
19485     }
19486
19487   M (ONE_MAP_RESOLVER_DUMP, mp);
19488   /* send it... */
19489   S (mp);
19490
19491   /* Use a control ping for synchronization */
19492   MPING (CONTROL_PING, mp_ping);
19493   S (mp_ping);
19494
19495   /* Wait for a reply... */
19496   W (ret);
19497   return ret;
19498 }
19499
19500 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19501
19502 static int
19503 api_one_stats_flush (vat_main_t * vam)
19504 {
19505   vl_api_one_stats_flush_t *mp;
19506   int ret = 0;
19507
19508   M (ONE_STATS_FLUSH, mp);
19509   S (mp);
19510   W (ret);
19511   return ret;
19512 }
19513
19514 static int
19515 api_one_stats_dump (vat_main_t * vam)
19516 {
19517   vl_api_one_stats_dump_t *mp;
19518   vl_api_control_ping_t *mp_ping;
19519   int ret;
19520
19521   M (ONE_STATS_DUMP, mp);
19522   /* send it... */
19523   S (mp);
19524
19525   /* Use a control ping for synchronization */
19526   MPING (CONTROL_PING, mp_ping);
19527   S (mp_ping);
19528
19529   /* Wait for a reply... */
19530   W (ret);
19531   return ret;
19532 }
19533
19534 static int
19535 api_show_one_status (vat_main_t * vam)
19536 {
19537   vl_api_show_one_status_t *mp;
19538   int ret;
19539
19540   if (!vam->json_output)
19541     {
19542       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19543     }
19544
19545   M (SHOW_ONE_STATUS, mp);
19546   /* send it... */
19547   S (mp);
19548   /* Wait for a reply... */
19549   W (ret);
19550   return ret;
19551 }
19552
19553 #define api_show_lisp_status api_show_one_status
19554
19555 static int
19556 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19557 {
19558   vl_api_gpe_fwd_entry_path_dump_t *mp;
19559   vl_api_control_ping_t *mp_ping;
19560   unformat_input_t *i = vam->input;
19561   u32 fwd_entry_index = ~0;
19562   int ret;
19563
19564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19565     {
19566       if (unformat (i, "index %d", &fwd_entry_index))
19567         ;
19568       else
19569         break;
19570     }
19571
19572   if (~0 == fwd_entry_index)
19573     {
19574       errmsg ("no index specified!");
19575       return -99;
19576     }
19577
19578   if (!vam->json_output)
19579     {
19580       print (vam->ofp, "first line");
19581     }
19582
19583   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19584
19585   /* send it... */
19586   S (mp);
19587   /* Use a control ping for synchronization */
19588   MPING (CONTROL_PING, mp_ping);
19589   S (mp_ping);
19590
19591   /* Wait for a reply... */
19592   W (ret);
19593   return ret;
19594 }
19595
19596 static int
19597 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19598 {
19599   vl_api_one_get_map_request_itr_rlocs_t *mp;
19600   int ret;
19601
19602   if (!vam->json_output)
19603     {
19604       print (vam->ofp, "%=20s", "itr-rlocs:");
19605     }
19606
19607   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19608   /* send it... */
19609   S (mp);
19610   /* Wait for a reply... */
19611   W (ret);
19612   return ret;
19613 }
19614
19615 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19616
19617 static int
19618 api_af_packet_create (vat_main_t * vam)
19619 {
19620   unformat_input_t *i = vam->input;
19621   vl_api_af_packet_create_t *mp;
19622   u8 *host_if_name = 0;
19623   u8 hw_addr[6];
19624   u8 random_hw_addr = 1;
19625   int ret;
19626
19627   memset (hw_addr, 0, sizeof (hw_addr));
19628
19629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19630     {
19631       if (unformat (i, "name %s", &host_if_name))
19632         vec_add1 (host_if_name, 0);
19633       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19634         random_hw_addr = 0;
19635       else
19636         break;
19637     }
19638
19639   if (!vec_len (host_if_name))
19640     {
19641       errmsg ("host-interface name must be specified");
19642       return -99;
19643     }
19644
19645   if (vec_len (host_if_name) > 64)
19646     {
19647       errmsg ("host-interface name too long");
19648       return -99;
19649     }
19650
19651   M (AF_PACKET_CREATE, mp);
19652
19653   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19654   clib_memcpy (mp->hw_addr, hw_addr, 6);
19655   mp->use_random_hw_addr = random_hw_addr;
19656   vec_free (host_if_name);
19657
19658   S (mp);
19659
19660   /* *INDENT-OFF* */
19661   W2 (ret,
19662       ({
19663         if (ret == 0)
19664           fprintf (vam->ofp ? vam->ofp : stderr,
19665                    " new sw_if_index = %d\n", vam->sw_if_index);
19666       }));
19667   /* *INDENT-ON* */
19668   return ret;
19669 }
19670
19671 static int
19672 api_af_packet_delete (vat_main_t * vam)
19673 {
19674   unformat_input_t *i = vam->input;
19675   vl_api_af_packet_delete_t *mp;
19676   u8 *host_if_name = 0;
19677   int ret;
19678
19679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19680     {
19681       if (unformat (i, "name %s", &host_if_name))
19682         vec_add1 (host_if_name, 0);
19683       else
19684         break;
19685     }
19686
19687   if (!vec_len (host_if_name))
19688     {
19689       errmsg ("host-interface name must be specified");
19690       return -99;
19691     }
19692
19693   if (vec_len (host_if_name) > 64)
19694     {
19695       errmsg ("host-interface name too long");
19696       return -99;
19697     }
19698
19699   M (AF_PACKET_DELETE, mp);
19700
19701   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19702   vec_free (host_if_name);
19703
19704   S (mp);
19705   W (ret);
19706   return ret;
19707 }
19708
19709 static void vl_api_af_packet_details_t_handler
19710   (vl_api_af_packet_details_t * mp)
19711 {
19712   vat_main_t *vam = &vat_main;
19713
19714   print (vam->ofp, "%-16s %d",
19715          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19716 }
19717
19718 static void vl_api_af_packet_details_t_handler_json
19719   (vl_api_af_packet_details_t * mp)
19720 {
19721   vat_main_t *vam = &vat_main;
19722   vat_json_node_t *node = NULL;
19723
19724   if (VAT_JSON_ARRAY != vam->json_tree.type)
19725     {
19726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19727       vat_json_init_array (&vam->json_tree);
19728     }
19729   node = vat_json_array_add (&vam->json_tree);
19730
19731   vat_json_init_object (node);
19732   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19733   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19734 }
19735
19736 static int
19737 api_af_packet_dump (vat_main_t * vam)
19738 {
19739   vl_api_af_packet_dump_t *mp;
19740   vl_api_control_ping_t *mp_ping;
19741   int ret;
19742
19743   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19744   /* Get list of tap interfaces */
19745   M (AF_PACKET_DUMP, mp);
19746   S (mp);
19747
19748   /* Use a control ping for synchronization */
19749   MPING (CONTROL_PING, mp_ping);
19750   S (mp_ping);
19751
19752   W (ret);
19753   return ret;
19754 }
19755
19756 static int
19757 api_policer_add_del (vat_main_t * vam)
19758 {
19759   unformat_input_t *i = vam->input;
19760   vl_api_policer_add_del_t *mp;
19761   u8 is_add = 1;
19762   u8 *name = 0;
19763   u32 cir = 0;
19764   u32 eir = 0;
19765   u64 cb = 0;
19766   u64 eb = 0;
19767   u8 rate_type = 0;
19768   u8 round_type = 0;
19769   u8 type = 0;
19770   u8 color_aware = 0;
19771   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19772   int ret;
19773
19774   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19775   conform_action.dscp = 0;
19776   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19777   exceed_action.dscp = 0;
19778   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19779   violate_action.dscp = 0;
19780
19781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19782     {
19783       if (unformat (i, "del"))
19784         is_add = 0;
19785       else if (unformat (i, "name %s", &name))
19786         vec_add1 (name, 0);
19787       else if (unformat (i, "cir %u", &cir))
19788         ;
19789       else if (unformat (i, "eir %u", &eir))
19790         ;
19791       else if (unformat (i, "cb %u", &cb))
19792         ;
19793       else if (unformat (i, "eb %u", &eb))
19794         ;
19795       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19796                          &rate_type))
19797         ;
19798       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19799                          &round_type))
19800         ;
19801       else if (unformat (i, "type %U", unformat_policer_type, &type))
19802         ;
19803       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19804                          &conform_action))
19805         ;
19806       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19807                          &exceed_action))
19808         ;
19809       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19810                          &violate_action))
19811         ;
19812       else if (unformat (i, "color-aware"))
19813         color_aware = 1;
19814       else
19815         break;
19816     }
19817
19818   if (!vec_len (name))
19819     {
19820       errmsg ("policer name must be specified");
19821       return -99;
19822     }
19823
19824   if (vec_len (name) > 64)
19825     {
19826       errmsg ("policer name too long");
19827       return -99;
19828     }
19829
19830   M (POLICER_ADD_DEL, mp);
19831
19832   clib_memcpy (mp->name, name, vec_len (name));
19833   vec_free (name);
19834   mp->is_add = is_add;
19835   mp->cir = ntohl (cir);
19836   mp->eir = ntohl (eir);
19837   mp->cb = clib_net_to_host_u64 (cb);
19838   mp->eb = clib_net_to_host_u64 (eb);
19839   mp->rate_type = rate_type;
19840   mp->round_type = round_type;
19841   mp->type = type;
19842   mp->conform_action_type = conform_action.action_type;
19843   mp->conform_dscp = conform_action.dscp;
19844   mp->exceed_action_type = exceed_action.action_type;
19845   mp->exceed_dscp = exceed_action.dscp;
19846   mp->violate_action_type = violate_action.action_type;
19847   mp->violate_dscp = violate_action.dscp;
19848   mp->color_aware = color_aware;
19849
19850   S (mp);
19851   W (ret);
19852   return ret;
19853 }
19854
19855 static int
19856 api_policer_dump (vat_main_t * vam)
19857 {
19858   unformat_input_t *i = vam->input;
19859   vl_api_policer_dump_t *mp;
19860   vl_api_control_ping_t *mp_ping;
19861   u8 *match_name = 0;
19862   u8 match_name_valid = 0;
19863   int ret;
19864
19865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19866     {
19867       if (unformat (i, "name %s", &match_name))
19868         {
19869           vec_add1 (match_name, 0);
19870           match_name_valid = 1;
19871         }
19872       else
19873         break;
19874     }
19875
19876   M (POLICER_DUMP, mp);
19877   mp->match_name_valid = match_name_valid;
19878   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19879   vec_free (match_name);
19880   /* send it... */
19881   S (mp);
19882
19883   /* Use a control ping for synchronization */
19884   MPING (CONTROL_PING, mp_ping);
19885   S (mp_ping);
19886
19887   /* Wait for a reply... */
19888   W (ret);
19889   return ret;
19890 }
19891
19892 static int
19893 api_policer_classify_set_interface (vat_main_t * vam)
19894 {
19895   unformat_input_t *i = vam->input;
19896   vl_api_policer_classify_set_interface_t *mp;
19897   u32 sw_if_index;
19898   int sw_if_index_set;
19899   u32 ip4_table_index = ~0;
19900   u32 ip6_table_index = ~0;
19901   u32 l2_table_index = ~0;
19902   u8 is_add = 1;
19903   int ret;
19904
19905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19906     {
19907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19908         sw_if_index_set = 1;
19909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19910         sw_if_index_set = 1;
19911       else if (unformat (i, "del"))
19912         is_add = 0;
19913       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19914         ;
19915       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19916         ;
19917       else if (unformat (i, "l2-table %d", &l2_table_index))
19918         ;
19919       else
19920         {
19921           clib_warning ("parse error '%U'", format_unformat_error, i);
19922           return -99;
19923         }
19924     }
19925
19926   if (sw_if_index_set == 0)
19927     {
19928       errmsg ("missing interface name or sw_if_index");
19929       return -99;
19930     }
19931
19932   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19933
19934   mp->sw_if_index = ntohl (sw_if_index);
19935   mp->ip4_table_index = ntohl (ip4_table_index);
19936   mp->ip6_table_index = ntohl (ip6_table_index);
19937   mp->l2_table_index = ntohl (l2_table_index);
19938   mp->is_add = is_add;
19939
19940   S (mp);
19941   W (ret);
19942   return ret;
19943 }
19944
19945 static int
19946 api_policer_classify_dump (vat_main_t * vam)
19947 {
19948   unformat_input_t *i = vam->input;
19949   vl_api_policer_classify_dump_t *mp;
19950   vl_api_control_ping_t *mp_ping;
19951   u8 type = POLICER_CLASSIFY_N_TABLES;
19952   int ret;
19953
19954   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19955     ;
19956   else
19957     {
19958       errmsg ("classify table type must be specified");
19959       return -99;
19960     }
19961
19962   if (!vam->json_output)
19963     {
19964       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19965     }
19966
19967   M (POLICER_CLASSIFY_DUMP, mp);
19968   mp->type = type;
19969   /* send it... */
19970   S (mp);
19971
19972   /* Use a control ping for synchronization */
19973   MPING (CONTROL_PING, mp_ping);
19974   S (mp_ping);
19975
19976   /* Wait for a reply... */
19977   W (ret);
19978   return ret;
19979 }
19980
19981 static int
19982 api_netmap_create (vat_main_t * vam)
19983 {
19984   unformat_input_t *i = vam->input;
19985   vl_api_netmap_create_t *mp;
19986   u8 *if_name = 0;
19987   u8 hw_addr[6];
19988   u8 random_hw_addr = 1;
19989   u8 is_pipe = 0;
19990   u8 is_master = 0;
19991   int ret;
19992
19993   memset (hw_addr, 0, sizeof (hw_addr));
19994
19995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19996     {
19997       if (unformat (i, "name %s", &if_name))
19998         vec_add1 (if_name, 0);
19999       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20000         random_hw_addr = 0;
20001       else if (unformat (i, "pipe"))
20002         is_pipe = 1;
20003       else if (unformat (i, "master"))
20004         is_master = 1;
20005       else if (unformat (i, "slave"))
20006         is_master = 0;
20007       else
20008         break;
20009     }
20010
20011   if (!vec_len (if_name))
20012     {
20013       errmsg ("interface name must be specified");
20014       return -99;
20015     }
20016
20017   if (vec_len (if_name) > 64)
20018     {
20019       errmsg ("interface name too long");
20020       return -99;
20021     }
20022
20023   M (NETMAP_CREATE, mp);
20024
20025   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20026   clib_memcpy (mp->hw_addr, hw_addr, 6);
20027   mp->use_random_hw_addr = random_hw_addr;
20028   mp->is_pipe = is_pipe;
20029   mp->is_master = is_master;
20030   vec_free (if_name);
20031
20032   S (mp);
20033   W (ret);
20034   return ret;
20035 }
20036
20037 static int
20038 api_netmap_delete (vat_main_t * vam)
20039 {
20040   unformat_input_t *i = vam->input;
20041   vl_api_netmap_delete_t *mp;
20042   u8 *if_name = 0;
20043   int ret;
20044
20045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20046     {
20047       if (unformat (i, "name %s", &if_name))
20048         vec_add1 (if_name, 0);
20049       else
20050         break;
20051     }
20052
20053   if (!vec_len (if_name))
20054     {
20055       errmsg ("interface name must be specified");
20056       return -99;
20057     }
20058
20059   if (vec_len (if_name) > 64)
20060     {
20061       errmsg ("interface name too long");
20062       return -99;
20063     }
20064
20065   M (NETMAP_DELETE, mp);
20066
20067   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20068   vec_free (if_name);
20069
20070   S (mp);
20071   W (ret);
20072   return ret;
20073 }
20074
20075 static void
20076 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20077 {
20078   if (fp->afi == IP46_TYPE_IP6)
20079     print (vam->ofp,
20080            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20081            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20082            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20083            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20084            format_ip6_address, fp->next_hop);
20085   else if (fp->afi == IP46_TYPE_IP4)
20086     print (vam->ofp,
20087            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20088            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20089            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20090            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20091            format_ip4_address, fp->next_hop);
20092 }
20093
20094 static void
20095 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20096                                  vl_api_fib_path_t * fp)
20097 {
20098   struct in_addr ip4;
20099   struct in6_addr ip6;
20100
20101   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20102   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20103   vat_json_object_add_uint (node, "is_local", fp->is_local);
20104   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20105   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20106   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20107   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20108   if (fp->afi == IP46_TYPE_IP4)
20109     {
20110       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20111       vat_json_object_add_ip4 (node, "next_hop", ip4);
20112     }
20113   else if (fp->afi == IP46_TYPE_IP6)
20114     {
20115       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20116       vat_json_object_add_ip6 (node, "next_hop", ip6);
20117     }
20118 }
20119
20120 static void
20121 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20122 {
20123   vat_main_t *vam = &vat_main;
20124   int count = ntohl (mp->mt_count);
20125   vl_api_fib_path_t *fp;
20126   i32 i;
20127
20128   print (vam->ofp, "[%d]: sw_if_index %d via:",
20129          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20130   fp = mp->mt_paths;
20131   for (i = 0; i < count; i++)
20132     {
20133       vl_api_mpls_fib_path_print (vam, fp);
20134       fp++;
20135     }
20136
20137   print (vam->ofp, "");
20138 }
20139
20140 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20141 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20142
20143 static void
20144 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20145 {
20146   vat_main_t *vam = &vat_main;
20147   vat_json_node_t *node = NULL;
20148   int count = ntohl (mp->mt_count);
20149   vl_api_fib_path_t *fp;
20150   i32 i;
20151
20152   if (VAT_JSON_ARRAY != vam->json_tree.type)
20153     {
20154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20155       vat_json_init_array (&vam->json_tree);
20156     }
20157   node = vat_json_array_add (&vam->json_tree);
20158
20159   vat_json_init_object (node);
20160   vat_json_object_add_uint (node, "tunnel_index",
20161                             ntohl (mp->mt_tunnel_index));
20162   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20163
20164   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20165
20166   fp = mp->mt_paths;
20167   for (i = 0; i < count; i++)
20168     {
20169       vl_api_mpls_fib_path_json_print (node, fp);
20170       fp++;
20171     }
20172 }
20173
20174 static int
20175 api_mpls_tunnel_dump (vat_main_t * vam)
20176 {
20177   vl_api_mpls_tunnel_dump_t *mp;
20178   vl_api_control_ping_t *mp_ping;
20179   i32 index = -1;
20180   int ret;
20181
20182   /* Parse args required to build the message */
20183   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20184     {
20185       if (!unformat (vam->input, "tunnel_index %d", &index))
20186         {
20187           index = -1;
20188           break;
20189         }
20190     }
20191
20192   print (vam->ofp, "  tunnel_index %d", index);
20193
20194   M (MPLS_TUNNEL_DUMP, mp);
20195   mp->tunnel_index = htonl (index);
20196   S (mp);
20197
20198   /* Use a control ping for synchronization */
20199   MPING (CONTROL_PING, mp_ping);
20200   S (mp_ping);
20201
20202   W (ret);
20203   return ret;
20204 }
20205
20206 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20207 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20208
20209
20210 static void
20211 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20212 {
20213   vat_main_t *vam = &vat_main;
20214   int count = ntohl (mp->count);
20215   vl_api_fib_path_t *fp;
20216   int i;
20217
20218   print (vam->ofp,
20219          "table-id %d, label %u, ess_bit %u",
20220          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20221   fp = mp->path;
20222   for (i = 0; i < count; i++)
20223     {
20224       vl_api_mpls_fib_path_print (vam, fp);
20225       fp++;
20226     }
20227 }
20228
20229 static void vl_api_mpls_fib_details_t_handler_json
20230   (vl_api_mpls_fib_details_t * mp)
20231 {
20232   vat_main_t *vam = &vat_main;
20233   int count = ntohl (mp->count);
20234   vat_json_node_t *node = NULL;
20235   vl_api_fib_path_t *fp;
20236   int i;
20237
20238   if (VAT_JSON_ARRAY != vam->json_tree.type)
20239     {
20240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20241       vat_json_init_array (&vam->json_tree);
20242     }
20243   node = vat_json_array_add (&vam->json_tree);
20244
20245   vat_json_init_object (node);
20246   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20247   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20248   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20249   vat_json_object_add_uint (node, "path_count", count);
20250   fp = mp->path;
20251   for (i = 0; i < count; i++)
20252     {
20253       vl_api_mpls_fib_path_json_print (node, fp);
20254       fp++;
20255     }
20256 }
20257
20258 static int
20259 api_mpls_fib_dump (vat_main_t * vam)
20260 {
20261   vl_api_mpls_fib_dump_t *mp;
20262   vl_api_control_ping_t *mp_ping;
20263   int ret;
20264
20265   M (MPLS_FIB_DUMP, mp);
20266   S (mp);
20267
20268   /* Use a control ping for synchronization */
20269   MPING (CONTROL_PING, mp_ping);
20270   S (mp_ping);
20271
20272   W (ret);
20273   return ret;
20274 }
20275
20276 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20277 #define vl_api_ip_fib_details_t_print vl_noop_handler
20278
20279 static void
20280 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20281 {
20282   vat_main_t *vam = &vat_main;
20283   int count = ntohl (mp->count);
20284   vl_api_fib_path_t *fp;
20285   int i;
20286
20287   print (vam->ofp,
20288          "table-id %d, prefix %U/%d",
20289          ntohl (mp->table_id), format_ip4_address, mp->address,
20290          mp->address_length);
20291   fp = mp->path;
20292   for (i = 0; i < count; i++)
20293     {
20294       if (fp->afi == IP46_TYPE_IP6)
20295         print (vam->ofp,
20296                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20297                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20298                "next_hop_table %d",
20299                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20300                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20301                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20302       else if (fp->afi == IP46_TYPE_IP4)
20303         print (vam->ofp,
20304                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20305                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20306                "next_hop_table %d",
20307                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20308                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20309                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20310       fp++;
20311     }
20312 }
20313
20314 static void vl_api_ip_fib_details_t_handler_json
20315   (vl_api_ip_fib_details_t * mp)
20316 {
20317   vat_main_t *vam = &vat_main;
20318   int count = ntohl (mp->count);
20319   vat_json_node_t *node = NULL;
20320   struct in_addr ip4;
20321   struct in6_addr ip6;
20322   vl_api_fib_path_t *fp;
20323   int i;
20324
20325   if (VAT_JSON_ARRAY != vam->json_tree.type)
20326     {
20327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20328       vat_json_init_array (&vam->json_tree);
20329     }
20330   node = vat_json_array_add (&vam->json_tree);
20331
20332   vat_json_init_object (node);
20333   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20334   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20335   vat_json_object_add_ip4 (node, "prefix", ip4);
20336   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20337   vat_json_object_add_uint (node, "path_count", count);
20338   fp = mp->path;
20339   for (i = 0; i < count; i++)
20340     {
20341       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20342       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20343       vat_json_object_add_uint (node, "is_local", fp->is_local);
20344       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20345       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20346       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20347       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20348       if (fp->afi == IP46_TYPE_IP4)
20349         {
20350           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20351           vat_json_object_add_ip4 (node, "next_hop", ip4);
20352         }
20353       else if (fp->afi == IP46_TYPE_IP6)
20354         {
20355           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20356           vat_json_object_add_ip6 (node, "next_hop", ip6);
20357         }
20358     }
20359 }
20360
20361 static int
20362 api_ip_fib_dump (vat_main_t * vam)
20363 {
20364   vl_api_ip_fib_dump_t *mp;
20365   vl_api_control_ping_t *mp_ping;
20366   int ret;
20367
20368   M (IP_FIB_DUMP, mp);
20369   S (mp);
20370
20371   /* Use a control ping for synchronization */
20372   MPING (CONTROL_PING, mp_ping);
20373   S (mp_ping);
20374
20375   W (ret);
20376   return ret;
20377 }
20378
20379 static int
20380 api_ip_mfib_dump (vat_main_t * vam)
20381 {
20382   vl_api_ip_mfib_dump_t *mp;
20383   vl_api_control_ping_t *mp_ping;
20384   int ret;
20385
20386   M (IP_MFIB_DUMP, mp);
20387   S (mp);
20388
20389   /* Use a control ping for synchronization */
20390   MPING (CONTROL_PING, mp_ping);
20391   S (mp_ping);
20392
20393   W (ret);
20394   return ret;
20395 }
20396
20397 static void vl_api_ip_neighbor_details_t_handler
20398   (vl_api_ip_neighbor_details_t * mp)
20399 {
20400   vat_main_t *vam = &vat_main;
20401
20402   print (vam->ofp, "%c %U %U",
20403          (mp->is_static) ? 'S' : 'D',
20404          format_ethernet_address, &mp->mac_address,
20405          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20406          &mp->ip_address);
20407 }
20408
20409 static void vl_api_ip_neighbor_details_t_handler_json
20410   (vl_api_ip_neighbor_details_t * mp)
20411 {
20412
20413   vat_main_t *vam = &vat_main;
20414   vat_json_node_t *node;
20415   struct in_addr ip4;
20416   struct in6_addr ip6;
20417
20418   if (VAT_JSON_ARRAY != vam->json_tree.type)
20419     {
20420       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20421       vat_json_init_array (&vam->json_tree);
20422     }
20423   node = vat_json_array_add (&vam->json_tree);
20424
20425   vat_json_init_object (node);
20426   vat_json_object_add_string_copy (node, "flag",
20427                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20428                                    "dynamic");
20429
20430   vat_json_object_add_string_copy (node, "link_layer",
20431                                    format (0, "%U", format_ethernet_address,
20432                                            &mp->mac_address));
20433
20434   if (mp->is_ipv6)
20435     {
20436       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20437       vat_json_object_add_ip6 (node, "ip_address", ip6);
20438     }
20439   else
20440     {
20441       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20442       vat_json_object_add_ip4 (node, "ip_address", ip4);
20443     }
20444 }
20445
20446 static int
20447 api_ip_neighbor_dump (vat_main_t * vam)
20448 {
20449   unformat_input_t *i = vam->input;
20450   vl_api_ip_neighbor_dump_t *mp;
20451   vl_api_control_ping_t *mp_ping;
20452   u8 is_ipv6 = 0;
20453   u32 sw_if_index = ~0;
20454   int ret;
20455
20456   /* Parse args required to build the message */
20457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20458     {
20459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20460         ;
20461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20462         ;
20463       else if (unformat (i, "ip6"))
20464         is_ipv6 = 1;
20465       else
20466         break;
20467     }
20468
20469   if (sw_if_index == ~0)
20470     {
20471       errmsg ("missing interface name or sw_if_index");
20472       return -99;
20473     }
20474
20475   M (IP_NEIGHBOR_DUMP, mp);
20476   mp->is_ipv6 = (u8) is_ipv6;
20477   mp->sw_if_index = ntohl (sw_if_index);
20478   S (mp);
20479
20480   /* Use a control ping for synchronization */
20481   MPING (CONTROL_PING, mp_ping);
20482   S (mp_ping);
20483
20484   W (ret);
20485   return ret;
20486 }
20487
20488 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20489 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20490
20491 static void
20492 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20493 {
20494   vat_main_t *vam = &vat_main;
20495   int count = ntohl (mp->count);
20496   vl_api_fib_path_t *fp;
20497   int i;
20498
20499   print (vam->ofp,
20500          "table-id %d, prefix %U/%d",
20501          ntohl (mp->table_id), format_ip6_address, mp->address,
20502          mp->address_length);
20503   fp = mp->path;
20504   for (i = 0; i < count; i++)
20505     {
20506       if (fp->afi == IP46_TYPE_IP6)
20507         print (vam->ofp,
20508                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20509                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20510                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20511                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20512                format_ip6_address, fp->next_hop);
20513       else if (fp->afi == IP46_TYPE_IP4)
20514         print (vam->ofp,
20515                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20516                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20517                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20518                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20519                format_ip4_address, fp->next_hop);
20520       fp++;
20521     }
20522 }
20523
20524 static void vl_api_ip6_fib_details_t_handler_json
20525   (vl_api_ip6_fib_details_t * mp)
20526 {
20527   vat_main_t *vam = &vat_main;
20528   int count = ntohl (mp->count);
20529   vat_json_node_t *node = NULL;
20530   struct in_addr ip4;
20531   struct in6_addr ip6;
20532   vl_api_fib_path_t *fp;
20533   int i;
20534
20535   if (VAT_JSON_ARRAY != vam->json_tree.type)
20536     {
20537       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20538       vat_json_init_array (&vam->json_tree);
20539     }
20540   node = vat_json_array_add (&vam->json_tree);
20541
20542   vat_json_init_object (node);
20543   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20544   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20545   vat_json_object_add_ip6 (node, "prefix", ip6);
20546   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20547   vat_json_object_add_uint (node, "path_count", count);
20548   fp = mp->path;
20549   for (i = 0; i < count; i++)
20550     {
20551       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20552       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20553       vat_json_object_add_uint (node, "is_local", fp->is_local);
20554       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20555       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20556       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20557       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20558       if (fp->afi == IP46_TYPE_IP4)
20559         {
20560           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20561           vat_json_object_add_ip4 (node, "next_hop", ip4);
20562         }
20563       else if (fp->afi == IP46_TYPE_IP6)
20564         {
20565           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20566           vat_json_object_add_ip6 (node, "next_hop", ip6);
20567         }
20568     }
20569 }
20570
20571 static int
20572 api_ip6_fib_dump (vat_main_t * vam)
20573 {
20574   vl_api_ip6_fib_dump_t *mp;
20575   vl_api_control_ping_t *mp_ping;
20576   int ret;
20577
20578   M (IP6_FIB_DUMP, mp);
20579   S (mp);
20580
20581   /* Use a control ping for synchronization */
20582   MPING (CONTROL_PING, mp_ping);
20583   S (mp_ping);
20584
20585   W (ret);
20586   return ret;
20587 }
20588
20589 static int
20590 api_ip6_mfib_dump (vat_main_t * vam)
20591 {
20592   vl_api_ip6_mfib_dump_t *mp;
20593   vl_api_control_ping_t *mp_ping;
20594   int ret;
20595
20596   M (IP6_MFIB_DUMP, mp);
20597   S (mp);
20598
20599   /* Use a control ping for synchronization */
20600   MPING (CONTROL_PING, mp_ping);
20601   S (mp_ping);
20602
20603   W (ret);
20604   return ret;
20605 }
20606
20607 int
20608 api_classify_table_ids (vat_main_t * vam)
20609 {
20610   vl_api_classify_table_ids_t *mp;
20611   int ret;
20612
20613   /* Construct the API message */
20614   M (CLASSIFY_TABLE_IDS, mp);
20615   mp->context = 0;
20616
20617   S (mp);
20618   W (ret);
20619   return ret;
20620 }
20621
20622 int
20623 api_classify_table_by_interface (vat_main_t * vam)
20624 {
20625   unformat_input_t *input = vam->input;
20626   vl_api_classify_table_by_interface_t *mp;
20627
20628   u32 sw_if_index = ~0;
20629   int ret;
20630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20631     {
20632       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20633         ;
20634       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20635         ;
20636       else
20637         break;
20638     }
20639   if (sw_if_index == ~0)
20640     {
20641       errmsg ("missing interface name or sw_if_index");
20642       return -99;
20643     }
20644
20645   /* Construct the API message */
20646   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20647   mp->context = 0;
20648   mp->sw_if_index = ntohl (sw_if_index);
20649
20650   S (mp);
20651   W (ret);
20652   return ret;
20653 }
20654
20655 int
20656 api_classify_table_info (vat_main_t * vam)
20657 {
20658   unformat_input_t *input = vam->input;
20659   vl_api_classify_table_info_t *mp;
20660
20661   u32 table_id = ~0;
20662   int ret;
20663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20664     {
20665       if (unformat (input, "table_id %d", &table_id))
20666         ;
20667       else
20668         break;
20669     }
20670   if (table_id == ~0)
20671     {
20672       errmsg ("missing table id");
20673       return -99;
20674     }
20675
20676   /* Construct the API message */
20677   M (CLASSIFY_TABLE_INFO, mp);
20678   mp->context = 0;
20679   mp->table_id = ntohl (table_id);
20680
20681   S (mp);
20682   W (ret);
20683   return ret;
20684 }
20685
20686 int
20687 api_classify_session_dump (vat_main_t * vam)
20688 {
20689   unformat_input_t *input = vam->input;
20690   vl_api_classify_session_dump_t *mp;
20691   vl_api_control_ping_t *mp_ping;
20692
20693   u32 table_id = ~0;
20694   int ret;
20695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20696     {
20697       if (unformat (input, "table_id %d", &table_id))
20698         ;
20699       else
20700         break;
20701     }
20702   if (table_id == ~0)
20703     {
20704       errmsg ("missing table id");
20705       return -99;
20706     }
20707
20708   /* Construct the API message */
20709   M (CLASSIFY_SESSION_DUMP, mp);
20710   mp->context = 0;
20711   mp->table_id = ntohl (table_id);
20712   S (mp);
20713
20714   /* Use a control ping for synchronization */
20715   MPING (CONTROL_PING, mp_ping);
20716   S (mp_ping);
20717
20718   W (ret);
20719   return ret;
20720 }
20721
20722 static void
20723 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20724 {
20725   vat_main_t *vam = &vat_main;
20726
20727   print (vam->ofp, "collector_address %U, collector_port %d, "
20728          "src_address %U, vrf_id %d, path_mtu %u, "
20729          "template_interval %u, udp_checksum %d",
20730          format_ip4_address, mp->collector_address,
20731          ntohs (mp->collector_port),
20732          format_ip4_address, mp->src_address,
20733          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20734          ntohl (mp->template_interval), mp->udp_checksum);
20735
20736   vam->retval = 0;
20737   vam->result_ready = 1;
20738 }
20739
20740 static void
20741   vl_api_ipfix_exporter_details_t_handler_json
20742   (vl_api_ipfix_exporter_details_t * mp)
20743 {
20744   vat_main_t *vam = &vat_main;
20745   vat_json_node_t node;
20746   struct in_addr collector_address;
20747   struct in_addr src_address;
20748
20749   vat_json_init_object (&node);
20750   clib_memcpy (&collector_address, &mp->collector_address,
20751                sizeof (collector_address));
20752   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20753   vat_json_object_add_uint (&node, "collector_port",
20754                             ntohs (mp->collector_port));
20755   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20756   vat_json_object_add_ip4 (&node, "src_address", src_address);
20757   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20758   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20759   vat_json_object_add_uint (&node, "template_interval",
20760                             ntohl (mp->template_interval));
20761   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20762
20763   vat_json_print (vam->ofp, &node);
20764   vat_json_free (&node);
20765   vam->retval = 0;
20766   vam->result_ready = 1;
20767 }
20768
20769 int
20770 api_ipfix_exporter_dump (vat_main_t * vam)
20771 {
20772   vl_api_ipfix_exporter_dump_t *mp;
20773   int ret;
20774
20775   /* Construct the API message */
20776   M (IPFIX_EXPORTER_DUMP, mp);
20777   mp->context = 0;
20778
20779   S (mp);
20780   W (ret);
20781   return ret;
20782 }
20783
20784 static int
20785 api_ipfix_classify_stream_dump (vat_main_t * vam)
20786 {
20787   vl_api_ipfix_classify_stream_dump_t *mp;
20788   int ret;
20789
20790   /* Construct the API message */
20791   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20792   mp->context = 0;
20793
20794   S (mp);
20795   W (ret);
20796   return ret;
20797   /* NOTREACHED */
20798   return 0;
20799 }
20800
20801 static void
20802   vl_api_ipfix_classify_stream_details_t_handler
20803   (vl_api_ipfix_classify_stream_details_t * mp)
20804 {
20805   vat_main_t *vam = &vat_main;
20806   print (vam->ofp, "domain_id %d, src_port %d",
20807          ntohl (mp->domain_id), ntohs (mp->src_port));
20808   vam->retval = 0;
20809   vam->result_ready = 1;
20810 }
20811
20812 static void
20813   vl_api_ipfix_classify_stream_details_t_handler_json
20814   (vl_api_ipfix_classify_stream_details_t * mp)
20815 {
20816   vat_main_t *vam = &vat_main;
20817   vat_json_node_t node;
20818
20819   vat_json_init_object (&node);
20820   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20821   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20822
20823   vat_json_print (vam->ofp, &node);
20824   vat_json_free (&node);
20825   vam->retval = 0;
20826   vam->result_ready = 1;
20827 }
20828
20829 static int
20830 api_ipfix_classify_table_dump (vat_main_t * vam)
20831 {
20832   vl_api_ipfix_classify_table_dump_t *mp;
20833   vl_api_control_ping_t *mp_ping;
20834   int ret;
20835
20836   if (!vam->json_output)
20837     {
20838       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20839              "transport_protocol");
20840     }
20841
20842   /* Construct the API message */
20843   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20844
20845   /* send it... */
20846   S (mp);
20847
20848   /* Use a control ping for synchronization */
20849   MPING (CONTROL_PING, mp_ping);
20850   S (mp_ping);
20851
20852   W (ret);
20853   return ret;
20854 }
20855
20856 static void
20857   vl_api_ipfix_classify_table_details_t_handler
20858   (vl_api_ipfix_classify_table_details_t * mp)
20859 {
20860   vat_main_t *vam = &vat_main;
20861   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20862          mp->transport_protocol);
20863 }
20864
20865 static void
20866   vl_api_ipfix_classify_table_details_t_handler_json
20867   (vl_api_ipfix_classify_table_details_t * mp)
20868 {
20869   vat_json_node_t *node = NULL;
20870   vat_main_t *vam = &vat_main;
20871
20872   if (VAT_JSON_ARRAY != vam->json_tree.type)
20873     {
20874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20875       vat_json_init_array (&vam->json_tree);
20876     }
20877
20878   node = vat_json_array_add (&vam->json_tree);
20879   vat_json_init_object (node);
20880
20881   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20882   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20883   vat_json_object_add_uint (node, "transport_protocol",
20884                             mp->transport_protocol);
20885 }
20886
20887 static int
20888 api_sw_interface_span_enable_disable (vat_main_t * vam)
20889 {
20890   unformat_input_t *i = vam->input;
20891   vl_api_sw_interface_span_enable_disable_t *mp;
20892   u32 src_sw_if_index = ~0;
20893   u32 dst_sw_if_index = ~0;
20894   u8 state = 3;
20895   int ret;
20896   u8 is_l2 = 0;
20897
20898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20899     {
20900       if (unformat
20901           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20902         ;
20903       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20904         ;
20905       else
20906         if (unformat
20907             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20908         ;
20909       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20910         ;
20911       else if (unformat (i, "disable"))
20912         state = 0;
20913       else if (unformat (i, "rx"))
20914         state = 1;
20915       else if (unformat (i, "tx"))
20916         state = 2;
20917       else if (unformat (i, "both"))
20918         state = 3;
20919       else if (unformat (i, "l2"))
20920         is_l2 = 1;
20921       else
20922         break;
20923     }
20924
20925   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20926
20927   mp->sw_if_index_from = htonl (src_sw_if_index);
20928   mp->sw_if_index_to = htonl (dst_sw_if_index);
20929   mp->state = state;
20930   mp->is_l2 = is_l2;
20931
20932   S (mp);
20933   W (ret);
20934   return ret;
20935 }
20936
20937 static void
20938 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20939                                             * mp)
20940 {
20941   vat_main_t *vam = &vat_main;
20942   u8 *sw_if_from_name = 0;
20943   u8 *sw_if_to_name = 0;
20944   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20945   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20946   char *states[] = { "none", "rx", "tx", "both" };
20947   hash_pair_t *p;
20948
20949   /* *INDENT-OFF* */
20950   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20951   ({
20952     if ((u32) p->value[0] == sw_if_index_from)
20953       {
20954         sw_if_from_name = (u8 *)(p->key);
20955         if (sw_if_to_name)
20956           break;
20957       }
20958     if ((u32) p->value[0] == sw_if_index_to)
20959       {
20960         sw_if_to_name = (u8 *)(p->key);
20961         if (sw_if_from_name)
20962           break;
20963       }
20964   }));
20965   /* *INDENT-ON* */
20966   print (vam->ofp, "%20s => %20s (%s) %s",
20967          sw_if_from_name, sw_if_to_name, states[mp->state],
20968          mp->is_l2 ? "l2" : "device");
20969 }
20970
20971 static void
20972   vl_api_sw_interface_span_details_t_handler_json
20973   (vl_api_sw_interface_span_details_t * mp)
20974 {
20975   vat_main_t *vam = &vat_main;
20976   vat_json_node_t *node = NULL;
20977   u8 *sw_if_from_name = 0;
20978   u8 *sw_if_to_name = 0;
20979   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20980   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20981   hash_pair_t *p;
20982
20983   /* *INDENT-OFF* */
20984   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20985   ({
20986     if ((u32) p->value[0] == sw_if_index_from)
20987       {
20988         sw_if_from_name = (u8 *)(p->key);
20989         if (sw_if_to_name)
20990           break;
20991       }
20992     if ((u32) p->value[0] == sw_if_index_to)
20993       {
20994         sw_if_to_name = (u8 *)(p->key);
20995         if (sw_if_from_name)
20996           break;
20997       }
20998   }));
20999   /* *INDENT-ON* */
21000
21001   if (VAT_JSON_ARRAY != vam->json_tree.type)
21002     {
21003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21004       vat_json_init_array (&vam->json_tree);
21005     }
21006   node = vat_json_array_add (&vam->json_tree);
21007
21008   vat_json_init_object (node);
21009   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21010   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21011   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21012   if (0 != sw_if_to_name)
21013     {
21014       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21015     }
21016   vat_json_object_add_uint (node, "state", mp->state);
21017   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21018 }
21019
21020 static int
21021 api_sw_interface_span_dump (vat_main_t * vam)
21022 {
21023   unformat_input_t *input = vam->input;
21024   vl_api_sw_interface_span_dump_t *mp;
21025   vl_api_control_ping_t *mp_ping;
21026   u8 is_l2 = 0;
21027   int ret;
21028
21029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21030     {
21031       if (unformat (input, "l2"))
21032         is_l2 = 1;
21033       else
21034         break;
21035     }
21036
21037   M (SW_INTERFACE_SPAN_DUMP, mp);
21038   mp->is_l2 = is_l2;
21039   S (mp);
21040
21041   /* Use a control ping for synchronization */
21042   MPING (CONTROL_PING, mp_ping);
21043   S (mp_ping);
21044
21045   W (ret);
21046   return ret;
21047 }
21048
21049 int
21050 api_pg_create_interface (vat_main_t * vam)
21051 {
21052   unformat_input_t *input = vam->input;
21053   vl_api_pg_create_interface_t *mp;
21054
21055   u32 if_id = ~0;
21056   int ret;
21057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21058     {
21059       if (unformat (input, "if_id %d", &if_id))
21060         ;
21061       else
21062         break;
21063     }
21064   if (if_id == ~0)
21065     {
21066       errmsg ("missing pg interface index");
21067       return -99;
21068     }
21069
21070   /* Construct the API message */
21071   M (PG_CREATE_INTERFACE, mp);
21072   mp->context = 0;
21073   mp->interface_id = ntohl (if_id);
21074
21075   S (mp);
21076   W (ret);
21077   return ret;
21078 }
21079
21080 int
21081 api_pg_capture (vat_main_t * vam)
21082 {
21083   unformat_input_t *input = vam->input;
21084   vl_api_pg_capture_t *mp;
21085
21086   u32 if_id = ~0;
21087   u8 enable = 1;
21088   u32 count = 1;
21089   u8 pcap_file_set = 0;
21090   u8 *pcap_file = 0;
21091   int ret;
21092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21093     {
21094       if (unformat (input, "if_id %d", &if_id))
21095         ;
21096       else if (unformat (input, "pcap %s", &pcap_file))
21097         pcap_file_set = 1;
21098       else if (unformat (input, "count %d", &count))
21099         ;
21100       else if (unformat (input, "disable"))
21101         enable = 0;
21102       else
21103         break;
21104     }
21105   if (if_id == ~0)
21106     {
21107       errmsg ("missing pg interface index");
21108       return -99;
21109     }
21110   if (pcap_file_set > 0)
21111     {
21112       if (vec_len (pcap_file) > 255)
21113         {
21114           errmsg ("pcap file name is too long");
21115           return -99;
21116         }
21117     }
21118
21119   u32 name_len = vec_len (pcap_file);
21120   /* Construct the API message */
21121   M (PG_CAPTURE, mp);
21122   mp->context = 0;
21123   mp->interface_id = ntohl (if_id);
21124   mp->is_enabled = enable;
21125   mp->count = ntohl (count);
21126   mp->pcap_name_length = ntohl (name_len);
21127   if (pcap_file_set != 0)
21128     {
21129       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21130     }
21131   vec_free (pcap_file);
21132
21133   S (mp);
21134   W (ret);
21135   return ret;
21136 }
21137
21138 int
21139 api_pg_enable_disable (vat_main_t * vam)
21140 {
21141   unformat_input_t *input = vam->input;
21142   vl_api_pg_enable_disable_t *mp;
21143
21144   u8 enable = 1;
21145   u8 stream_name_set = 0;
21146   u8 *stream_name = 0;
21147   int ret;
21148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21149     {
21150       if (unformat (input, "stream %s", &stream_name))
21151         stream_name_set = 1;
21152       else if (unformat (input, "disable"))
21153         enable = 0;
21154       else
21155         break;
21156     }
21157
21158   if (stream_name_set > 0)
21159     {
21160       if (vec_len (stream_name) > 255)
21161         {
21162           errmsg ("stream name too long");
21163           return -99;
21164         }
21165     }
21166
21167   u32 name_len = vec_len (stream_name);
21168   /* Construct the API message */
21169   M (PG_ENABLE_DISABLE, mp);
21170   mp->context = 0;
21171   mp->is_enabled = enable;
21172   if (stream_name_set != 0)
21173     {
21174       mp->stream_name_length = ntohl (name_len);
21175       clib_memcpy (mp->stream_name, stream_name, name_len);
21176     }
21177   vec_free (stream_name);
21178
21179   S (mp);
21180   W (ret);
21181   return ret;
21182 }
21183
21184 int
21185 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21186 {
21187   unformat_input_t *input = vam->input;
21188   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21189
21190   u16 *low_ports = 0;
21191   u16 *high_ports = 0;
21192   u16 this_low;
21193   u16 this_hi;
21194   ip4_address_t ip4_addr;
21195   ip6_address_t ip6_addr;
21196   u32 length;
21197   u32 tmp, tmp2;
21198   u8 prefix_set = 0;
21199   u32 vrf_id = ~0;
21200   u8 is_add = 1;
21201   u8 is_ipv6 = 0;
21202   int ret;
21203
21204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21205     {
21206       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21207         {
21208           prefix_set = 1;
21209         }
21210       else
21211         if (unformat
21212             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21213         {
21214           prefix_set = 1;
21215           is_ipv6 = 1;
21216         }
21217       else if (unformat (input, "vrf %d", &vrf_id))
21218         ;
21219       else if (unformat (input, "del"))
21220         is_add = 0;
21221       else if (unformat (input, "port %d", &tmp))
21222         {
21223           if (tmp == 0 || tmp > 65535)
21224             {
21225               errmsg ("port %d out of range", tmp);
21226               return -99;
21227             }
21228           this_low = tmp;
21229           this_hi = this_low + 1;
21230           vec_add1 (low_ports, this_low);
21231           vec_add1 (high_ports, this_hi);
21232         }
21233       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21234         {
21235           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21236             {
21237               errmsg ("incorrect range parameters");
21238               return -99;
21239             }
21240           this_low = tmp;
21241           /* Note: in debug CLI +1 is added to high before
21242              passing to real fn that does "the work"
21243              (ip_source_and_port_range_check_add_del).
21244              This fn is a wrapper around the binary API fn a
21245              control plane will call, which expects this increment
21246              to have occurred. Hence letting the binary API control
21247              plane fn do the increment for consistency between VAT
21248              and other control planes.
21249            */
21250           this_hi = tmp2;
21251           vec_add1 (low_ports, this_low);
21252           vec_add1 (high_ports, this_hi);
21253         }
21254       else
21255         break;
21256     }
21257
21258   if (prefix_set == 0)
21259     {
21260       errmsg ("<address>/<mask> not specified");
21261       return -99;
21262     }
21263
21264   if (vrf_id == ~0)
21265     {
21266       errmsg ("VRF ID required, not specified");
21267       return -99;
21268     }
21269
21270   if (vrf_id == 0)
21271     {
21272       errmsg
21273         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21274       return -99;
21275     }
21276
21277   if (vec_len (low_ports) == 0)
21278     {
21279       errmsg ("At least one port or port range required");
21280       return -99;
21281     }
21282
21283   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21284
21285   mp->is_add = is_add;
21286
21287   if (is_ipv6)
21288     {
21289       mp->is_ipv6 = 1;
21290       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21291     }
21292   else
21293     {
21294       mp->is_ipv6 = 0;
21295       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21296     }
21297
21298   mp->mask_length = length;
21299   mp->number_of_ranges = vec_len (low_ports);
21300
21301   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21302   vec_free (low_ports);
21303
21304   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21305   vec_free (high_ports);
21306
21307   mp->vrf_id = ntohl (vrf_id);
21308
21309   S (mp);
21310   W (ret);
21311   return ret;
21312 }
21313
21314 int
21315 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21316 {
21317   unformat_input_t *input = vam->input;
21318   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21319   u32 sw_if_index = ~0;
21320   int vrf_set = 0;
21321   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21322   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21323   u8 is_add = 1;
21324   int ret;
21325
21326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21327     {
21328       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21329         ;
21330       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21331         ;
21332       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21333         vrf_set = 1;
21334       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21335         vrf_set = 1;
21336       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21337         vrf_set = 1;
21338       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21339         vrf_set = 1;
21340       else if (unformat (input, "del"))
21341         is_add = 0;
21342       else
21343         break;
21344     }
21345
21346   if (sw_if_index == ~0)
21347     {
21348       errmsg ("Interface required but not specified");
21349       return -99;
21350     }
21351
21352   if (vrf_set == 0)
21353     {
21354       errmsg ("VRF ID required but not specified");
21355       return -99;
21356     }
21357
21358   if (tcp_out_vrf_id == 0
21359       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21360     {
21361       errmsg
21362         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21363       return -99;
21364     }
21365
21366   /* Construct the API message */
21367   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21368
21369   mp->sw_if_index = ntohl (sw_if_index);
21370   mp->is_add = is_add;
21371   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21372   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21373   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21374   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21375
21376   /* send it... */
21377   S (mp);
21378
21379   /* Wait for a reply... */
21380   W (ret);
21381   return ret;
21382 }
21383
21384 static int
21385 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21386 {
21387   unformat_input_t *i = vam->input;
21388   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21389   u32 local_sa_id = 0;
21390   u32 remote_sa_id = 0;
21391   ip4_address_t src_address;
21392   ip4_address_t dst_address;
21393   u8 is_add = 1;
21394   int ret;
21395
21396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21397     {
21398       if (unformat (i, "local_sa %d", &local_sa_id))
21399         ;
21400       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21401         ;
21402       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21403         ;
21404       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21405         ;
21406       else if (unformat (i, "del"))
21407         is_add = 0;
21408       else
21409         {
21410           clib_warning ("parse error '%U'", format_unformat_error, i);
21411           return -99;
21412         }
21413     }
21414
21415   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21416
21417   mp->local_sa_id = ntohl (local_sa_id);
21418   mp->remote_sa_id = ntohl (remote_sa_id);
21419   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21420   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21421   mp->is_add = is_add;
21422
21423   S (mp);
21424   W (ret);
21425   return ret;
21426 }
21427
21428 static int
21429 api_punt (vat_main_t * vam)
21430 {
21431   unformat_input_t *i = vam->input;
21432   vl_api_punt_t *mp;
21433   u32 ipv = ~0;
21434   u32 protocol = ~0;
21435   u32 port = ~0;
21436   int is_add = 1;
21437   int ret;
21438
21439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21440     {
21441       if (unformat (i, "ip %d", &ipv))
21442         ;
21443       else if (unformat (i, "protocol %d", &protocol))
21444         ;
21445       else if (unformat (i, "port %d", &port))
21446         ;
21447       else if (unformat (i, "del"))
21448         is_add = 0;
21449       else
21450         {
21451           clib_warning ("parse error '%U'", format_unformat_error, i);
21452           return -99;
21453         }
21454     }
21455
21456   M (PUNT, mp);
21457
21458   mp->is_add = (u8) is_add;
21459   mp->ipv = (u8) ipv;
21460   mp->l4_protocol = (u8) protocol;
21461   mp->l4_port = htons ((u16) port);
21462
21463   S (mp);
21464   W (ret);
21465   return ret;
21466 }
21467
21468 static void vl_api_ipsec_gre_tunnel_details_t_handler
21469   (vl_api_ipsec_gre_tunnel_details_t * mp)
21470 {
21471   vat_main_t *vam = &vat_main;
21472
21473   print (vam->ofp, "%11d%15U%15U%14d%14d",
21474          ntohl (mp->sw_if_index),
21475          format_ip4_address, &mp->src_address,
21476          format_ip4_address, &mp->dst_address,
21477          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21478 }
21479
21480 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21481   (vl_api_ipsec_gre_tunnel_details_t * mp)
21482 {
21483   vat_main_t *vam = &vat_main;
21484   vat_json_node_t *node = NULL;
21485   struct in_addr ip4;
21486
21487   if (VAT_JSON_ARRAY != vam->json_tree.type)
21488     {
21489       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21490       vat_json_init_array (&vam->json_tree);
21491     }
21492   node = vat_json_array_add (&vam->json_tree);
21493
21494   vat_json_init_object (node);
21495   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21496   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21497   vat_json_object_add_ip4 (node, "src_address", ip4);
21498   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21499   vat_json_object_add_ip4 (node, "dst_address", ip4);
21500   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21501   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21502 }
21503
21504 static int
21505 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21506 {
21507   unformat_input_t *i = vam->input;
21508   vl_api_ipsec_gre_tunnel_dump_t *mp;
21509   vl_api_control_ping_t *mp_ping;
21510   u32 sw_if_index;
21511   u8 sw_if_index_set = 0;
21512   int ret;
21513
21514   /* Parse args required to build the message */
21515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21516     {
21517       if (unformat (i, "sw_if_index %d", &sw_if_index))
21518         sw_if_index_set = 1;
21519       else
21520         break;
21521     }
21522
21523   if (sw_if_index_set == 0)
21524     {
21525       sw_if_index = ~0;
21526     }
21527
21528   if (!vam->json_output)
21529     {
21530       print (vam->ofp, "%11s%15s%15s%14s%14s",
21531              "sw_if_index", "src_address", "dst_address",
21532              "local_sa_id", "remote_sa_id");
21533     }
21534
21535   /* Get list of gre-tunnel interfaces */
21536   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21537
21538   mp->sw_if_index = htonl (sw_if_index);
21539
21540   S (mp);
21541
21542   /* Use a control ping for synchronization */
21543   MPING (CONTROL_PING, mp_ping);
21544   S (mp_ping);
21545
21546   W (ret);
21547   return ret;
21548 }
21549
21550 static int
21551 api_delete_subif (vat_main_t * vam)
21552 {
21553   unformat_input_t *i = vam->input;
21554   vl_api_delete_subif_t *mp;
21555   u32 sw_if_index = ~0;
21556   int ret;
21557
21558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21559     {
21560       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21561         ;
21562       if (unformat (i, "sw_if_index %d", &sw_if_index))
21563         ;
21564       else
21565         break;
21566     }
21567
21568   if (sw_if_index == ~0)
21569     {
21570       errmsg ("missing sw_if_index");
21571       return -99;
21572     }
21573
21574   /* Construct the API message */
21575   M (DELETE_SUBIF, mp);
21576   mp->sw_if_index = ntohl (sw_if_index);
21577
21578   S (mp);
21579   W (ret);
21580   return ret;
21581 }
21582
21583 #define foreach_pbb_vtr_op      \
21584 _("disable",  L2_VTR_DISABLED)  \
21585 _("pop",  L2_VTR_POP_2)         \
21586 _("push",  L2_VTR_PUSH_2)
21587
21588 static int
21589 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21590 {
21591   unformat_input_t *i = vam->input;
21592   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21593   u32 sw_if_index = ~0, vtr_op = ~0;
21594   u16 outer_tag = ~0;
21595   u8 dmac[6], smac[6];
21596   u8 dmac_set = 0, smac_set = 0;
21597   u16 vlanid = 0;
21598   u32 sid = ~0;
21599   u32 tmp;
21600   int ret;
21601
21602   /* Shut up coverity */
21603   memset (dmac, 0, sizeof (dmac));
21604   memset (smac, 0, sizeof (smac));
21605
21606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21607     {
21608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21609         ;
21610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21611         ;
21612       else if (unformat (i, "vtr_op %d", &vtr_op))
21613         ;
21614 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21615       foreach_pbb_vtr_op
21616 #undef _
21617         else if (unformat (i, "translate_pbb_stag"))
21618         {
21619           if (unformat (i, "%d", &tmp))
21620             {
21621               vtr_op = L2_VTR_TRANSLATE_2_1;
21622               outer_tag = tmp;
21623             }
21624           else
21625             {
21626               errmsg
21627                 ("translate_pbb_stag operation requires outer tag definition");
21628               return -99;
21629             }
21630         }
21631       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21632         dmac_set++;
21633       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21634         smac_set++;
21635       else if (unformat (i, "sid %d", &sid))
21636         ;
21637       else if (unformat (i, "vlanid %d", &tmp))
21638         vlanid = tmp;
21639       else
21640         {
21641           clib_warning ("parse error '%U'", format_unformat_error, i);
21642           return -99;
21643         }
21644     }
21645
21646   if ((sw_if_index == ~0) || (vtr_op == ~0))
21647     {
21648       errmsg ("missing sw_if_index or vtr operation");
21649       return -99;
21650     }
21651   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21652       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21653     {
21654       errmsg
21655         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21656       return -99;
21657     }
21658
21659   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21660   mp->sw_if_index = ntohl (sw_if_index);
21661   mp->vtr_op = ntohl (vtr_op);
21662   mp->outer_tag = ntohs (outer_tag);
21663   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21664   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21665   mp->b_vlanid = ntohs (vlanid);
21666   mp->i_sid = ntohl (sid);
21667
21668   S (mp);
21669   W (ret);
21670   return ret;
21671 }
21672
21673 static int
21674 api_flow_classify_set_interface (vat_main_t * vam)
21675 {
21676   unformat_input_t *i = vam->input;
21677   vl_api_flow_classify_set_interface_t *mp;
21678   u32 sw_if_index;
21679   int sw_if_index_set;
21680   u32 ip4_table_index = ~0;
21681   u32 ip6_table_index = ~0;
21682   u8 is_add = 1;
21683   int ret;
21684
21685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21686     {
21687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21688         sw_if_index_set = 1;
21689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21690         sw_if_index_set = 1;
21691       else if (unformat (i, "del"))
21692         is_add = 0;
21693       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21694         ;
21695       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21696         ;
21697       else
21698         {
21699           clib_warning ("parse error '%U'", format_unformat_error, i);
21700           return -99;
21701         }
21702     }
21703
21704   if (sw_if_index_set == 0)
21705     {
21706       errmsg ("missing interface name or sw_if_index");
21707       return -99;
21708     }
21709
21710   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21711
21712   mp->sw_if_index = ntohl (sw_if_index);
21713   mp->ip4_table_index = ntohl (ip4_table_index);
21714   mp->ip6_table_index = ntohl (ip6_table_index);
21715   mp->is_add = is_add;
21716
21717   S (mp);
21718   W (ret);
21719   return ret;
21720 }
21721
21722 static int
21723 api_flow_classify_dump (vat_main_t * vam)
21724 {
21725   unformat_input_t *i = vam->input;
21726   vl_api_flow_classify_dump_t *mp;
21727   vl_api_control_ping_t *mp_ping;
21728   u8 type = FLOW_CLASSIFY_N_TABLES;
21729   int ret;
21730
21731   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21732     ;
21733   else
21734     {
21735       errmsg ("classify table type must be specified");
21736       return -99;
21737     }
21738
21739   if (!vam->json_output)
21740     {
21741       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21742     }
21743
21744   M (FLOW_CLASSIFY_DUMP, mp);
21745   mp->type = type;
21746   /* send it... */
21747   S (mp);
21748
21749   /* Use a control ping for synchronization */
21750   MPING (CONTROL_PING, mp_ping);
21751   S (mp_ping);
21752
21753   /* Wait for a reply... */
21754   W (ret);
21755   return ret;
21756 }
21757
21758 static int
21759 api_feature_enable_disable (vat_main_t * vam)
21760 {
21761   unformat_input_t *i = vam->input;
21762   vl_api_feature_enable_disable_t *mp;
21763   u8 *arc_name = 0;
21764   u8 *feature_name = 0;
21765   u32 sw_if_index = ~0;
21766   u8 enable = 1;
21767   int ret;
21768
21769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21770     {
21771       if (unformat (i, "arc_name %s", &arc_name))
21772         ;
21773       else if (unformat (i, "feature_name %s", &feature_name))
21774         ;
21775       else
21776         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21777         ;
21778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21779         ;
21780       else if (unformat (i, "disable"))
21781         enable = 0;
21782       else
21783         break;
21784     }
21785
21786   if (arc_name == 0)
21787     {
21788       errmsg ("missing arc name");
21789       return -99;
21790     }
21791   if (vec_len (arc_name) > 63)
21792     {
21793       errmsg ("arc name too long");
21794     }
21795
21796   if (feature_name == 0)
21797     {
21798       errmsg ("missing feature name");
21799       return -99;
21800     }
21801   if (vec_len (feature_name) > 63)
21802     {
21803       errmsg ("feature name too long");
21804     }
21805
21806   if (sw_if_index == ~0)
21807     {
21808       errmsg ("missing interface name or sw_if_index");
21809       return -99;
21810     }
21811
21812   /* Construct the API message */
21813   M (FEATURE_ENABLE_DISABLE, mp);
21814   mp->sw_if_index = ntohl (sw_if_index);
21815   mp->enable = enable;
21816   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21817   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21818   vec_free (arc_name);
21819   vec_free (feature_name);
21820
21821   S (mp);
21822   W (ret);
21823   return ret;
21824 }
21825
21826 static int
21827 api_sw_interface_tag_add_del (vat_main_t * vam)
21828 {
21829   unformat_input_t *i = vam->input;
21830   vl_api_sw_interface_tag_add_del_t *mp;
21831   u32 sw_if_index = ~0;
21832   u8 *tag = 0;
21833   u8 enable = 1;
21834   int ret;
21835
21836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21837     {
21838       if (unformat (i, "tag %s", &tag))
21839         ;
21840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21841         ;
21842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21843         ;
21844       else if (unformat (i, "del"))
21845         enable = 0;
21846       else
21847         break;
21848     }
21849
21850   if (sw_if_index == ~0)
21851     {
21852       errmsg ("missing interface name or sw_if_index");
21853       return -99;
21854     }
21855
21856   if (enable && (tag == 0))
21857     {
21858       errmsg ("no tag specified");
21859       return -99;
21860     }
21861
21862   /* Construct the API message */
21863   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21864   mp->sw_if_index = ntohl (sw_if_index);
21865   mp->is_add = enable;
21866   if (enable)
21867     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21868   vec_free (tag);
21869
21870   S (mp);
21871   W (ret);
21872   return ret;
21873 }
21874
21875 static void vl_api_l2_xconnect_details_t_handler
21876   (vl_api_l2_xconnect_details_t * mp)
21877 {
21878   vat_main_t *vam = &vat_main;
21879
21880   print (vam->ofp, "%15d%15d",
21881          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21882 }
21883
21884 static void vl_api_l2_xconnect_details_t_handler_json
21885   (vl_api_l2_xconnect_details_t * mp)
21886 {
21887   vat_main_t *vam = &vat_main;
21888   vat_json_node_t *node = NULL;
21889
21890   if (VAT_JSON_ARRAY != vam->json_tree.type)
21891     {
21892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21893       vat_json_init_array (&vam->json_tree);
21894     }
21895   node = vat_json_array_add (&vam->json_tree);
21896
21897   vat_json_init_object (node);
21898   vat_json_object_add_uint (node, "rx_sw_if_index",
21899                             ntohl (mp->rx_sw_if_index));
21900   vat_json_object_add_uint (node, "tx_sw_if_index",
21901                             ntohl (mp->tx_sw_if_index));
21902 }
21903
21904 static int
21905 api_l2_xconnect_dump (vat_main_t * vam)
21906 {
21907   vl_api_l2_xconnect_dump_t *mp;
21908   vl_api_control_ping_t *mp_ping;
21909   int ret;
21910
21911   if (!vam->json_output)
21912     {
21913       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21914     }
21915
21916   M (L2_XCONNECT_DUMP, mp);
21917
21918   S (mp);
21919
21920   /* Use a control ping for synchronization */
21921   MPING (CONTROL_PING, mp_ping);
21922   S (mp_ping);
21923
21924   W (ret);
21925   return ret;
21926 }
21927
21928 static int
21929 api_hw_interface_set_mtu (vat_main_t * vam)
21930 {
21931   unformat_input_t *i = vam->input;
21932   vl_api_hw_interface_set_mtu_t *mp;
21933   u32 sw_if_index = ~0;
21934   u32 mtu = 0;
21935   int ret;
21936
21937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21938     {
21939       if (unformat (i, "mtu %d", &mtu))
21940         ;
21941       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21942         ;
21943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21944         ;
21945       else
21946         break;
21947     }
21948
21949   if (sw_if_index == ~0)
21950     {
21951       errmsg ("missing interface name or sw_if_index");
21952       return -99;
21953     }
21954
21955   if (mtu == 0)
21956     {
21957       errmsg ("no mtu specified");
21958       return -99;
21959     }
21960
21961   /* Construct the API message */
21962   M (HW_INTERFACE_SET_MTU, mp);
21963   mp->sw_if_index = ntohl (sw_if_index);
21964   mp->mtu = ntohs ((u16) mtu);
21965
21966   S (mp);
21967   W (ret);
21968   return ret;
21969 }
21970
21971 static int
21972 api_p2p_ethernet_add (vat_main_t * vam)
21973 {
21974   unformat_input_t *i = vam->input;
21975   vl_api_p2p_ethernet_add_t *mp;
21976   u32 parent_if_index = ~0;
21977   u32 sub_id = ~0;
21978   u8 remote_mac[6];
21979   u8 mac_set = 0;
21980   int ret;
21981
21982   memset (remote_mac, 0, sizeof (remote_mac));
21983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21984     {
21985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21986         ;
21987       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21988         ;
21989       else
21990         if (unformat
21991             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21992         mac_set++;
21993       else if (unformat (i, "sub_id %d", &sub_id))
21994         ;
21995       else
21996         {
21997           clib_warning ("parse error '%U'", format_unformat_error, i);
21998           return -99;
21999         }
22000     }
22001
22002   if (parent_if_index == ~0)
22003     {
22004       errmsg ("missing interface name or sw_if_index");
22005       return -99;
22006     }
22007   if (mac_set == 0)
22008     {
22009       errmsg ("missing remote mac address");
22010       return -99;
22011     }
22012   if (sub_id == ~0)
22013     {
22014       errmsg ("missing sub-interface id");
22015       return -99;
22016     }
22017
22018   M (P2P_ETHERNET_ADD, mp);
22019   mp->parent_if_index = ntohl (parent_if_index);
22020   mp->subif_id = ntohl (sub_id);
22021   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22022
22023   S (mp);
22024   W (ret);
22025   return ret;
22026 }
22027
22028 static int
22029 api_p2p_ethernet_del (vat_main_t * vam)
22030 {
22031   unformat_input_t *i = vam->input;
22032   vl_api_p2p_ethernet_del_t *mp;
22033   u32 parent_if_index = ~0;
22034   u8 remote_mac[6];
22035   u8 mac_set = 0;
22036   int ret;
22037
22038   memset (remote_mac, 0, sizeof (remote_mac));
22039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22040     {
22041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22042         ;
22043       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22044         ;
22045       else
22046         if (unformat
22047             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22048         mac_set++;
22049       else
22050         {
22051           clib_warning ("parse error '%U'", format_unformat_error, i);
22052           return -99;
22053         }
22054     }
22055
22056   if (parent_if_index == ~0)
22057     {
22058       errmsg ("missing interface name or sw_if_index");
22059       return -99;
22060     }
22061   if (mac_set == 0)
22062     {
22063       errmsg ("missing remote mac address");
22064       return -99;
22065     }
22066
22067   M (P2P_ETHERNET_DEL, mp);
22068   mp->parent_if_index = ntohl (parent_if_index);
22069   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22070
22071   S (mp);
22072   W (ret);
22073   return ret;
22074 }
22075
22076 static int
22077 api_lldp_config (vat_main_t * vam)
22078 {
22079   unformat_input_t *i = vam->input;
22080   vl_api_lldp_config_t *mp;
22081   int tx_hold = 0;
22082   int tx_interval = 0;
22083   u8 *sys_name = NULL;
22084   int ret;
22085
22086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22087     {
22088       if (unformat (i, "system-name %s", &sys_name))
22089         ;
22090       else if (unformat (i, "tx-hold %d", &tx_hold))
22091         ;
22092       else if (unformat (i, "tx-interval %d", &tx_interval))
22093         ;
22094       else
22095         {
22096           clib_warning ("parse error '%U'", format_unformat_error, i);
22097           return -99;
22098         }
22099     }
22100
22101   vec_add1 (sys_name, 0);
22102
22103   M (LLDP_CONFIG, mp);
22104   mp->tx_hold = htonl (tx_hold);
22105   mp->tx_interval = htonl (tx_interval);
22106   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22107   vec_free (sys_name);
22108
22109   S (mp);
22110   W (ret);
22111   return ret;
22112 }
22113
22114 static int
22115 api_sw_interface_set_lldp (vat_main_t * vam)
22116 {
22117   unformat_input_t *i = vam->input;
22118   vl_api_sw_interface_set_lldp_t *mp;
22119   u32 sw_if_index = ~0;
22120   u32 enable = 1;
22121   u8 *port_desc = NULL, *mgmt_oid = NULL;
22122   ip4_address_t ip4_addr;
22123   ip6_address_t ip6_addr;
22124   int ret;
22125
22126   memset (&ip4_addr, 0, sizeof (ip4_addr));
22127   memset (&ip6_addr, 0, sizeof (ip6_addr));
22128
22129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22130     {
22131       if (unformat (i, "disable"))
22132         enable = 0;
22133       else
22134         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22135         ;
22136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22137         ;
22138       else if (unformat (i, "port-desc %s", &port_desc))
22139         ;
22140       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22141         ;
22142       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22143         ;
22144       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22145         ;
22146       else
22147         break;
22148     }
22149
22150   if (sw_if_index == ~0)
22151     {
22152       errmsg ("missing interface name or sw_if_index");
22153       return -99;
22154     }
22155
22156   /* Construct the API message */
22157   vec_add1 (port_desc, 0);
22158   vec_add1 (mgmt_oid, 0);
22159   M (SW_INTERFACE_SET_LLDP, mp);
22160   mp->sw_if_index = ntohl (sw_if_index);
22161   mp->enable = enable;
22162   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22163   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22164   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22165   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22166   vec_free (port_desc);
22167   vec_free (mgmt_oid);
22168
22169   S (mp);
22170   W (ret);
22171   return ret;
22172 }
22173
22174 static int
22175 api_tcp_configure_src_addresses (vat_main_t * vam)
22176 {
22177   vl_api_tcp_configure_src_addresses_t *mp;
22178   unformat_input_t *i = vam->input;
22179   ip4_address_t v4first, v4last;
22180   ip6_address_t v6first, v6last;
22181   u8 range_set = 0;
22182   u32 vrf_id = 0;
22183   int ret;
22184
22185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22186     {
22187       if (unformat (i, "%U - %U",
22188                     unformat_ip4_address, &v4first,
22189                     unformat_ip4_address, &v4last))
22190         {
22191           if (range_set)
22192             {
22193               errmsg ("one range per message (range already set)");
22194               return -99;
22195             }
22196           range_set = 1;
22197         }
22198       else if (unformat (i, "%U - %U",
22199                          unformat_ip6_address, &v6first,
22200                          unformat_ip6_address, &v6last))
22201         {
22202           if (range_set)
22203             {
22204               errmsg ("one range per message (range already set)");
22205               return -99;
22206             }
22207           range_set = 2;
22208         }
22209       else if (unformat (i, "vrf %d", &vrf_id))
22210         ;
22211       else
22212         break;
22213     }
22214
22215   if (range_set == 0)
22216     {
22217       errmsg ("address range not set");
22218       return -99;
22219     }
22220
22221   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22222   mp->vrf_id = ntohl (vrf_id);
22223   /* ipv6? */
22224   if (range_set == 2)
22225     {
22226       mp->is_ipv6 = 1;
22227       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22228       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22229     }
22230   else
22231     {
22232       mp->is_ipv6 = 0;
22233       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22234       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22235     }
22236   S (mp);
22237   W (ret);
22238   return ret;
22239 }
22240
22241 static void vl_api_app_namespace_add_del_reply_t_handler
22242   (vl_api_app_namespace_add_del_reply_t * mp)
22243 {
22244   vat_main_t *vam = &vat_main;
22245   i32 retval = ntohl (mp->retval);
22246   if (vam->async_mode)
22247     {
22248       vam->async_errors += (retval < 0);
22249     }
22250   else
22251     {
22252       vam->retval = retval;
22253       if (retval == 0)
22254         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22255       vam->result_ready = 1;
22256     }
22257 }
22258
22259 static void vl_api_app_namespace_add_del_reply_t_handler_json
22260   (vl_api_app_namespace_add_del_reply_t * mp)
22261 {
22262   vat_main_t *vam = &vat_main;
22263   vat_json_node_t node;
22264
22265   vat_json_init_object (&node);
22266   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22267   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22268
22269   vat_json_print (vam->ofp, &node);
22270   vat_json_free (&node);
22271
22272   vam->retval = ntohl (mp->retval);
22273   vam->result_ready = 1;
22274 }
22275
22276 static int
22277 api_app_namespace_add_del (vat_main_t * vam)
22278 {
22279   vl_api_app_namespace_add_del_t *mp;
22280   unformat_input_t *i = vam->input;
22281   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22282   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22283   u64 secret;
22284   int ret;
22285
22286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22287     {
22288       if (unformat (i, "id %_%v%_", &ns_id))
22289         ;
22290       else if (unformat (i, "secret %lu", &secret))
22291         secret_set = 1;
22292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22293         sw_if_index_set = 1;
22294       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22295         ;
22296       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22297         ;
22298       else
22299         break;
22300     }
22301   if (!ns_id || !secret_set || !sw_if_index_set)
22302     {
22303       errmsg ("namespace id, secret and sw_if_index must be set");
22304       return -99;
22305     }
22306   if (vec_len (ns_id) > 64)
22307     {
22308       errmsg ("namespace id too long");
22309       return -99;
22310     }
22311   M (APP_NAMESPACE_ADD_DEL, mp);
22312
22313   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22314   mp->namespace_id_len = vec_len (ns_id);
22315   mp->secret = clib_host_to_net_u64 (secret);
22316   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22317   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22318   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22319   vec_free (ns_id);
22320   S (mp);
22321   W (ret);
22322   return ret;
22323 }
22324
22325 static int
22326 api_sock_init_shm (vat_main_t * vam)
22327 {
22328 #if VPP_API_TEST_BUILTIN == 0
22329   unformat_input_t *i = vam->input;
22330   vl_api_shm_elem_config_t *config = 0;
22331   u64 size = 64 << 20;
22332   int rv;
22333
22334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22335     {
22336       if (unformat (i, "size %U", unformat_memory_size, &size))
22337         ;
22338       else
22339         break;
22340     }
22341
22342   /*
22343    * Canned custom ring allocator config.
22344    * Should probably parse all of this
22345    */
22346   vec_validate (config, 6);
22347   config[0].type = VL_API_VLIB_RING;
22348   config[0].size = 256;
22349   config[0].count = 32;
22350
22351   config[1].type = VL_API_VLIB_RING;
22352   config[1].size = 1024;
22353   config[1].count = 16;
22354
22355   config[2].type = VL_API_VLIB_RING;
22356   config[2].size = 4096;
22357   config[2].count = 2;
22358
22359   config[3].type = VL_API_CLIENT_RING;
22360   config[3].size = 256;
22361   config[3].count = 32;
22362
22363   config[4].type = VL_API_CLIENT_RING;
22364   config[4].size = 1024;
22365   config[4].count = 16;
22366
22367   config[5].type = VL_API_CLIENT_RING;
22368   config[5].size = 4096;
22369   config[5].count = 2;
22370
22371   config[6].type = VL_API_QUEUE;
22372   config[6].count = 128;
22373   config[6].size = sizeof (uword);
22374
22375   rv = vl_socket_client_init_shm (config);
22376   if (!rv)
22377     vam->client_index_invalid = 1;
22378   return rv;
22379 #else
22380   return -99;
22381 #endif
22382 }
22383
22384 static int
22385 api_dns_enable_disable (vat_main_t * vam)
22386 {
22387   unformat_input_t *line_input = vam->input;
22388   vl_api_dns_enable_disable_t *mp;
22389   u8 enable_disable = 1;
22390   int ret;
22391
22392   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22393     {
22394       if (unformat (line_input, "disable"))
22395         enable_disable = 0;
22396       if (unformat (line_input, "enable"))
22397         enable_disable = 1;
22398       else
22399         break;
22400     }
22401
22402   /* Construct the API message */
22403   M (DNS_ENABLE_DISABLE, mp);
22404   mp->enable = enable_disable;
22405
22406   /* send it... */
22407   S (mp);
22408   /* Wait for the reply */
22409   W (ret);
22410   return ret;
22411 }
22412
22413 static int
22414 api_dns_resolve_name (vat_main_t * vam)
22415 {
22416   unformat_input_t *line_input = vam->input;
22417   vl_api_dns_resolve_name_t *mp;
22418   u8 *name = 0;
22419   int ret;
22420
22421   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22422     {
22423       if (unformat (line_input, "%s", &name))
22424         ;
22425       else
22426         break;
22427     }
22428
22429   if (vec_len (name) > 127)
22430     {
22431       errmsg ("name too long");
22432       return -99;
22433     }
22434
22435   /* Construct the API message */
22436   M (DNS_RESOLVE_NAME, mp);
22437   memcpy (mp->name, name, vec_len (name));
22438   vec_free (name);
22439
22440   /* send it... */
22441   S (mp);
22442   /* Wait for the reply */
22443   W (ret);
22444   return ret;
22445 }
22446
22447 static int
22448 api_dns_resolve_ip (vat_main_t * vam)
22449 {
22450   unformat_input_t *line_input = vam->input;
22451   vl_api_dns_resolve_ip_t *mp;
22452   int is_ip6 = -1;
22453   ip4_address_t addr4;
22454   ip6_address_t addr6;
22455   int ret;
22456
22457   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22458     {
22459       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22460         is_ip6 = 1;
22461       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22462         is_ip6 = 0;
22463       else
22464         break;
22465     }
22466
22467   if (is_ip6 == -1)
22468     {
22469       errmsg ("missing address");
22470       return -99;
22471     }
22472
22473   /* Construct the API message */
22474   M (DNS_RESOLVE_IP, mp);
22475   mp->is_ip6 = is_ip6;
22476   if (is_ip6)
22477     memcpy (mp->address, &addr6, sizeof (addr6));
22478   else
22479     memcpy (mp->address, &addr4, sizeof (addr4));
22480
22481   /* send it... */
22482   S (mp);
22483   /* Wait for the reply */
22484   W (ret);
22485   return ret;
22486 }
22487
22488 static int
22489 api_dns_name_server_add_del (vat_main_t * vam)
22490 {
22491   unformat_input_t *i = vam->input;
22492   vl_api_dns_name_server_add_del_t *mp;
22493   u8 is_add = 1;
22494   ip6_address_t ip6_server;
22495   ip4_address_t ip4_server;
22496   int ip6_set = 0;
22497   int ip4_set = 0;
22498   int ret = 0;
22499
22500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22501     {
22502       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22503         ip6_set = 1;
22504       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22505         ip4_set = 1;
22506       else if (unformat (i, "del"))
22507         is_add = 0;
22508       else
22509         {
22510           clib_warning ("parse error '%U'", format_unformat_error, i);
22511           return -99;
22512         }
22513     }
22514
22515   if (ip4_set && ip6_set)
22516     {
22517       errmsg ("Only one server address allowed per message");
22518       return -99;
22519     }
22520   if ((ip4_set + ip6_set) == 0)
22521     {
22522       errmsg ("Server address required");
22523       return -99;
22524     }
22525
22526   /* Construct the API message */
22527   M (DNS_NAME_SERVER_ADD_DEL, mp);
22528
22529   if (ip6_set)
22530     {
22531       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22532       mp->is_ip6 = 1;
22533     }
22534   else
22535     {
22536       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22537       mp->is_ip6 = 0;
22538     }
22539
22540   mp->is_add = is_add;
22541
22542   /* send it... */
22543   S (mp);
22544
22545   /* Wait for a reply, return good/bad news  */
22546   W (ret);
22547   return ret;
22548 }
22549
22550 static void
22551 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22552 {
22553   vat_main_t *vam = &vat_main;
22554
22555   if (mp->is_ip4)
22556     {
22557       print (vam->ofp,
22558              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22559              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22560              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22561              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22562              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22563              clib_net_to_host_u32 (mp->action_index), mp->tag);
22564     }
22565   else
22566     {
22567       print (vam->ofp,
22568              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22569              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22570              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22571              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22572              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22573              clib_net_to_host_u32 (mp->action_index), mp->tag);
22574     }
22575 }
22576
22577 static void
22578 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22579                                              mp)
22580 {
22581   vat_main_t *vam = &vat_main;
22582   vat_json_node_t *node = NULL;
22583   struct in6_addr ip6;
22584   struct in_addr ip4;
22585
22586   if (VAT_JSON_ARRAY != vam->json_tree.type)
22587     {
22588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22589       vat_json_init_array (&vam->json_tree);
22590     }
22591   node = vat_json_array_add (&vam->json_tree);
22592   vat_json_init_object (node);
22593
22594   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22595   vat_json_object_add_uint (node, "appns_index",
22596                             clib_net_to_host_u32 (mp->appns_index));
22597   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22598   vat_json_object_add_uint (node, "scope", mp->scope);
22599   vat_json_object_add_uint (node, "action_index",
22600                             clib_net_to_host_u32 (mp->action_index));
22601   vat_json_object_add_uint (node, "lcl_port",
22602                             clib_net_to_host_u16 (mp->lcl_port));
22603   vat_json_object_add_uint (node, "rmt_port",
22604                             clib_net_to_host_u16 (mp->rmt_port));
22605   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22606   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22607   vat_json_object_add_string_copy (node, "tag", mp->tag);
22608   if (mp->is_ip4)
22609     {
22610       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22611       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22612       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22613       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22614     }
22615   else
22616     {
22617       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22618       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22619       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22620       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22621     }
22622 }
22623
22624 static int
22625 api_session_rule_add_del (vat_main_t * vam)
22626 {
22627   vl_api_session_rule_add_del_t *mp;
22628   unformat_input_t *i = vam->input;
22629   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22630   u32 appns_index = 0, scope = 0;
22631   ip4_address_t lcl_ip4, rmt_ip4;
22632   ip6_address_t lcl_ip6, rmt_ip6;
22633   u8 is_ip4 = 1, conn_set = 0;
22634   u8 is_add = 1, *tag = 0;
22635   int ret;
22636
22637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22638     {
22639       if (unformat (i, "del"))
22640         is_add = 0;
22641       else if (unformat (i, "add"))
22642         ;
22643       else if (unformat (i, "proto tcp"))
22644         proto = 0;
22645       else if (unformat (i, "proto udp"))
22646         proto = 1;
22647       else if (unformat (i, "appns %d", &appns_index))
22648         ;
22649       else if (unformat (i, "scope %d", &scope))
22650         ;
22651       else if (unformat (i, "tag %_%v%_", &tag))
22652         ;
22653       else
22654         if (unformat
22655             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22656              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22657              &rmt_port))
22658         {
22659           is_ip4 = 1;
22660           conn_set = 1;
22661         }
22662       else
22663         if (unformat
22664             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22665              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22666              &rmt_port))
22667         {
22668           is_ip4 = 0;
22669           conn_set = 1;
22670         }
22671       else if (unformat (i, "action %d", &action))
22672         ;
22673       else
22674         break;
22675     }
22676   if (proto == ~0 || !conn_set || action == ~0)
22677     {
22678       errmsg ("transport proto, connection and action must be set");
22679       return -99;
22680     }
22681
22682   if (scope > 3)
22683     {
22684       errmsg ("scope should be 0-3");
22685       return -99;
22686     }
22687
22688   M (SESSION_RULE_ADD_DEL, mp);
22689
22690   mp->is_ip4 = is_ip4;
22691   mp->transport_proto = proto;
22692   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22693   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22694   mp->lcl_plen = lcl_plen;
22695   mp->rmt_plen = rmt_plen;
22696   mp->action_index = clib_host_to_net_u32 (action);
22697   mp->appns_index = clib_host_to_net_u32 (appns_index);
22698   mp->scope = scope;
22699   mp->is_add = is_add;
22700   if (is_ip4)
22701     {
22702       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22703       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22704     }
22705   else
22706     {
22707       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22708       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22709     }
22710   if (tag)
22711     {
22712       clib_memcpy (mp->tag, tag, vec_len (tag));
22713       vec_free (tag);
22714     }
22715
22716   S (mp);
22717   W (ret);
22718   return ret;
22719 }
22720
22721 static int
22722 api_session_rules_dump (vat_main_t * vam)
22723 {
22724   vl_api_session_rules_dump_t *mp;
22725   vl_api_control_ping_t *mp_ping;
22726   int ret;
22727
22728   if (!vam->json_output)
22729     {
22730       print (vam->ofp, "%=20s", "Session Rules");
22731     }
22732
22733   M (SESSION_RULES_DUMP, mp);
22734   /* send it... */
22735   S (mp);
22736
22737   /* Use a control ping for synchronization */
22738   MPING (CONTROL_PING, mp_ping);
22739   S (mp_ping);
22740
22741   /* Wait for a reply... */
22742   W (ret);
22743   return ret;
22744 }
22745
22746 static int
22747 api_ip_container_proxy_add_del (vat_main_t * vam)
22748 {
22749   vl_api_ip_container_proxy_add_del_t *mp;
22750   unformat_input_t *i = vam->input;
22751   u32 plen = ~0, sw_if_index = ~0;
22752   ip4_address_t ip4;
22753   ip6_address_t ip6;
22754   u8 is_ip4 = 1;
22755   u8 is_add = 1;
22756   int ret;
22757
22758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22759     {
22760       if (unformat (i, "del"))
22761         is_add = 0;
22762       else if (unformat (i, "add"))
22763         ;
22764       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22765         {
22766           is_ip4 = 1;
22767           plen = 32;
22768         }
22769       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22770         {
22771           is_ip4 = 0;
22772           plen = 128;
22773         }
22774       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22775         ;
22776       else
22777         break;
22778     }
22779   if (sw_if_index == ~0 || plen == ~0)
22780     {
22781       errmsg ("address and sw_if_index must be set");
22782       return -99;
22783     }
22784
22785   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22786
22787   mp->is_ip4 = is_ip4;
22788   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22789   mp->plen = plen;
22790   mp->is_add = is_add;
22791   if (is_ip4)
22792     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22793   else
22794     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22795
22796   S (mp);
22797   W (ret);
22798   return ret;
22799 }
22800
22801 static int
22802 api_qos_record_enable_disable (vat_main_t * vam)
22803 {
22804   unformat_input_t *i = vam->input;
22805   vl_api_qos_record_enable_disable_t *mp;
22806   u32 sw_if_index, qs = 0xff;
22807   u8 sw_if_index_set = 0;
22808   u8 enable = 1;
22809   int ret;
22810
22811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22812     {
22813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22814         sw_if_index_set = 1;
22815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22816         sw_if_index_set = 1;
22817       else if (unformat (i, "%U", unformat_qos_source, &qs))
22818         ;
22819       else if (unformat (i, "disable"))
22820         enable = 0;
22821       else
22822         {
22823           clib_warning ("parse error '%U'", format_unformat_error, i);
22824           return -99;
22825         }
22826     }
22827
22828   if (sw_if_index_set == 0)
22829     {
22830       errmsg ("missing interface name or sw_if_index");
22831       return -99;
22832     }
22833   if (qs == 0xff)
22834     {
22835       errmsg ("input location must be specified");
22836       return -99;
22837     }
22838
22839   M (QOS_RECORD_ENABLE_DISABLE, mp);
22840
22841   mp->sw_if_index = ntohl (sw_if_index);
22842   mp->input_source = qs;
22843   mp->enable = enable;
22844
22845   S (mp);
22846   W (ret);
22847   return ret;
22848 }
22849
22850
22851 static int
22852 q_or_quit (vat_main_t * vam)
22853 {
22854 #if VPP_API_TEST_BUILTIN == 0
22855   longjmp (vam->jump_buf, 1);
22856 #endif
22857   return 0;                     /* not so much */
22858 }
22859
22860 static int
22861 q (vat_main_t * vam)
22862 {
22863   return q_or_quit (vam);
22864 }
22865
22866 static int
22867 quit (vat_main_t * vam)
22868 {
22869   return q_or_quit (vam);
22870 }
22871
22872 static int
22873 comment (vat_main_t * vam)
22874 {
22875   return 0;
22876 }
22877
22878 static int
22879 statseg (vat_main_t * vam)
22880 {
22881   ssvm_private_t *ssvmp = &vam->stat_segment;
22882   ssvm_shared_header_t *shared_header = ssvmp->sh;
22883   vlib_counter_t **counters;
22884   u64 thread0_index1_packets;
22885   u64 thread0_index1_bytes;
22886   f64 vector_rate, input_rate;
22887   uword *p;
22888
22889   uword *counter_vector_by_name;
22890   if (vam->stat_segment_lockp == 0)
22891     {
22892       errmsg ("Stat segment not mapped...");
22893       return -99;
22894     }
22895
22896   /* look up "/if/rx for sw_if_index 1 as a test */
22897
22898   clib_spinlock_lock (vam->stat_segment_lockp);
22899
22900   counter_vector_by_name = (uword *) shared_header->opaque[1];
22901
22902   p = hash_get_mem (counter_vector_by_name, "/if/rx");
22903   if (p == 0)
22904     {
22905       clib_spinlock_unlock (vam->stat_segment_lockp);
22906       errmsg ("/if/tx not found?");
22907       return -99;
22908     }
22909
22910   /* Fish per-thread vector of combined counters from shared memory */
22911   counters = (vlib_counter_t **) p[0];
22912
22913   if (vec_len (counters[0]) < 2)
22914     {
22915       clib_spinlock_unlock (vam->stat_segment_lockp);
22916       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
22917       return -99;
22918     }
22919
22920   /* Read thread 0 sw_if_index 1 counter */
22921   thread0_index1_packets = counters[0][1].packets;
22922   thread0_index1_bytes = counters[0][1].bytes;
22923
22924   p = hash_get_mem (counter_vector_by_name, "vector_rate");
22925   if (p == 0)
22926     {
22927       clib_spinlock_unlock (vam->stat_segment_lockp);
22928       errmsg ("vector_rate not found?");
22929       return -99;
22930     }
22931
22932   vector_rate = *(f64 *) (p[0]);
22933   p = hash_get_mem (counter_vector_by_name, "input_rate");
22934   if (p == 0)
22935     {
22936       clib_spinlock_unlock (vam->stat_segment_lockp);
22937       errmsg ("input_rate not found?");
22938       return -99;
22939     }
22940   input_rate = *(f64 *) (p[0]);
22941
22942   clib_spinlock_unlock (vam->stat_segment_lockp);
22943
22944   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
22945          vector_rate, input_rate);
22946   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
22947          thread0_index1_packets, thread0_index1_bytes);
22948
22949   return 0;
22950 }
22951
22952 static int
22953 cmd_cmp (void *a1, void *a2)
22954 {
22955   u8 **c1 = a1;
22956   u8 **c2 = a2;
22957
22958   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22959 }
22960
22961 static int
22962 help (vat_main_t * vam)
22963 {
22964   u8 **cmds = 0;
22965   u8 *name = 0;
22966   hash_pair_t *p;
22967   unformat_input_t *i = vam->input;
22968   int j;
22969
22970   if (unformat (i, "%s", &name))
22971     {
22972       uword *hs;
22973
22974       vec_add1 (name, 0);
22975
22976       hs = hash_get_mem (vam->help_by_name, name);
22977       if (hs)
22978         print (vam->ofp, "usage: %s %s", name, hs[0]);
22979       else
22980         print (vam->ofp, "No such msg / command '%s'", name);
22981       vec_free (name);
22982       return 0;
22983     }
22984
22985   print (vam->ofp, "Help is available for the following:");
22986
22987     /* *INDENT-OFF* */
22988     hash_foreach_pair (p, vam->function_by_name,
22989     ({
22990       vec_add1 (cmds, (u8 *)(p->key));
22991     }));
22992     /* *INDENT-ON* */
22993
22994   vec_sort_with_function (cmds, cmd_cmp);
22995
22996   for (j = 0; j < vec_len (cmds); j++)
22997     print (vam->ofp, "%s", cmds[j]);
22998
22999   vec_free (cmds);
23000   return 0;
23001 }
23002
23003 static int
23004 set (vat_main_t * vam)
23005 {
23006   u8 *name = 0, *value = 0;
23007   unformat_input_t *i = vam->input;
23008
23009   if (unformat (i, "%s", &name))
23010     {
23011       /* The input buffer is a vector, not a string. */
23012       value = vec_dup (i->buffer);
23013       vec_delete (value, i->index, 0);
23014       /* Almost certainly has a trailing newline */
23015       if (value[vec_len (value) - 1] == '\n')
23016         value[vec_len (value) - 1] = 0;
23017       /* Make sure it's a proper string, one way or the other */
23018       vec_add1 (value, 0);
23019       (void) clib_macro_set_value (&vam->macro_main,
23020                                    (char *) name, (char *) value);
23021     }
23022   else
23023     errmsg ("usage: set <name> <value>");
23024
23025   vec_free (name);
23026   vec_free (value);
23027   return 0;
23028 }
23029
23030 static int
23031 unset (vat_main_t * vam)
23032 {
23033   u8 *name = 0;
23034
23035   if (unformat (vam->input, "%s", &name))
23036     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23037       errmsg ("unset: %s wasn't set", name);
23038   vec_free (name);
23039   return 0;
23040 }
23041
23042 typedef struct
23043 {
23044   u8 *name;
23045   u8 *value;
23046 } macro_sort_t;
23047
23048
23049 static int
23050 macro_sort_cmp (void *a1, void *a2)
23051 {
23052   macro_sort_t *s1 = a1;
23053   macro_sort_t *s2 = a2;
23054
23055   return strcmp ((char *) (s1->name), (char *) (s2->name));
23056 }
23057
23058 static int
23059 dump_macro_table (vat_main_t * vam)
23060 {
23061   macro_sort_t *sort_me = 0, *sm;
23062   int i;
23063   hash_pair_t *p;
23064
23065     /* *INDENT-OFF* */
23066     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23067     ({
23068       vec_add2 (sort_me, sm, 1);
23069       sm->name = (u8 *)(p->key);
23070       sm->value = (u8 *) (p->value[0]);
23071     }));
23072     /* *INDENT-ON* */
23073
23074   vec_sort_with_function (sort_me, macro_sort_cmp);
23075
23076   if (vec_len (sort_me))
23077     print (vam->ofp, "%-15s%s", "Name", "Value");
23078   else
23079     print (vam->ofp, "The macro table is empty...");
23080
23081   for (i = 0; i < vec_len (sort_me); i++)
23082     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23083   return 0;
23084 }
23085
23086 static int
23087 dump_node_table (vat_main_t * vam)
23088 {
23089   int i, j;
23090   vlib_node_t *node, *next_node;
23091
23092   if (vec_len (vam->graph_nodes) == 0)
23093     {
23094       print (vam->ofp, "Node table empty, issue get_node_graph...");
23095       return 0;
23096     }
23097
23098   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23099     {
23100       node = vam->graph_nodes[0][i];
23101       print (vam->ofp, "[%d] %s", i, node->name);
23102       for (j = 0; j < vec_len (node->next_nodes); j++)
23103         {
23104           if (node->next_nodes[j] != ~0)
23105             {
23106               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23107               print (vam->ofp, "  [%d] %s", j, next_node->name);
23108             }
23109         }
23110     }
23111   return 0;
23112 }
23113
23114 static int
23115 value_sort_cmp (void *a1, void *a2)
23116 {
23117   name_sort_t *n1 = a1;
23118   name_sort_t *n2 = a2;
23119
23120   if (n1->value < n2->value)
23121     return -1;
23122   if (n1->value > n2->value)
23123     return 1;
23124   return 0;
23125 }
23126
23127
23128 static int
23129 dump_msg_api_table (vat_main_t * vam)
23130 {
23131   api_main_t *am = &api_main;
23132   name_sort_t *nses = 0, *ns;
23133   hash_pair_t *hp;
23134   int i;
23135
23136   /* *INDENT-OFF* */
23137   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23138   ({
23139     vec_add2 (nses, ns, 1);
23140     ns->name = (u8 *)(hp->key);
23141     ns->value = (u32) hp->value[0];
23142   }));
23143   /* *INDENT-ON* */
23144
23145   vec_sort_with_function (nses, value_sort_cmp);
23146
23147   for (i = 0; i < vec_len (nses); i++)
23148     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23149   vec_free (nses);
23150   return 0;
23151 }
23152
23153 static int
23154 get_msg_id (vat_main_t * vam)
23155 {
23156   u8 *name_and_crc;
23157   u32 message_index;
23158
23159   if (unformat (vam->input, "%s", &name_and_crc))
23160     {
23161       message_index = vl_msg_api_get_msg_index (name_and_crc);
23162       if (message_index == ~0)
23163         {
23164           print (vam->ofp, " '%s' not found", name_and_crc);
23165           return 0;
23166         }
23167       print (vam->ofp, " '%s' has message index %d",
23168              name_and_crc, message_index);
23169       return 0;
23170     }
23171   errmsg ("name_and_crc required...");
23172   return 0;
23173 }
23174
23175 static int
23176 search_node_table (vat_main_t * vam)
23177 {
23178   unformat_input_t *line_input = vam->input;
23179   u8 *node_to_find;
23180   int j;
23181   vlib_node_t *node, *next_node;
23182   uword *p;
23183
23184   if (vam->graph_node_index_by_name == 0)
23185     {
23186       print (vam->ofp, "Node table empty, issue get_node_graph...");
23187       return 0;
23188     }
23189
23190   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23191     {
23192       if (unformat (line_input, "%s", &node_to_find))
23193         {
23194           vec_add1 (node_to_find, 0);
23195           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23196           if (p == 0)
23197             {
23198               print (vam->ofp, "%s not found...", node_to_find);
23199               goto out;
23200             }
23201           node = vam->graph_nodes[0][p[0]];
23202           print (vam->ofp, "[%d] %s", p[0], node->name);
23203           for (j = 0; j < vec_len (node->next_nodes); j++)
23204             {
23205               if (node->next_nodes[j] != ~0)
23206                 {
23207                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23208                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23209                 }
23210             }
23211         }
23212
23213       else
23214         {
23215           clib_warning ("parse error '%U'", format_unformat_error,
23216                         line_input);
23217           return -99;
23218         }
23219
23220     out:
23221       vec_free (node_to_find);
23222
23223     }
23224
23225   return 0;
23226 }
23227
23228
23229 static int
23230 script (vat_main_t * vam)
23231 {
23232 #if (VPP_API_TEST_BUILTIN==0)
23233   u8 *s = 0;
23234   char *save_current_file;
23235   unformat_input_t save_input;
23236   jmp_buf save_jump_buf;
23237   u32 save_line_number;
23238
23239   FILE *new_fp, *save_ifp;
23240
23241   if (unformat (vam->input, "%s", &s))
23242     {
23243       new_fp = fopen ((char *) s, "r");
23244       if (new_fp == 0)
23245         {
23246           errmsg ("Couldn't open script file %s", s);
23247           vec_free (s);
23248           return -99;
23249         }
23250     }
23251   else
23252     {
23253       errmsg ("Missing script name");
23254       return -99;
23255     }
23256
23257   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23258   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23259   save_ifp = vam->ifp;
23260   save_line_number = vam->input_line_number;
23261   save_current_file = (char *) vam->current_file;
23262
23263   vam->input_line_number = 0;
23264   vam->ifp = new_fp;
23265   vam->current_file = s;
23266   do_one_file (vam);
23267
23268   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23269   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23270   vam->ifp = save_ifp;
23271   vam->input_line_number = save_line_number;
23272   vam->current_file = (u8 *) save_current_file;
23273   vec_free (s);
23274
23275   return 0;
23276 #else
23277   clib_warning ("use the exec command...");
23278   return -99;
23279 #endif
23280 }
23281
23282 static int
23283 echo (vat_main_t * vam)
23284 {
23285   print (vam->ofp, "%v", vam->input->buffer);
23286   return 0;
23287 }
23288
23289 /* List of API message constructors, CLI names map to api_xxx */
23290 #define foreach_vpe_api_msg                                             \
23291 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23292 _(sw_interface_dump,"")                                                 \
23293 _(sw_interface_set_flags,                                               \
23294   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23295 _(sw_interface_add_del_address,                                         \
23296   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23297 _(sw_interface_set_rx_mode,                                             \
23298   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23299 _(sw_interface_set_rx_placement,                                        \
23300   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23301 _(sw_interface_set_table,                                               \
23302   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23303 _(sw_interface_set_mpls_enable,                                         \
23304   "<intfc> | sw_if_index [disable | dis]")                              \
23305 _(sw_interface_set_vpath,                                               \
23306   "<intfc> | sw_if_index <id> enable | disable")                        \
23307 _(sw_interface_set_vxlan_bypass,                                        \
23308   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23309 _(sw_interface_set_geneve_bypass,                                       \
23310   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23311 _(sw_interface_set_l2_xconnect,                                         \
23312   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23313   "enable | disable")                                                   \
23314 _(sw_interface_set_l2_bridge,                                           \
23315   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23316   "[shg <split-horizon-group>] [bvi]\n"                                 \
23317   "enable | disable")                                                   \
23318 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23319 _(bridge_domain_add_del,                                                \
23320   "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") \
23321 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23322 _(l2fib_add_del,                                                        \
23323   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23324 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23325 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23326 _(l2_flags,                                                             \
23327   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23328 _(bridge_flags,                                                         \
23329   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23330 _(tap_connect,                                                          \
23331   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23332 _(tap_modify,                                                           \
23333   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23334 _(tap_delete,                                                           \
23335   "<vpp-if-name> | sw_if_index <id>")                                   \
23336 _(sw_interface_tap_dump, "")                                            \
23337 _(tap_create_v2,                                                        \
23338   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23339 _(tap_delete_v2,                                                        \
23340   "<vpp-if-name> | sw_if_index <id>")                                   \
23341 _(sw_interface_tap_v2_dump, "")                                         \
23342 _(bond_create,                                                          \
23343   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23344   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23345 _(bond_delete,                                                          \
23346   "<vpp-if-name> | sw_if_index <id>")                                   \
23347 _(bond_enslave,                                                         \
23348   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23349 _(bond_detach_slave,                                                    \
23350   "sw_if_index <n>")                                                    \
23351 _(sw_interface_bond_dump, "")                                           \
23352 _(sw_interface_slave_dump,                                              \
23353   "<vpp-if-name> | sw_if_index <id>")                                   \
23354 _(ip_table_add_del,                                                     \
23355   "table-id <n> [ipv6]\n")                                              \
23356 _(ip_add_del_route,                                                     \
23357   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
23358   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23359   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23360   "[multipath] [count <n>]")                                            \
23361 _(ip_mroute_add_del,                                                    \
23362   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23363   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23364 _(mpls_table_add_del,                                                   \
23365   "table-id <n>\n")                                                     \
23366 _(mpls_route_add_del,                                                   \
23367   "<label> <eos> via <addr> [table-id <n>]\n"                           \
23368   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23369   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23370   "[multipath] [count <n>]")                                            \
23371 _(mpls_ip_bind_unbind,                                                  \
23372   "<label> <addr/len>")                                                 \
23373 _(mpls_tunnel_add_del,                                                  \
23374   " via <addr> [table-id <n>]\n"                                        \
23375   "sw_if_index <id>] [l2]  [del]")                                      \
23376 _(bier_table_add_del,                                                   \
23377   "<label> <sub-domain> <set> <bsl> [del]")                             \
23378 _(bier_route_add_del,                                                   \
23379   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23380   "[<intfc> | sw_if_index <id>]"                                        \
23381   "[weight <n>] [del] [multipath]")                                     \
23382 _(proxy_arp_add_del,                                                    \
23383   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23384 _(proxy_arp_intfc_enable_disable,                                       \
23385   "<intfc> | sw_if_index <id> enable | disable")                        \
23386 _(sw_interface_set_unnumbered,                                          \
23387   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23388 _(ip_neighbor_add_del,                                                  \
23389   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23390   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23391 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23392 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23393   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23394   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23395   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23396 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23397 _(reset_fib, "vrf <n> [ipv6]")                                          \
23398 _(dhcp_proxy_config,                                                    \
23399   "svr <v46-address> src <v46-address>\n"                               \
23400    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23401 _(dhcp_proxy_set_vss,                                                   \
23402   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23403 _(dhcp_proxy_dump, "ip6")                                               \
23404 _(dhcp_client_config,                                                   \
23405   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23406 _(set_ip_flow_hash,                                                     \
23407   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23408 _(sw_interface_ip6_enable_disable,                                      \
23409   "<intfc> | sw_if_index <id> enable | disable")                        \
23410 _(sw_interface_ip6_set_link_local_address,                              \
23411   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23412 _(ip6nd_proxy_add_del,                                                  \
23413   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23414 _(ip6nd_proxy_dump, "")                                                 \
23415 _(sw_interface_ip6nd_ra_prefix,                                         \
23416   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23417   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23418   "[nolink] [isno]")                                                    \
23419 _(sw_interface_ip6nd_ra_config,                                         \
23420   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23421   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23422   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23423 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23424 _(l2_patch_add_del,                                                     \
23425   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23426   "enable | disable")                                                   \
23427 _(sr_localsid_add_del,                                                  \
23428   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23429   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23430 _(classify_add_del_table,                                               \
23431   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23432   " [del] [del-chain] mask <mask-value>\n"                              \
23433   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23434   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23435 _(classify_add_del_session,                                             \
23436   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23437   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23438   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23439   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23440 _(classify_set_interface_ip_table,                                      \
23441   "<intfc> | sw_if_index <nn> table <nn>")                              \
23442 _(classify_set_interface_l2_tables,                                     \
23443   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23444   "  [other-table <nn>]")                                               \
23445 _(get_node_index, "node <node-name")                                    \
23446 _(add_node_next, "node <node-name> next <next-node-name>")              \
23447 _(l2tpv3_create_tunnel,                                                 \
23448   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23449   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23450   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23451 _(l2tpv3_set_tunnel_cookies,                                            \
23452   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23453   "[new_remote_cookie <nn>]\n")                                         \
23454 _(l2tpv3_interface_enable_disable,                                      \
23455   "<intfc> | sw_if_index <nn> enable | disable")                        \
23456 _(l2tpv3_set_lookup_key,                                                \
23457   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23458 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23459 _(vxlan_offload_rx,                                                     \
23460   "hw { <interface name> | hw_if_index <nn>} "                          \
23461   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23462 _(vxlan_add_del_tunnel,                                                 \
23463   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23464   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23465   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23466 _(geneve_add_del_tunnel,                                                \
23467   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23468   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23469   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23470 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23471 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23472 _(gre_add_del_tunnel,                                                   \
23473   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23474   "[teb | erspan <session-id>] [del]")                                  \
23475 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23476 _(l2_fib_clear_table, "")                                               \
23477 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23478 _(l2_interface_vlan_tag_rewrite,                                        \
23479   "<intfc> | sw_if_index <nn> \n"                                       \
23480   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23481   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23482 _(create_vhost_user_if,                                                 \
23483         "socket <filename> [server] [renumber <dev_instance>] "         \
23484         "[mac <mac_address>]")                                          \
23485 _(modify_vhost_user_if,                                                 \
23486         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23487         "[server] [renumber <dev_instance>]")                           \
23488 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23489 _(sw_interface_vhost_user_dump, "")                                     \
23490 _(show_version, "")                                                     \
23491 _(vxlan_gpe_add_del_tunnel,                                             \
23492   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23493   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23494   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23495   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23496 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23497 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23498 _(interface_name_renumber,                                              \
23499   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23500 _(input_acl_set_interface,                                              \
23501   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23502   "  [l2-table <nn>] [del]")                                            \
23503 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23504 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23505   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23506 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23507 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23508 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23509 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23510 _(ip_dump, "ipv4 | ipv6")                                               \
23511 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23512 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23513   "  spid_id <n> ")                                                     \
23514 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23515   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23516   "  integ_alg <alg> integ_key <hex>")                                  \
23517 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23518   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23519   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23520   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23521 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23522 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23523   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23524   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23525   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23526   "  [instance <n>]")     \
23527 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23528 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23529   "  <alg> <hex>\n")                                                    \
23530 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23531 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23532 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23533   "(auth_data 0x<data> | auth_data <data>)")                            \
23534 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23535   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23536 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23537   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23538   "(local|remote)")                                                     \
23539 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23540 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23541 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23542 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23543 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23544 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23545 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23546 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23547 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23548 _(delete_loopback,"sw_if_index <nn>")                                   \
23549 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23550 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23551 _(want_interface_events,  "enable|disable")                             \
23552 _(want_stats,"enable|disable")                                          \
23553 _(get_first_msg_id, "client <name>")                                    \
23554 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23555 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23556   "fib-id <nn> [ip4][ip6][default]")                                    \
23557 _(get_node_graph, " ")                                                  \
23558 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23559 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23560 _(ioam_disable, "")                                                     \
23561 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23562                             " sw_if_index <sw_if_index> p <priority> "  \
23563                             "w <weight>] [del]")                        \
23564 _(one_add_del_locator, "locator-set <locator_name> "                    \
23565                         "iface <intf> | sw_if_index <sw_if_index> "     \
23566                         "p <priority> w <weight> [del]")                \
23567 _(one_add_del_local_eid,"vni <vni> eid "                                \
23568                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23569                          "locator-set <locator_name> [del]"             \
23570                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23571 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23572 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23573 _(one_enable_disable, "enable|disable")                                 \
23574 _(one_map_register_enable_disable, "enable|disable")                    \
23575 _(one_map_register_fallback_threshold, "<value>")                       \
23576 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23577 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23578                                "[seid <seid>] "                         \
23579                                "rloc <locator> p <prio> "               \
23580                                "w <weight> [rloc <loc> ... ] "          \
23581                                "action <action> [del-all]")             \
23582 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23583                           "<local-eid>")                                \
23584 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23585 _(one_use_petr, "ip-address> | disable")                                \
23586 _(one_map_request_mode, "src-dst|dst-only")                             \
23587 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23588 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23589 _(one_locator_set_dump, "[local | remote]")                             \
23590 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23591 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23592                        "[local] | [remote]")                            \
23593 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23594 _(one_ndp_bd_get, "")                                                   \
23595 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23596 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23597 _(one_l2_arp_bd_get, "")                                                \
23598 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23599 _(one_stats_enable_disable, "enable|disalbe")                           \
23600 _(show_one_stats_enable_disable, "")                                    \
23601 _(one_eid_table_vni_dump, "")                                           \
23602 _(one_eid_table_map_dump, "l2|l3")                                      \
23603 _(one_map_resolver_dump, "")                                            \
23604 _(one_map_server_dump, "")                                              \
23605 _(one_adjacencies_get, "vni <vni>")                                     \
23606 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23607 _(show_one_rloc_probe_state, "")                                        \
23608 _(show_one_map_register_state, "")                                      \
23609 _(show_one_status, "")                                                  \
23610 _(one_stats_dump, "")                                                   \
23611 _(one_stats_flush, "")                                                  \
23612 _(one_get_map_request_itr_rlocs, "")                                    \
23613 _(one_map_register_set_ttl, "<ttl>")                                    \
23614 _(one_set_transport_protocol, "udp|api")                                \
23615 _(one_get_transport_protocol, "")                                       \
23616 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23617 _(one_show_xtr_mode, "")                                                \
23618 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23619 _(one_show_pitr_mode, "")                                               \
23620 _(one_enable_disable_petr_mode, "enable|disable")                       \
23621 _(one_show_petr_mode, "")                                               \
23622 _(show_one_nsh_mapping, "")                                             \
23623 _(show_one_pitr, "")                                                    \
23624 _(show_one_use_petr, "")                                                \
23625 _(show_one_map_request_mode, "")                                        \
23626 _(show_one_map_register_ttl, "")                                        \
23627 _(show_one_map_register_fallback_threshold, "")                         \
23628 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23629                             " sw_if_index <sw_if_index> p <priority> "  \
23630                             "w <weight>] [del]")                        \
23631 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23632                         "iface <intf> | sw_if_index <sw_if_index> "     \
23633                         "p <priority> w <weight> [del]")                \
23634 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23635                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23636                          "locator-set <locator_name> [del]"             \
23637                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23638 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23639 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23640 _(lisp_enable_disable, "enable|disable")                                \
23641 _(lisp_map_register_enable_disable, "enable|disable")                   \
23642 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23643 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23644                                "[seid <seid>] "                         \
23645                                "rloc <locator> p <prio> "               \
23646                                "w <weight> [rloc <loc> ... ] "          \
23647                                "action <action> [del-all]")             \
23648 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23649                           "<local-eid>")                                \
23650 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23651 _(lisp_use_petr, "<ip-address> | disable")                              \
23652 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23653 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23654 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23655 _(lisp_locator_set_dump, "[local | remote]")                            \
23656 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23657 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23658                        "[local] | [remote]")                            \
23659 _(lisp_eid_table_vni_dump, "")                                          \
23660 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23661 _(lisp_map_resolver_dump, "")                                           \
23662 _(lisp_map_server_dump, "")                                             \
23663 _(lisp_adjacencies_get, "vni <vni>")                                    \
23664 _(gpe_fwd_entry_vnis_get, "")                                           \
23665 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23666 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23667                                 "[table <table-id>]")                   \
23668 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23669 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23670 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23671 _(gpe_get_encap_mode, "")                                               \
23672 _(lisp_gpe_add_del_iface, "up|down")                                    \
23673 _(lisp_gpe_enable_disable, "enable|disable")                            \
23674 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23675   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23676 _(show_lisp_rloc_probe_state, "")                                       \
23677 _(show_lisp_map_register_state, "")                                     \
23678 _(show_lisp_status, "")                                                 \
23679 _(lisp_get_map_request_itr_rlocs, "")                                   \
23680 _(show_lisp_pitr, "")                                                   \
23681 _(show_lisp_use_petr, "")                                               \
23682 _(show_lisp_map_request_mode, "")                                       \
23683 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23684 _(af_packet_delete, "name <host interface name>")                       \
23685 _(af_packet_dump, "")                                                   \
23686 _(policer_add_del, "name <policer name> <params> [del]")                \
23687 _(policer_dump, "[name <policer name>]")                                \
23688 _(policer_classify_set_interface,                                       \
23689   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23690   "  [l2-table <nn>] [del]")                                            \
23691 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23692 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23693     "[master|slave]")                                                   \
23694 _(netmap_delete, "name <interface name>")                               \
23695 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23696 _(mpls_fib_dump, "")                                                    \
23697 _(classify_table_ids, "")                                               \
23698 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23699 _(classify_table_info, "table_id <nn>")                                 \
23700 _(classify_session_dump, "table_id <nn>")                               \
23701 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23702     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23703     "[template_interval <nn>] [udp_checksum]")                          \
23704 _(ipfix_exporter_dump, "")                                              \
23705 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23706 _(ipfix_classify_stream_dump, "")                                       \
23707 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23708 _(ipfix_classify_table_dump, "")                                        \
23709 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23710 _(sw_interface_span_dump, "[l2]")                                           \
23711 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23712 _(pg_create_interface, "if_id <nn>")                                    \
23713 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23714 _(pg_enable_disable, "[stream <id>] disable")                           \
23715 _(ip_source_and_port_range_check_add_del,                               \
23716   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23717 _(ip_source_and_port_range_check_interface_add_del,                     \
23718   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23719   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23720 _(ipsec_gre_add_del_tunnel,                                             \
23721   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23722 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23723 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23724 _(l2_interface_pbb_tag_rewrite,                                         \
23725   "<intfc> | sw_if_index <nn> \n"                                       \
23726   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23727   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23728 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23729 _(flow_classify_set_interface,                                          \
23730   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23731 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23732 _(ip_fib_dump, "")                                                      \
23733 _(ip_mfib_dump, "")                                                     \
23734 _(ip6_fib_dump, "")                                                     \
23735 _(ip6_mfib_dump, "")                                                    \
23736 _(feature_enable_disable, "arc_name <arc_name> "                        \
23737   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23738 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23739 "[disable]")                                                            \
23740 _(l2_xconnect_dump, "")                                                 \
23741 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23742 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23743 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23744 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23745 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23746 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23747 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23748   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23749 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23750 _(sock_init_shm, "size <nnn>")                                          \
23751 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23752 _(dns_enable_disable, "[enable][disable]")                              \
23753 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23754 _(dns_resolve_name, "<hostname>")                                       \
23755 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23756 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23757 _(dns_resolve_name, "<hostname>")                                       \
23758 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23759   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23760 _(session_rules_dump, "")                                               \
23761 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23762 _(output_acl_set_interface,                                             \
23763   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23764   "  [l2-table <nn>] [del]")                                            \
23765 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23766
23767 /* List of command functions, CLI names map directly to functions */
23768 #define foreach_cli_function                                    \
23769 _(comment, "usage: comment <ignore-rest-of-line>")              \
23770 _(dump_interface_table, "usage: dump_interface_table")          \
23771 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23772 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23773 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23774 _(dump_stats_table, "usage: dump_stats_table")                  \
23775 _(dump_macro_table, "usage: dump_macro_table ")                 \
23776 _(dump_node_table, "usage: dump_node_table")                    \
23777 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23778 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23779 _(echo, "usage: echo <message>")                                \
23780 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23781 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23782 _(help, "usage: help")                                          \
23783 _(q, "usage: quit")                                             \
23784 _(quit, "usage: quit")                                          \
23785 _(search_node_table, "usage: search_node_table <name>...")      \
23786 _(set, "usage: set <variable-name> <value>")                    \
23787 _(script, "usage: script <file-name>")                          \
23788 _(statseg, "usage: statseg");                                   \
23789 _(unset, "usage: unset <variable-name>")
23790
23791 #define _(N,n)                                  \
23792     static void vl_api_##n##_t_handler_uni      \
23793     (vl_api_##n##_t * mp)                       \
23794     {                                           \
23795         vat_main_t * vam = &vat_main;           \
23796         if (vam->json_output) {                 \
23797             vl_api_##n##_t_handler_json(mp);    \
23798         } else {                                \
23799             vl_api_##n##_t_handler(mp);         \
23800         }                                       \
23801     }
23802 foreach_vpe_api_reply_msg;
23803 #if VPP_API_TEST_BUILTIN == 0
23804 foreach_standalone_reply_msg;
23805 #endif
23806 #undef _
23807
23808 void
23809 vat_api_hookup (vat_main_t * vam)
23810 {
23811 #define _(N,n)                                                  \
23812     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23813                            vl_api_##n##_t_handler_uni,          \
23814                            vl_noop_handler,                     \
23815                            vl_api_##n##_t_endian,               \
23816                            vl_api_##n##_t_print,                \
23817                            sizeof(vl_api_##n##_t), 1);
23818   foreach_vpe_api_reply_msg;
23819 #if VPP_API_TEST_BUILTIN == 0
23820   foreach_standalone_reply_msg;
23821 #endif
23822 #undef _
23823
23824 #if (VPP_API_TEST_BUILTIN==0)
23825   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23826
23827   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23828
23829   vam->function_by_name = hash_create_string (0, sizeof (uword));
23830
23831   vam->help_by_name = hash_create_string (0, sizeof (uword));
23832 #endif
23833
23834   /* API messages we can send */
23835 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23836   foreach_vpe_api_msg;
23837 #undef _
23838
23839   /* Help strings */
23840 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23841   foreach_vpe_api_msg;
23842 #undef _
23843
23844   /* CLI functions */
23845 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23846   foreach_cli_function;
23847 #undef _
23848
23849   /* Help strings */
23850 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23851   foreach_cli_function;
23852 #undef _
23853 }
23854
23855 #if VPP_API_TEST_BUILTIN
23856 static clib_error_t *
23857 vat_api_hookup_shim (vlib_main_t * vm)
23858 {
23859   vat_api_hookup (&vat_main);
23860   return 0;
23861 }
23862
23863 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
23864 #endif
23865
23866 /*
23867  * fd.io coding-style-patch-verification: ON
23868  *
23869  * Local Variables:
23870  * eval: (c-set-style "gnu")
23871  * End:
23872  */