thread: Add show threads api
[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 vl_api_show_threads_reply_t_handler
1323   (vl_api_show_threads_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327   int i, count = 0;
1328
1329   if (retval >= 0)
1330     count = ntohl (mp->count);
1331
1332   for (i = 0; i < count; i++)
1333     print (vam->ofp,
1334            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1335            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1336            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1337            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1338            ntohl (mp->thread_data[i].cpu_socket));
1339
1340   vam->retval = retval;
1341   vam->result_ready = 1;
1342 }
1343
1344 static void vl_api_show_threads_reply_t_handler_json
1345   (vl_api_show_threads_reply_t * mp)
1346 {
1347   vat_main_t *vam = &vat_main;
1348   vat_json_node_t node;
1349   vl_api_thread_data_t *td;
1350   int i, count = ntohl (mp->count);
1351
1352   vat_json_init_object (&node);
1353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1354   vat_json_object_add_uint (&node, "count", count);
1355
1356   for (i = 0; i < count; i++)
1357     {
1358       td = &mp->thread_data[i];
1359       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1360       vat_json_object_add_string_copy (&node, "name", td->name);
1361       vat_json_object_add_string_copy (&node, "type", td->type);
1362       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1363       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1364       vat_json_object_add_int (&node, "core", ntohl (td->id));
1365       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1366     }
1367
1368   vat_json_print (vam->ofp, &node);
1369   vat_json_free (&node);
1370
1371   vam->retval = ntohl (mp->retval);
1372   vam->result_ready = 1;
1373 }
1374
1375 static int
1376 api_show_threads (vat_main_t * vam)
1377 {
1378   vl_api_show_threads_t *mp;
1379   int ret;
1380
1381   print (vam->ofp,
1382          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1383          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1384
1385   M (SHOW_THREADS, mp);
1386
1387   S (mp);
1388   W (ret);
1389   return ret;
1390 }
1391
1392 static void
1393 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1394 {
1395   u32 sw_if_index = ntohl (mp->sw_if_index);
1396   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1397           mp->mac_ip ? "mac/ip binding" : "address resolution",
1398           ntohl (mp->pid), format_ip4_address, &mp->address,
1399           format_ethernet_address, mp->new_mac, sw_if_index);
1400 }
1401
1402 static void
1403 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1404 {
1405   /* JSON output not supported */
1406 }
1407
1408 static void
1409 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1410 {
1411   u32 sw_if_index = ntohl (mp->sw_if_index);
1412   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1413           mp->mac_ip ? "mac/ip binding" : "address resolution",
1414           ntohl (mp->pid), format_ip6_address, mp->address,
1415           format_ethernet_address, mp->new_mac, sw_if_index);
1416 }
1417
1418 static void
1419 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1420 {
1421   /* JSON output not supported */
1422 }
1423
1424 static void
1425 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1426 {
1427   u32 n_macs = ntohl (mp->n_macs);
1428   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1429           ntohl (mp->pid), mp->client_index, n_macs);
1430   int i;
1431   for (i = 0; i < n_macs; i++)
1432     {
1433       vl_api_mac_entry_t *mac = &mp->mac[i];
1434       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1435               i + 1, ntohl (mac->sw_if_index),
1436               format_ethernet_address, mac->mac_addr, mac->action);
1437       if (i == 1000)
1438         break;
1439     }
1440 }
1441
1442 static void
1443 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1444 {
1445   /* JSON output not supported */
1446 }
1447
1448 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1449 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1450
1451 /*
1452  * Special-case: build the bridge domain table, maintain
1453  * the next bd id vbl.
1454  */
1455 static void vl_api_bridge_domain_details_t_handler
1456   (vl_api_bridge_domain_details_t * mp)
1457 {
1458   vat_main_t *vam = &vat_main;
1459   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1460   int i;
1461
1462   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1463          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1464
1465   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1466          ntohl (mp->bd_id), mp->learn, mp->forward,
1467          mp->flood, ntohl (mp->bvi_sw_if_index),
1468          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1469
1470   if (n_sw_ifs)
1471     {
1472       vl_api_bridge_domain_sw_if_t *sw_ifs;
1473       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1474              "Interface Name");
1475
1476       sw_ifs = mp->sw_if_details;
1477       for (i = 0; i < n_sw_ifs; i++)
1478         {
1479           u8 *sw_if_name = 0;
1480           u32 sw_if_index;
1481           hash_pair_t *p;
1482
1483           sw_if_index = ntohl (sw_ifs->sw_if_index);
1484
1485           /* *INDENT-OFF* */
1486           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1487                              ({
1488                                if ((u32) p->value[0] == sw_if_index)
1489                                  {
1490                                    sw_if_name = (u8 *)(p->key);
1491                                    break;
1492                                  }
1493                              }));
1494           /* *INDENT-ON* */
1495           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1496                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1497                  "sw_if_index not found!");
1498
1499           sw_ifs++;
1500         }
1501     }
1502 }
1503
1504 static void vl_api_bridge_domain_details_t_handler_json
1505   (vl_api_bridge_domain_details_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   vat_json_node_t *node, *array = NULL;
1509   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1510
1511   if (VAT_JSON_ARRAY != vam->json_tree.type)
1512     {
1513       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1514       vat_json_init_array (&vam->json_tree);
1515     }
1516   node = vat_json_array_add (&vam->json_tree);
1517
1518   vat_json_init_object (node);
1519   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1520   vat_json_object_add_uint (node, "flood", mp->flood);
1521   vat_json_object_add_uint (node, "forward", mp->forward);
1522   vat_json_object_add_uint (node, "learn", mp->learn);
1523   vat_json_object_add_uint (node, "bvi_sw_if_index",
1524                             ntohl (mp->bvi_sw_if_index));
1525   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1526   array = vat_json_object_add (node, "sw_if");
1527   vat_json_init_array (array);
1528
1529
1530
1531   if (n_sw_ifs)
1532     {
1533       vl_api_bridge_domain_sw_if_t *sw_ifs;
1534       int i;
1535
1536       sw_ifs = mp->sw_if_details;
1537       for (i = 0; i < n_sw_ifs; i++)
1538         {
1539           node = vat_json_array_add (array);
1540           vat_json_init_object (node);
1541           vat_json_object_add_uint (node, "sw_if_index",
1542                                     ntohl (sw_ifs->sw_if_index));
1543           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1544           sw_ifs++;
1545         }
1546     }
1547 }
1548
1549 static void vl_api_control_ping_reply_t_handler
1550   (vl_api_control_ping_reply_t * mp)
1551 {
1552   vat_main_t *vam = &vat_main;
1553   i32 retval = ntohl (mp->retval);
1554   if (vam->async_mode)
1555     {
1556       vam->async_errors += (retval < 0);
1557     }
1558   else
1559     {
1560       vam->retval = retval;
1561       vam->result_ready = 1;
1562     }
1563   if (vam->socket_client_main)
1564     vam->socket_client_main->control_pings_outstanding--;
1565 }
1566
1567 static void vl_api_control_ping_reply_t_handler_json
1568   (vl_api_control_ping_reply_t * mp)
1569 {
1570   vat_main_t *vam = &vat_main;
1571   i32 retval = ntohl (mp->retval);
1572
1573   if (VAT_JSON_NONE != vam->json_tree.type)
1574     {
1575       vat_json_print (vam->ofp, &vam->json_tree);
1576       vat_json_free (&vam->json_tree);
1577       vam->json_tree.type = VAT_JSON_NONE;
1578     }
1579   else
1580     {
1581       /* just print [] */
1582       vat_json_init_array (&vam->json_tree);
1583       vat_json_print (vam->ofp, &vam->json_tree);
1584       vam->json_tree.type = VAT_JSON_NONE;
1585     }
1586
1587   vam->retval = retval;
1588   vam->result_ready = 1;
1589 }
1590
1591 static void
1592   vl_api_bridge_domain_set_mac_age_reply_t_handler
1593   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->result_ready = 1;
1605     }
1606 }
1607
1608 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1609   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1610 {
1611   vat_main_t *vam = &vat_main;
1612   vat_json_node_t node;
1613
1614   vat_json_init_object (&node);
1615   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void
1625 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->result_ready = 1;
1637     }
1638 }
1639
1640 static void vl_api_l2_flags_reply_t_handler_json
1641   (vl_api_l2_flags_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   vat_json_node_t node;
1645
1646   vat_json_init_object (&node);
1647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1649                             ntohl (mp->resulting_feature_bitmap));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void vl_api_bridge_flags_reply_t_handler
1659   (vl_api_bridge_flags_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_bridge_flags_reply_t_handler_json
1675   (vl_api_bridge_flags_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, "resulting_feature_bitmap",
1683                             ntohl (mp->resulting_feature_bitmap));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_tap_connect_reply_t_handler
1693   (vl_api_tap_connect_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   i32 retval = ntohl (mp->retval);
1697   if (vam->async_mode)
1698     {
1699       vam->async_errors += (retval < 0);
1700     }
1701   else
1702     {
1703       vam->retval = retval;
1704       vam->sw_if_index = ntohl (mp->sw_if_index);
1705       vam->result_ready = 1;
1706     }
1707
1708 }
1709
1710 static void vl_api_tap_connect_reply_t_handler_json
1711   (vl_api_tap_connect_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725
1726 }
1727
1728 static void
1729 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732   i32 retval = ntohl (mp->retval);
1733   if (vam->async_mode)
1734     {
1735       vam->async_errors += (retval < 0);
1736     }
1737   else
1738     {
1739       vam->retval = retval;
1740       vam->sw_if_index = ntohl (mp->sw_if_index);
1741       vam->result_ready = 1;
1742     }
1743 }
1744
1745 static void vl_api_tap_modify_reply_t_handler_json
1746   (vl_api_tap_modify_reply_t * mp)
1747 {
1748   vat_main_t *vam = &vat_main;
1749   vat_json_node_t node;
1750
1751   vat_json_init_object (&node);
1752   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1753   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1754
1755   vat_json_print (vam->ofp, &node);
1756   vat_json_free (&node);
1757
1758   vam->retval = ntohl (mp->retval);
1759   vam->result_ready = 1;
1760 }
1761
1762 static void
1763 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1764 {
1765   vat_main_t *vam = &vat_main;
1766   i32 retval = ntohl (mp->retval);
1767   if (vam->async_mode)
1768     {
1769       vam->async_errors += (retval < 0);
1770     }
1771   else
1772     {
1773       vam->retval = retval;
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_tap_delete_reply_t_handler_json
1779   (vl_api_tap_delete_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786
1787   vat_json_print (vam->ofp, &node);
1788   vat_json_free (&node);
1789
1790   vam->retval = ntohl (mp->retval);
1791   vam->result_ready = 1;
1792 }
1793
1794 static void
1795 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1796 {
1797   vat_main_t *vam = &vat_main;
1798   i32 retval = ntohl (mp->retval);
1799   if (vam->async_mode)
1800     {
1801       vam->async_errors += (retval < 0);
1802     }
1803   else
1804     {
1805       vam->retval = retval;
1806       vam->sw_if_index = ntohl (mp->sw_if_index);
1807       vam->result_ready = 1;
1808     }
1809
1810 }
1811
1812 static void vl_api_tap_create_v2_reply_t_handler_json
1813   (vl_api_tap_create_v2_reply_t * mp)
1814 {
1815   vat_main_t *vam = &vat_main;
1816   vat_json_node_t node;
1817
1818   vat_json_init_object (&node);
1819   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1820   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1821
1822   vat_json_print (vam->ofp, &node);
1823   vat_json_free (&node);
1824
1825   vam->retval = ntohl (mp->retval);
1826   vam->result_ready = 1;
1827
1828 }
1829
1830 static void
1831 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1832 {
1833   vat_main_t *vam = &vat_main;
1834   i32 retval = ntohl (mp->retval);
1835   if (vam->async_mode)
1836     {
1837       vam->async_errors += (retval < 0);
1838     }
1839   else
1840     {
1841       vam->retval = retval;
1842       vam->result_ready = 1;
1843     }
1844 }
1845
1846 static void vl_api_tap_delete_v2_reply_t_handler_json
1847   (vl_api_tap_delete_v2_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   vat_json_node_t node;
1851
1852   vat_json_init_object (&node);
1853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1854
1855   vat_json_print (vam->ofp, &node);
1856   vat_json_free (&node);
1857
1858   vam->retval = ntohl (mp->retval);
1859   vam->result_ready = 1;
1860 }
1861
1862 static void
1863 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   i32 retval = ntohl (mp->retval);
1867
1868   if (vam->async_mode)
1869     {
1870       vam->async_errors += (retval < 0);
1871     }
1872   else
1873     {
1874       vam->retval = retval;
1875       vam->sw_if_index = ntohl (mp->sw_if_index);
1876       vam->result_ready = 1;
1877     }
1878 }
1879
1880 static void vl_api_bond_create_reply_t_handler_json
1881   (vl_api_bond_create_reply_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   vat_json_node_t node;
1885
1886   vat_json_init_object (&node);
1887   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1888   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1889
1890   vat_json_print (vam->ofp, &node);
1891   vat_json_free (&node);
1892
1893   vam->retval = ntohl (mp->retval);
1894   vam->result_ready = 1;
1895 }
1896
1897 static void
1898 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   i32 retval = ntohl (mp->retval);
1902
1903   if (vam->async_mode)
1904     {
1905       vam->async_errors += (retval < 0);
1906     }
1907   else
1908     {
1909       vam->retval = retval;
1910       vam->result_ready = 1;
1911     }
1912 }
1913
1914 static void vl_api_bond_delete_reply_t_handler_json
1915   (vl_api_bond_delete_reply_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918   vat_json_node_t node;
1919
1920   vat_json_init_object (&node);
1921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1922
1923   vat_json_print (vam->ofp, &node);
1924   vat_json_free (&node);
1925
1926   vam->retval = ntohl (mp->retval);
1927   vam->result_ready = 1;
1928 }
1929
1930 static void
1931 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   i32 retval = ntohl (mp->retval);
1935
1936   if (vam->async_mode)
1937     {
1938       vam->async_errors += (retval < 0);
1939     }
1940   else
1941     {
1942       vam->retval = retval;
1943       vam->result_ready = 1;
1944     }
1945 }
1946
1947 static void vl_api_bond_enslave_reply_t_handler_json
1948   (vl_api_bond_enslave_reply_t * mp)
1949 {
1950   vat_main_t *vam = &vat_main;
1951   vat_json_node_t node;
1952
1953   vat_json_init_object (&node);
1954   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1955
1956   vat_json_print (vam->ofp, &node);
1957   vat_json_free (&node);
1958
1959   vam->retval = ntohl (mp->retval);
1960   vam->result_ready = 1;
1961 }
1962
1963 static void
1964 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1965                                           mp)
1966 {
1967   vat_main_t *vam = &vat_main;
1968   i32 retval = ntohl (mp->retval);
1969
1970   if (vam->async_mode)
1971     {
1972       vam->async_errors += (retval < 0);
1973     }
1974   else
1975     {
1976       vam->retval = retval;
1977       vam->result_ready = 1;
1978     }
1979 }
1980
1981 static void vl_api_bond_detach_slave_reply_t_handler_json
1982   (vl_api_bond_detach_slave_reply_t * mp)
1983 {
1984   vat_main_t *vam = &vat_main;
1985   vat_json_node_t node;
1986
1987   vat_json_init_object (&node);
1988   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1989
1990   vat_json_print (vam->ofp, &node);
1991   vat_json_free (&node);
1992
1993   vam->retval = ntohl (mp->retval);
1994   vam->result_ready = 1;
1995 }
1996
1997 static void vl_api_sw_interface_bond_details_t_handler
1998   (vl_api_sw_interface_bond_details_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001
2002   print (vam->ofp,
2003          "%-16s %-12d %-12U %-13U %-14u %-14u",
2004          mp->interface_name, ntohl (mp->sw_if_index),
2005          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2006          ntohl (mp->active_slaves), ntohl (mp->slaves));
2007 }
2008
2009 static void vl_api_sw_interface_bond_details_t_handler_json
2010   (vl_api_sw_interface_bond_details_t * mp)
2011 {
2012   vat_main_t *vam = &vat_main;
2013   vat_json_node_t *node = NULL;
2014
2015   if (VAT_JSON_ARRAY != vam->json_tree.type)
2016     {
2017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2018       vat_json_init_array (&vam->json_tree);
2019     }
2020   node = vat_json_array_add (&vam->json_tree);
2021
2022   vat_json_init_object (node);
2023   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2024   vat_json_object_add_string_copy (node, "interface_name",
2025                                    mp->interface_name);
2026   vat_json_object_add_uint (node, "mode", mp->mode);
2027   vat_json_object_add_uint (node, "load_balance", mp->lb);
2028   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2029   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2030 }
2031
2032 static int
2033 api_sw_interface_bond_dump (vat_main_t * vam)
2034 {
2035   vl_api_sw_interface_bond_dump_t *mp;
2036   vl_api_control_ping_t *mp_ping;
2037   int ret;
2038
2039   print (vam->ofp,
2040          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2041          "interface name", "sw_if_index", "mode", "load balance",
2042          "active slaves", "slaves");
2043
2044   /* Get list of bond interfaces */
2045   M (SW_INTERFACE_BOND_DUMP, mp);
2046   S (mp);
2047
2048   /* Use a control ping for synchronization */
2049   MPING (CONTROL_PING, mp_ping);
2050   S (mp_ping);
2051
2052   W (ret);
2053   return ret;
2054 }
2055
2056 static void vl_api_sw_interface_slave_details_t_handler
2057   (vl_api_sw_interface_slave_details_t * mp)
2058 {
2059   vat_main_t *vam = &vat_main;
2060
2061   print (vam->ofp,
2062          "%-25s %-12d %-12d %d", mp->interface_name,
2063          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2064 }
2065
2066 static void vl_api_sw_interface_slave_details_t_handler_json
2067   (vl_api_sw_interface_slave_details_t * mp)
2068 {
2069   vat_main_t *vam = &vat_main;
2070   vat_json_node_t *node = NULL;
2071
2072   if (VAT_JSON_ARRAY != vam->json_tree.type)
2073     {
2074       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2075       vat_json_init_array (&vam->json_tree);
2076     }
2077   node = vat_json_array_add (&vam->json_tree);
2078
2079   vat_json_init_object (node);
2080   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2081   vat_json_object_add_string_copy (node, "interface_name",
2082                                    mp->interface_name);
2083   vat_json_object_add_uint (node, "passive", mp->is_passive);
2084   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2085 }
2086
2087 static int
2088 api_sw_interface_slave_dump (vat_main_t * vam)
2089 {
2090   unformat_input_t *i = vam->input;
2091   vl_api_sw_interface_slave_dump_t *mp;
2092   vl_api_control_ping_t *mp_ping;
2093   u32 sw_if_index = ~0;
2094   u8 sw_if_index_set = 0;
2095   int ret;
2096
2097   /* Parse args required to build the message */
2098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2099     {
2100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2101         sw_if_index_set = 1;
2102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2103         sw_if_index_set = 1;
2104       else
2105         break;
2106     }
2107
2108   if (sw_if_index_set == 0)
2109     {
2110       errmsg ("missing vpp interface name. ");
2111       return -99;
2112     }
2113
2114   print (vam->ofp,
2115          "\n%-25s %-12s %-12s %s",
2116          "slave interface name", "sw_if_index", "passive", "long_timeout");
2117
2118   /* Get list of bond interfaces */
2119   M (SW_INTERFACE_SLAVE_DUMP, mp);
2120   mp->sw_if_index = ntohl (sw_if_index);
2121   S (mp);
2122
2123   /* Use a control ping for synchronization */
2124   MPING (CONTROL_PING, mp_ping);
2125   S (mp_ping);
2126
2127   W (ret);
2128   return ret;
2129 }
2130
2131 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2132   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2133 {
2134   vat_main_t *vam = &vat_main;
2135   i32 retval = ntohl (mp->retval);
2136   if (vam->async_mode)
2137     {
2138       vam->async_errors += (retval < 0);
2139     }
2140   else
2141     {
2142       vam->retval = retval;
2143       vam->result_ready = 1;
2144     }
2145 }
2146
2147 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2148   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2149 {
2150   vat_main_t *vam = &vat_main;
2151   vat_json_node_t node;
2152
2153   vat_json_init_object (&node);
2154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2155   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2156                             ntohl (mp->sw_if_index));
2157
2158   vat_json_print (vam->ofp, &node);
2159   vat_json_free (&node);
2160
2161   vam->retval = ntohl (mp->retval);
2162   vam->result_ready = 1;
2163 }
2164
2165 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2166   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   i32 retval = ntohl (mp->retval);
2170   if (vam->async_mode)
2171     {
2172       vam->async_errors += (retval < 0);
2173     }
2174   else
2175     {
2176       vam->retval = retval;
2177       vam->sw_if_index = ntohl (mp->sw_if_index);
2178       vam->result_ready = 1;
2179     }
2180 }
2181
2182 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2183   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   vat_json_node_t node;
2187
2188   vat_json_init_object (&node);
2189   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2190   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2191
2192   vat_json_print (vam->ofp, &node);
2193   vat_json_free (&node);
2194
2195   vam->retval = ntohl (mp->retval);
2196   vam->result_ready = 1;
2197 }
2198
2199 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2200   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   i32 retval = ntohl (mp->retval);
2204   if (vam->async_mode)
2205     {
2206       vam->async_errors += (retval < 0);
2207     }
2208   else
2209     {
2210       vam->retval = retval;
2211       vam->result_ready = 1;
2212     }
2213 }
2214
2215 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2216   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   vat_json_node_t node;
2220
2221   vat_json_init_object (&node);
2222   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2223   vat_json_object_add_uint (&node, "fwd_entry_index",
2224                             clib_net_to_host_u32 (mp->fwd_entry_index));
2225
2226   vat_json_print (vam->ofp, &node);
2227   vat_json_free (&node);
2228
2229   vam->retval = ntohl (mp->retval);
2230   vam->result_ready = 1;
2231 }
2232
2233 u8 *
2234 format_lisp_transport_protocol (u8 * s, va_list * args)
2235 {
2236   u32 proto = va_arg (*args, u32);
2237
2238   switch (proto)
2239     {
2240     case 1:
2241       return format (s, "udp");
2242     case 2:
2243       return format (s, "api");
2244     default:
2245       return 0;
2246     }
2247   return 0;
2248 }
2249
2250 static void vl_api_one_get_transport_protocol_reply_t_handler
2251   (vl_api_one_get_transport_protocol_reply_t * mp)
2252 {
2253   vat_main_t *vam = &vat_main;
2254   i32 retval = ntohl (mp->retval);
2255   if (vam->async_mode)
2256     {
2257       vam->async_errors += (retval < 0);
2258     }
2259   else
2260     {
2261       u32 proto = mp->protocol;
2262       print (vam->ofp, "Transport protocol: %U",
2263              format_lisp_transport_protocol, proto);
2264       vam->retval = retval;
2265       vam->result_ready = 1;
2266     }
2267 }
2268
2269 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2270   (vl_api_one_get_transport_protocol_reply_t * mp)
2271 {
2272   vat_main_t *vam = &vat_main;
2273   vat_json_node_t node;
2274   u8 *s;
2275
2276   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2277   vec_add1 (s, 0);
2278
2279   vat_json_init_object (&node);
2280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2281   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2282
2283   vec_free (s);
2284   vat_json_print (vam->ofp, &node);
2285   vat_json_free (&node);
2286
2287   vam->retval = ntohl (mp->retval);
2288   vam->result_ready = 1;
2289 }
2290
2291 static void vl_api_one_add_del_locator_set_reply_t_handler
2292   (vl_api_one_add_del_locator_set_reply_t * mp)
2293 {
2294   vat_main_t *vam = &vat_main;
2295   i32 retval = ntohl (mp->retval);
2296   if (vam->async_mode)
2297     {
2298       vam->async_errors += (retval < 0);
2299     }
2300   else
2301     {
2302       vam->retval = retval;
2303       vam->result_ready = 1;
2304     }
2305 }
2306
2307 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2308   (vl_api_one_add_del_locator_set_reply_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   vat_json_node_t node;
2312
2313   vat_json_init_object (&node);
2314   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2315   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2316
2317   vat_json_print (vam->ofp, &node);
2318   vat_json_free (&node);
2319
2320   vam->retval = ntohl (mp->retval);
2321   vam->result_ready = 1;
2322 }
2323
2324 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2325   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   i32 retval = ntohl (mp->retval);
2329   if (vam->async_mode)
2330     {
2331       vam->async_errors += (retval < 0);
2332     }
2333   else
2334     {
2335       vam->retval = retval;
2336       vam->sw_if_index = ntohl (mp->sw_if_index);
2337       vam->result_ready = 1;
2338     }
2339   vam->regenerate_interface_table = 1;
2340 }
2341
2342 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2343   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2344 {
2345   vat_main_t *vam = &vat_main;
2346   vat_json_node_t node;
2347
2348   vat_json_init_object (&node);
2349   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2350   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2351
2352   vat_json_print (vam->ofp, &node);
2353   vat_json_free (&node);
2354
2355   vam->retval = ntohl (mp->retval);
2356   vam->result_ready = 1;
2357 }
2358
2359 static void vl_api_vxlan_offload_rx_reply_t_handler
2360   (vl_api_vxlan_offload_rx_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   i32 retval = ntohl (mp->retval);
2364   if (vam->async_mode)
2365     {
2366       vam->async_errors += (retval < 0);
2367     }
2368   else
2369     {
2370       vam->retval = retval;
2371       vam->result_ready = 1;
2372     }
2373 }
2374
2375 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2376   (vl_api_vxlan_offload_rx_reply_t * mp)
2377 {
2378   vat_main_t *vam = &vat_main;
2379   vat_json_node_t node;
2380
2381   vat_json_init_object (&node);
2382   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2383
2384   vat_json_print (vam->ofp, &node);
2385   vat_json_free (&node);
2386
2387   vam->retval = ntohl (mp->retval);
2388   vam->result_ready = 1;
2389 }
2390
2391 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2392   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2393 {
2394   vat_main_t *vam = &vat_main;
2395   i32 retval = ntohl (mp->retval);
2396   if (vam->async_mode)
2397     {
2398       vam->async_errors += (retval < 0);
2399     }
2400   else
2401     {
2402       vam->retval = retval;
2403       vam->sw_if_index = ntohl (mp->sw_if_index);
2404       vam->result_ready = 1;
2405     }
2406 }
2407
2408 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2409   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t node;
2413
2414   vat_json_init_object (&node);
2415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2416   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2417
2418   vat_json_print (vam->ofp, &node);
2419   vat_json_free (&node);
2420
2421   vam->retval = ntohl (mp->retval);
2422   vam->result_ready = 1;
2423 }
2424
2425 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2426   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   i32 retval = ntohl (mp->retval);
2430   if (vam->async_mode)
2431     {
2432       vam->async_errors += (retval < 0);
2433     }
2434   else
2435     {
2436       vam->retval = retval;
2437       vam->sw_if_index = ntohl (mp->sw_if_index);
2438       vam->result_ready = 1;
2439     }
2440   vam->regenerate_interface_table = 1;
2441 }
2442
2443 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2444   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   vat_json_node_t node;
2448
2449   vat_json_init_object (&node);
2450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2451   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2452
2453   vat_json_print (vam->ofp, &node);
2454   vat_json_free (&node);
2455
2456   vam->retval = ntohl (mp->retval);
2457   vam->result_ready = 1;
2458 }
2459
2460 static void vl_api_gre_add_del_tunnel_reply_t_handler
2461   (vl_api_gre_add_del_tunnel_reply_t * mp)
2462 {
2463   vat_main_t *vam = &vat_main;
2464   i32 retval = ntohl (mp->retval);
2465   if (vam->async_mode)
2466     {
2467       vam->async_errors += (retval < 0);
2468     }
2469   else
2470     {
2471       vam->retval = retval;
2472       vam->sw_if_index = ntohl (mp->sw_if_index);
2473       vam->result_ready = 1;
2474     }
2475 }
2476
2477 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2478   (vl_api_gre_add_del_tunnel_reply_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   vat_json_node_t node;
2482
2483   vat_json_init_object (&node);
2484   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2485   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2486
2487   vat_json_print (vam->ofp, &node);
2488   vat_json_free (&node);
2489
2490   vam->retval = ntohl (mp->retval);
2491   vam->result_ready = 1;
2492 }
2493
2494 static void vl_api_create_vhost_user_if_reply_t_handler
2495   (vl_api_create_vhost_user_if_reply_t * mp)
2496 {
2497   vat_main_t *vam = &vat_main;
2498   i32 retval = ntohl (mp->retval);
2499   if (vam->async_mode)
2500     {
2501       vam->async_errors += (retval < 0);
2502     }
2503   else
2504     {
2505       vam->retval = retval;
2506       vam->sw_if_index = ntohl (mp->sw_if_index);
2507       vam->result_ready = 1;
2508     }
2509   vam->regenerate_interface_table = 1;
2510 }
2511
2512 static void vl_api_create_vhost_user_if_reply_t_handler_json
2513   (vl_api_create_vhost_user_if_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   vat_json_node_t node;
2517
2518   vat_json_init_object (&node);
2519   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2520   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2521
2522   vat_json_print (vam->ofp, &node);
2523   vat_json_free (&node);
2524
2525   vam->retval = ntohl (mp->retval);
2526   vam->result_ready = 1;
2527 }
2528
2529 static void vl_api_dns_resolve_name_reply_t_handler
2530   (vl_api_dns_resolve_name_reply_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   i32 retval = ntohl (mp->retval);
2534   if (vam->async_mode)
2535     {
2536       vam->async_errors += (retval < 0);
2537     }
2538   else
2539     {
2540       vam->retval = retval;
2541       vam->result_ready = 1;
2542
2543       if (retval == 0)
2544         {
2545           if (mp->ip4_set)
2546             clib_warning ("ip4 address %U", format_ip4_address,
2547                           (ip4_address_t *) mp->ip4_address);
2548           if (mp->ip6_set)
2549             clib_warning ("ip6 address %U", format_ip6_address,
2550                           (ip6_address_t *) mp->ip6_address);
2551         }
2552       else
2553         clib_warning ("retval %d", retval);
2554     }
2555 }
2556
2557 static void vl_api_dns_resolve_name_reply_t_handler_json
2558   (vl_api_dns_resolve_name_reply_t * mp)
2559 {
2560   clib_warning ("not implemented");
2561 }
2562
2563 static void vl_api_dns_resolve_ip_reply_t_handler
2564   (vl_api_dns_resolve_ip_reply_t * mp)
2565 {
2566   vat_main_t *vam = &vat_main;
2567   i32 retval = ntohl (mp->retval);
2568   if (vam->async_mode)
2569     {
2570       vam->async_errors += (retval < 0);
2571     }
2572   else
2573     {
2574       vam->retval = retval;
2575       vam->result_ready = 1;
2576
2577       if (retval == 0)
2578         {
2579           clib_warning ("canonical name %s", mp->name);
2580         }
2581       else
2582         clib_warning ("retval %d", retval);
2583     }
2584 }
2585
2586 static void vl_api_dns_resolve_ip_reply_t_handler_json
2587   (vl_api_dns_resolve_ip_reply_t * mp)
2588 {
2589   clib_warning ("not implemented");
2590 }
2591
2592
2593 static void vl_api_ip_address_details_t_handler
2594   (vl_api_ip_address_details_t * mp)
2595 {
2596   vat_main_t *vam = &vat_main;
2597   static ip_address_details_t empty_ip_address_details = { {0} };
2598   ip_address_details_t *address = NULL;
2599   ip_details_t *current_ip_details = NULL;
2600   ip_details_t *details = NULL;
2601
2602   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2603
2604   if (!details || vam->current_sw_if_index >= vec_len (details)
2605       || !details[vam->current_sw_if_index].present)
2606     {
2607       errmsg ("ip address details arrived but not stored");
2608       errmsg ("ip_dump should be called first");
2609       return;
2610     }
2611
2612   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2613
2614 #define addresses (current_ip_details->addr)
2615
2616   vec_validate_init_empty (addresses, vec_len (addresses),
2617                            empty_ip_address_details);
2618
2619   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2620
2621   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2622   address->prefix_length = mp->prefix_length;
2623 #undef addresses
2624 }
2625
2626 static void vl_api_ip_address_details_t_handler_json
2627   (vl_api_ip_address_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (vam->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "ip", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "ip", ip4);
2651     }
2652   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2653 }
2654
2655 static void
2656 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   static ip_details_t empty_ip_details = { 0 };
2660   ip_details_t *ip = NULL;
2661   u32 sw_if_index = ~0;
2662
2663   sw_if_index = ntohl (mp->sw_if_index);
2664
2665   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2666                            sw_if_index, empty_ip_details);
2667
2668   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2669                          sw_if_index);
2670
2671   ip->present = 1;
2672 }
2673
2674 static void
2675 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678
2679   if (VAT_JSON_ARRAY != vam->json_tree.type)
2680     {
2681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2682       vat_json_init_array (&vam->json_tree);
2683     }
2684   vat_json_array_add_uint (&vam->json_tree,
2685                            clib_net_to_host_u32 (mp->sw_if_index));
2686 }
2687
2688 static void
2689 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2690 {
2691   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2692           "router_addr %U host_mac %U",
2693           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2694           mp->lease.hostname,
2695           format_ip4_address, &mp->lease.host_address,
2696           format_ip4_address, &mp->lease.router_address,
2697           format_ethernet_address, mp->lease.host_mac);
2698 }
2699
2700 static void vl_api_dhcp_compl_event_t_handler_json
2701   (vl_api_dhcp_compl_event_t * mp)
2702 {
2703   /* JSON output not supported */
2704 }
2705
2706 static void
2707 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2708                               u32 counter)
2709 {
2710   vat_main_t *vam = &vat_main;
2711   static u64 default_counter = 0;
2712
2713   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2714                            NULL);
2715   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2716                            sw_if_index, default_counter);
2717   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2718 }
2719
2720 static void
2721 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2722                                 interface_counter_t counter)
2723 {
2724   vat_main_t *vam = &vat_main;
2725   static interface_counter_t default_counter = { 0, };
2726
2727   vec_validate_init_empty (vam->combined_interface_counters,
2728                            vnet_counter_type, NULL);
2729   vec_validate_init_empty (vam->combined_interface_counters
2730                            [vnet_counter_type], sw_if_index, default_counter);
2731   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2732 }
2733
2734 static void vl_api_vnet_interface_simple_counters_t_handler
2735   (vl_api_vnet_interface_simple_counters_t * mp)
2736 {
2737   /* not supported */
2738 }
2739
2740 static void vl_api_vnet_interface_combined_counters_t_handler
2741   (vl_api_vnet_interface_combined_counters_t * mp)
2742 {
2743   /* not supported */
2744 }
2745
2746 static void vl_api_vnet_interface_simple_counters_t_handler_json
2747   (vl_api_vnet_interface_simple_counters_t * mp)
2748 {
2749   u64 *v_packets;
2750   u64 packets;
2751   u32 count;
2752   u32 first_sw_if_index;
2753   int i;
2754
2755   count = ntohl (mp->count);
2756   first_sw_if_index = ntohl (mp->first_sw_if_index);
2757
2758   v_packets = (u64 *) & mp->data;
2759   for (i = 0; i < count; i++)
2760     {
2761       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2762       set_simple_interface_counter (mp->vnet_counter_type,
2763                                     first_sw_if_index + i, packets);
2764       v_packets++;
2765     }
2766 }
2767
2768 static void vl_api_vnet_interface_combined_counters_t_handler_json
2769   (vl_api_vnet_interface_combined_counters_t * mp)
2770 {
2771   interface_counter_t counter;
2772   vlib_counter_t *v;
2773   u32 first_sw_if_index;
2774   int i;
2775   u32 count;
2776
2777   count = ntohl (mp->count);
2778   first_sw_if_index = ntohl (mp->first_sw_if_index);
2779
2780   v = (vlib_counter_t *) & mp->data;
2781   for (i = 0; i < count; i++)
2782     {
2783       counter.packets =
2784         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2785       counter.bytes =
2786         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2787       set_combined_interface_counter (mp->vnet_counter_type,
2788                                       first_sw_if_index + i, counter);
2789       v++;
2790     }
2791 }
2792
2793 static u32
2794 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2795 {
2796   vat_main_t *vam = &vat_main;
2797   u32 i;
2798
2799   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2800     {
2801       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2802         {
2803           return i;
2804         }
2805     }
2806   return ~0;
2807 }
2808
2809 static u32
2810 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2811 {
2812   vat_main_t *vam = &vat_main;
2813   u32 i;
2814
2815   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2816     {
2817       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2818         {
2819           return i;
2820         }
2821     }
2822   return ~0;
2823 }
2824
2825 static void vl_api_vnet_ip4_fib_counters_t_handler
2826   (vl_api_vnet_ip4_fib_counters_t * mp)
2827 {
2828   /* not supported */
2829 }
2830
2831 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2832   (vl_api_vnet_ip4_fib_counters_t * mp)
2833 {
2834   vat_main_t *vam = &vat_main;
2835   vl_api_ip4_fib_counter_t *v;
2836   ip4_fib_counter_t *counter;
2837   struct in_addr ip4;
2838   u32 vrf_id;
2839   u32 vrf_index;
2840   u32 count;
2841   int i;
2842
2843   vrf_id = ntohl (mp->vrf_id);
2844   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2845   if (~0 == vrf_index)
2846     {
2847       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2848       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2849       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2850       vec_validate (vam->ip4_fib_counters, vrf_index);
2851       vam->ip4_fib_counters[vrf_index] = NULL;
2852     }
2853
2854   vec_free (vam->ip4_fib_counters[vrf_index]);
2855   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2856   count = ntohl (mp->count);
2857   for (i = 0; i < count; i++)
2858     {
2859       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2860       counter = &vam->ip4_fib_counters[vrf_index][i];
2861       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2862       counter->address = ip4;
2863       counter->address_length = v->address_length;
2864       counter->packets = clib_net_to_host_u64 (v->packets);
2865       counter->bytes = clib_net_to_host_u64 (v->bytes);
2866       v++;
2867     }
2868 }
2869
2870 static void vl_api_vnet_ip4_nbr_counters_t_handler
2871   (vl_api_vnet_ip4_nbr_counters_t * mp)
2872 {
2873   /* not supported */
2874 }
2875
2876 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2877   (vl_api_vnet_ip4_nbr_counters_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   vl_api_ip4_nbr_counter_t *v;
2881   ip4_nbr_counter_t *counter;
2882   u32 sw_if_index;
2883   u32 count;
2884   int i;
2885
2886   sw_if_index = ntohl (mp->sw_if_index);
2887   count = ntohl (mp->count);
2888   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2889
2890   if (mp->begin)
2891     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2892
2893   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2894   for (i = 0; i < count; i++)
2895     {
2896       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2897       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2898       counter->address.s_addr = v->address;
2899       counter->packets = clib_net_to_host_u64 (v->packets);
2900       counter->bytes = clib_net_to_host_u64 (v->bytes);
2901       counter->linkt = v->link_type;
2902       v++;
2903     }
2904 }
2905
2906 static void vl_api_vnet_ip6_fib_counters_t_handler
2907   (vl_api_vnet_ip6_fib_counters_t * mp)
2908 {
2909   /* not supported */
2910 }
2911
2912 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2913   (vl_api_vnet_ip6_fib_counters_t * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916   vl_api_ip6_fib_counter_t *v;
2917   ip6_fib_counter_t *counter;
2918   struct in6_addr ip6;
2919   u32 vrf_id;
2920   u32 vrf_index;
2921   u32 count;
2922   int i;
2923
2924   vrf_id = ntohl (mp->vrf_id);
2925   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2926   if (~0 == vrf_index)
2927     {
2928       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2929       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2930       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2931       vec_validate (vam->ip6_fib_counters, vrf_index);
2932       vam->ip6_fib_counters[vrf_index] = NULL;
2933     }
2934
2935   vec_free (vam->ip6_fib_counters[vrf_index]);
2936   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2937   count = ntohl (mp->count);
2938   for (i = 0; i < count; i++)
2939     {
2940       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2941       counter = &vam->ip6_fib_counters[vrf_index][i];
2942       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2943       counter->address = ip6;
2944       counter->address_length = v->address_length;
2945       counter->packets = clib_net_to_host_u64 (v->packets);
2946       counter->bytes = clib_net_to_host_u64 (v->bytes);
2947       v++;
2948     }
2949 }
2950
2951 static void vl_api_vnet_ip6_nbr_counters_t_handler
2952   (vl_api_vnet_ip6_nbr_counters_t * mp)
2953 {
2954   /* not supported */
2955 }
2956
2957 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2958   (vl_api_vnet_ip6_nbr_counters_t * mp)
2959 {
2960   vat_main_t *vam = &vat_main;
2961   vl_api_ip6_nbr_counter_t *v;
2962   ip6_nbr_counter_t *counter;
2963   struct in6_addr ip6;
2964   u32 sw_if_index;
2965   u32 count;
2966   int i;
2967
2968   sw_if_index = ntohl (mp->sw_if_index);
2969   count = ntohl (mp->count);
2970   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2971
2972   if (mp->begin)
2973     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2974
2975   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2976   for (i = 0; i < count; i++)
2977     {
2978       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2979       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2980       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2981       counter->address = ip6;
2982       counter->packets = clib_net_to_host_u64 (v->packets);
2983       counter->bytes = clib_net_to_host_u64 (v->bytes);
2984       v++;
2985     }
2986 }
2987
2988 static void vl_api_get_first_msg_id_reply_t_handler
2989   (vl_api_get_first_msg_id_reply_t * mp)
2990 {
2991   vat_main_t *vam = &vat_main;
2992   i32 retval = ntohl (mp->retval);
2993
2994   if (vam->async_mode)
2995     {
2996       vam->async_errors += (retval < 0);
2997     }
2998   else
2999     {
3000       vam->retval = retval;
3001       vam->result_ready = 1;
3002     }
3003   if (retval >= 0)
3004     {
3005       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3006     }
3007 }
3008
3009 static void vl_api_get_first_msg_id_reply_t_handler_json
3010   (vl_api_get_first_msg_id_reply_t * mp)
3011 {
3012   vat_main_t *vam = &vat_main;
3013   vat_json_node_t node;
3014
3015   vat_json_init_object (&node);
3016   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3017   vat_json_object_add_uint (&node, "first_msg_id",
3018                             (uint) ntohs (mp->first_msg_id));
3019
3020   vat_json_print (vam->ofp, &node);
3021   vat_json_free (&node);
3022
3023   vam->retval = ntohl (mp->retval);
3024   vam->result_ready = 1;
3025 }
3026
3027 static void vl_api_get_node_graph_reply_t_handler
3028   (vl_api_get_node_graph_reply_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   api_main_t *am = &api_main;
3032   i32 retval = ntohl (mp->retval);
3033   u8 *pvt_copy, *reply;
3034   void *oldheap;
3035   vlib_node_t *node;
3036   int i;
3037
3038   if (vam->async_mode)
3039     {
3040       vam->async_errors += (retval < 0);
3041     }
3042   else
3043     {
3044       vam->retval = retval;
3045       vam->result_ready = 1;
3046     }
3047
3048   /* "Should never happen..." */
3049   if (retval != 0)
3050     return;
3051
3052   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3053   pvt_copy = vec_dup (reply);
3054
3055   /* Toss the shared-memory original... */
3056   pthread_mutex_lock (&am->vlib_rp->mutex);
3057   oldheap = svm_push_data_heap (am->vlib_rp);
3058
3059   vec_free (reply);
3060
3061   svm_pop_heap (oldheap);
3062   pthread_mutex_unlock (&am->vlib_rp->mutex);
3063
3064   if (vam->graph_nodes)
3065     {
3066       hash_free (vam->graph_node_index_by_name);
3067
3068       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3069         {
3070           node = vam->graph_nodes[0][i];
3071           vec_free (node->name);
3072           vec_free (node->next_nodes);
3073           vec_free (node);
3074         }
3075       vec_free (vam->graph_nodes[0]);
3076       vec_free (vam->graph_nodes);
3077     }
3078
3079   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3080   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3081   vec_free (pvt_copy);
3082
3083   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3084     {
3085       node = vam->graph_nodes[0][i];
3086       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3087     }
3088 }
3089
3090 static void vl_api_get_node_graph_reply_t_handler_json
3091   (vl_api_get_node_graph_reply_t * mp)
3092 {
3093   vat_main_t *vam = &vat_main;
3094   api_main_t *am = &api_main;
3095   void *oldheap;
3096   vat_json_node_t node;
3097   u8 *reply;
3098
3099   /* $$$$ make this real? */
3100   vat_json_init_object (&node);
3101   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3102   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3103
3104   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3105
3106   /* Toss the shared-memory original... */
3107   pthread_mutex_lock (&am->vlib_rp->mutex);
3108   oldheap = svm_push_data_heap (am->vlib_rp);
3109
3110   vec_free (reply);
3111
3112   svm_pop_heap (oldheap);
3113   pthread_mutex_unlock (&am->vlib_rp->mutex);
3114
3115   vat_json_print (vam->ofp, &node);
3116   vat_json_free (&node);
3117
3118   vam->retval = ntohl (mp->retval);
3119   vam->result_ready = 1;
3120 }
3121
3122 static void
3123 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126   u8 *s = 0;
3127
3128   if (mp->local)
3129     {
3130       s = format (s, "%=16d%=16d%=16d",
3131                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3132     }
3133   else
3134     {
3135       s = format (s, "%=16U%=16d%=16d",
3136                   mp->is_ipv6 ? format_ip6_address :
3137                   format_ip4_address,
3138                   mp->ip_address, mp->priority, mp->weight);
3139     }
3140
3141   print (vam->ofp, "%v", s);
3142   vec_free (s);
3143 }
3144
3145 static void
3146 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   vat_json_node_t *node = NULL;
3150   struct in6_addr ip6;
3151   struct in_addr ip4;
3152
3153   if (VAT_JSON_ARRAY != vam->json_tree.type)
3154     {
3155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3156       vat_json_init_array (&vam->json_tree);
3157     }
3158   node = vat_json_array_add (&vam->json_tree);
3159   vat_json_init_object (node);
3160
3161   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3162   vat_json_object_add_uint (node, "priority", mp->priority);
3163   vat_json_object_add_uint (node, "weight", mp->weight);
3164
3165   if (mp->local)
3166     vat_json_object_add_uint (node, "sw_if_index",
3167                               clib_net_to_host_u32 (mp->sw_if_index));
3168   else
3169     {
3170       if (mp->is_ipv6)
3171         {
3172           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3173           vat_json_object_add_ip6 (node, "address", ip6);
3174         }
3175       else
3176         {
3177           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3178           vat_json_object_add_ip4 (node, "address", ip4);
3179         }
3180     }
3181 }
3182
3183 static void
3184 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3185                                           mp)
3186 {
3187   vat_main_t *vam = &vat_main;
3188   u8 *ls_name = 0;
3189
3190   ls_name = format (0, "%s", mp->ls_name);
3191
3192   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3193          ls_name);
3194   vec_free (ls_name);
3195 }
3196
3197 static void
3198   vl_api_one_locator_set_details_t_handler_json
3199   (vl_api_one_locator_set_details_t * mp)
3200 {
3201   vat_main_t *vam = &vat_main;
3202   vat_json_node_t *node = 0;
3203   u8 *ls_name = 0;
3204
3205   ls_name = format (0, "%s", mp->ls_name);
3206   vec_add1 (ls_name, 0);
3207
3208   if (VAT_JSON_ARRAY != vam->json_tree.type)
3209     {
3210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3211       vat_json_init_array (&vam->json_tree);
3212     }
3213   node = vat_json_array_add (&vam->json_tree);
3214
3215   vat_json_init_object (node);
3216   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3217   vat_json_object_add_uint (node, "ls_index",
3218                             clib_net_to_host_u32 (mp->ls_index));
3219   vec_free (ls_name);
3220 }
3221
3222 typedef struct
3223 {
3224   u32 spi;
3225   u8 si;
3226 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3227
3228 uword
3229 unformat_nsh_address (unformat_input_t * input, va_list * args)
3230 {
3231   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3232   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3233 }
3234
3235 u8 *
3236 format_nsh_address_vat (u8 * s, va_list * args)
3237 {
3238   nsh_t *a = va_arg (*args, nsh_t *);
3239   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3240 }
3241
3242 static u8 *
3243 format_lisp_flat_eid (u8 * s, va_list * args)
3244 {
3245   u32 type = va_arg (*args, u32);
3246   u8 *eid = va_arg (*args, u8 *);
3247   u32 eid_len = va_arg (*args, u32);
3248
3249   switch (type)
3250     {
3251     case 0:
3252       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3253     case 1:
3254       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3255     case 2:
3256       return format (s, "%U", format_ethernet_address, eid);
3257     case 3:
3258       return format (s, "%U", format_nsh_address_vat, eid);
3259     }
3260   return 0;
3261 }
3262
3263 static u8 *
3264 format_lisp_eid_vat (u8 * s, va_list * args)
3265 {
3266   u32 type = va_arg (*args, u32);
3267   u8 *eid = va_arg (*args, u8 *);
3268   u32 eid_len = va_arg (*args, u32);
3269   u8 *seid = va_arg (*args, u8 *);
3270   u32 seid_len = va_arg (*args, u32);
3271   u32 is_src_dst = va_arg (*args, u32);
3272
3273   if (is_src_dst)
3274     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3275
3276   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3277
3278   return s;
3279 }
3280
3281 static void
3282 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3283 {
3284   vat_main_t *vam = &vat_main;
3285   u8 *s = 0, *eid = 0;
3286
3287   if (~0 == mp->locator_set_index)
3288     s = format (0, "action: %d", mp->action);
3289   else
3290     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3291
3292   eid = format (0, "%U", format_lisp_eid_vat,
3293                 mp->eid_type,
3294                 mp->eid,
3295                 mp->eid_prefix_len,
3296                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3297   vec_add1 (eid, 0);
3298
3299   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3300          clib_net_to_host_u32 (mp->vni),
3301          eid,
3302          mp->is_local ? "local" : "remote",
3303          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3304          clib_net_to_host_u16 (mp->key_id), mp->key);
3305
3306   vec_free (s);
3307   vec_free (eid);
3308 }
3309
3310 static void
3311 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3312                                              * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315   vat_json_node_t *node = 0;
3316   u8 *eid = 0;
3317
3318   if (VAT_JSON_ARRAY != vam->json_tree.type)
3319     {
3320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3321       vat_json_init_array (&vam->json_tree);
3322     }
3323   node = vat_json_array_add (&vam->json_tree);
3324
3325   vat_json_init_object (node);
3326   if (~0 == mp->locator_set_index)
3327     vat_json_object_add_uint (node, "action", mp->action);
3328   else
3329     vat_json_object_add_uint (node, "locator_set_index",
3330                               clib_net_to_host_u32 (mp->locator_set_index));
3331
3332   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3333   if (mp->eid_type == 3)
3334     {
3335       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3336       vat_json_init_object (nsh_json);
3337       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3338       vat_json_object_add_uint (nsh_json, "spi",
3339                                 clib_net_to_host_u32 (nsh->spi));
3340       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3341     }
3342   else
3343     {
3344       eid = format (0, "%U", format_lisp_eid_vat,
3345                     mp->eid_type,
3346                     mp->eid,
3347                     mp->eid_prefix_len,
3348                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3349       vec_add1 (eid, 0);
3350       vat_json_object_add_string_copy (node, "eid", eid);
3351       vec_free (eid);
3352     }
3353   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3354   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3355   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3356
3357   if (mp->key_id)
3358     {
3359       vat_json_object_add_uint (node, "key_id",
3360                                 clib_net_to_host_u16 (mp->key_id));
3361       vat_json_object_add_string_copy (node, "key", mp->key);
3362     }
3363 }
3364
3365 static void
3366 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   u8 *seid = 0, *deid = 0;
3370   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3371
3372   deid = format (0, "%U", format_lisp_eid_vat,
3373                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3374
3375   seid = format (0, "%U", format_lisp_eid_vat,
3376                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3377
3378   vec_add1 (deid, 0);
3379   vec_add1 (seid, 0);
3380
3381   if (mp->is_ip4)
3382     format_ip_address_fcn = format_ip4_address;
3383   else
3384     format_ip_address_fcn = format_ip6_address;
3385
3386
3387   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3388          clib_net_to_host_u32 (mp->vni),
3389          seid, deid,
3390          format_ip_address_fcn, mp->lloc,
3391          format_ip_address_fcn, mp->rloc,
3392          clib_net_to_host_u32 (mp->pkt_count),
3393          clib_net_to_host_u32 (mp->bytes));
3394
3395   vec_free (deid);
3396   vec_free (seid);
3397 }
3398
3399 static void
3400 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3401 {
3402   struct in6_addr ip6;
3403   struct in_addr ip4;
3404   vat_main_t *vam = &vat_main;
3405   vat_json_node_t *node = 0;
3406   u8 *deid = 0, *seid = 0;
3407
3408   if (VAT_JSON_ARRAY != vam->json_tree.type)
3409     {
3410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3411       vat_json_init_array (&vam->json_tree);
3412     }
3413   node = vat_json_array_add (&vam->json_tree);
3414
3415   vat_json_init_object (node);
3416   deid = format (0, "%U", format_lisp_eid_vat,
3417                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3418
3419   seid = format (0, "%U", format_lisp_eid_vat,
3420                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3421
3422   vec_add1 (deid, 0);
3423   vec_add1 (seid, 0);
3424
3425   vat_json_object_add_string_copy (node, "seid", seid);
3426   vat_json_object_add_string_copy (node, "deid", deid);
3427   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3428
3429   if (mp->is_ip4)
3430     {
3431       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3432       vat_json_object_add_ip4 (node, "lloc", ip4);
3433       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3434       vat_json_object_add_ip4 (node, "rloc", ip4);
3435     }
3436   else
3437     {
3438       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3439       vat_json_object_add_ip6 (node, "lloc", ip6);
3440       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3441       vat_json_object_add_ip6 (node, "rloc", ip6);
3442     }
3443   vat_json_object_add_uint (node, "pkt_count",
3444                             clib_net_to_host_u32 (mp->pkt_count));
3445   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3446
3447   vec_free (deid);
3448   vec_free (seid);
3449 }
3450
3451 static void
3452   vl_api_one_eid_table_map_details_t_handler
3453   (vl_api_one_eid_table_map_details_t * mp)
3454 {
3455   vat_main_t *vam = &vat_main;
3456
3457   u8 *line = format (0, "%=10d%=10d",
3458                      clib_net_to_host_u32 (mp->vni),
3459                      clib_net_to_host_u32 (mp->dp_table));
3460   print (vam->ofp, "%v", line);
3461   vec_free (line);
3462 }
3463
3464 static void
3465   vl_api_one_eid_table_map_details_t_handler_json
3466   (vl_api_one_eid_table_map_details_t * mp)
3467 {
3468   vat_main_t *vam = &vat_main;
3469   vat_json_node_t *node = NULL;
3470
3471   if (VAT_JSON_ARRAY != vam->json_tree.type)
3472     {
3473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3474       vat_json_init_array (&vam->json_tree);
3475     }
3476   node = vat_json_array_add (&vam->json_tree);
3477   vat_json_init_object (node);
3478   vat_json_object_add_uint (node, "dp_table",
3479                             clib_net_to_host_u32 (mp->dp_table));
3480   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3481 }
3482
3483 static void
3484   vl_api_one_eid_table_vni_details_t_handler
3485   (vl_api_one_eid_table_vni_details_t * mp)
3486 {
3487   vat_main_t *vam = &vat_main;
3488
3489   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3490   print (vam->ofp, "%v", line);
3491   vec_free (line);
3492 }
3493
3494 static void
3495   vl_api_one_eid_table_vni_details_t_handler_json
3496   (vl_api_one_eid_table_vni_details_t * mp)
3497 {
3498   vat_main_t *vam = &vat_main;
3499   vat_json_node_t *node = NULL;
3500
3501   if (VAT_JSON_ARRAY != vam->json_tree.type)
3502     {
3503       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3504       vat_json_init_array (&vam->json_tree);
3505     }
3506   node = vat_json_array_add (&vam->json_tree);
3507   vat_json_init_object (node);
3508   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3509 }
3510
3511 static void
3512   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3513   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3514 {
3515   vat_main_t *vam = &vat_main;
3516   int retval = clib_net_to_host_u32 (mp->retval);
3517
3518   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3519   print (vam->ofp, "fallback threshold value: %d", mp->value);
3520
3521   vam->retval = retval;
3522   vam->result_ready = 1;
3523 }
3524
3525 static void
3526   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3527   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530   vat_json_node_t _node, *node = &_node;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532
3533   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3534   vat_json_init_object (node);
3535   vat_json_object_add_uint (node, "value", mp->value);
3536
3537   vat_json_print (vam->ofp, node);
3538   vat_json_free (node);
3539
3540   vam->retval = retval;
3541   vam->result_ready = 1;
3542 }
3543
3544 static void
3545   vl_api_show_one_map_register_state_reply_t_handler
3546   (vl_api_show_one_map_register_state_reply_t * mp)
3547 {
3548   vat_main_t *vam = &vat_main;
3549   int retval = clib_net_to_host_u32 (mp->retval);
3550
3551   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3552
3553   vam->retval = retval;
3554   vam->result_ready = 1;
3555 }
3556
3557 static void
3558   vl_api_show_one_map_register_state_reply_t_handler_json
3559   (vl_api_show_one_map_register_state_reply_t * mp)
3560 {
3561   vat_main_t *vam = &vat_main;
3562   vat_json_node_t _node, *node = &_node;
3563   int retval = clib_net_to_host_u32 (mp->retval);
3564
3565   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3566
3567   vat_json_init_object (node);
3568   vat_json_object_add_string_copy (node, "state", s);
3569
3570   vat_json_print (vam->ofp, node);
3571   vat_json_free (node);
3572
3573   vam->retval = retval;
3574   vam->result_ready = 1;
3575   vec_free (s);
3576 }
3577
3578 static void
3579   vl_api_show_one_rloc_probe_state_reply_t_handler
3580   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3581 {
3582   vat_main_t *vam = &vat_main;
3583   int retval = clib_net_to_host_u32 (mp->retval);
3584
3585   if (retval)
3586     goto end;
3587
3588   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3589 end:
3590   vam->retval = retval;
3591   vam->result_ready = 1;
3592 }
3593
3594 static void
3595   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3596   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3597 {
3598   vat_main_t *vam = &vat_main;
3599   vat_json_node_t _node, *node = &_node;
3600   int retval = clib_net_to_host_u32 (mp->retval);
3601
3602   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3603   vat_json_init_object (node);
3604   vat_json_object_add_string_copy (node, "state", s);
3605
3606   vat_json_print (vam->ofp, node);
3607   vat_json_free (node);
3608
3609   vam->retval = retval;
3610   vam->result_ready = 1;
3611   vec_free (s);
3612 }
3613
3614 static void
3615   vl_api_show_one_stats_enable_disable_reply_t_handler
3616   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   int retval = clib_net_to_host_u32 (mp->retval);
3620
3621   if (retval)
3622     goto end;
3623
3624   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3625 end:
3626   vam->retval = retval;
3627   vam->result_ready = 1;
3628 }
3629
3630 static void
3631   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3632   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3633 {
3634   vat_main_t *vam = &vat_main;
3635   vat_json_node_t _node, *node = &_node;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637
3638   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3639   vat_json_init_object (node);
3640   vat_json_object_add_string_copy (node, "state", s);
3641
3642   vat_json_print (vam->ofp, node);
3643   vat_json_free (node);
3644
3645   vam->retval = retval;
3646   vam->result_ready = 1;
3647   vec_free (s);
3648 }
3649
3650 static void
3651 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3652 {
3653   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3654   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3655   e->vni = clib_net_to_host_u32 (e->vni);
3656 }
3657
3658 static void
3659   gpe_fwd_entries_get_reply_t_net_to_host
3660   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3661 {
3662   u32 i;
3663
3664   mp->count = clib_net_to_host_u32 (mp->count);
3665   for (i = 0; i < mp->count; i++)
3666     {
3667       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3668     }
3669 }
3670
3671 static u8 *
3672 format_gpe_encap_mode (u8 * s, va_list * args)
3673 {
3674   u32 mode = va_arg (*args, u32);
3675
3676   switch (mode)
3677     {
3678     case 0:
3679       return format (s, "lisp");
3680     case 1:
3681       return format (s, "vxlan");
3682     }
3683   return 0;
3684 }
3685
3686 static void
3687   vl_api_gpe_get_encap_mode_reply_t_handler
3688   (vl_api_gpe_get_encap_mode_reply_t * mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691
3692   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3693   vam->retval = ntohl (mp->retval);
3694   vam->result_ready = 1;
3695 }
3696
3697 static void
3698   vl_api_gpe_get_encap_mode_reply_t_handler_json
3699   (vl_api_gpe_get_encap_mode_reply_t * mp)
3700 {
3701   vat_main_t *vam = &vat_main;
3702   vat_json_node_t node;
3703
3704   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3705   vec_add1 (encap_mode, 0);
3706
3707   vat_json_init_object (&node);
3708   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3709
3710   vec_free (encap_mode);
3711   vat_json_print (vam->ofp, &node);
3712   vat_json_free (&node);
3713
3714   vam->retval = ntohl (mp->retval);
3715   vam->result_ready = 1;
3716 }
3717
3718 static void
3719   vl_api_gpe_fwd_entry_path_details_t_handler
3720   (vl_api_gpe_fwd_entry_path_details_t * mp)
3721 {
3722   vat_main_t *vam = &vat_main;
3723   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3724
3725   if (mp->lcl_loc.is_ip4)
3726     format_ip_address_fcn = format_ip4_address;
3727   else
3728     format_ip_address_fcn = format_ip6_address;
3729
3730   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3731          format_ip_address_fcn, &mp->lcl_loc,
3732          format_ip_address_fcn, &mp->rmt_loc);
3733 }
3734
3735 static void
3736 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3737 {
3738   struct in6_addr ip6;
3739   struct in_addr ip4;
3740
3741   if (loc->is_ip4)
3742     {
3743       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3744       vat_json_object_add_ip4 (n, "address", ip4);
3745     }
3746   else
3747     {
3748       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3749       vat_json_object_add_ip6 (n, "address", ip6);
3750     }
3751   vat_json_object_add_uint (n, "weight", loc->weight);
3752 }
3753
3754 static void
3755   vl_api_gpe_fwd_entry_path_details_t_handler_json
3756   (vl_api_gpe_fwd_entry_path_details_t * mp)
3757 {
3758   vat_main_t *vam = &vat_main;
3759   vat_json_node_t *node = NULL;
3760   vat_json_node_t *loc_node;
3761
3762   if (VAT_JSON_ARRAY != vam->json_tree.type)
3763     {
3764       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3765       vat_json_init_array (&vam->json_tree);
3766     }
3767   node = vat_json_array_add (&vam->json_tree);
3768   vat_json_init_object (node);
3769
3770   loc_node = vat_json_object_add (node, "local_locator");
3771   vat_json_init_object (loc_node);
3772   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3773
3774   loc_node = vat_json_object_add (node, "remote_locator");
3775   vat_json_init_object (loc_node);
3776   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3777 }
3778
3779 static void
3780   vl_api_gpe_fwd_entries_get_reply_t_handler
3781   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3782 {
3783   vat_main_t *vam = &vat_main;
3784   u32 i;
3785   int retval = clib_net_to_host_u32 (mp->retval);
3786   vl_api_gpe_fwd_entry_t *e;
3787
3788   if (retval)
3789     goto end;
3790
3791   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3792
3793   for (i = 0; i < mp->count; i++)
3794     {
3795       e = &mp->entries[i];
3796       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3797              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3798              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3799     }
3800
3801 end:
3802   vam->retval = retval;
3803   vam->result_ready = 1;
3804 }
3805
3806 static void
3807   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3808   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3809 {
3810   u8 *s = 0;
3811   vat_main_t *vam = &vat_main;
3812   vat_json_node_t *e = 0, root;
3813   u32 i;
3814   int retval = clib_net_to_host_u32 (mp->retval);
3815   vl_api_gpe_fwd_entry_t *fwd;
3816
3817   if (retval)
3818     goto end;
3819
3820   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3821   vat_json_init_array (&root);
3822
3823   for (i = 0; i < mp->count; i++)
3824     {
3825       e = vat_json_array_add (&root);
3826       fwd = &mp->entries[i];
3827
3828       vat_json_init_object (e);
3829       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3830       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3831       vat_json_object_add_int (e, "vni", fwd->vni);
3832       vat_json_object_add_int (e, "action", fwd->action);
3833
3834       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3835                   fwd->leid_prefix_len);
3836       vec_add1 (s, 0);
3837       vat_json_object_add_string_copy (e, "leid", s);
3838       vec_free (s);
3839
3840       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3841                   fwd->reid_prefix_len);
3842       vec_add1 (s, 0);
3843       vat_json_object_add_string_copy (e, "reid", s);
3844       vec_free (s);
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_native_fwd_rpaths_get_reply_t_handler
3857   (vl_api_gpe_native_fwd_rpaths_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   vl_api_gpe_native_fwd_rpath_t *r;
3863
3864   if (retval)
3865     goto end;
3866
3867   n = clib_net_to_host_u32 (mp->count);
3868
3869   for (i = 0; i < n; i++)
3870     {
3871       r = &mp->entries[i];
3872       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3873              clib_net_to_host_u32 (r->fib_index),
3874              clib_net_to_host_u32 (r->nh_sw_if_index),
3875              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3876     }
3877
3878 end:
3879   vam->retval = retval;
3880   vam->result_ready = 1;
3881 }
3882
3883 static void
3884   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3885   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3886 {
3887   vat_main_t *vam = &vat_main;
3888   vat_json_node_t root, *e;
3889   u32 i, n;
3890   int retval = clib_net_to_host_u32 (mp->retval);
3891   vl_api_gpe_native_fwd_rpath_t *r;
3892   u8 *s;
3893
3894   if (retval)
3895     goto end;
3896
3897   n = clib_net_to_host_u32 (mp->count);
3898   vat_json_init_array (&root);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       e = vat_json_array_add (&root);
3903       vat_json_init_object (e);
3904       r = &mp->entries[i];
3905       s =
3906         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3907                 r->nh_addr);
3908       vec_add1 (s, 0);
3909       vat_json_object_add_string_copy (e, "ip4", s);
3910       vec_free (s);
3911
3912       vat_json_object_add_uint (e, "fib_index",
3913                                 clib_net_to_host_u32 (r->fib_index));
3914       vat_json_object_add_uint (e, "nh_sw_if_index",
3915                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3916     }
3917
3918   vat_json_print (vam->ofp, &root);
3919   vat_json_free (&root);
3920
3921 end:
3922   vam->retval = retval;
3923   vam->result_ready = 1;
3924 }
3925
3926 static void
3927   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3928   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3929 {
3930   vat_main_t *vam = &vat_main;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933
3934   if (retval)
3935     goto end;
3936
3937   n = clib_net_to_host_u32 (mp->count);
3938
3939   for (i = 0; i < n; i++)
3940     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3941
3942 end:
3943   vam->retval = retval;
3944   vam->result_ready = 1;
3945 }
3946
3947 static void
3948   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3949   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3950 {
3951   vat_main_t *vam = &vat_main;
3952   vat_json_node_t root;
3953   u32 i, n;
3954   int retval = clib_net_to_host_u32 (mp->retval);
3955
3956   if (retval)
3957     goto end;
3958
3959   n = clib_net_to_host_u32 (mp->count);
3960   vat_json_init_array (&root);
3961
3962   for (i = 0; i < n; i++)
3963     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3964
3965   vat_json_print (vam->ofp, &root);
3966   vat_json_free (&root);
3967
3968 end:
3969   vam->retval = retval;
3970   vam->result_ready = 1;
3971 }
3972
3973 static void
3974   vl_api_one_ndp_entries_get_reply_t_handler
3975   (vl_api_one_ndp_entries_get_reply_t * mp)
3976 {
3977   vat_main_t *vam = &vat_main;
3978   u32 i, n;
3979   int retval = clib_net_to_host_u32 (mp->retval);
3980
3981   if (retval)
3982     goto end;
3983
3984   n = clib_net_to_host_u32 (mp->count);
3985
3986   for (i = 0; i < n; i++)
3987     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3988            format_ethernet_address, mp->entries[i].mac);
3989
3990 end:
3991   vam->retval = retval;
3992   vam->result_ready = 1;
3993 }
3994
3995 static void
3996   vl_api_one_ndp_entries_get_reply_t_handler_json
3997   (vl_api_one_ndp_entries_get_reply_t * mp)
3998 {
3999   u8 *s = 0;
4000   vat_main_t *vam = &vat_main;
4001   vat_json_node_t *e = 0, root;
4002   u32 i, n;
4003   int retval = clib_net_to_host_u32 (mp->retval);
4004   vl_api_one_ndp_entry_t *arp_entry;
4005
4006   if (retval)
4007     goto end;
4008
4009   n = clib_net_to_host_u32 (mp->count);
4010   vat_json_init_array (&root);
4011
4012   for (i = 0; i < n; i++)
4013     {
4014       e = vat_json_array_add (&root);
4015       arp_entry = &mp->entries[i];
4016
4017       vat_json_init_object (e);
4018       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4019       vec_add1 (s, 0);
4020
4021       vat_json_object_add_string_copy (e, "mac", s);
4022       vec_free (s);
4023
4024       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4025       vec_add1 (s, 0);
4026       vat_json_object_add_string_copy (e, "ip6", s);
4027       vec_free (s);
4028     }
4029
4030   vat_json_print (vam->ofp, &root);
4031   vat_json_free (&root);
4032
4033 end:
4034   vam->retval = retval;
4035   vam->result_ready = 1;
4036 }
4037
4038 static void
4039   vl_api_one_l2_arp_entries_get_reply_t_handler
4040   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4041 {
4042   vat_main_t *vam = &vat_main;
4043   u32 i, n;
4044   int retval = clib_net_to_host_u32 (mp->retval);
4045
4046   if (retval)
4047     goto end;
4048
4049   n = clib_net_to_host_u32 (mp->count);
4050
4051   for (i = 0; i < n; i++)
4052     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4053            format_ethernet_address, mp->entries[i].mac);
4054
4055 end:
4056   vam->retval = retval;
4057   vam->result_ready = 1;
4058 }
4059
4060 static void
4061   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4062   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4063 {
4064   u8 *s = 0;
4065   vat_main_t *vam = &vat_main;
4066   vat_json_node_t *e = 0, root;
4067   u32 i, n;
4068   int retval = clib_net_to_host_u32 (mp->retval);
4069   vl_api_one_l2_arp_entry_t *arp_entry;
4070
4071   if (retval)
4072     goto end;
4073
4074   n = clib_net_to_host_u32 (mp->count);
4075   vat_json_init_array (&root);
4076
4077   for (i = 0; i < n; i++)
4078     {
4079       e = vat_json_array_add (&root);
4080       arp_entry = &mp->entries[i];
4081
4082       vat_json_init_object (e);
4083       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4084       vec_add1 (s, 0);
4085
4086       vat_json_object_add_string_copy (e, "mac", s);
4087       vec_free (s);
4088
4089       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4090       vec_add1 (s, 0);
4091       vat_json_object_add_string_copy (e, "ip4", s);
4092       vec_free (s);
4093     }
4094
4095   vat_json_print (vam->ofp, &root);
4096   vat_json_free (&root);
4097
4098 end:
4099   vam->retval = retval;
4100   vam->result_ready = 1;
4101 }
4102
4103 static void
4104 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   u32 i, n;
4108   int retval = clib_net_to_host_u32 (mp->retval);
4109
4110   if (retval)
4111     goto end;
4112
4113   n = clib_net_to_host_u32 (mp->count);
4114
4115   for (i = 0; i < n; i++)
4116     {
4117       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4118     }
4119
4120 end:
4121   vam->retval = retval;
4122   vam->result_ready = 1;
4123 }
4124
4125 static void
4126   vl_api_one_ndp_bd_get_reply_t_handler_json
4127   (vl_api_one_ndp_bd_get_reply_t * mp)
4128 {
4129   vat_main_t *vam = &vat_main;
4130   vat_json_node_t root;
4131   u32 i, n;
4132   int retval = clib_net_to_host_u32 (mp->retval);
4133
4134   if (retval)
4135     goto end;
4136
4137   n = clib_net_to_host_u32 (mp->count);
4138   vat_json_init_array (&root);
4139
4140   for (i = 0; i < n; i++)
4141     {
4142       vat_json_array_add_uint (&root,
4143                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4144     }
4145
4146   vat_json_print (vam->ofp, &root);
4147   vat_json_free (&root);
4148
4149 end:
4150   vam->retval = retval;
4151   vam->result_ready = 1;
4152 }
4153
4154 static void
4155   vl_api_one_l2_arp_bd_get_reply_t_handler
4156   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4157 {
4158   vat_main_t *vam = &vat_main;
4159   u32 i, n;
4160   int retval = clib_net_to_host_u32 (mp->retval);
4161
4162   if (retval)
4163     goto end;
4164
4165   n = clib_net_to_host_u32 (mp->count);
4166
4167   for (i = 0; i < n; i++)
4168     {
4169       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4170     }
4171
4172 end:
4173   vam->retval = retval;
4174   vam->result_ready = 1;
4175 }
4176
4177 static void
4178   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4179   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4180 {
4181   vat_main_t *vam = &vat_main;
4182   vat_json_node_t root;
4183   u32 i, n;
4184   int retval = clib_net_to_host_u32 (mp->retval);
4185
4186   if (retval)
4187     goto end;
4188
4189   n = clib_net_to_host_u32 (mp->count);
4190   vat_json_init_array (&root);
4191
4192   for (i = 0; i < n; i++)
4193     {
4194       vat_json_array_add_uint (&root,
4195                                clib_net_to_host_u32 (mp->bridge_domains[i]));
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_adjacencies_get_reply_t_handler
4208   (vl_api_one_adjacencies_get_reply_t * mp)
4209 {
4210   vat_main_t *vam = &vat_main;
4211   u32 i, n;
4212   int retval = clib_net_to_host_u32 (mp->retval);
4213   vl_api_one_adjacency_t *a;
4214
4215   if (retval)
4216     goto end;
4217
4218   n = clib_net_to_host_u32 (mp->count);
4219
4220   for (i = 0; i < n; i++)
4221     {
4222       a = &mp->adjacencies[i];
4223       print (vam->ofp, "%U %40U",
4224              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4225              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4226     }
4227
4228 end:
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_one_adjacencies_get_reply_t_handler_json
4235   (vl_api_one_adjacencies_get_reply_t * mp)
4236 {
4237   u8 *s = 0;
4238   vat_main_t *vam = &vat_main;
4239   vat_json_node_t *e = 0, root;
4240   u32 i, n;
4241   int retval = clib_net_to_host_u32 (mp->retval);
4242   vl_api_one_adjacency_t *a;
4243
4244   if (retval)
4245     goto end;
4246
4247   n = clib_net_to_host_u32 (mp->count);
4248   vat_json_init_array (&root);
4249
4250   for (i = 0; i < n; i++)
4251     {
4252       e = vat_json_array_add (&root);
4253       a = &mp->adjacencies[i];
4254
4255       vat_json_init_object (e);
4256       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4257                   a->leid_prefix_len);
4258       vec_add1 (s, 0);
4259       vat_json_object_add_string_copy (e, "leid", s);
4260       vec_free (s);
4261
4262       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4263                   a->reid_prefix_len);
4264       vec_add1 (s, 0);
4265       vat_json_object_add_string_copy (e, "reid", s);
4266       vec_free (s);
4267     }
4268
4269   vat_json_print (vam->ofp, &root);
4270   vat_json_free (&root);
4271
4272 end:
4273   vam->retval = retval;
4274   vam->result_ready = 1;
4275 }
4276
4277 static void
4278 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4279 {
4280   vat_main_t *vam = &vat_main;
4281
4282   print (vam->ofp, "%=20U",
4283          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4284          mp->ip_address);
4285 }
4286
4287 static void
4288   vl_api_one_map_server_details_t_handler_json
4289   (vl_api_one_map_server_details_t * mp)
4290 {
4291   vat_main_t *vam = &vat_main;
4292   vat_json_node_t *node = NULL;
4293   struct in6_addr ip6;
4294   struct in_addr ip4;
4295
4296   if (VAT_JSON_ARRAY != vam->json_tree.type)
4297     {
4298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4299       vat_json_init_array (&vam->json_tree);
4300     }
4301   node = vat_json_array_add (&vam->json_tree);
4302
4303   vat_json_init_object (node);
4304   if (mp->is_ipv6)
4305     {
4306       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4307       vat_json_object_add_ip6 (node, "map-server", ip6);
4308     }
4309   else
4310     {
4311       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4312       vat_json_object_add_ip4 (node, "map-server", ip4);
4313     }
4314 }
4315
4316 static void
4317 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4318                                            * mp)
4319 {
4320   vat_main_t *vam = &vat_main;
4321
4322   print (vam->ofp, "%=20U",
4323          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4324          mp->ip_address);
4325 }
4326
4327 static void
4328   vl_api_one_map_resolver_details_t_handler_json
4329   (vl_api_one_map_resolver_details_t * mp)
4330 {
4331   vat_main_t *vam = &vat_main;
4332   vat_json_node_t *node = NULL;
4333   struct in6_addr ip6;
4334   struct in_addr ip4;
4335
4336   if (VAT_JSON_ARRAY != vam->json_tree.type)
4337     {
4338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4339       vat_json_init_array (&vam->json_tree);
4340     }
4341   node = vat_json_array_add (&vam->json_tree);
4342
4343   vat_json_init_object (node);
4344   if (mp->is_ipv6)
4345     {
4346       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4347       vat_json_object_add_ip6 (node, "map resolver", ip6);
4348     }
4349   else
4350     {
4351       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4352       vat_json_object_add_ip4 (node, "map resolver", ip4);
4353     }
4354 }
4355
4356 static void
4357 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4358 {
4359   vat_main_t *vam = &vat_main;
4360   i32 retval = ntohl (mp->retval);
4361
4362   if (0 <= retval)
4363     {
4364       print (vam->ofp, "feature: %s\ngpe: %s",
4365              mp->feature_status ? "enabled" : "disabled",
4366              mp->gpe_status ? "enabled" : "disabled");
4367     }
4368
4369   vam->retval = retval;
4370   vam->result_ready = 1;
4371 }
4372
4373 static void
4374   vl_api_show_one_status_reply_t_handler_json
4375   (vl_api_show_one_status_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   vat_json_node_t node;
4379   u8 *gpe_status = NULL;
4380   u8 *feature_status = NULL;
4381
4382   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4383   feature_status = format (0, "%s",
4384                            mp->feature_status ? "enabled" : "disabled");
4385   vec_add1 (gpe_status, 0);
4386   vec_add1 (feature_status, 0);
4387
4388   vat_json_init_object (&node);
4389   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4390   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4391
4392   vec_free (gpe_status);
4393   vec_free (feature_status);
4394
4395   vat_json_print (vam->ofp, &node);
4396   vat_json_free (&node);
4397
4398   vam->retval = ntohl (mp->retval);
4399   vam->result_ready = 1;
4400 }
4401
4402 static void
4403   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4404   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   i32 retval = ntohl (mp->retval);
4408
4409   if (retval >= 0)
4410     {
4411       print (vam->ofp, "%=20s", mp->locator_set_name);
4412     }
4413
4414   vam->retval = retval;
4415   vam->result_ready = 1;
4416 }
4417
4418 static void
4419   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4420   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4421 {
4422   vat_main_t *vam = &vat_main;
4423   vat_json_node_t *node = NULL;
4424
4425   if (VAT_JSON_ARRAY != vam->json_tree.type)
4426     {
4427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4428       vat_json_init_array (&vam->json_tree);
4429     }
4430   node = vat_json_array_add (&vam->json_tree);
4431
4432   vat_json_init_object (node);
4433   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4434
4435   vat_json_print (vam->ofp, node);
4436   vat_json_free (node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static u8 *
4443 format_lisp_map_request_mode (u8 * s, va_list * args)
4444 {
4445   u32 mode = va_arg (*args, u32);
4446
4447   switch (mode)
4448     {
4449     case 0:
4450       return format (0, "dst-only");
4451     case 1:
4452       return format (0, "src-dst");
4453     }
4454   return 0;
4455 }
4456
4457 static void
4458   vl_api_show_one_map_request_mode_reply_t_handler
4459   (vl_api_show_one_map_request_mode_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462   i32 retval = ntohl (mp->retval);
4463
4464   if (0 <= retval)
4465     {
4466       u32 mode = mp->mode;
4467       print (vam->ofp, "map_request_mode: %U",
4468              format_lisp_map_request_mode, mode);
4469     }
4470
4471   vam->retval = retval;
4472   vam->result_ready = 1;
4473 }
4474
4475 static void
4476   vl_api_show_one_map_request_mode_reply_t_handler_json
4477   (vl_api_show_one_map_request_mode_reply_t * mp)
4478 {
4479   vat_main_t *vam = &vat_main;
4480   vat_json_node_t node;
4481   u8 *s = 0;
4482   u32 mode;
4483
4484   mode = mp->mode;
4485   s = format (0, "%U", format_lisp_map_request_mode, mode);
4486   vec_add1 (s, 0);
4487
4488   vat_json_init_object (&node);
4489   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4490   vat_json_print (vam->ofp, &node);
4491   vat_json_free (&node);
4492
4493   vec_free (s);
4494   vam->retval = ntohl (mp->retval);
4495   vam->result_ready = 1;
4496 }
4497
4498 static void
4499   vl_api_one_show_xtr_mode_reply_t_handler
4500   (vl_api_one_show_xtr_mode_reply_t * mp)
4501 {
4502   vat_main_t *vam = &vat_main;
4503   i32 retval = ntohl (mp->retval);
4504
4505   if (0 <= retval)
4506     {
4507       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4508     }
4509
4510   vam->retval = retval;
4511   vam->result_ready = 1;
4512 }
4513
4514 static void
4515   vl_api_one_show_xtr_mode_reply_t_handler_json
4516   (vl_api_one_show_xtr_mode_reply_t * mp)
4517 {
4518   vat_main_t *vam = &vat_main;
4519   vat_json_node_t node;
4520   u8 *status = 0;
4521
4522   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4523   vec_add1 (status, 0);
4524
4525   vat_json_init_object (&node);
4526   vat_json_object_add_string_copy (&node, "status", status);
4527
4528   vec_free (status);
4529
4530   vat_json_print (vam->ofp, &node);
4531   vat_json_free (&node);
4532
4533   vam->retval = ntohl (mp->retval);
4534   vam->result_ready = 1;
4535 }
4536
4537 static void
4538   vl_api_one_show_pitr_mode_reply_t_handler
4539   (vl_api_one_show_pitr_mode_reply_t * mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542   i32 retval = ntohl (mp->retval);
4543
4544   if (0 <= retval)
4545     {
4546       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4547     }
4548
4549   vam->retval = retval;
4550   vam->result_ready = 1;
4551 }
4552
4553 static void
4554   vl_api_one_show_pitr_mode_reply_t_handler_json
4555   (vl_api_one_show_pitr_mode_reply_t * mp)
4556 {
4557   vat_main_t *vam = &vat_main;
4558   vat_json_node_t node;
4559   u8 *status = 0;
4560
4561   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4562   vec_add1 (status, 0);
4563
4564   vat_json_init_object (&node);
4565   vat_json_object_add_string_copy (&node, "status", status);
4566
4567   vec_free (status);
4568
4569   vat_json_print (vam->ofp, &node);
4570   vat_json_free (&node);
4571
4572   vam->retval = ntohl (mp->retval);
4573   vam->result_ready = 1;
4574 }
4575
4576 static void
4577   vl_api_one_show_petr_mode_reply_t_handler
4578   (vl_api_one_show_petr_mode_reply_t * mp)
4579 {
4580   vat_main_t *vam = &vat_main;
4581   i32 retval = ntohl (mp->retval);
4582
4583   if (0 <= retval)
4584     {
4585       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4586     }
4587
4588   vam->retval = retval;
4589   vam->result_ready = 1;
4590 }
4591
4592 static void
4593   vl_api_one_show_petr_mode_reply_t_handler_json
4594   (vl_api_one_show_petr_mode_reply_t * mp)
4595 {
4596   vat_main_t *vam = &vat_main;
4597   vat_json_node_t node;
4598   u8 *status = 0;
4599
4600   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4601   vec_add1 (status, 0);
4602
4603   vat_json_init_object (&node);
4604   vat_json_object_add_string_copy (&node, "status", status);
4605
4606   vec_free (status);
4607
4608   vat_json_print (vam->ofp, &node);
4609   vat_json_free (&node);
4610
4611   vam->retval = ntohl (mp->retval);
4612   vam->result_ready = 1;
4613 }
4614
4615 static void
4616   vl_api_show_one_use_petr_reply_t_handler
4617   (vl_api_show_one_use_petr_reply_t * mp)
4618 {
4619   vat_main_t *vam = &vat_main;
4620   i32 retval = ntohl (mp->retval);
4621
4622   if (0 <= retval)
4623     {
4624       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4625       if (mp->status)
4626         {
4627           print (vam->ofp, "Proxy-ETR address; %U",
4628                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4629                  mp->address);
4630         }
4631     }
4632
4633   vam->retval = retval;
4634   vam->result_ready = 1;
4635 }
4636
4637 static void
4638   vl_api_show_one_use_petr_reply_t_handler_json
4639   (vl_api_show_one_use_petr_reply_t * mp)
4640 {
4641   vat_main_t *vam = &vat_main;
4642   vat_json_node_t node;
4643   u8 *status = 0;
4644   struct in_addr ip4;
4645   struct in6_addr ip6;
4646
4647   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4648   vec_add1 (status, 0);
4649
4650   vat_json_init_object (&node);
4651   vat_json_object_add_string_copy (&node, "status", status);
4652   if (mp->status)
4653     {
4654       if (mp->is_ip4)
4655         {
4656           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4657           vat_json_object_add_ip6 (&node, "address", ip6);
4658         }
4659       else
4660         {
4661           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4662           vat_json_object_add_ip4 (&node, "address", ip4);
4663         }
4664     }
4665
4666   vec_free (status);
4667
4668   vat_json_print (vam->ofp, &node);
4669   vat_json_free (&node);
4670
4671   vam->retval = ntohl (mp->retval);
4672   vam->result_ready = 1;
4673 }
4674
4675 static void
4676   vl_api_show_one_nsh_mapping_reply_t_handler
4677   (vl_api_show_one_nsh_mapping_reply_t * mp)
4678 {
4679   vat_main_t *vam = &vat_main;
4680   i32 retval = ntohl (mp->retval);
4681
4682   if (0 <= retval)
4683     {
4684       print (vam->ofp, "%-20s%-16s",
4685              mp->is_set ? "set" : "not-set",
4686              mp->is_set ? (char *) mp->locator_set_name : "");
4687     }
4688
4689   vam->retval = retval;
4690   vam->result_ready = 1;
4691 }
4692
4693 static void
4694   vl_api_show_one_nsh_mapping_reply_t_handler_json
4695   (vl_api_show_one_nsh_mapping_reply_t * mp)
4696 {
4697   vat_main_t *vam = &vat_main;
4698   vat_json_node_t node;
4699   u8 *status = 0;
4700
4701   status = format (0, "%s", mp->is_set ? "yes" : "no");
4702   vec_add1 (status, 0);
4703
4704   vat_json_init_object (&node);
4705   vat_json_object_add_string_copy (&node, "is_set", status);
4706   if (mp->is_set)
4707     {
4708       vat_json_object_add_string_copy (&node, "locator_set",
4709                                        mp->locator_set_name);
4710     }
4711
4712   vec_free (status);
4713
4714   vat_json_print (vam->ofp, &node);
4715   vat_json_free (&node);
4716
4717   vam->retval = ntohl (mp->retval);
4718   vam->result_ready = 1;
4719 }
4720
4721 static void
4722   vl_api_show_one_map_register_ttl_reply_t_handler
4723   (vl_api_show_one_map_register_ttl_reply_t * mp)
4724 {
4725   vat_main_t *vam = &vat_main;
4726   i32 retval = ntohl (mp->retval);
4727
4728   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4729
4730   if (0 <= retval)
4731     {
4732       print (vam->ofp, "ttl: %u", mp->ttl);
4733     }
4734
4735   vam->retval = retval;
4736   vam->result_ready = 1;
4737 }
4738
4739 static void
4740   vl_api_show_one_map_register_ttl_reply_t_handler_json
4741   (vl_api_show_one_map_register_ttl_reply_t * mp)
4742 {
4743   vat_main_t *vam = &vat_main;
4744   vat_json_node_t node;
4745
4746   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4747   vat_json_init_object (&node);
4748   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4749
4750   vat_json_print (vam->ofp, &node);
4751   vat_json_free (&node);
4752
4753   vam->retval = ntohl (mp->retval);
4754   vam->result_ready = 1;
4755 }
4756
4757 static void
4758 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4759 {
4760   vat_main_t *vam = &vat_main;
4761   i32 retval = ntohl (mp->retval);
4762
4763   if (0 <= retval)
4764     {
4765       print (vam->ofp, "%-20s%-16s",
4766              mp->status ? "enabled" : "disabled",
4767              mp->status ? (char *) mp->locator_set_name : "");
4768     }
4769
4770   vam->retval = retval;
4771   vam->result_ready = 1;
4772 }
4773
4774 static void
4775 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   vat_json_node_t node;
4779   u8 *status = 0;
4780
4781   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4782   vec_add1 (status, 0);
4783
4784   vat_json_init_object (&node);
4785   vat_json_object_add_string_copy (&node, "status", status);
4786   if (mp->status)
4787     {
4788       vat_json_object_add_string_copy (&node, "locator_set",
4789                                        mp->locator_set_name);
4790     }
4791
4792   vec_free (status);
4793
4794   vat_json_print (vam->ofp, &node);
4795   vat_json_free (&node);
4796
4797   vam->retval = ntohl (mp->retval);
4798   vam->result_ready = 1;
4799 }
4800
4801 static u8 *
4802 format_policer_type (u8 * s, va_list * va)
4803 {
4804   u32 i = va_arg (*va, u32);
4805
4806   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4807     s = format (s, "1r2c");
4808   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4809     s = format (s, "1r3c");
4810   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4811     s = format (s, "2r3c-2698");
4812   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4813     s = format (s, "2r3c-4115");
4814   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4815     s = format (s, "2r3c-mef5cf1");
4816   else
4817     s = format (s, "ILLEGAL");
4818   return s;
4819 }
4820
4821 static u8 *
4822 format_policer_rate_type (u8 * s, va_list * va)
4823 {
4824   u32 i = va_arg (*va, u32);
4825
4826   if (i == SSE2_QOS_RATE_KBPS)
4827     s = format (s, "kbps");
4828   else if (i == SSE2_QOS_RATE_PPS)
4829     s = format (s, "pps");
4830   else
4831     s = format (s, "ILLEGAL");
4832   return s;
4833 }
4834
4835 static u8 *
4836 format_policer_round_type (u8 * s, va_list * va)
4837 {
4838   u32 i = va_arg (*va, u32);
4839
4840   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4841     s = format (s, "closest");
4842   else if (i == SSE2_QOS_ROUND_TO_UP)
4843     s = format (s, "up");
4844   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4845     s = format (s, "down");
4846   else
4847     s = format (s, "ILLEGAL");
4848   return s;
4849 }
4850
4851 static u8 *
4852 format_policer_action_type (u8 * s, va_list * va)
4853 {
4854   u32 i = va_arg (*va, u32);
4855
4856   if (i == SSE2_QOS_ACTION_DROP)
4857     s = format (s, "drop");
4858   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4859     s = format (s, "transmit");
4860   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4861     s = format (s, "mark-and-transmit");
4862   else
4863     s = format (s, "ILLEGAL");
4864   return s;
4865 }
4866
4867 static u8 *
4868 format_dscp (u8 * s, va_list * va)
4869 {
4870   u32 i = va_arg (*va, u32);
4871   char *t = 0;
4872
4873   switch (i)
4874     {
4875 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4876       foreach_vnet_dscp
4877 #undef _
4878     default:
4879       return format (s, "ILLEGAL");
4880     }
4881   s = format (s, "%s", t);
4882   return s;
4883 }
4884
4885 static void
4886 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4887 {
4888   vat_main_t *vam = &vat_main;
4889   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4890
4891   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4892     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4893   else
4894     conform_dscp_str = format (0, "");
4895
4896   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4897     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4898   else
4899     exceed_dscp_str = format (0, "");
4900
4901   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4902     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4903   else
4904     violate_dscp_str = format (0, "");
4905
4906   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4907          "rate type %U, round type %U, %s rate, %s color-aware, "
4908          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4909          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4910          "conform action %U%s, exceed action %U%s, violate action %U%s",
4911          mp->name,
4912          format_policer_type, mp->type,
4913          ntohl (mp->cir),
4914          ntohl (mp->eir),
4915          clib_net_to_host_u64 (mp->cb),
4916          clib_net_to_host_u64 (mp->eb),
4917          format_policer_rate_type, mp->rate_type,
4918          format_policer_round_type, mp->round_type,
4919          mp->single_rate ? "single" : "dual",
4920          mp->color_aware ? "is" : "not",
4921          ntohl (mp->cir_tokens_per_period),
4922          ntohl (mp->pir_tokens_per_period),
4923          ntohl (mp->scale),
4924          ntohl (mp->current_limit),
4925          ntohl (mp->current_bucket),
4926          ntohl (mp->extended_limit),
4927          ntohl (mp->extended_bucket),
4928          clib_net_to_host_u64 (mp->last_update_time),
4929          format_policer_action_type, mp->conform_action_type,
4930          conform_dscp_str,
4931          format_policer_action_type, mp->exceed_action_type,
4932          exceed_dscp_str,
4933          format_policer_action_type, mp->violate_action_type,
4934          violate_dscp_str);
4935
4936   vec_free (conform_dscp_str);
4937   vec_free (exceed_dscp_str);
4938   vec_free (violate_dscp_str);
4939 }
4940
4941 static void vl_api_policer_details_t_handler_json
4942   (vl_api_policer_details_t * mp)
4943 {
4944   vat_main_t *vam = &vat_main;
4945   vat_json_node_t *node;
4946   u8 *rate_type_str, *round_type_str, *type_str;
4947   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4948
4949   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4950   round_type_str =
4951     format (0, "%U", format_policer_round_type, mp->round_type);
4952   type_str = format (0, "%U", format_policer_type, mp->type);
4953   conform_action_str = format (0, "%U", format_policer_action_type,
4954                                mp->conform_action_type);
4955   exceed_action_str = format (0, "%U", format_policer_action_type,
4956                               mp->exceed_action_type);
4957   violate_action_str = format (0, "%U", format_policer_action_type,
4958                                mp->violate_action_type);
4959
4960   if (VAT_JSON_ARRAY != vam->json_tree.type)
4961     {
4962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4963       vat_json_init_array (&vam->json_tree);
4964     }
4965   node = vat_json_array_add (&vam->json_tree);
4966
4967   vat_json_init_object (node);
4968   vat_json_object_add_string_copy (node, "name", mp->name);
4969   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4970   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4971   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4972   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4973   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4974   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4975   vat_json_object_add_string_copy (node, "type", type_str);
4976   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4977   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4978   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4979   vat_json_object_add_uint (node, "cir_tokens_per_period",
4980                             ntohl (mp->cir_tokens_per_period));
4981   vat_json_object_add_uint (node, "eir_tokens_per_period",
4982                             ntohl (mp->pir_tokens_per_period));
4983   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4984   vat_json_object_add_uint (node, "current_bucket",
4985                             ntohl (mp->current_bucket));
4986   vat_json_object_add_uint (node, "extended_limit",
4987                             ntohl (mp->extended_limit));
4988   vat_json_object_add_uint (node, "extended_bucket",
4989                             ntohl (mp->extended_bucket));
4990   vat_json_object_add_uint (node, "last_update_time",
4991                             ntohl (mp->last_update_time));
4992   vat_json_object_add_string_copy (node, "conform_action",
4993                                    conform_action_str);
4994   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4995     {
4996       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4997       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4998       vec_free (dscp_str);
4999     }
5000   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5001   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5002     {
5003       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5004       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5005       vec_free (dscp_str);
5006     }
5007   vat_json_object_add_string_copy (node, "violate_action",
5008                                    violate_action_str);
5009   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5010     {
5011       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5012       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5013       vec_free (dscp_str);
5014     }
5015
5016   vec_free (rate_type_str);
5017   vec_free (round_type_str);
5018   vec_free (type_str);
5019   vec_free (conform_action_str);
5020   vec_free (exceed_action_str);
5021   vec_free (violate_action_str);
5022 }
5023
5024 static void
5025 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5026                                            mp)
5027 {
5028   vat_main_t *vam = &vat_main;
5029   int i, count = ntohl (mp->count);
5030
5031   if (count > 0)
5032     print (vam->ofp, "classify table ids (%d) : ", count);
5033   for (i = 0; i < count; i++)
5034     {
5035       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5036       print (vam->ofp, (i < count - 1) ? "," : "");
5037     }
5038   vam->retval = ntohl (mp->retval);
5039   vam->result_ready = 1;
5040 }
5041
5042 static void
5043   vl_api_classify_table_ids_reply_t_handler_json
5044   (vl_api_classify_table_ids_reply_t * mp)
5045 {
5046   vat_main_t *vam = &vat_main;
5047   int i, count = ntohl (mp->count);
5048
5049   if (count > 0)
5050     {
5051       vat_json_node_t node;
5052
5053       vat_json_init_object (&node);
5054       for (i = 0; i < count; i++)
5055         {
5056           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5057         }
5058       vat_json_print (vam->ofp, &node);
5059       vat_json_free (&node);
5060     }
5061   vam->retval = ntohl (mp->retval);
5062   vam->result_ready = 1;
5063 }
5064
5065 static void
5066   vl_api_classify_table_by_interface_reply_t_handler
5067   (vl_api_classify_table_by_interface_reply_t * mp)
5068 {
5069   vat_main_t *vam = &vat_main;
5070   u32 table_id;
5071
5072   table_id = ntohl (mp->l2_table_id);
5073   if (table_id != ~0)
5074     print (vam->ofp, "l2 table id : %d", table_id);
5075   else
5076     print (vam->ofp, "l2 table id : No input ACL tables configured");
5077   table_id = ntohl (mp->ip4_table_id);
5078   if (table_id != ~0)
5079     print (vam->ofp, "ip4 table id : %d", table_id);
5080   else
5081     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5082   table_id = ntohl (mp->ip6_table_id);
5083   if (table_id != ~0)
5084     print (vam->ofp, "ip6 table id : %d", table_id);
5085   else
5086     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5087   vam->retval = ntohl (mp->retval);
5088   vam->result_ready = 1;
5089 }
5090
5091 static void
5092   vl_api_classify_table_by_interface_reply_t_handler_json
5093   (vl_api_classify_table_by_interface_reply_t * mp)
5094 {
5095   vat_main_t *vam = &vat_main;
5096   vat_json_node_t node;
5097
5098   vat_json_init_object (&node);
5099
5100   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5101   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5102   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5103
5104   vat_json_print (vam->ofp, &node);
5105   vat_json_free (&node);
5106
5107   vam->retval = ntohl (mp->retval);
5108   vam->result_ready = 1;
5109 }
5110
5111 static void vl_api_policer_add_del_reply_t_handler
5112   (vl_api_policer_add_del_reply_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   i32 retval = ntohl (mp->retval);
5116   if (vam->async_mode)
5117     {
5118       vam->async_errors += (retval < 0);
5119     }
5120   else
5121     {
5122       vam->retval = retval;
5123       vam->result_ready = 1;
5124       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5125         /*
5126          * Note: this is just barely thread-safe, depends on
5127          * the main thread spinning waiting for an answer...
5128          */
5129         errmsg ("policer index %d", ntohl (mp->policer_index));
5130     }
5131 }
5132
5133 static void vl_api_policer_add_del_reply_t_handler_json
5134   (vl_api_policer_add_del_reply_t * mp)
5135 {
5136   vat_main_t *vam = &vat_main;
5137   vat_json_node_t node;
5138
5139   vat_json_init_object (&node);
5140   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5141   vat_json_object_add_uint (&node, "policer_index",
5142                             ntohl (mp->policer_index));
5143
5144   vat_json_print (vam->ofp, &node);
5145   vat_json_free (&node);
5146
5147   vam->retval = ntohl (mp->retval);
5148   vam->result_ready = 1;
5149 }
5150
5151 /* Format hex dump. */
5152 u8 *
5153 format_hex_bytes (u8 * s, va_list * va)
5154 {
5155   u8 *bytes = va_arg (*va, u8 *);
5156   int n_bytes = va_arg (*va, int);
5157   uword i;
5158
5159   /* Print short or long form depending on byte count. */
5160   uword short_form = n_bytes <= 32;
5161   u32 indent = format_get_indent (s);
5162
5163   if (n_bytes == 0)
5164     return s;
5165
5166   for (i = 0; i < n_bytes; i++)
5167     {
5168       if (!short_form && (i % 32) == 0)
5169         s = format (s, "%08x: ", i);
5170       s = format (s, "%02x", bytes[i]);
5171       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5172         s = format (s, "\n%U", format_white_space, indent);
5173     }
5174
5175   return s;
5176 }
5177
5178 static void
5179 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5180                                             * mp)
5181 {
5182   vat_main_t *vam = &vat_main;
5183   i32 retval = ntohl (mp->retval);
5184   if (retval == 0)
5185     {
5186       print (vam->ofp, "classify table info :");
5187       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5188              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5189              ntohl (mp->miss_next_index));
5190       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5191              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5192              ntohl (mp->match_n_vectors));
5193       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5194              ntohl (mp->mask_length));
5195     }
5196   vam->retval = retval;
5197   vam->result_ready = 1;
5198 }
5199
5200 static void
5201   vl_api_classify_table_info_reply_t_handler_json
5202   (vl_api_classify_table_info_reply_t * mp)
5203 {
5204   vat_main_t *vam = &vat_main;
5205   vat_json_node_t node;
5206
5207   i32 retval = ntohl (mp->retval);
5208   if (retval == 0)
5209     {
5210       vat_json_init_object (&node);
5211
5212       vat_json_object_add_int (&node, "sessions",
5213                                ntohl (mp->active_sessions));
5214       vat_json_object_add_int (&node, "nexttbl",
5215                                ntohl (mp->next_table_index));
5216       vat_json_object_add_int (&node, "nextnode",
5217                                ntohl (mp->miss_next_index));
5218       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5219       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5220       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5221       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5222                       ntohl (mp->mask_length), 0);
5223       vat_json_object_add_string_copy (&node, "mask", s);
5224
5225       vat_json_print (vam->ofp, &node);
5226       vat_json_free (&node);
5227     }
5228   vam->retval = ntohl (mp->retval);
5229   vam->result_ready = 1;
5230 }
5231
5232 static void
5233 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5234                                            mp)
5235 {
5236   vat_main_t *vam = &vat_main;
5237
5238   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5239          ntohl (mp->hit_next_index), ntohl (mp->advance),
5240          ntohl (mp->opaque_index));
5241   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5242          ntohl (mp->match_length));
5243 }
5244
5245 static void
5246   vl_api_classify_session_details_t_handler_json
5247   (vl_api_classify_session_details_t * mp)
5248 {
5249   vat_main_t *vam = &vat_main;
5250   vat_json_node_t *node = NULL;
5251
5252   if (VAT_JSON_ARRAY != vam->json_tree.type)
5253     {
5254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5255       vat_json_init_array (&vam->json_tree);
5256     }
5257   node = vat_json_array_add (&vam->json_tree);
5258
5259   vat_json_init_object (node);
5260   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5261   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5262   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5263   u8 *s =
5264     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5265             0);
5266   vat_json_object_add_string_copy (node, "match", s);
5267 }
5268
5269 static void vl_api_pg_create_interface_reply_t_handler
5270   (vl_api_pg_create_interface_reply_t * mp)
5271 {
5272   vat_main_t *vam = &vat_main;
5273
5274   vam->retval = ntohl (mp->retval);
5275   vam->result_ready = 1;
5276 }
5277
5278 static void vl_api_pg_create_interface_reply_t_handler_json
5279   (vl_api_pg_create_interface_reply_t * mp)
5280 {
5281   vat_main_t *vam = &vat_main;
5282   vat_json_node_t node;
5283
5284   i32 retval = ntohl (mp->retval);
5285   if (retval == 0)
5286     {
5287       vat_json_init_object (&node);
5288
5289       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5290
5291       vat_json_print (vam->ofp, &node);
5292       vat_json_free (&node);
5293     }
5294   vam->retval = ntohl (mp->retval);
5295   vam->result_ready = 1;
5296 }
5297
5298 static void vl_api_policer_classify_details_t_handler
5299   (vl_api_policer_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302
5303   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5304          ntohl (mp->table_index));
5305 }
5306
5307 static void vl_api_policer_classify_details_t_handler_json
5308   (vl_api_policer_classify_details_t * mp)
5309 {
5310   vat_main_t *vam = &vat_main;
5311   vat_json_node_t *node;
5312
5313   if (VAT_JSON_ARRAY != vam->json_tree.type)
5314     {
5315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5316       vat_json_init_array (&vam->json_tree);
5317     }
5318   node = vat_json_array_add (&vam->json_tree);
5319
5320   vat_json_init_object (node);
5321   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5322   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5323 }
5324
5325 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5326   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5327 {
5328   vat_main_t *vam = &vat_main;
5329   i32 retval = ntohl (mp->retval);
5330   if (vam->async_mode)
5331     {
5332       vam->async_errors += (retval < 0);
5333     }
5334   else
5335     {
5336       vam->retval = retval;
5337       vam->sw_if_index = ntohl (mp->sw_if_index);
5338       vam->result_ready = 1;
5339     }
5340   vam->regenerate_interface_table = 1;
5341 }
5342
5343 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5344   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5345 {
5346   vat_main_t *vam = &vat_main;
5347   vat_json_node_t node;
5348
5349   vat_json_init_object (&node);
5350   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5351   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5352
5353   vat_json_print (vam->ofp, &node);
5354   vat_json_free (&node);
5355
5356   vam->retval = ntohl (mp->retval);
5357   vam->result_ready = 1;
5358 }
5359
5360 static void vl_api_flow_classify_details_t_handler
5361   (vl_api_flow_classify_details_t * mp)
5362 {
5363   vat_main_t *vam = &vat_main;
5364
5365   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5366          ntohl (mp->table_index));
5367 }
5368
5369 static void vl_api_flow_classify_details_t_handler_json
5370   (vl_api_flow_classify_details_t * mp)
5371 {
5372   vat_main_t *vam = &vat_main;
5373   vat_json_node_t *node;
5374
5375   if (VAT_JSON_ARRAY != vam->json_tree.type)
5376     {
5377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5378       vat_json_init_array (&vam->json_tree);
5379     }
5380   node = vat_json_array_add (&vam->json_tree);
5381
5382   vat_json_init_object (node);
5383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5384   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5385 }
5386
5387 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5388 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5389 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5390 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5391 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5392 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5393 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5394 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5395 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5396 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5397 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5398 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5399 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5400 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5401 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5402 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5403 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5404 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5405 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5406 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5407 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5408 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5409
5410 /*
5411  * Generate boilerplate reply handlers, which
5412  * dig the return value out of the xxx_reply_t API message,
5413  * stick it into vam->retval, and set vam->result_ready
5414  *
5415  * Could also do this by pointing N message decode slots at
5416  * a single function, but that could break in subtle ways.
5417  */
5418
5419 #define foreach_standard_reply_retval_handler           \
5420 _(sw_interface_set_flags_reply)                         \
5421 _(sw_interface_add_del_address_reply)                   \
5422 _(sw_interface_set_rx_mode_reply)                       \
5423 _(sw_interface_set_rx_placement_reply)                  \
5424 _(sw_interface_set_table_reply)                         \
5425 _(sw_interface_set_mpls_enable_reply)                   \
5426 _(sw_interface_set_vpath_reply)                         \
5427 _(sw_interface_set_vxlan_bypass_reply)                  \
5428 _(sw_interface_set_geneve_bypass_reply)                 \
5429 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5430 _(sw_interface_set_l2_bridge_reply)                     \
5431 _(bridge_domain_add_del_reply)                          \
5432 _(sw_interface_set_l2_xconnect_reply)                   \
5433 _(l2fib_add_del_reply)                                  \
5434 _(l2fib_flush_int_reply)                                \
5435 _(l2fib_flush_bd_reply)                                 \
5436 _(ip_add_del_route_reply)                               \
5437 _(ip_table_add_del_reply)                               \
5438 _(ip_mroute_add_del_reply)                              \
5439 _(mpls_route_add_del_reply)                             \
5440 _(mpls_table_add_del_reply)                             \
5441 _(mpls_ip_bind_unbind_reply)                            \
5442 _(bier_route_add_del_reply)                             \
5443 _(bier_table_add_del_reply)                             \
5444 _(proxy_arp_add_del_reply)                              \
5445 _(proxy_arp_intfc_enable_disable_reply)                 \
5446 _(sw_interface_set_unnumbered_reply)                    \
5447 _(ip_neighbor_add_del_reply)                            \
5448 _(oam_add_del_reply)                                    \
5449 _(reset_fib_reply)                                      \
5450 _(dhcp_proxy_config_reply)                              \
5451 _(dhcp_proxy_set_vss_reply)                             \
5452 _(dhcp_client_config_reply)                             \
5453 _(set_ip_flow_hash_reply)                               \
5454 _(sw_interface_ip6_enable_disable_reply)                \
5455 _(sw_interface_ip6_set_link_local_address_reply)        \
5456 _(ip6nd_proxy_add_del_reply)                            \
5457 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5458 _(sw_interface_ip6nd_ra_config_reply)                   \
5459 _(set_arp_neighbor_limit_reply)                         \
5460 _(l2_patch_add_del_reply)                               \
5461 _(sr_mpls_policy_add_reply)                             \
5462 _(sr_mpls_policy_mod_reply)                             \
5463 _(sr_mpls_policy_del_reply)                             \
5464 _(sr_policy_add_reply)                                  \
5465 _(sr_policy_mod_reply)                                  \
5466 _(sr_policy_del_reply)                                  \
5467 _(sr_localsid_add_del_reply)                            \
5468 _(sr_steering_add_del_reply)                            \
5469 _(classify_add_del_session_reply)                       \
5470 _(classify_set_interface_ip_table_reply)                \
5471 _(classify_set_interface_l2_tables_reply)               \
5472 _(l2tpv3_set_tunnel_cookies_reply)                      \
5473 _(l2tpv3_interface_enable_disable_reply)                \
5474 _(l2tpv3_set_lookup_key_reply)                          \
5475 _(l2_fib_clear_table_reply)                             \
5476 _(l2_interface_efp_filter_reply)                        \
5477 _(l2_interface_vlan_tag_rewrite_reply)                  \
5478 _(modify_vhost_user_if_reply)                           \
5479 _(delete_vhost_user_if_reply)                           \
5480 _(ip_probe_neighbor_reply)                              \
5481 _(ip_scan_neighbor_enable_disable_reply)                \
5482 _(want_ip4_arp_events_reply)                            \
5483 _(want_ip6_nd_events_reply)                             \
5484 _(want_l2_macs_events_reply)                            \
5485 _(input_acl_set_interface_reply)                        \
5486 _(ipsec_spd_add_del_reply)                              \
5487 _(ipsec_interface_add_del_spd_reply)                    \
5488 _(ipsec_spd_add_del_entry_reply)                        \
5489 _(ipsec_sad_add_del_entry_reply)                        \
5490 _(ipsec_sa_set_key_reply)                               \
5491 _(ipsec_tunnel_if_add_del_reply)                        \
5492 _(ipsec_tunnel_if_set_key_reply)                        \
5493 _(ipsec_tunnel_if_set_sa_reply)                         \
5494 _(ikev2_profile_add_del_reply)                          \
5495 _(ikev2_profile_set_auth_reply)                         \
5496 _(ikev2_profile_set_id_reply)                           \
5497 _(ikev2_profile_set_ts_reply)                           \
5498 _(ikev2_set_local_key_reply)                            \
5499 _(ikev2_set_responder_reply)                            \
5500 _(ikev2_set_ike_transforms_reply)                       \
5501 _(ikev2_set_esp_transforms_reply)                       \
5502 _(ikev2_set_sa_lifetime_reply)                          \
5503 _(ikev2_initiate_sa_init_reply)                         \
5504 _(ikev2_initiate_del_ike_sa_reply)                      \
5505 _(ikev2_initiate_del_child_sa_reply)                    \
5506 _(ikev2_initiate_rekey_child_sa_reply)                  \
5507 _(delete_loopback_reply)                                \
5508 _(bd_ip_mac_add_del_reply)                              \
5509 _(want_interface_events_reply)                          \
5510 _(want_stats_reply)                                     \
5511 _(cop_interface_enable_disable_reply)                   \
5512 _(cop_whitelist_enable_disable_reply)                   \
5513 _(sw_interface_clear_stats_reply)                       \
5514 _(ioam_enable_reply)                                    \
5515 _(ioam_disable_reply)                                   \
5516 _(one_add_del_locator_reply)                            \
5517 _(one_add_del_local_eid_reply)                          \
5518 _(one_add_del_remote_mapping_reply)                     \
5519 _(one_add_del_adjacency_reply)                          \
5520 _(one_add_del_map_resolver_reply)                       \
5521 _(one_add_del_map_server_reply)                         \
5522 _(one_enable_disable_reply)                             \
5523 _(one_rloc_probe_enable_disable_reply)                  \
5524 _(one_map_register_enable_disable_reply)                \
5525 _(one_map_register_set_ttl_reply)                       \
5526 _(one_set_transport_protocol_reply)                     \
5527 _(one_map_register_fallback_threshold_reply)            \
5528 _(one_pitr_set_locator_set_reply)                       \
5529 _(one_map_request_mode_reply)                           \
5530 _(one_add_del_map_request_itr_rlocs_reply)              \
5531 _(one_eid_table_add_del_map_reply)                      \
5532 _(one_use_petr_reply)                                   \
5533 _(one_stats_enable_disable_reply)                       \
5534 _(one_add_del_l2_arp_entry_reply)                       \
5535 _(one_add_del_ndp_entry_reply)                          \
5536 _(one_stats_flush_reply)                                \
5537 _(one_enable_disable_xtr_mode_reply)                    \
5538 _(one_enable_disable_pitr_mode_reply)                   \
5539 _(one_enable_disable_petr_mode_reply)                   \
5540 _(gpe_enable_disable_reply)                             \
5541 _(gpe_set_encap_mode_reply)                             \
5542 _(gpe_add_del_iface_reply)                              \
5543 _(gpe_add_del_native_fwd_rpath_reply)                   \
5544 _(af_packet_delete_reply)                               \
5545 _(policer_classify_set_interface_reply)                 \
5546 _(netmap_create_reply)                                  \
5547 _(netmap_delete_reply)                                  \
5548 _(set_ipfix_exporter_reply)                             \
5549 _(set_ipfix_classify_stream_reply)                      \
5550 _(ipfix_classify_table_add_del_reply)                   \
5551 _(flow_classify_set_interface_reply)                    \
5552 _(sw_interface_span_enable_disable_reply)               \
5553 _(pg_capture_reply)                                     \
5554 _(pg_enable_disable_reply)                              \
5555 _(ip_source_and_port_range_check_add_del_reply)         \
5556 _(ip_source_and_port_range_check_interface_add_del_reply)\
5557 _(delete_subif_reply)                                   \
5558 _(l2_interface_pbb_tag_rewrite_reply)                   \
5559 _(punt_reply)                                           \
5560 _(feature_enable_disable_reply)                         \
5561 _(sw_interface_tag_add_del_reply)                       \
5562 _(hw_interface_set_mtu_reply)                           \
5563 _(p2p_ethernet_add_reply)                               \
5564 _(p2p_ethernet_del_reply)                               \
5565 _(lldp_config_reply)                                    \
5566 _(sw_interface_set_lldp_reply)                          \
5567 _(tcp_configure_src_addresses_reply)                    \
5568 _(dns_enable_disable_reply)                             \
5569 _(dns_name_server_add_del_reply)                        \
5570 _(session_rule_add_del_reply)                           \
5571 _(ip_container_proxy_add_del_reply)                     \
5572 _(output_acl_set_interface_reply)                       \
5573 _(qos_record_enable_disable_reply)
5574
5575 #define _(n)                                    \
5576     static void vl_api_##n##_t_handler          \
5577     (vl_api_##n##_t * mp)                       \
5578     {                                           \
5579         vat_main_t * vam = &vat_main;           \
5580         i32 retval = ntohl(mp->retval);         \
5581         if (vam->async_mode) {                  \
5582             vam->async_errors += (retval < 0);  \
5583         } else {                                \
5584             vam->retval = retval;               \
5585             vam->result_ready = 1;              \
5586         }                                       \
5587     }
5588 foreach_standard_reply_retval_handler;
5589 #undef _
5590
5591 #define _(n)                                    \
5592     static void vl_api_##n##_t_handler_json     \
5593     (vl_api_##n##_t * mp)                       \
5594     {                                           \
5595         vat_main_t * vam = &vat_main;           \
5596         vat_json_node_t node;                   \
5597         vat_json_init_object(&node);            \
5598         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5599         vat_json_print(vam->ofp, &node);        \
5600         vam->retval = ntohl(mp->retval);        \
5601         vam->result_ready = 1;                  \
5602     }
5603 foreach_standard_reply_retval_handler;
5604 #undef _
5605
5606 /*
5607  * Table of message reply handlers, must include boilerplate handlers
5608  * we just generated
5609  */
5610
5611 #define foreach_vpe_api_reply_msg                                       \
5612 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5613 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5614 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5615 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5616 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5617 _(CLI_REPLY, cli_reply)                                                 \
5618 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5619 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5620   sw_interface_add_del_address_reply)                                   \
5621 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5622 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5623 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5624 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5625 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5626 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5627 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5628 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5629 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5630 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5631   sw_interface_set_l2_xconnect_reply)                                   \
5632 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5633   sw_interface_set_l2_bridge_reply)                                     \
5634 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5635 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5636 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5637 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5638 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5639 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5640 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5641 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5642 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5643 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5644 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5645 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5646 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5647 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5648 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5649 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5650 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5651 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5652 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5653 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5654 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5655 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5656 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5657 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5658 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5659 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5660 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5661 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5662 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5663 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5664 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5665   proxy_arp_intfc_enable_disable_reply)                                 \
5666 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5667 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5668   sw_interface_set_unnumbered_reply)                                    \
5669 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5670 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5671 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5672 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5673 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5674 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5675 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5676 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5677 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5678 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5679 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5680   sw_interface_ip6_enable_disable_reply)                                \
5681 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5682   sw_interface_ip6_set_link_local_address_reply)                        \
5683 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5684 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5685 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5686   sw_interface_ip6nd_ra_prefix_reply)                                   \
5687 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5688   sw_interface_ip6nd_ra_config_reply)                                   \
5689 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5690 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5691 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5692 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5693 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5694 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5695 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5696 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5697 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5698 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5699 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5700 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5701 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5702 classify_set_interface_ip_table_reply)                                  \
5703 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5704   classify_set_interface_l2_tables_reply)                               \
5705 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5706 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5707 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5708 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5709 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5710   l2tpv3_interface_enable_disable_reply)                                \
5711 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5712 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5713 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5714 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5715 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5716 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5717 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5718 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5719 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5720 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5721 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5722 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5723 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5724 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5725 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5726 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5727 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5728 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5729 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5730 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5731 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5732 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5733 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5734 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5735 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5736 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5737 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5738 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5739 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5740 _(L2_MACS_EVENT, l2_macs_event)                                         \
5741 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5742 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5743 _(IP_DETAILS, ip_details)                                               \
5744 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5745 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5746 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5747 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5748 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5749 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5750 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5751 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5752 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5753 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5754 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5755 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5756 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5757 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5758 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5759 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5760 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5761 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5762 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5763 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5764 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5765 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5766 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5767 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5768 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5769 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5770 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5771 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5772 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5773 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5774 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5775 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5776 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5777 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5778 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5779 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5780 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5781 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5782 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5783 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5784 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5785 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5786 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5787 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5788   one_map_register_enable_disable_reply)                                \
5789 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5790 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5791 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5792 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5793   one_map_register_fallback_threshold_reply)                            \
5794 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5795   one_rloc_probe_enable_disable_reply)                                  \
5796 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5797 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5798 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5799 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5800 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5801 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5802 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5803 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5804 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5805 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5806 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5807 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5808 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5809 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5810 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5811 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5812   show_one_stats_enable_disable_reply)                                  \
5813 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5814 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5815 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5816 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5817 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5818 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5819 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5820 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5821   one_enable_disable_pitr_mode_reply)                                   \
5822 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5823   one_enable_disable_petr_mode_reply)                                   \
5824 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5825 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5826 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5827 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5828 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5829 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5830 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5831 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5832 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5833 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5834 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5835 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5836   gpe_add_del_native_fwd_rpath_reply)                                   \
5837 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5838   gpe_fwd_entry_path_details)                                           \
5839 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5840 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5841   one_add_del_map_request_itr_rlocs_reply)                              \
5842 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5843   one_get_map_request_itr_rlocs_reply)                                  \
5844 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5845 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5846 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5847 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5848 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5849 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5850   show_one_map_register_state_reply)                                    \
5851 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5852 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5853   show_one_map_register_fallback_threshold_reply)                       \
5854 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5855 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5856 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5857 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5858 _(POLICER_DETAILS, policer_details)                                     \
5859 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5860 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5861 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5862 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5863 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5864 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5865 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5866 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5867 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5868 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5869 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5870 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5871 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5872 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5873 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5874 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5875 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5876 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5877 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5878 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5879 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5880 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5881 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5882 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5883 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5884  ip_source_and_port_range_check_add_del_reply)                          \
5885 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5886  ip_source_and_port_range_check_interface_add_del_reply)                \
5887 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5888 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5889 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5890 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5891 _(PUNT_REPLY, punt_reply)                                               \
5892 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5893 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5894 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5895 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5896 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5897 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5898 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5899 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5900 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5901 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5902 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5903 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5904 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5905 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5906 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5907 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5908 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5909 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5910 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5911 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5912 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5913 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5914 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5915
5916 #define foreach_standalone_reply_msg                                    \
5917 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5918 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5919 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5920 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5921 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5922 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5923 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5924
5925 typedef struct
5926 {
5927   u8 *name;
5928   u32 value;
5929 } name_sort_t;
5930
5931 #define STR_VTR_OP_CASE(op)     \
5932     case L2_VTR_ ## op:         \
5933         return "" # op;
5934
5935 static const char *
5936 str_vtr_op (u32 vtr_op)
5937 {
5938   switch (vtr_op)
5939     {
5940       STR_VTR_OP_CASE (DISABLED);
5941       STR_VTR_OP_CASE (PUSH_1);
5942       STR_VTR_OP_CASE (PUSH_2);
5943       STR_VTR_OP_CASE (POP_1);
5944       STR_VTR_OP_CASE (POP_2);
5945       STR_VTR_OP_CASE (TRANSLATE_1_1);
5946       STR_VTR_OP_CASE (TRANSLATE_1_2);
5947       STR_VTR_OP_CASE (TRANSLATE_2_1);
5948       STR_VTR_OP_CASE (TRANSLATE_2_2);
5949     }
5950
5951   return "UNKNOWN";
5952 }
5953
5954 static int
5955 dump_sub_interface_table (vat_main_t * vam)
5956 {
5957   const sw_interface_subif_t *sub = NULL;
5958
5959   if (vam->json_output)
5960     {
5961       clib_warning
5962         ("JSON output supported only for VPE API calls and dump_stats_table");
5963       return -99;
5964     }
5965
5966   print (vam->ofp,
5967          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5968          "Interface", "sw_if_index",
5969          "sub id", "dot1ad", "tags", "outer id",
5970          "inner id", "exact", "default", "outer any", "inner any");
5971
5972   vec_foreach (sub, vam->sw_if_subif_table)
5973   {
5974     print (vam->ofp,
5975            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5976            sub->interface_name,
5977            sub->sw_if_index,
5978            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5979            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5980            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5981            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5982     if (sub->vtr_op != L2_VTR_DISABLED)
5983       {
5984         print (vam->ofp,
5985                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5986                "tag1: %d tag2: %d ]",
5987                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5988                sub->vtr_tag1, sub->vtr_tag2);
5989       }
5990   }
5991
5992   return 0;
5993 }
5994
5995 static int
5996 name_sort_cmp (void *a1, void *a2)
5997 {
5998   name_sort_t *n1 = a1;
5999   name_sort_t *n2 = a2;
6000
6001   return strcmp ((char *) n1->name, (char *) n2->name);
6002 }
6003
6004 static int
6005 dump_interface_table (vat_main_t * vam)
6006 {
6007   hash_pair_t *p;
6008   name_sort_t *nses = 0, *ns;
6009
6010   if (vam->json_output)
6011     {
6012       clib_warning
6013         ("JSON output supported only for VPE API calls and dump_stats_table");
6014       return -99;
6015     }
6016
6017   /* *INDENT-OFF* */
6018   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6019   ({
6020     vec_add2 (nses, ns, 1);
6021     ns->name = (u8 *)(p->key);
6022     ns->value = (u32) p->value[0];
6023   }));
6024   /* *INDENT-ON* */
6025
6026   vec_sort_with_function (nses, name_sort_cmp);
6027
6028   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6029   vec_foreach (ns, nses)
6030   {
6031     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6032   }
6033   vec_free (nses);
6034   return 0;
6035 }
6036
6037 static int
6038 dump_ip_table (vat_main_t * vam, int is_ipv6)
6039 {
6040   const ip_details_t *det = NULL;
6041   const ip_address_details_t *address = NULL;
6042   u32 i = ~0;
6043
6044   print (vam->ofp, "%-12s", "sw_if_index");
6045
6046   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6047   {
6048     i++;
6049     if (!det->present)
6050       {
6051         continue;
6052       }
6053     print (vam->ofp, "%-12d", i);
6054     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6055     if (!det->addr)
6056       {
6057         continue;
6058       }
6059     vec_foreach (address, det->addr)
6060     {
6061       print (vam->ofp,
6062              "            %-30U%-13d",
6063              is_ipv6 ? format_ip6_address : format_ip4_address,
6064              address->ip, address->prefix_length);
6065     }
6066   }
6067
6068   return 0;
6069 }
6070
6071 static int
6072 dump_ipv4_table (vat_main_t * vam)
6073 {
6074   if (vam->json_output)
6075     {
6076       clib_warning
6077         ("JSON output supported only for VPE API calls and dump_stats_table");
6078       return -99;
6079     }
6080
6081   return dump_ip_table (vam, 0);
6082 }
6083
6084 static int
6085 dump_ipv6_table (vat_main_t * vam)
6086 {
6087   if (vam->json_output)
6088     {
6089       clib_warning
6090         ("JSON output supported only for VPE API calls and dump_stats_table");
6091       return -99;
6092     }
6093
6094   return dump_ip_table (vam, 1);
6095 }
6096
6097 static char *
6098 counter_type_to_str (u8 counter_type, u8 is_combined)
6099 {
6100   if (!is_combined)
6101     {
6102       switch (counter_type)
6103         {
6104         case VNET_INTERFACE_COUNTER_DROP:
6105           return "drop";
6106         case VNET_INTERFACE_COUNTER_PUNT:
6107           return "punt";
6108         case VNET_INTERFACE_COUNTER_IP4:
6109           return "ip4";
6110         case VNET_INTERFACE_COUNTER_IP6:
6111           return "ip6";
6112         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6113           return "rx-no-buf";
6114         case VNET_INTERFACE_COUNTER_RX_MISS:
6115           return "rx-miss";
6116         case VNET_INTERFACE_COUNTER_RX_ERROR:
6117           return "rx-error";
6118         case VNET_INTERFACE_COUNTER_TX_ERROR:
6119           return "tx-error";
6120         default:
6121           return "INVALID-COUNTER-TYPE";
6122         }
6123     }
6124   else
6125     {
6126       switch (counter_type)
6127         {
6128         case VNET_INTERFACE_COUNTER_RX:
6129           return "rx";
6130         case VNET_INTERFACE_COUNTER_TX:
6131           return "tx";
6132         default:
6133           return "INVALID-COUNTER-TYPE";
6134         }
6135     }
6136 }
6137
6138 static int
6139 dump_stats_table (vat_main_t * vam)
6140 {
6141   vat_json_node_t node;
6142   vat_json_node_t *msg_array;
6143   vat_json_node_t *msg;
6144   vat_json_node_t *counter_array;
6145   vat_json_node_t *counter;
6146   interface_counter_t c;
6147   u64 packets;
6148   ip4_fib_counter_t *c4;
6149   ip6_fib_counter_t *c6;
6150   ip4_nbr_counter_t *n4;
6151   ip6_nbr_counter_t *n6;
6152   int i, j;
6153
6154   if (!vam->json_output)
6155     {
6156       clib_warning ("dump_stats_table supported only in JSON format");
6157       return -99;
6158     }
6159
6160   vat_json_init_object (&node);
6161
6162   /* interface counters */
6163   msg_array = vat_json_object_add (&node, "interface_counters");
6164   vat_json_init_array (msg_array);
6165   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6166     {
6167       msg = vat_json_array_add (msg_array);
6168       vat_json_init_object (msg);
6169       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6170                                        (u8 *) counter_type_to_str (i, 0));
6171       vat_json_object_add_int (msg, "is_combined", 0);
6172       counter_array = vat_json_object_add (msg, "data");
6173       vat_json_init_array (counter_array);
6174       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6175         {
6176           packets = vam->simple_interface_counters[i][j];
6177           vat_json_array_add_uint (counter_array, packets);
6178         }
6179     }
6180   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6181     {
6182       msg = vat_json_array_add (msg_array);
6183       vat_json_init_object (msg);
6184       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6185                                        (u8 *) counter_type_to_str (i, 1));
6186       vat_json_object_add_int (msg, "is_combined", 1);
6187       counter_array = vat_json_object_add (msg, "data");
6188       vat_json_init_array (counter_array);
6189       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6190         {
6191           c = vam->combined_interface_counters[i][j];
6192           counter = vat_json_array_add (counter_array);
6193           vat_json_init_object (counter);
6194           vat_json_object_add_uint (counter, "packets", c.packets);
6195           vat_json_object_add_uint (counter, "bytes", c.bytes);
6196         }
6197     }
6198
6199   /* ip4 fib counters */
6200   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6201   vat_json_init_array (msg_array);
6202   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6203     {
6204       msg = vat_json_array_add (msg_array);
6205       vat_json_init_object (msg);
6206       vat_json_object_add_uint (msg, "vrf_id",
6207                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6208       counter_array = vat_json_object_add (msg, "c");
6209       vat_json_init_array (counter_array);
6210       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6211         {
6212           counter = vat_json_array_add (counter_array);
6213           vat_json_init_object (counter);
6214           c4 = &vam->ip4_fib_counters[i][j];
6215           vat_json_object_add_ip4 (counter, "address", c4->address);
6216           vat_json_object_add_uint (counter, "address_length",
6217                                     c4->address_length);
6218           vat_json_object_add_uint (counter, "packets", c4->packets);
6219           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6220         }
6221     }
6222
6223   /* ip6 fib counters */
6224   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6225   vat_json_init_array (msg_array);
6226   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6227     {
6228       msg = vat_json_array_add (msg_array);
6229       vat_json_init_object (msg);
6230       vat_json_object_add_uint (msg, "vrf_id",
6231                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6232       counter_array = vat_json_object_add (msg, "c");
6233       vat_json_init_array (counter_array);
6234       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6235         {
6236           counter = vat_json_array_add (counter_array);
6237           vat_json_init_object (counter);
6238           c6 = &vam->ip6_fib_counters[i][j];
6239           vat_json_object_add_ip6 (counter, "address", c6->address);
6240           vat_json_object_add_uint (counter, "address_length",
6241                                     c6->address_length);
6242           vat_json_object_add_uint (counter, "packets", c6->packets);
6243           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6244         }
6245     }
6246
6247   /* ip4 nbr counters */
6248   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6249   vat_json_init_array (msg_array);
6250   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6251     {
6252       msg = vat_json_array_add (msg_array);
6253       vat_json_init_object (msg);
6254       vat_json_object_add_uint (msg, "sw_if_index", i);
6255       counter_array = vat_json_object_add (msg, "c");
6256       vat_json_init_array (counter_array);
6257       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6258         {
6259           counter = vat_json_array_add (counter_array);
6260           vat_json_init_object (counter);
6261           n4 = &vam->ip4_nbr_counters[i][j];
6262           vat_json_object_add_ip4 (counter, "address", n4->address);
6263           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6264           vat_json_object_add_uint (counter, "packets", n4->packets);
6265           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6266         }
6267     }
6268
6269   /* ip6 nbr counters */
6270   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6271   vat_json_init_array (msg_array);
6272   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6273     {
6274       msg = vat_json_array_add (msg_array);
6275       vat_json_init_object (msg);
6276       vat_json_object_add_uint (msg, "sw_if_index", i);
6277       counter_array = vat_json_object_add (msg, "c");
6278       vat_json_init_array (counter_array);
6279       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6280         {
6281           counter = vat_json_array_add (counter_array);
6282           vat_json_init_object (counter);
6283           n6 = &vam->ip6_nbr_counters[i][j];
6284           vat_json_object_add_ip6 (counter, "address", n6->address);
6285           vat_json_object_add_uint (counter, "packets", n6->packets);
6286           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6287         }
6288     }
6289
6290   vat_json_print (vam->ofp, &node);
6291   vat_json_free (&node);
6292
6293   return 0;
6294 }
6295
6296 /*
6297  * Pass CLI buffers directly in the CLI_INBAND API message,
6298  * instead of an additional shared memory area.
6299  */
6300 static int
6301 exec_inband (vat_main_t * vam)
6302 {
6303   vl_api_cli_inband_t *mp;
6304   unformat_input_t *i = vam->input;
6305   int ret;
6306
6307   if (vec_len (i->buffer) == 0)
6308     return -1;
6309
6310   if (vam->exec_mode == 0 && unformat (i, "mode"))
6311     {
6312       vam->exec_mode = 1;
6313       return 0;
6314     }
6315   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6316     {
6317       vam->exec_mode = 0;
6318       return 0;
6319     }
6320
6321   /*
6322    * In order for the CLI command to work, it
6323    * must be a vector ending in \n, not a C-string ending
6324    * in \n\0.
6325    */
6326   u32 len = vec_len (vam->input->buffer);
6327   M2 (CLI_INBAND, mp, len);
6328   clib_memcpy (mp->cmd, vam->input->buffer, len);
6329   mp->length = htonl (len);
6330
6331   S (mp);
6332   W (ret);
6333   /* json responses may or may not include a useful reply... */
6334   if (vec_len (vam->cmd_reply))
6335     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6336   return ret;
6337 }
6338
6339 int
6340 exec (vat_main_t * vam)
6341 {
6342   return exec_inband (vam);
6343 }
6344
6345 static int
6346 api_create_loopback (vat_main_t * vam)
6347 {
6348   unformat_input_t *i = vam->input;
6349   vl_api_create_loopback_t *mp;
6350   vl_api_create_loopback_instance_t *mp_lbi;
6351   u8 mac_address[6];
6352   u8 mac_set = 0;
6353   u8 is_specified = 0;
6354   u32 user_instance = 0;
6355   int ret;
6356
6357   memset (mac_address, 0, sizeof (mac_address));
6358
6359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6360     {
6361       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6362         mac_set = 1;
6363       if (unformat (i, "instance %d", &user_instance))
6364         is_specified = 1;
6365       else
6366         break;
6367     }
6368
6369   if (is_specified)
6370     {
6371       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6372       mp_lbi->is_specified = is_specified;
6373       if (is_specified)
6374         mp_lbi->user_instance = htonl (user_instance);
6375       if (mac_set)
6376         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6377       S (mp_lbi);
6378     }
6379   else
6380     {
6381       /* Construct the API message */
6382       M (CREATE_LOOPBACK, mp);
6383       if (mac_set)
6384         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6385       S (mp);
6386     }
6387
6388   W (ret);
6389   return ret;
6390 }
6391
6392 static int
6393 api_delete_loopback (vat_main_t * vam)
6394 {
6395   unformat_input_t *i = vam->input;
6396   vl_api_delete_loopback_t *mp;
6397   u32 sw_if_index = ~0;
6398   int ret;
6399
6400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6401     {
6402       if (unformat (i, "sw_if_index %d", &sw_if_index))
6403         ;
6404       else
6405         break;
6406     }
6407
6408   if (sw_if_index == ~0)
6409     {
6410       errmsg ("missing sw_if_index");
6411       return -99;
6412     }
6413
6414   /* Construct the API message */
6415   M (DELETE_LOOPBACK, mp);
6416   mp->sw_if_index = ntohl (sw_if_index);
6417
6418   S (mp);
6419   W (ret);
6420   return ret;
6421 }
6422
6423 static int
6424 api_want_stats (vat_main_t * vam)
6425 {
6426   unformat_input_t *i = vam->input;
6427   vl_api_want_stats_t *mp;
6428   int enable = -1;
6429   int ret;
6430
6431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6432     {
6433       if (unformat (i, "enable"))
6434         enable = 1;
6435       else if (unformat (i, "disable"))
6436         enable = 0;
6437       else
6438         break;
6439     }
6440
6441   if (enable == -1)
6442     {
6443       errmsg ("missing enable|disable");
6444       return -99;
6445     }
6446
6447   M (WANT_STATS, mp);
6448   mp->enable_disable = enable;
6449
6450   S (mp);
6451   W (ret);
6452   return ret;
6453 }
6454
6455 static int
6456 api_want_interface_events (vat_main_t * vam)
6457 {
6458   unformat_input_t *i = vam->input;
6459   vl_api_want_interface_events_t *mp;
6460   int enable = -1;
6461   int ret;
6462
6463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6464     {
6465       if (unformat (i, "enable"))
6466         enable = 1;
6467       else if (unformat (i, "disable"))
6468         enable = 0;
6469       else
6470         break;
6471     }
6472
6473   if (enable == -1)
6474     {
6475       errmsg ("missing enable|disable");
6476       return -99;
6477     }
6478
6479   M (WANT_INTERFACE_EVENTS, mp);
6480   mp->enable_disable = enable;
6481
6482   vam->interface_event_display = enable;
6483
6484   S (mp);
6485   W (ret);
6486   return ret;
6487 }
6488
6489
6490 /* Note: non-static, called once to set up the initial intfc table */
6491 int
6492 api_sw_interface_dump (vat_main_t * vam)
6493 {
6494   vl_api_sw_interface_dump_t *mp;
6495   vl_api_control_ping_t *mp_ping;
6496   hash_pair_t *p;
6497   name_sort_t *nses = 0, *ns;
6498   sw_interface_subif_t *sub = NULL;
6499   int ret;
6500
6501   /* Toss the old name table */
6502   /* *INDENT-OFF* */
6503   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6504   ({
6505     vec_add2 (nses, ns, 1);
6506     ns->name = (u8 *)(p->key);
6507     ns->value = (u32) p->value[0];
6508   }));
6509   /* *INDENT-ON* */
6510
6511   hash_free (vam->sw_if_index_by_interface_name);
6512
6513   vec_foreach (ns, nses) vec_free (ns->name);
6514
6515   vec_free (nses);
6516
6517   vec_foreach (sub, vam->sw_if_subif_table)
6518   {
6519     vec_free (sub->interface_name);
6520   }
6521   vec_free (vam->sw_if_subif_table);
6522
6523   /* recreate the interface name hash table */
6524   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6525
6526   /*
6527    * Ask for all interface names. Otherwise, the epic catalog of
6528    * name filters becomes ridiculously long, and vat ends up needing
6529    * to be taught about new interface types.
6530    */
6531   M (SW_INTERFACE_DUMP, mp);
6532   S (mp);
6533
6534   /* Use a control ping for synchronization */
6535   MPING (CONTROL_PING, mp_ping);
6536   S (mp_ping);
6537
6538   W (ret);
6539   return ret;
6540 }
6541
6542 static int
6543 api_sw_interface_set_flags (vat_main_t * vam)
6544 {
6545   unformat_input_t *i = vam->input;
6546   vl_api_sw_interface_set_flags_t *mp;
6547   u32 sw_if_index;
6548   u8 sw_if_index_set = 0;
6549   u8 admin_up = 0;
6550   int ret;
6551
6552   /* Parse args required to build the message */
6553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6554     {
6555       if (unformat (i, "admin-up"))
6556         admin_up = 1;
6557       else if (unformat (i, "admin-down"))
6558         admin_up = 0;
6559       else
6560         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6561         sw_if_index_set = 1;
6562       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6563         sw_if_index_set = 1;
6564       else
6565         break;
6566     }
6567
6568   if (sw_if_index_set == 0)
6569     {
6570       errmsg ("missing interface name or sw_if_index");
6571       return -99;
6572     }
6573
6574   /* Construct the API message */
6575   M (SW_INTERFACE_SET_FLAGS, mp);
6576   mp->sw_if_index = ntohl (sw_if_index);
6577   mp->admin_up_down = admin_up;
6578
6579   /* send it... */
6580   S (mp);
6581
6582   /* Wait for a reply, return the good/bad news... */
6583   W (ret);
6584   return ret;
6585 }
6586
6587 static int
6588 api_sw_interface_set_rx_mode (vat_main_t * vam)
6589 {
6590   unformat_input_t *i = vam->input;
6591   vl_api_sw_interface_set_rx_mode_t *mp;
6592   u32 sw_if_index;
6593   u8 sw_if_index_set = 0;
6594   int ret;
6595   u8 queue_id_valid = 0;
6596   u32 queue_id;
6597   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6598
6599   /* Parse args required to build the message */
6600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6601     {
6602       if (unformat (i, "queue %d", &queue_id))
6603         queue_id_valid = 1;
6604       else if (unformat (i, "polling"))
6605         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6606       else if (unformat (i, "interrupt"))
6607         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6608       else if (unformat (i, "adaptive"))
6609         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6610       else
6611         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6612         sw_if_index_set = 1;
6613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6614         sw_if_index_set = 1;
6615       else
6616         break;
6617     }
6618
6619   if (sw_if_index_set == 0)
6620     {
6621       errmsg ("missing interface name or sw_if_index");
6622       return -99;
6623     }
6624   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6625     {
6626       errmsg ("missing rx-mode");
6627       return -99;
6628     }
6629
6630   /* Construct the API message */
6631   M (SW_INTERFACE_SET_RX_MODE, mp);
6632   mp->sw_if_index = ntohl (sw_if_index);
6633   mp->mode = mode;
6634   mp->queue_id_valid = queue_id_valid;
6635   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6636
6637   /* send it... */
6638   S (mp);
6639
6640   /* Wait for a reply, return the good/bad news... */
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_sw_interface_set_rx_placement (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_sw_interface_set_rx_placement_t *mp;
6650   u32 sw_if_index;
6651   u8 sw_if_index_set = 0;
6652   int ret;
6653   u8 is_main = 0;
6654   u32 queue_id, thread_index;
6655
6656   /* Parse args required to build the message */
6657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6658     {
6659       if (unformat (i, "queue %d", &queue_id))
6660         ;
6661       else if (unformat (i, "main"))
6662         is_main = 1;
6663       else if (unformat (i, "worker %d", &thread_index))
6664         ;
6665       else
6666         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667         sw_if_index_set = 1;
6668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         sw_if_index_set = 1;
6670       else
6671         break;
6672     }
6673
6674   if (sw_if_index_set == 0)
6675     {
6676       errmsg ("missing interface name or sw_if_index");
6677       return -99;
6678     }
6679
6680   if (is_main)
6681     thread_index = 0;
6682   /* Construct the API message */
6683   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6684   mp->sw_if_index = ntohl (sw_if_index);
6685   mp->worker_id = ntohl (thread_index);
6686   mp->queue_id = ntohl (queue_id);
6687   mp->is_main = is_main;
6688
6689   /* send it... */
6690   S (mp);
6691   /* Wait for a reply, return the good/bad news... */
6692   W (ret);
6693   return ret;
6694 }
6695
6696 static void vl_api_sw_interface_rx_placement_details_t_handler
6697   (vl_api_sw_interface_rx_placement_details_t * mp)
6698 {
6699   vat_main_t *vam = &vat_main;
6700   u32 worker_id = ntohl (mp->worker_id);
6701
6702   print (vam->ofp,
6703          "\n%-11d %-11s %-6d %-5d %-9s",
6704          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6705          worker_id, ntohl (mp->queue_id),
6706          (mp->mode ==
6707           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6708 }
6709
6710 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6711   (vl_api_sw_interface_rx_placement_details_t * mp)
6712 {
6713   vat_main_t *vam = &vat_main;
6714   vat_json_node_t *node = NULL;
6715
6716   if (VAT_JSON_ARRAY != vam->json_tree.type)
6717     {
6718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6719       vat_json_init_array (&vam->json_tree);
6720     }
6721   node = vat_json_array_add (&vam->json_tree);
6722
6723   vat_json_init_object (node);
6724   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6725   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6726   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6727   vat_json_object_add_uint (node, "mode", mp->mode);
6728 }
6729
6730 static int
6731 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6732 {
6733   unformat_input_t *i = vam->input;
6734   vl_api_sw_interface_rx_placement_dump_t *mp;
6735   vl_api_control_ping_t *mp_ping;
6736   int ret;
6737   u32 sw_if_index;
6738   u8 sw_if_index_set = 0;
6739
6740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6741     {
6742       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6743         sw_if_index_set++;
6744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6745         sw_if_index_set++;
6746       else
6747         break;
6748     }
6749
6750   print (vam->ofp,
6751          "\n%-11s %-11s %-6s %-5s %-4s",
6752          "sw_if_index", "main/worker", "thread", "queue", "mode");
6753
6754   /* Dump Interface rx placement */
6755   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6756
6757   if (sw_if_index_set)
6758     mp->sw_if_index = htonl (sw_if_index);
6759   else
6760     mp->sw_if_index = ~0;
6761
6762   S (mp);
6763
6764   /* Use a control ping for synchronization */
6765   MPING (CONTROL_PING, mp_ping);
6766   S (mp_ping);
6767
6768   W (ret);
6769   return ret;
6770 }
6771
6772 static int
6773 api_sw_interface_clear_stats (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_sw_interface_clear_stats_t *mp;
6777   u32 sw_if_index;
6778   u8 sw_if_index_set = 0;
6779   int ret;
6780
6781   /* Parse args required to build the message */
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6785         sw_if_index_set = 1;
6786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6787         sw_if_index_set = 1;
6788       else
6789         break;
6790     }
6791
6792   /* Construct the API message */
6793   M (SW_INTERFACE_CLEAR_STATS, mp);
6794
6795   if (sw_if_index_set == 1)
6796     mp->sw_if_index = ntohl (sw_if_index);
6797   else
6798     mp->sw_if_index = ~0;
6799
6800   /* send it... */
6801   S (mp);
6802
6803   /* Wait for a reply, return the good/bad news... */
6804   W (ret);
6805   return ret;
6806 }
6807
6808 static int
6809 api_sw_interface_add_del_address (vat_main_t * vam)
6810 {
6811   unformat_input_t *i = vam->input;
6812   vl_api_sw_interface_add_del_address_t *mp;
6813   u32 sw_if_index;
6814   u8 sw_if_index_set = 0;
6815   u8 is_add = 1, del_all = 0;
6816   u32 address_length = 0;
6817   u8 v4_address_set = 0;
6818   u8 v6_address_set = 0;
6819   ip4_address_t v4address;
6820   ip6_address_t v6address;
6821   int ret;
6822
6823   /* Parse args required to build the message */
6824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825     {
6826       if (unformat (i, "del-all"))
6827         del_all = 1;
6828       else if (unformat (i, "del"))
6829         is_add = 0;
6830       else
6831         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6834         sw_if_index_set = 1;
6835       else if (unformat (i, "%U/%d",
6836                          unformat_ip4_address, &v4address, &address_length))
6837         v4_address_set = 1;
6838       else if (unformat (i, "%U/%d",
6839                          unformat_ip6_address, &v6address, &address_length))
6840         v6_address_set = 1;
6841       else
6842         break;
6843     }
6844
6845   if (sw_if_index_set == 0)
6846     {
6847       errmsg ("missing interface name or sw_if_index");
6848       return -99;
6849     }
6850   if (v4_address_set && v6_address_set)
6851     {
6852       errmsg ("both v4 and v6 addresses set");
6853       return -99;
6854     }
6855   if (!v4_address_set && !v6_address_set && !del_all)
6856     {
6857       errmsg ("no addresses set");
6858       return -99;
6859     }
6860
6861   /* Construct the API message */
6862   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6863
6864   mp->sw_if_index = ntohl (sw_if_index);
6865   mp->is_add = is_add;
6866   mp->del_all = del_all;
6867   if (v6_address_set)
6868     {
6869       mp->is_ipv6 = 1;
6870       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6871     }
6872   else
6873     {
6874       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6875     }
6876   mp->address_length = address_length;
6877
6878   /* send it... */
6879   S (mp);
6880
6881   /* Wait for a reply, return good/bad news  */
6882   W (ret);
6883   return ret;
6884 }
6885
6886 static int
6887 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6888 {
6889   unformat_input_t *i = vam->input;
6890   vl_api_sw_interface_set_mpls_enable_t *mp;
6891   u32 sw_if_index;
6892   u8 sw_if_index_set = 0;
6893   u8 enable = 1;
6894   int ret;
6895
6896   /* Parse args required to build the message */
6897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6898     {
6899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6900         sw_if_index_set = 1;
6901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6902         sw_if_index_set = 1;
6903       else if (unformat (i, "disable"))
6904         enable = 0;
6905       else if (unformat (i, "dis"))
6906         enable = 0;
6907       else
6908         break;
6909     }
6910
6911   if (sw_if_index_set == 0)
6912     {
6913       errmsg ("missing interface name or sw_if_index");
6914       return -99;
6915     }
6916
6917   /* Construct the API message */
6918   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6919
6920   mp->sw_if_index = ntohl (sw_if_index);
6921   mp->enable = enable;
6922
6923   /* send it... */
6924   S (mp);
6925
6926   /* Wait for a reply... */
6927   W (ret);
6928   return ret;
6929 }
6930
6931 static int
6932 api_sw_interface_set_table (vat_main_t * vam)
6933 {
6934   unformat_input_t *i = vam->input;
6935   vl_api_sw_interface_set_table_t *mp;
6936   u32 sw_if_index, vrf_id = 0;
6937   u8 sw_if_index_set = 0;
6938   u8 is_ipv6 = 0;
6939   int ret;
6940
6941   /* Parse args required to build the message */
6942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6943     {
6944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6945         sw_if_index_set = 1;
6946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6947         sw_if_index_set = 1;
6948       else if (unformat (i, "vrf %d", &vrf_id))
6949         ;
6950       else if (unformat (i, "ipv6"))
6951         is_ipv6 = 1;
6952       else
6953         break;
6954     }
6955
6956   if (sw_if_index_set == 0)
6957     {
6958       errmsg ("missing interface name or sw_if_index");
6959       return -99;
6960     }
6961
6962   /* Construct the API message */
6963   M (SW_INTERFACE_SET_TABLE, mp);
6964
6965   mp->sw_if_index = ntohl (sw_if_index);
6966   mp->is_ipv6 = is_ipv6;
6967   mp->vrf_id = ntohl (vrf_id);
6968
6969   /* send it... */
6970   S (mp);
6971
6972   /* Wait for a reply... */
6973   W (ret);
6974   return ret;
6975 }
6976
6977 static void vl_api_sw_interface_get_table_reply_t_handler
6978   (vl_api_sw_interface_get_table_reply_t * mp)
6979 {
6980   vat_main_t *vam = &vat_main;
6981
6982   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6983
6984   vam->retval = ntohl (mp->retval);
6985   vam->result_ready = 1;
6986
6987 }
6988
6989 static void vl_api_sw_interface_get_table_reply_t_handler_json
6990   (vl_api_sw_interface_get_table_reply_t * mp)
6991 {
6992   vat_main_t *vam = &vat_main;
6993   vat_json_node_t node;
6994
6995   vat_json_init_object (&node);
6996   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6997   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6998
6999   vat_json_print (vam->ofp, &node);
7000   vat_json_free (&node);
7001
7002   vam->retval = ntohl (mp->retval);
7003   vam->result_ready = 1;
7004 }
7005
7006 static int
7007 api_sw_interface_get_table (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_sw_interface_get_table_t *mp;
7011   u32 sw_if_index;
7012   u8 sw_if_index_set = 0;
7013   u8 is_ipv6 = 0;
7014   int ret;
7015
7016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7017     {
7018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7019         sw_if_index_set = 1;
7020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7021         sw_if_index_set = 1;
7022       else if (unformat (i, "ipv6"))
7023         is_ipv6 = 1;
7024       else
7025         break;
7026     }
7027
7028   if (sw_if_index_set == 0)
7029     {
7030       errmsg ("missing interface name or sw_if_index");
7031       return -99;
7032     }
7033
7034   M (SW_INTERFACE_GET_TABLE, mp);
7035   mp->sw_if_index = htonl (sw_if_index);
7036   mp->is_ipv6 = is_ipv6;
7037
7038   S (mp);
7039   W (ret);
7040   return ret;
7041 }
7042
7043 static int
7044 api_sw_interface_set_vpath (vat_main_t * vam)
7045 {
7046   unformat_input_t *i = vam->input;
7047   vl_api_sw_interface_set_vpath_t *mp;
7048   u32 sw_if_index = 0;
7049   u8 sw_if_index_set = 0;
7050   u8 is_enable = 0;
7051   int ret;
7052
7053   /* Parse args required to build the message */
7054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7055     {
7056       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7057         sw_if_index_set = 1;
7058       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7059         sw_if_index_set = 1;
7060       else if (unformat (i, "enable"))
7061         is_enable = 1;
7062       else if (unformat (i, "disable"))
7063         is_enable = 0;
7064       else
7065         break;
7066     }
7067
7068   if (sw_if_index_set == 0)
7069     {
7070       errmsg ("missing interface name or sw_if_index");
7071       return -99;
7072     }
7073
7074   /* Construct the API message */
7075   M (SW_INTERFACE_SET_VPATH, mp);
7076
7077   mp->sw_if_index = ntohl (sw_if_index);
7078   mp->enable = is_enable;
7079
7080   /* send it... */
7081   S (mp);
7082
7083   /* Wait for a reply... */
7084   W (ret);
7085   return ret;
7086 }
7087
7088 static int
7089 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7090 {
7091   unformat_input_t *i = vam->input;
7092   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7093   u32 sw_if_index = 0;
7094   u8 sw_if_index_set = 0;
7095   u8 is_enable = 1;
7096   u8 is_ipv6 = 0;
7097   int ret;
7098
7099   /* Parse args required to build the message */
7100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7101     {
7102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7103         sw_if_index_set = 1;
7104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7105         sw_if_index_set = 1;
7106       else if (unformat (i, "enable"))
7107         is_enable = 1;
7108       else if (unformat (i, "disable"))
7109         is_enable = 0;
7110       else if (unformat (i, "ip4"))
7111         is_ipv6 = 0;
7112       else if (unformat (i, "ip6"))
7113         is_ipv6 = 1;
7114       else
7115         break;
7116     }
7117
7118   if (sw_if_index_set == 0)
7119     {
7120       errmsg ("missing interface name or sw_if_index");
7121       return -99;
7122     }
7123
7124   /* Construct the API message */
7125   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7126
7127   mp->sw_if_index = ntohl (sw_if_index);
7128   mp->enable = is_enable;
7129   mp->is_ipv6 = is_ipv6;
7130
7131   /* send it... */
7132   S (mp);
7133
7134   /* Wait for a reply... */
7135   W (ret);
7136   return ret;
7137 }
7138
7139 static int
7140 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7141 {
7142   unformat_input_t *i = vam->input;
7143   vl_api_sw_interface_set_geneve_bypass_t *mp;
7144   u32 sw_if_index = 0;
7145   u8 sw_if_index_set = 0;
7146   u8 is_enable = 1;
7147   u8 is_ipv6 = 0;
7148   int ret;
7149
7150   /* Parse args required to build the message */
7151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152     {
7153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7154         sw_if_index_set = 1;
7155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7156         sw_if_index_set = 1;
7157       else if (unformat (i, "enable"))
7158         is_enable = 1;
7159       else if (unformat (i, "disable"))
7160         is_enable = 0;
7161       else if (unformat (i, "ip4"))
7162         is_ipv6 = 0;
7163       else if (unformat (i, "ip6"))
7164         is_ipv6 = 1;
7165       else
7166         break;
7167     }
7168
7169   if (sw_if_index_set == 0)
7170     {
7171       errmsg ("missing interface name or sw_if_index");
7172       return -99;
7173     }
7174
7175   /* Construct the API message */
7176   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7177
7178   mp->sw_if_index = ntohl (sw_if_index);
7179   mp->enable = is_enable;
7180   mp->is_ipv6 = is_ipv6;
7181
7182   /* send it... */
7183   S (mp);
7184
7185   /* Wait for a reply... */
7186   W (ret);
7187   return ret;
7188 }
7189
7190 static int
7191 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7192 {
7193   unformat_input_t *i = vam->input;
7194   vl_api_sw_interface_set_l2_xconnect_t *mp;
7195   u32 rx_sw_if_index;
7196   u8 rx_sw_if_index_set = 0;
7197   u32 tx_sw_if_index;
7198   u8 tx_sw_if_index_set = 0;
7199   u8 enable = 1;
7200   int ret;
7201
7202   /* Parse args required to build the message */
7203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7204     {
7205       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7206         rx_sw_if_index_set = 1;
7207       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7208         tx_sw_if_index_set = 1;
7209       else if (unformat (i, "rx"))
7210         {
7211           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7212             {
7213               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7214                             &rx_sw_if_index))
7215                 rx_sw_if_index_set = 1;
7216             }
7217           else
7218             break;
7219         }
7220       else if (unformat (i, "tx"))
7221         {
7222           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223             {
7224               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7225                             &tx_sw_if_index))
7226                 tx_sw_if_index_set = 1;
7227             }
7228           else
7229             break;
7230         }
7231       else if (unformat (i, "enable"))
7232         enable = 1;
7233       else if (unformat (i, "disable"))
7234         enable = 0;
7235       else
7236         break;
7237     }
7238
7239   if (rx_sw_if_index_set == 0)
7240     {
7241       errmsg ("missing rx interface name or rx_sw_if_index");
7242       return -99;
7243     }
7244
7245   if (enable && (tx_sw_if_index_set == 0))
7246     {
7247       errmsg ("missing tx interface name or tx_sw_if_index");
7248       return -99;
7249     }
7250
7251   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7252
7253   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7254   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7255   mp->enable = enable;
7256
7257   S (mp);
7258   W (ret);
7259   return ret;
7260 }
7261
7262 static int
7263 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7264 {
7265   unformat_input_t *i = vam->input;
7266   vl_api_sw_interface_set_l2_bridge_t *mp;
7267   vl_api_l2_port_type_t port_type;
7268   u32 rx_sw_if_index;
7269   u8 rx_sw_if_index_set = 0;
7270   u32 bd_id;
7271   u8 bd_id_set = 0;
7272   u32 shg = 0;
7273   u8 enable = 1;
7274   int ret;
7275
7276   port_type = L2_API_PORT_TYPE_NORMAL;
7277
7278   /* Parse args required to build the message */
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7282         rx_sw_if_index_set = 1;
7283       else if (unformat (i, "bd_id %d", &bd_id))
7284         bd_id_set = 1;
7285       else
7286         if (unformat
7287             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7288         rx_sw_if_index_set = 1;
7289       else if (unformat (i, "shg %d", &shg))
7290         ;
7291       else if (unformat (i, "bvi"))
7292         port_type = L2_API_PORT_TYPE_BVI;
7293       else if (unformat (i, "uu-fwd"))
7294         port_type = L2_API_PORT_TYPE_UU_FWD;
7295       else if (unformat (i, "enable"))
7296         enable = 1;
7297       else if (unformat (i, "disable"))
7298         enable = 0;
7299       else
7300         break;
7301     }
7302
7303   if (rx_sw_if_index_set == 0)
7304     {
7305       errmsg ("missing rx interface name or sw_if_index");
7306       return -99;
7307     }
7308
7309   if (enable && (bd_id_set == 0))
7310     {
7311       errmsg ("missing bridge domain");
7312       return -99;
7313     }
7314
7315   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7316
7317   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7318   mp->bd_id = ntohl (bd_id);
7319   mp->shg = (u8) shg;
7320   mp->port_type = ntohl (port_type);
7321   mp->enable = enable;
7322
7323   S (mp);
7324   W (ret);
7325   return ret;
7326 }
7327
7328 static int
7329 api_bridge_domain_dump (vat_main_t * vam)
7330 {
7331   unformat_input_t *i = vam->input;
7332   vl_api_bridge_domain_dump_t *mp;
7333   vl_api_control_ping_t *mp_ping;
7334   u32 bd_id = ~0;
7335   int ret;
7336
7337   /* Parse args required to build the message */
7338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7339     {
7340       if (unformat (i, "bd_id %d", &bd_id))
7341         ;
7342       else
7343         break;
7344     }
7345
7346   M (BRIDGE_DOMAIN_DUMP, mp);
7347   mp->bd_id = ntohl (bd_id);
7348   S (mp);
7349
7350   /* Use a control ping for synchronization */
7351   MPING (CONTROL_PING, mp_ping);
7352   S (mp_ping);
7353
7354   W (ret);
7355   return ret;
7356 }
7357
7358 static int
7359 api_bridge_domain_add_del (vat_main_t * vam)
7360 {
7361   unformat_input_t *i = vam->input;
7362   vl_api_bridge_domain_add_del_t *mp;
7363   u32 bd_id = ~0;
7364   u8 is_add = 1;
7365   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7366   u8 *bd_tag = NULL;
7367   u32 mac_age = 0;
7368   int ret;
7369
7370   /* Parse args required to build the message */
7371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (i, "bd_id %d", &bd_id))
7374         ;
7375       else if (unformat (i, "flood %d", &flood))
7376         ;
7377       else if (unformat (i, "uu-flood %d", &uu_flood))
7378         ;
7379       else if (unformat (i, "forward %d", &forward))
7380         ;
7381       else if (unformat (i, "learn %d", &learn))
7382         ;
7383       else if (unformat (i, "arp-term %d", &arp_term))
7384         ;
7385       else if (unformat (i, "mac-age %d", &mac_age))
7386         ;
7387       else if (unformat (i, "bd-tag %s", &bd_tag))
7388         ;
7389       else if (unformat (i, "del"))
7390         {
7391           is_add = 0;
7392           flood = uu_flood = forward = learn = 0;
7393         }
7394       else
7395         break;
7396     }
7397
7398   if (bd_id == ~0)
7399     {
7400       errmsg ("missing bridge domain");
7401       ret = -99;
7402       goto done;
7403     }
7404
7405   if (mac_age > 255)
7406     {
7407       errmsg ("mac age must be less than 256 ");
7408       ret = -99;
7409       goto done;
7410     }
7411
7412   if ((bd_tag) && (vec_len (bd_tag) > 63))
7413     {
7414       errmsg ("bd-tag cannot be longer than 63");
7415       ret = -99;
7416       goto done;
7417     }
7418
7419   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7420
7421   mp->bd_id = ntohl (bd_id);
7422   mp->flood = flood;
7423   mp->uu_flood = uu_flood;
7424   mp->forward = forward;
7425   mp->learn = learn;
7426   mp->arp_term = arp_term;
7427   mp->is_add = is_add;
7428   mp->mac_age = (u8) mac_age;
7429   if (bd_tag)
7430     {
7431       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7432       mp->bd_tag[vec_len (bd_tag)] = 0;
7433     }
7434   S (mp);
7435   W (ret);
7436
7437 done:
7438   vec_free (bd_tag);
7439   return ret;
7440 }
7441
7442 static int
7443 api_l2fib_flush_bd (vat_main_t * vam)
7444 {
7445   unformat_input_t *i = vam->input;
7446   vl_api_l2fib_flush_bd_t *mp;
7447   u32 bd_id = ~0;
7448   int ret;
7449
7450   /* Parse args required to build the message */
7451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7452     {
7453       if (unformat (i, "bd_id %d", &bd_id));
7454       else
7455         break;
7456     }
7457
7458   if (bd_id == ~0)
7459     {
7460       errmsg ("missing bridge domain");
7461       return -99;
7462     }
7463
7464   M (L2FIB_FLUSH_BD, mp);
7465
7466   mp->bd_id = htonl (bd_id);
7467
7468   S (mp);
7469   W (ret);
7470   return ret;
7471 }
7472
7473 static int
7474 api_l2fib_flush_int (vat_main_t * vam)
7475 {
7476   unformat_input_t *i = vam->input;
7477   vl_api_l2fib_flush_int_t *mp;
7478   u32 sw_if_index = ~0;
7479   int ret;
7480
7481   /* Parse args required to build the message */
7482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7483     {
7484       if (unformat (i, "sw_if_index %d", &sw_if_index));
7485       else
7486         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7487       else
7488         break;
7489     }
7490
7491   if (sw_if_index == ~0)
7492     {
7493       errmsg ("missing interface name or sw_if_index");
7494       return -99;
7495     }
7496
7497   M (L2FIB_FLUSH_INT, mp);
7498
7499   mp->sw_if_index = ntohl (sw_if_index);
7500
7501   S (mp);
7502   W (ret);
7503   return ret;
7504 }
7505
7506 static int
7507 api_l2fib_add_del (vat_main_t * vam)
7508 {
7509   unformat_input_t *i = vam->input;
7510   vl_api_l2fib_add_del_t *mp;
7511   f64 timeout;
7512   u8 mac[6] = { 0 };
7513   u8 mac_set = 0;
7514   u32 bd_id;
7515   u8 bd_id_set = 0;
7516   u32 sw_if_index = 0;
7517   u8 sw_if_index_set = 0;
7518   u8 is_add = 1;
7519   u8 static_mac = 0;
7520   u8 filter_mac = 0;
7521   u8 bvi_mac = 0;
7522   int count = 1;
7523   f64 before = 0;
7524   int j;
7525
7526   /* Parse args required to build the message */
7527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7528     {
7529       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7530         mac_set = 1;
7531       else if (unformat (i, "bd_id %d", &bd_id))
7532         bd_id_set = 1;
7533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7534         sw_if_index_set = 1;
7535       else if (unformat (i, "sw_if"))
7536         {
7537           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7538             {
7539               if (unformat
7540                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7541                 sw_if_index_set = 1;
7542             }
7543           else
7544             break;
7545         }
7546       else if (unformat (i, "static"))
7547         static_mac = 1;
7548       else if (unformat (i, "filter"))
7549         {
7550           filter_mac = 1;
7551           static_mac = 1;
7552         }
7553       else if (unformat (i, "bvi"))
7554         {
7555           bvi_mac = 1;
7556           static_mac = 1;
7557         }
7558       else if (unformat (i, "del"))
7559         is_add = 0;
7560       else if (unformat (i, "count %d", &count))
7561         ;
7562       else
7563         break;
7564     }
7565
7566   if (mac_set == 0)
7567     {
7568       errmsg ("missing mac address");
7569       return -99;
7570     }
7571
7572   if (bd_id_set == 0)
7573     {
7574       errmsg ("missing bridge domain");
7575       return -99;
7576     }
7577
7578   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7579     {
7580       errmsg ("missing interface name or sw_if_index");
7581       return -99;
7582     }
7583
7584   if (count > 1)
7585     {
7586       /* Turn on async mode */
7587       vam->async_mode = 1;
7588       vam->async_errors = 0;
7589       before = vat_time_now (vam);
7590     }
7591
7592   for (j = 0; j < count; j++)
7593     {
7594       M (L2FIB_ADD_DEL, mp);
7595
7596       clib_memcpy (mp->mac, mac, 6);
7597       mp->bd_id = ntohl (bd_id);
7598       mp->is_add = is_add;
7599       mp->sw_if_index = ntohl (sw_if_index);
7600
7601       if (is_add)
7602         {
7603           mp->static_mac = static_mac;
7604           mp->filter_mac = filter_mac;
7605           mp->bvi_mac = bvi_mac;
7606         }
7607       increment_mac_address (mac);
7608       /* send it... */
7609       S (mp);
7610     }
7611
7612   if (count > 1)
7613     {
7614       vl_api_control_ping_t *mp_ping;
7615       f64 after;
7616
7617       /* Shut off async mode */
7618       vam->async_mode = 0;
7619
7620       MPING (CONTROL_PING, mp_ping);
7621       S (mp_ping);
7622
7623       timeout = vat_time_now (vam) + 1.0;
7624       while (vat_time_now (vam) < timeout)
7625         if (vam->result_ready == 1)
7626           goto out;
7627       vam->retval = -99;
7628
7629     out:
7630       if (vam->retval == -99)
7631         errmsg ("timeout");
7632
7633       if (vam->async_errors > 0)
7634         {
7635           errmsg ("%d asynchronous errors", vam->async_errors);
7636           vam->retval = -98;
7637         }
7638       vam->async_errors = 0;
7639       after = vat_time_now (vam);
7640
7641       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7642              count, after - before, count / (after - before));
7643     }
7644   else
7645     {
7646       int ret;
7647
7648       /* Wait for a reply... */
7649       W (ret);
7650       return ret;
7651     }
7652   /* Return the good/bad news */
7653   return (vam->retval);
7654 }
7655
7656 static int
7657 api_bridge_domain_set_mac_age (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_bridge_domain_set_mac_age_t *mp;
7661   u32 bd_id = ~0;
7662   u32 mac_age = 0;
7663   int ret;
7664
7665   /* Parse args required to build the message */
7666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7667     {
7668       if (unformat (i, "bd_id %d", &bd_id));
7669       else if (unformat (i, "mac-age %d", &mac_age));
7670       else
7671         break;
7672     }
7673
7674   if (bd_id == ~0)
7675     {
7676       errmsg ("missing bridge domain");
7677       return -99;
7678     }
7679
7680   if (mac_age > 255)
7681     {
7682       errmsg ("mac age must be less than 256 ");
7683       return -99;
7684     }
7685
7686   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7687
7688   mp->bd_id = htonl (bd_id);
7689   mp->mac_age = (u8) mac_age;
7690
7691   S (mp);
7692   W (ret);
7693   return ret;
7694 }
7695
7696 static int
7697 api_l2_flags (vat_main_t * vam)
7698 {
7699   unformat_input_t *i = vam->input;
7700   vl_api_l2_flags_t *mp;
7701   u32 sw_if_index;
7702   u32 flags = 0;
7703   u8 sw_if_index_set = 0;
7704   u8 is_set = 0;
7705   int ret;
7706
7707   /* Parse args required to build the message */
7708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7709     {
7710       if (unformat (i, "sw_if_index %d", &sw_if_index))
7711         sw_if_index_set = 1;
7712       else if (unformat (i, "sw_if"))
7713         {
7714           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715             {
7716               if (unformat
7717                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7718                 sw_if_index_set = 1;
7719             }
7720           else
7721             break;
7722         }
7723       else if (unformat (i, "learn"))
7724         flags |= L2_LEARN;
7725       else if (unformat (i, "forward"))
7726         flags |= L2_FWD;
7727       else if (unformat (i, "flood"))
7728         flags |= L2_FLOOD;
7729       else if (unformat (i, "uu-flood"))
7730         flags |= L2_UU_FLOOD;
7731       else if (unformat (i, "arp-term"))
7732         flags |= L2_ARP_TERM;
7733       else if (unformat (i, "off"))
7734         is_set = 0;
7735       else if (unformat (i, "disable"))
7736         is_set = 0;
7737       else
7738         break;
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing interface name or sw_if_index");
7744       return -99;
7745     }
7746
7747   M (L2_FLAGS, mp);
7748
7749   mp->sw_if_index = ntohl (sw_if_index);
7750   mp->feature_bitmap = ntohl (flags);
7751   mp->is_set = is_set;
7752
7753   S (mp);
7754   W (ret);
7755   return ret;
7756 }
7757
7758 static int
7759 api_bridge_flags (vat_main_t * vam)
7760 {
7761   unformat_input_t *i = vam->input;
7762   vl_api_bridge_flags_t *mp;
7763   u32 bd_id;
7764   u8 bd_id_set = 0;
7765   u8 is_set = 1;
7766   bd_flags_t flags = 0;
7767   int ret;
7768
7769   /* Parse args required to build the message */
7770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7771     {
7772       if (unformat (i, "bd_id %d", &bd_id))
7773         bd_id_set = 1;
7774       else if (unformat (i, "learn"))
7775         flags |= BRIDGE_API_FLAG_LEARN;
7776       else if (unformat (i, "forward"))
7777         flags |= BRIDGE_API_FLAG_FWD;
7778       else if (unformat (i, "flood"))
7779         flags |= BRIDGE_API_FLAG_FLOOD;
7780       else if (unformat (i, "uu-flood"))
7781         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7782       else if (unformat (i, "arp-term"))
7783         flags |= BRIDGE_API_FLAG_ARP_TERM;
7784       else if (unformat (i, "off"))
7785         is_set = 0;
7786       else if (unformat (i, "disable"))
7787         is_set = 0;
7788       else
7789         break;
7790     }
7791
7792   if (bd_id_set == 0)
7793     {
7794       errmsg ("missing bridge domain");
7795       return -99;
7796     }
7797
7798   M (BRIDGE_FLAGS, mp);
7799
7800   mp->bd_id = ntohl (bd_id);
7801   mp->flags = ntohl (flags);
7802   mp->is_set = is_set;
7803
7804   S (mp);
7805   W (ret);
7806   return ret;
7807 }
7808
7809 static int
7810 api_bd_ip_mac_add_del (vat_main_t * vam)
7811 {
7812   unformat_input_t *i = vam->input;
7813   vl_api_bd_ip_mac_add_del_t *mp;
7814   u32 bd_id;
7815   u8 is_ipv6 = 0;
7816   u8 is_add = 1;
7817   u8 bd_id_set = 0;
7818   u8 ip_set = 0;
7819   u8 mac_set = 0;
7820   ip4_address_t v4addr;
7821   ip6_address_t v6addr;
7822   u8 macaddr[6];
7823   int ret;
7824
7825
7826   /* Parse args required to build the message */
7827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (i, "bd_id %d", &bd_id))
7830         {
7831           bd_id_set++;
7832         }
7833       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7834         {
7835           ip_set++;
7836         }
7837       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7838         {
7839           ip_set++;
7840           is_ipv6++;
7841         }
7842       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7843         {
7844           mac_set++;
7845         }
7846       else if (unformat (i, "del"))
7847         is_add = 0;
7848       else
7849         break;
7850     }
7851
7852   if (bd_id_set == 0)
7853     {
7854       errmsg ("missing bridge domain");
7855       return -99;
7856     }
7857   else if (ip_set == 0)
7858     {
7859       errmsg ("missing IP address");
7860       return -99;
7861     }
7862   else if (mac_set == 0)
7863     {
7864       errmsg ("missing MAC address");
7865       return -99;
7866     }
7867
7868   M (BD_IP_MAC_ADD_DEL, mp);
7869
7870   mp->bd_id = ntohl (bd_id);
7871   mp->is_ipv6 = is_ipv6;
7872   mp->is_add = is_add;
7873   if (is_ipv6)
7874     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7875   else
7876     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7877   clib_memcpy (mp->mac_address, macaddr, 6);
7878   S (mp);
7879   W (ret);
7880   return ret;
7881 }
7882
7883 static void vl_api_bd_ip_mac_details_t_handler
7884   (vl_api_bd_ip_mac_details_t * mp)
7885 {
7886   vat_main_t *vam = &vat_main;
7887   u8 *ip = 0;
7888
7889   if (!mp->is_ipv6)
7890     ip =
7891       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7892   else
7893     ip =
7894       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7895
7896   print (vam->ofp,
7897          "\n%-5d %-7s %-20U %-30s",
7898          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7899          format_ethernet_address, mp->mac_address, ip);
7900
7901   vec_free (ip);
7902 }
7903
7904 static void vl_api_bd_ip_mac_details_t_handler_json
7905   (vl_api_bd_ip_mac_details_t * mp)
7906 {
7907   vat_main_t *vam = &vat_main;
7908   vat_json_node_t *node = NULL;
7909
7910   if (VAT_JSON_ARRAY != vam->json_tree.type)
7911     {
7912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7913       vat_json_init_array (&vam->json_tree);
7914     }
7915   node = vat_json_array_add (&vam->json_tree);
7916
7917   vat_json_init_object (node);
7918   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7919   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7920   vat_json_object_add_string_copy (node, "mac_address",
7921                                    format (0, "%U", format_ethernet_address,
7922                                            &mp->mac_address));
7923   u8 *ip = 0;
7924
7925   if (!mp->is_ipv6)
7926     ip =
7927       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7928   else
7929     ip =
7930       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7931   vat_json_object_add_string_copy (node, "ip_address", ip);
7932   vec_free (ip);
7933 }
7934
7935 static int
7936 api_bd_ip_mac_dump (vat_main_t * vam)
7937 {
7938   unformat_input_t *i = vam->input;
7939   vl_api_bd_ip_mac_dump_t *mp;
7940   vl_api_control_ping_t *mp_ping;
7941   int ret;
7942   u32 bd_id;
7943   u8 bd_id_set = 0;
7944
7945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7946     {
7947       if (unformat (i, "bd_id %d", &bd_id))
7948         {
7949           bd_id_set++;
7950         }
7951       else
7952         break;
7953     }
7954
7955   print (vam->ofp,
7956          "\n%-5s %-7s %-20s %-30s",
7957          "bd_id", "is_ipv6", "mac_address", "ip_address");
7958
7959   /* Dump Bridge Domain Ip to Mac entries */
7960   M (BD_IP_MAC_DUMP, mp);
7961
7962   if (bd_id_set)
7963     mp->bd_id = htonl (bd_id);
7964   else
7965     mp->bd_id = ~0;
7966
7967   S (mp);
7968
7969   /* Use a control ping for synchronization */
7970   MPING (CONTROL_PING, mp_ping);
7971   S (mp_ping);
7972
7973   W (ret);
7974   return ret;
7975 }
7976
7977 static int
7978 api_tap_connect (vat_main_t * vam)
7979 {
7980   unformat_input_t *i = vam->input;
7981   vl_api_tap_connect_t *mp;
7982   u8 mac_address[6];
7983   u8 random_mac = 1;
7984   u8 name_set = 0;
7985   u8 *tap_name;
7986   u8 *tag = 0;
7987   ip4_address_t ip4_address;
7988   u32 ip4_mask_width;
7989   int ip4_address_set = 0;
7990   ip6_address_t ip6_address;
7991   u32 ip6_mask_width;
7992   int ip6_address_set = 0;
7993   int ret;
7994
7995   memset (mac_address, 0, sizeof (mac_address));
7996
7997   /* Parse args required to build the message */
7998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7999     {
8000       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8001         {
8002           random_mac = 0;
8003         }
8004       else if (unformat (i, "random-mac"))
8005         random_mac = 1;
8006       else if (unformat (i, "tapname %s", &tap_name))
8007         name_set = 1;
8008       else if (unformat (i, "tag %s", &tag))
8009         ;
8010       else if (unformat (i, "address %U/%d",
8011                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8012         ip4_address_set = 1;
8013       else if (unformat (i, "address %U/%d",
8014                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8015         ip6_address_set = 1;
8016       else
8017         break;
8018     }
8019
8020   if (name_set == 0)
8021     {
8022       errmsg ("missing tap name");
8023       return -99;
8024     }
8025   if (vec_len (tap_name) > 63)
8026     {
8027       errmsg ("tap name too long");
8028       return -99;
8029     }
8030   vec_add1 (tap_name, 0);
8031
8032   if (vec_len (tag) > 63)
8033     {
8034       errmsg ("tag too long");
8035       return -99;
8036     }
8037
8038   /* Construct the API message */
8039   M (TAP_CONNECT, mp);
8040
8041   mp->use_random_mac = random_mac;
8042   clib_memcpy (mp->mac_address, mac_address, 6);
8043   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8044   if (tag)
8045     clib_memcpy (mp->tag, tag, vec_len (tag));
8046
8047   if (ip4_address_set)
8048     {
8049       mp->ip4_address_set = 1;
8050       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8051       mp->ip4_mask_width = ip4_mask_width;
8052     }
8053   if (ip6_address_set)
8054     {
8055       mp->ip6_address_set = 1;
8056       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8057       mp->ip6_mask_width = ip6_mask_width;
8058     }
8059
8060   vec_free (tap_name);
8061   vec_free (tag);
8062
8063   /* send it... */
8064   S (mp);
8065
8066   /* Wait for a reply... */
8067   W (ret);
8068   return ret;
8069 }
8070
8071 static int
8072 api_tap_modify (vat_main_t * vam)
8073 {
8074   unformat_input_t *i = vam->input;
8075   vl_api_tap_modify_t *mp;
8076   u8 mac_address[6];
8077   u8 random_mac = 1;
8078   u8 name_set = 0;
8079   u8 *tap_name;
8080   u32 sw_if_index = ~0;
8081   u8 sw_if_index_set = 0;
8082   int ret;
8083
8084   memset (mac_address, 0, sizeof (mac_address));
8085
8086   /* Parse args required to build the message */
8087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8088     {
8089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8090         sw_if_index_set = 1;
8091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8092         sw_if_index_set = 1;
8093       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8094         {
8095           random_mac = 0;
8096         }
8097       else if (unformat (i, "random-mac"))
8098         random_mac = 1;
8099       else if (unformat (i, "tapname %s", &tap_name))
8100         name_set = 1;
8101       else
8102         break;
8103     }
8104
8105   if (sw_if_index_set == 0)
8106     {
8107       errmsg ("missing vpp interface name");
8108       return -99;
8109     }
8110   if (name_set == 0)
8111     {
8112       errmsg ("missing tap name");
8113       return -99;
8114     }
8115   if (vec_len (tap_name) > 63)
8116     {
8117       errmsg ("tap name too long");
8118     }
8119   vec_add1 (tap_name, 0);
8120
8121   /* Construct the API message */
8122   M (TAP_MODIFY, mp);
8123
8124   mp->use_random_mac = random_mac;
8125   mp->sw_if_index = ntohl (sw_if_index);
8126   clib_memcpy (mp->mac_address, mac_address, 6);
8127   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8128   vec_free (tap_name);
8129
8130   /* send it... */
8131   S (mp);
8132
8133   /* Wait for a reply... */
8134   W (ret);
8135   return ret;
8136 }
8137
8138 static int
8139 api_tap_delete (vat_main_t * vam)
8140 {
8141   unformat_input_t *i = vam->input;
8142   vl_api_tap_delete_t *mp;
8143   u32 sw_if_index = ~0;
8144   u8 sw_if_index_set = 0;
8145   int ret;
8146
8147   /* Parse args required to build the message */
8148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8149     {
8150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8151         sw_if_index_set = 1;
8152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8153         sw_if_index_set = 1;
8154       else
8155         break;
8156     }
8157
8158   if (sw_if_index_set == 0)
8159     {
8160       errmsg ("missing vpp interface name");
8161       return -99;
8162     }
8163
8164   /* Construct the API message */
8165   M (TAP_DELETE, mp);
8166
8167   mp->sw_if_index = ntohl (sw_if_index);
8168
8169   /* send it... */
8170   S (mp);
8171
8172   /* Wait for a reply... */
8173   W (ret);
8174   return ret;
8175 }
8176
8177 static int
8178 api_tap_create_v2 (vat_main_t * vam)
8179 {
8180   unformat_input_t *i = vam->input;
8181   vl_api_tap_create_v2_t *mp;
8182   u8 mac_address[6];
8183   u8 random_mac = 1;
8184   u32 id = ~0;
8185   u8 *host_if_name = 0;
8186   u8 *host_ns = 0;
8187   u8 host_mac_addr[6];
8188   u8 host_mac_addr_set = 0;
8189   u8 *host_bridge = 0;
8190   ip4_address_t host_ip4_addr;
8191   ip4_address_t host_ip4_gw;
8192   u8 host_ip4_gw_set = 0;
8193   u32 host_ip4_prefix_len = 0;
8194   ip6_address_t host_ip6_addr;
8195   ip6_address_t host_ip6_gw;
8196   u8 host_ip6_gw_set = 0;
8197   u32 host_ip6_prefix_len = 0;
8198   int ret;
8199   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8200
8201   memset (mac_address, 0, sizeof (mac_address));
8202
8203   /* Parse args required to build the message */
8204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8205     {
8206       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8207         {
8208           random_mac = 0;
8209         }
8210       else if (unformat (i, "id %u", &id))
8211         ;
8212       else if (unformat (i, "host-if-name %s", &host_if_name))
8213         ;
8214       else if (unformat (i, "host-ns %s", &host_ns))
8215         ;
8216       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8217                          host_mac_addr))
8218         host_mac_addr_set = 1;
8219       else if (unformat (i, "host-bridge %s", &host_bridge))
8220         ;
8221       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8222                          &host_ip4_addr, &host_ip4_prefix_len))
8223         ;
8224       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8225                          &host_ip6_addr, &host_ip6_prefix_len))
8226         ;
8227       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8228                          &host_ip4_gw))
8229         host_ip4_gw_set = 1;
8230       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8231                          &host_ip6_gw))
8232         host_ip6_gw_set = 1;
8233       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8234         ;
8235       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8236         ;
8237       else
8238         break;
8239     }
8240
8241   if (vec_len (host_if_name) > 63)
8242     {
8243       errmsg ("tap name too long. ");
8244       return -99;
8245     }
8246   if (vec_len (host_ns) > 63)
8247     {
8248       errmsg ("host name space too long. ");
8249       return -99;
8250     }
8251   if (vec_len (host_bridge) > 63)
8252     {
8253       errmsg ("host bridge name too long. ");
8254       return -99;
8255     }
8256   if (host_ip4_prefix_len > 32)
8257     {
8258       errmsg ("host ip4 prefix length not valid. ");
8259       return -99;
8260     }
8261   if (host_ip6_prefix_len > 128)
8262     {
8263       errmsg ("host ip6 prefix length not valid. ");
8264       return -99;
8265     }
8266   if (!is_pow2 (rx_ring_sz))
8267     {
8268       errmsg ("rx ring size must be power of 2. ");
8269       return -99;
8270     }
8271   if (rx_ring_sz > 32768)
8272     {
8273       errmsg ("rx ring size must be 32768 or lower. ");
8274       return -99;
8275     }
8276   if (!is_pow2 (tx_ring_sz))
8277     {
8278       errmsg ("tx ring size must be power of 2. ");
8279       return -99;
8280     }
8281   if (tx_ring_sz > 32768)
8282     {
8283       errmsg ("tx ring size must be 32768 or lower. ");
8284       return -99;
8285     }
8286
8287   /* Construct the API message */
8288   M (TAP_CREATE_V2, mp);
8289
8290   mp->use_random_mac = random_mac;
8291
8292   mp->id = ntohl (id);
8293   mp->host_namespace_set = host_ns != 0;
8294   mp->host_bridge_set = host_bridge != 0;
8295   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8296   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8297   mp->rx_ring_sz = ntohs (rx_ring_sz);
8298   mp->tx_ring_sz = ntohs (tx_ring_sz);
8299
8300   if (random_mac == 0)
8301     clib_memcpy (mp->mac_address, mac_address, 6);
8302   if (host_mac_addr_set)
8303     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8304   if (host_if_name)
8305     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8306   if (host_ns)
8307     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8308   if (host_bridge)
8309     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8310   if (host_ip4_prefix_len)
8311     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8312   if (host_ip4_prefix_len)
8313     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8314   if (host_ip4_gw_set)
8315     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8316   if (host_ip6_gw_set)
8317     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8318
8319   vec_free (host_ns);
8320   vec_free (host_if_name);
8321   vec_free (host_bridge);
8322
8323   /* send it... */
8324   S (mp);
8325
8326   /* Wait for a reply... */
8327   W (ret);
8328   return ret;
8329 }
8330
8331 static int
8332 api_tap_delete_v2 (vat_main_t * vam)
8333 {
8334   unformat_input_t *i = vam->input;
8335   vl_api_tap_delete_v2_t *mp;
8336   u32 sw_if_index = ~0;
8337   u8 sw_if_index_set = 0;
8338   int ret;
8339
8340   /* Parse args required to build the message */
8341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8342     {
8343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8344         sw_if_index_set = 1;
8345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8346         sw_if_index_set = 1;
8347       else
8348         break;
8349     }
8350
8351   if (sw_if_index_set == 0)
8352     {
8353       errmsg ("missing vpp interface name. ");
8354       return -99;
8355     }
8356
8357   /* Construct the API message */
8358   M (TAP_DELETE_V2, mp);
8359
8360   mp->sw_if_index = ntohl (sw_if_index);
8361
8362   /* send it... */
8363   S (mp);
8364
8365   /* Wait for a reply... */
8366   W (ret);
8367   return ret;
8368 }
8369
8370 static int
8371 api_bond_create (vat_main_t * vam)
8372 {
8373   unformat_input_t *i = vam->input;
8374   vl_api_bond_create_t *mp;
8375   u8 mac_address[6];
8376   u8 custom_mac = 0;
8377   int ret;
8378   u8 mode;
8379   u8 lb;
8380   u8 mode_is_set = 0;
8381
8382   memset (mac_address, 0, sizeof (mac_address));
8383   lb = BOND_LB_L2;
8384
8385   /* Parse args required to build the message */
8386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8387     {
8388       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8389         mode_is_set = 1;
8390       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8391                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8392         ;
8393       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8394                          mac_address))
8395         custom_mac = 1;
8396       else
8397         break;
8398     }
8399
8400   if (mode_is_set == 0)
8401     {
8402       errmsg ("Missing bond mode. ");
8403       return -99;
8404     }
8405
8406   /* Construct the API message */
8407   M (BOND_CREATE, mp);
8408
8409   mp->use_custom_mac = custom_mac;
8410
8411   mp->mode = mode;
8412   mp->lb = lb;
8413
8414   if (custom_mac)
8415     clib_memcpy (mp->mac_address, mac_address, 6);
8416
8417   /* send it... */
8418   S (mp);
8419
8420   /* Wait for a reply... */
8421   W (ret);
8422   return ret;
8423 }
8424
8425 static int
8426 api_bond_delete (vat_main_t * vam)
8427 {
8428   unformat_input_t *i = vam->input;
8429   vl_api_bond_delete_t *mp;
8430   u32 sw_if_index = ~0;
8431   u8 sw_if_index_set = 0;
8432   int ret;
8433
8434   /* Parse args required to build the message */
8435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8436     {
8437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8438         sw_if_index_set = 1;
8439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8440         sw_if_index_set = 1;
8441       else
8442         break;
8443     }
8444
8445   if (sw_if_index_set == 0)
8446     {
8447       errmsg ("missing vpp interface name. ");
8448       return -99;
8449     }
8450
8451   /* Construct the API message */
8452   M (BOND_DELETE, mp);
8453
8454   mp->sw_if_index = ntohl (sw_if_index);
8455
8456   /* send it... */
8457   S (mp);
8458
8459   /* Wait for a reply... */
8460   W (ret);
8461   return ret;
8462 }
8463
8464 static int
8465 api_bond_enslave (vat_main_t * vam)
8466 {
8467   unformat_input_t *i = vam->input;
8468   vl_api_bond_enslave_t *mp;
8469   u32 bond_sw_if_index;
8470   int ret;
8471   u8 is_passive;
8472   u8 is_long_timeout;
8473   u32 bond_sw_if_index_is_set = 0;
8474   u32 sw_if_index;
8475   u8 sw_if_index_is_set = 0;
8476
8477   /* Parse args required to build the message */
8478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8479     {
8480       if (unformat (i, "sw_if_index %d", &sw_if_index))
8481         sw_if_index_is_set = 1;
8482       else if (unformat (i, "bond %u", &bond_sw_if_index))
8483         bond_sw_if_index_is_set = 1;
8484       else if (unformat (i, "passive %d", &is_passive))
8485         ;
8486       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8487         ;
8488       else
8489         break;
8490     }
8491
8492   if (bond_sw_if_index_is_set == 0)
8493     {
8494       errmsg ("Missing bond sw_if_index. ");
8495       return -99;
8496     }
8497   if (sw_if_index_is_set == 0)
8498     {
8499       errmsg ("Missing slave sw_if_index. ");
8500       return -99;
8501     }
8502
8503   /* Construct the API message */
8504   M (BOND_ENSLAVE, mp);
8505
8506   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8507   mp->sw_if_index = ntohl (sw_if_index);
8508   mp->is_long_timeout = is_long_timeout;
8509   mp->is_passive = is_passive;
8510
8511   /* send it... */
8512   S (mp);
8513
8514   /* Wait for a reply... */
8515   W (ret);
8516   return ret;
8517 }
8518
8519 static int
8520 api_bond_detach_slave (vat_main_t * vam)
8521 {
8522   unformat_input_t *i = vam->input;
8523   vl_api_bond_detach_slave_t *mp;
8524   u32 sw_if_index = ~0;
8525   u8 sw_if_index_set = 0;
8526   int ret;
8527
8528   /* Parse args required to build the message */
8529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8530     {
8531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8532         sw_if_index_set = 1;
8533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8534         sw_if_index_set = 1;
8535       else
8536         break;
8537     }
8538
8539   if (sw_if_index_set == 0)
8540     {
8541       errmsg ("missing vpp interface name. ");
8542       return -99;
8543     }
8544
8545   /* Construct the API message */
8546   M (BOND_DETACH_SLAVE, mp);
8547
8548   mp->sw_if_index = ntohl (sw_if_index);
8549
8550   /* send it... */
8551   S (mp);
8552
8553   /* Wait for a reply... */
8554   W (ret);
8555   return ret;
8556 }
8557
8558 static int
8559 api_ip_table_add_del (vat_main_t * vam)
8560 {
8561   unformat_input_t *i = vam->input;
8562   vl_api_ip_table_add_del_t *mp;
8563   u32 table_id = ~0;
8564   u8 is_ipv6 = 0;
8565   u8 is_add = 1;
8566   int ret = 0;
8567
8568   /* Parse args required to build the message */
8569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8570     {
8571       if (unformat (i, "ipv6"))
8572         is_ipv6 = 1;
8573       else if (unformat (i, "del"))
8574         is_add = 0;
8575       else if (unformat (i, "add"))
8576         is_add = 1;
8577       else if (unformat (i, "table %d", &table_id))
8578         ;
8579       else
8580         {
8581           clib_warning ("parse error '%U'", format_unformat_error, i);
8582           return -99;
8583         }
8584     }
8585
8586   if (~0 == table_id)
8587     {
8588       errmsg ("missing table-ID");
8589       return -99;
8590     }
8591
8592   /* Construct the API message */
8593   M (IP_TABLE_ADD_DEL, mp);
8594
8595   mp->table_id = ntohl (table_id);
8596   mp->is_ipv6 = is_ipv6;
8597   mp->is_add = is_add;
8598
8599   /* send it... */
8600   S (mp);
8601
8602   /* Wait for a reply... */
8603   W (ret);
8604
8605   return ret;
8606 }
8607
8608 static int
8609 api_ip_add_del_route (vat_main_t * vam)
8610 {
8611   unformat_input_t *i = vam->input;
8612   vl_api_ip_add_del_route_t *mp;
8613   u32 sw_if_index = ~0, vrf_id = 0;
8614   u8 is_ipv6 = 0;
8615   u8 is_local = 0, is_drop = 0;
8616   u8 is_unreach = 0, is_prohibit = 0;
8617   u8 is_add = 1;
8618   u32 next_hop_weight = 1;
8619   u8 is_multipath = 0;
8620   u8 address_set = 0;
8621   u8 address_length_set = 0;
8622   u32 next_hop_table_id = 0;
8623   u32 resolve_attempts = 0;
8624   u32 dst_address_length = 0;
8625   u8 next_hop_set = 0;
8626   ip4_address_t v4_dst_address, v4_next_hop_address;
8627   ip6_address_t v6_dst_address, v6_next_hop_address;
8628   int count = 1;
8629   int j;
8630   f64 before = 0;
8631   u32 random_add_del = 0;
8632   u32 *random_vector = 0;
8633   uword *random_hash;
8634   u32 random_seed = 0xdeaddabe;
8635   u32 classify_table_index = ~0;
8636   u8 is_classify = 0;
8637   u8 resolve_host = 0, resolve_attached = 0;
8638   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8639   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8640   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8641
8642   memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8643   memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8644   /* Parse args required to build the message */
8645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8646     {
8647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8648         ;
8649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8650         ;
8651       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8652         {
8653           address_set = 1;
8654           is_ipv6 = 0;
8655         }
8656       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8657         {
8658           address_set = 1;
8659           is_ipv6 = 1;
8660         }
8661       else if (unformat (i, "/%d", &dst_address_length))
8662         {
8663           address_length_set = 1;
8664         }
8665
8666       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8667                                          &v4_next_hop_address))
8668         {
8669           next_hop_set = 1;
8670         }
8671       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8672                                          &v6_next_hop_address))
8673         {
8674           next_hop_set = 1;
8675         }
8676       else
8677         if (unformat
8678             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8679         {
8680           next_hop_set = 1;
8681         }
8682       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8683         {
8684           next_hop_set = 1;
8685         }
8686       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8687         ;
8688       else if (unformat (i, "weight %d", &next_hop_weight))
8689         ;
8690       else if (unformat (i, "drop"))
8691         {
8692           is_drop = 1;
8693         }
8694       else if (unformat (i, "null-send-unreach"))
8695         {
8696           is_unreach = 1;
8697         }
8698       else if (unformat (i, "null-send-prohibit"))
8699         {
8700           is_prohibit = 1;
8701         }
8702       else if (unformat (i, "local"))
8703         {
8704           is_local = 1;
8705         }
8706       else if (unformat (i, "classify %d", &classify_table_index))
8707         {
8708           is_classify = 1;
8709         }
8710       else if (unformat (i, "del"))
8711         is_add = 0;
8712       else if (unformat (i, "add"))
8713         is_add = 1;
8714       else if (unformat (i, "resolve-via-host"))
8715         resolve_host = 1;
8716       else if (unformat (i, "resolve-via-attached"))
8717         resolve_attached = 1;
8718       else if (unformat (i, "multipath"))
8719         is_multipath = 1;
8720       else if (unformat (i, "vrf %d", &vrf_id))
8721         ;
8722       else if (unformat (i, "count %d", &count))
8723         ;
8724       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8725         ;
8726       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8727         ;
8728       else if (unformat (i, "out-label %d", &next_hop_out_label))
8729         {
8730           vl_api_fib_mpls_label_t fib_label = {
8731             .label = ntohl (next_hop_out_label),
8732             .ttl = 64,
8733             .exp = 0,
8734           };
8735           vec_add1 (next_hop_out_label_stack, fib_label);
8736         }
8737       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8738         ;
8739       else if (unformat (i, "random"))
8740         random_add_del = 1;
8741       else if (unformat (i, "seed %d", &random_seed))
8742         ;
8743       else
8744         {
8745           clib_warning ("parse error '%U'", format_unformat_error, i);
8746           return -99;
8747         }
8748     }
8749
8750   if (!next_hop_set && !is_drop && !is_local &&
8751       !is_classify && !is_unreach && !is_prohibit &&
8752       MPLS_LABEL_INVALID == next_hop_via_label)
8753     {
8754       errmsg
8755         ("next hop / local / drop / unreach / prohibit / classify not set");
8756       return -99;
8757     }
8758
8759   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8760     {
8761       errmsg ("next hop and next-hop via label set");
8762       return -99;
8763     }
8764   if (address_set == 0)
8765     {
8766       errmsg ("missing addresses");
8767       return -99;
8768     }
8769
8770   if (address_length_set == 0)
8771     {
8772       errmsg ("missing address length");
8773       return -99;
8774     }
8775
8776   /* Generate a pile of unique, random routes */
8777   if (random_add_del)
8778     {
8779       u32 this_random_address;
8780       random_hash = hash_create (count, sizeof (uword));
8781
8782       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8783       for (j = 0; j <= count; j++)
8784         {
8785           do
8786             {
8787               this_random_address = random_u32 (&random_seed);
8788               this_random_address =
8789                 clib_host_to_net_u32 (this_random_address);
8790             }
8791           while (hash_get (random_hash, this_random_address));
8792           vec_add1 (random_vector, this_random_address);
8793           hash_set (random_hash, this_random_address, 1);
8794         }
8795       hash_free (random_hash);
8796       v4_dst_address.as_u32 = random_vector[0];
8797     }
8798
8799   if (count > 1)
8800     {
8801       /* Turn on async mode */
8802       vam->async_mode = 1;
8803       vam->async_errors = 0;
8804       before = vat_time_now (vam);
8805     }
8806
8807   for (j = 0; j < count; j++)
8808     {
8809       /* Construct the API message */
8810       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8811           vec_len (next_hop_out_label_stack));
8812
8813       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8814       mp->table_id = ntohl (vrf_id);
8815
8816       mp->is_add = is_add;
8817       mp->is_drop = is_drop;
8818       mp->is_unreach = is_unreach;
8819       mp->is_prohibit = is_prohibit;
8820       mp->is_ipv6 = is_ipv6;
8821       mp->is_local = is_local;
8822       mp->is_classify = is_classify;
8823       mp->is_multipath = is_multipath;
8824       mp->is_resolve_host = resolve_host;
8825       mp->is_resolve_attached = resolve_attached;
8826       mp->next_hop_weight = next_hop_weight;
8827       mp->dst_address_length = dst_address_length;
8828       mp->next_hop_table_id = ntohl (next_hop_table_id);
8829       mp->classify_table_index = ntohl (classify_table_index);
8830       mp->next_hop_via_label = ntohl (next_hop_via_label);
8831       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8832       if (0 != mp->next_hop_n_out_labels)
8833         {
8834           memcpy (mp->next_hop_out_label_stack,
8835                   next_hop_out_label_stack,
8836                   (vec_len (next_hop_out_label_stack) *
8837                    sizeof (vl_api_fib_mpls_label_t)));
8838           vec_free (next_hop_out_label_stack);
8839         }
8840
8841       if (is_ipv6)
8842         {
8843           clib_memcpy (mp->dst_address, &v6_dst_address,
8844                        sizeof (v6_dst_address));
8845           if (next_hop_set)
8846             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8847                          sizeof (v6_next_hop_address));
8848           increment_v6_address (&v6_dst_address);
8849         }
8850       else
8851         {
8852           clib_memcpy (mp->dst_address, &v4_dst_address,
8853                        sizeof (v4_dst_address));
8854           if (next_hop_set)
8855             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8856                          sizeof (v4_next_hop_address));
8857           if (random_add_del)
8858             v4_dst_address.as_u32 = random_vector[j + 1];
8859           else
8860             increment_v4_address (&v4_dst_address);
8861         }
8862       /* send it... */
8863       S (mp);
8864       /* If we receive SIGTERM, stop now... */
8865       if (vam->do_exit)
8866         break;
8867     }
8868
8869   /* When testing multiple add/del ops, use a control-ping to sync */
8870   if (count > 1)
8871     {
8872       vl_api_control_ping_t *mp_ping;
8873       f64 after;
8874       f64 timeout;
8875
8876       /* Shut off async mode */
8877       vam->async_mode = 0;
8878
8879       MPING (CONTROL_PING, mp_ping);
8880       S (mp_ping);
8881
8882       timeout = vat_time_now (vam) + 1.0;
8883       while (vat_time_now (vam) < timeout)
8884         if (vam->result_ready == 1)
8885           goto out;
8886       vam->retval = -99;
8887
8888     out:
8889       if (vam->retval == -99)
8890         errmsg ("timeout");
8891
8892       if (vam->async_errors > 0)
8893         {
8894           errmsg ("%d asynchronous errors", vam->async_errors);
8895           vam->retval = -98;
8896         }
8897       vam->async_errors = 0;
8898       after = vat_time_now (vam);
8899
8900       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8901       if (j > 0)
8902         count = j;
8903
8904       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8905              count, after - before, count / (after - before));
8906     }
8907   else
8908     {
8909       int ret;
8910
8911       /* Wait for a reply... */
8912       W (ret);
8913       return ret;
8914     }
8915
8916   /* Return the good/bad news */
8917   return (vam->retval);
8918 }
8919
8920 static int
8921 api_ip_mroute_add_del (vat_main_t * vam)
8922 {
8923   unformat_input_t *i = vam->input;
8924   vl_api_ip_mroute_add_del_t *mp;
8925   u32 sw_if_index = ~0, vrf_id = 0;
8926   u8 is_ipv6 = 0;
8927   u8 is_local = 0;
8928   u8 is_add = 1;
8929   u8 address_set = 0;
8930   u32 grp_address_length = 0;
8931   ip4_address_t v4_grp_address, v4_src_address;
8932   ip6_address_t v6_grp_address, v6_src_address;
8933   mfib_itf_flags_t iflags = 0;
8934   mfib_entry_flags_t eflags = 0;
8935   int ret;
8936
8937   /* Parse args required to build the message */
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "sw_if_index %d", &sw_if_index))
8941         ;
8942       else if (unformat (i, "%U %U",
8943                          unformat_ip4_address, &v4_src_address,
8944                          unformat_ip4_address, &v4_grp_address))
8945         {
8946           grp_address_length = 64;
8947           address_set = 1;
8948           is_ipv6 = 0;
8949         }
8950       else if (unformat (i, "%U %U",
8951                          unformat_ip6_address, &v6_src_address,
8952                          unformat_ip6_address, &v6_grp_address))
8953         {
8954           grp_address_length = 256;
8955           address_set = 1;
8956           is_ipv6 = 1;
8957         }
8958       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8959         {
8960           memset (&v4_src_address, 0, sizeof (v4_src_address));
8961           grp_address_length = 32;
8962           address_set = 1;
8963           is_ipv6 = 0;
8964         }
8965       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8966         {
8967           memset (&v6_src_address, 0, sizeof (v6_src_address));
8968           grp_address_length = 128;
8969           address_set = 1;
8970           is_ipv6 = 1;
8971         }
8972       else if (unformat (i, "/%d", &grp_address_length))
8973         ;
8974       else if (unformat (i, "local"))
8975         {
8976           is_local = 1;
8977         }
8978       else if (unformat (i, "del"))
8979         is_add = 0;
8980       else if (unformat (i, "add"))
8981         is_add = 1;
8982       else if (unformat (i, "vrf %d", &vrf_id))
8983         ;
8984       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8985         ;
8986       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8987         ;
8988       else
8989         {
8990           clib_warning ("parse error '%U'", format_unformat_error, i);
8991           return -99;
8992         }
8993     }
8994
8995   if (address_set == 0)
8996     {
8997       errmsg ("missing addresses\n");
8998       return -99;
8999     }
9000
9001   /* Construct the API message */
9002   M (IP_MROUTE_ADD_DEL, mp);
9003
9004   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9005   mp->table_id = ntohl (vrf_id);
9006
9007   mp->is_add = is_add;
9008   mp->is_ipv6 = is_ipv6;
9009   mp->is_local = is_local;
9010   mp->itf_flags = ntohl (iflags);
9011   mp->entry_flags = ntohl (eflags);
9012   mp->grp_address_length = grp_address_length;
9013   mp->grp_address_length = ntohs (mp->grp_address_length);
9014
9015   if (is_ipv6)
9016     {
9017       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9018       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9019     }
9020   else
9021     {
9022       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9023       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9024
9025     }
9026
9027   /* send it... */
9028   S (mp);
9029   /* Wait for a reply... */
9030   W (ret);
9031   return ret;
9032 }
9033
9034 static int
9035 api_mpls_table_add_del (vat_main_t * vam)
9036 {
9037   unformat_input_t *i = vam->input;
9038   vl_api_mpls_table_add_del_t *mp;
9039   u32 table_id = ~0;
9040   u8 is_add = 1;
9041   int ret = 0;
9042
9043   /* Parse args required to build the message */
9044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9045     {
9046       if (unformat (i, "table %d", &table_id))
9047         ;
9048       else if (unformat (i, "del"))
9049         is_add = 0;
9050       else if (unformat (i, "add"))
9051         is_add = 1;
9052       else
9053         {
9054           clib_warning ("parse error '%U'", format_unformat_error, i);
9055           return -99;
9056         }
9057     }
9058
9059   if (~0 == table_id)
9060     {
9061       errmsg ("missing table-ID");
9062       return -99;
9063     }
9064
9065   /* Construct the API message */
9066   M (MPLS_TABLE_ADD_DEL, mp);
9067
9068   mp->mt_table_id = ntohl (table_id);
9069   mp->mt_is_add = is_add;
9070
9071   /* send it... */
9072   S (mp);
9073
9074   /* Wait for a reply... */
9075   W (ret);
9076
9077   return ret;
9078 }
9079
9080 static int
9081 api_mpls_route_add_del (vat_main_t * vam)
9082 {
9083   unformat_input_t *i = vam->input;
9084   vl_api_mpls_route_add_del_t *mp;
9085   u32 sw_if_index = ~0, table_id = 0;
9086   u8 is_add = 1;
9087   u32 next_hop_weight = 1;
9088   u8 is_multipath = 0;
9089   u32 next_hop_table_id = 0;
9090   u8 next_hop_set = 0;
9091   ip4_address_t v4_next_hop_address = {
9092     .as_u32 = 0,
9093   };
9094   ip6_address_t v6_next_hop_address = { {0} };
9095   int count = 1;
9096   int j;
9097   f64 before = 0;
9098   u32 classify_table_index = ~0;
9099   u8 is_classify = 0;
9100   u8 resolve_host = 0, resolve_attached = 0;
9101   u8 is_interface_rx = 0;
9102   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9103   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9104   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9105   mpls_label_t local_label = MPLS_LABEL_INVALID;
9106   u8 is_eos = 0;
9107   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9108
9109   /* Parse args required to build the message */
9110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9113         ;
9114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9115         ;
9116       else if (unformat (i, "%d", &local_label))
9117         ;
9118       else if (unformat (i, "eos"))
9119         is_eos = 1;
9120       else if (unformat (i, "non-eos"))
9121         is_eos = 0;
9122       else if (unformat (i, "via %U", unformat_ip4_address,
9123                          &v4_next_hop_address))
9124         {
9125           next_hop_set = 1;
9126           next_hop_proto = DPO_PROTO_IP4;
9127         }
9128       else if (unformat (i, "via %U", unformat_ip6_address,
9129                          &v6_next_hop_address))
9130         {
9131           next_hop_set = 1;
9132           next_hop_proto = DPO_PROTO_IP6;
9133         }
9134       else if (unformat (i, "weight %d", &next_hop_weight))
9135         ;
9136       else if (unformat (i, "classify %d", &classify_table_index))
9137         {
9138           is_classify = 1;
9139         }
9140       else if (unformat (i, "del"))
9141         is_add = 0;
9142       else if (unformat (i, "add"))
9143         is_add = 1;
9144       else if (unformat (i, "resolve-via-host"))
9145         resolve_host = 1;
9146       else if (unformat (i, "resolve-via-attached"))
9147         resolve_attached = 1;
9148       else if (unformat (i, "multipath"))
9149         is_multipath = 1;
9150       else if (unformat (i, "count %d", &count))
9151         ;
9152       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9153         {
9154           next_hop_set = 1;
9155           next_hop_proto = DPO_PROTO_IP4;
9156         }
9157       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9158         {
9159           next_hop_set = 1;
9160           next_hop_proto = DPO_PROTO_IP6;
9161         }
9162       else
9163         if (unformat
9164             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9165              &sw_if_index))
9166         {
9167           next_hop_set = 1;
9168           next_hop_proto = DPO_PROTO_ETHERNET;
9169           is_interface_rx = 1;
9170         }
9171       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9172         {
9173           next_hop_set = 1;
9174           next_hop_proto = DPO_PROTO_ETHERNET;
9175           is_interface_rx = 1;
9176         }
9177       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9178         next_hop_set = 1;
9179       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9180         next_hop_set = 1;
9181       else if (unformat (i, "out-label %d", &next_hop_out_label))
9182         {
9183           vl_api_fib_mpls_label_t fib_label = {
9184             .label = ntohl (next_hop_out_label),
9185             .ttl = 64,
9186             .exp = 0,
9187           };
9188           vec_add1 (next_hop_out_label_stack, fib_label);
9189         }
9190       else
9191         {
9192           clib_warning ("parse error '%U'", format_unformat_error, i);
9193           return -99;
9194         }
9195     }
9196
9197   if (!next_hop_set && !is_classify)
9198     {
9199       errmsg ("next hop / classify not set");
9200       return -99;
9201     }
9202
9203   if (MPLS_LABEL_INVALID == local_label)
9204     {
9205       errmsg ("missing label");
9206       return -99;
9207     }
9208
9209   if (count > 1)
9210     {
9211       /* Turn on async mode */
9212       vam->async_mode = 1;
9213       vam->async_errors = 0;
9214       before = vat_time_now (vam);
9215     }
9216
9217   for (j = 0; j < count; j++)
9218     {
9219       /* Construct the API message */
9220       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9221           vec_len (next_hop_out_label_stack));
9222
9223       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9224       mp->mr_table_id = ntohl (table_id);
9225
9226       mp->mr_is_add = is_add;
9227       mp->mr_next_hop_proto = next_hop_proto;
9228       mp->mr_is_classify = is_classify;
9229       mp->mr_is_multipath = is_multipath;
9230       mp->mr_is_resolve_host = resolve_host;
9231       mp->mr_is_resolve_attached = resolve_attached;
9232       mp->mr_is_interface_rx = is_interface_rx;
9233       mp->mr_next_hop_weight = next_hop_weight;
9234       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9235       mp->mr_classify_table_index = ntohl (classify_table_index);
9236       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9237       mp->mr_label = ntohl (local_label);
9238       mp->mr_eos = is_eos;
9239
9240       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9241       if (0 != mp->mr_next_hop_n_out_labels)
9242         {
9243           memcpy (mp->mr_next_hop_out_label_stack,
9244                   next_hop_out_label_stack,
9245                   vec_len (next_hop_out_label_stack) *
9246                   sizeof (vl_api_fib_mpls_label_t));
9247           vec_free (next_hop_out_label_stack);
9248         }
9249
9250       if (next_hop_set)
9251         {
9252           if (DPO_PROTO_IP4 == next_hop_proto)
9253             {
9254               clib_memcpy (mp->mr_next_hop,
9255                            &v4_next_hop_address,
9256                            sizeof (v4_next_hop_address));
9257             }
9258           else if (DPO_PROTO_IP6 == next_hop_proto)
9259
9260             {
9261               clib_memcpy (mp->mr_next_hop,
9262                            &v6_next_hop_address,
9263                            sizeof (v6_next_hop_address));
9264             }
9265         }
9266       local_label++;
9267
9268       /* send it... */
9269       S (mp);
9270       /* If we receive SIGTERM, stop now... */
9271       if (vam->do_exit)
9272         break;
9273     }
9274
9275   /* When testing multiple add/del ops, use a control-ping to sync */
9276   if (count > 1)
9277     {
9278       vl_api_control_ping_t *mp_ping;
9279       f64 after;
9280       f64 timeout;
9281
9282       /* Shut off async mode */
9283       vam->async_mode = 0;
9284
9285       MPING (CONTROL_PING, mp_ping);
9286       S (mp_ping);
9287
9288       timeout = vat_time_now (vam) + 1.0;
9289       while (vat_time_now (vam) < timeout)
9290         if (vam->result_ready == 1)
9291           goto out;
9292       vam->retval = -99;
9293
9294     out:
9295       if (vam->retval == -99)
9296         errmsg ("timeout");
9297
9298       if (vam->async_errors > 0)
9299         {
9300           errmsg ("%d asynchronous errors", vam->async_errors);
9301           vam->retval = -98;
9302         }
9303       vam->async_errors = 0;
9304       after = vat_time_now (vam);
9305
9306       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9307       if (j > 0)
9308         count = j;
9309
9310       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9311              count, after - before, count / (after - before));
9312     }
9313   else
9314     {
9315       int ret;
9316
9317       /* Wait for a reply... */
9318       W (ret);
9319       return ret;
9320     }
9321
9322   /* Return the good/bad news */
9323   return (vam->retval);
9324 }
9325
9326 static int
9327 api_mpls_ip_bind_unbind (vat_main_t * vam)
9328 {
9329   unformat_input_t *i = vam->input;
9330   vl_api_mpls_ip_bind_unbind_t *mp;
9331   u32 ip_table_id = 0;
9332   u8 is_bind = 1;
9333   u8 is_ip4 = 1;
9334   ip4_address_t v4_address;
9335   ip6_address_t v6_address;
9336   u32 address_length;
9337   u8 address_set = 0;
9338   mpls_label_t local_label = MPLS_LABEL_INVALID;
9339   int ret;
9340
9341   /* Parse args required to build the message */
9342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9343     {
9344       if (unformat (i, "%U/%d", unformat_ip4_address,
9345                     &v4_address, &address_length))
9346         {
9347           is_ip4 = 1;
9348           address_set = 1;
9349         }
9350       else if (unformat (i, "%U/%d", unformat_ip6_address,
9351                          &v6_address, &address_length))
9352         {
9353           is_ip4 = 0;
9354           address_set = 1;
9355         }
9356       else if (unformat (i, "%d", &local_label))
9357         ;
9358       else if (unformat (i, "table-id %d", &ip_table_id))
9359         ;
9360       else if (unformat (i, "unbind"))
9361         is_bind = 0;
9362       else if (unformat (i, "bind"))
9363         is_bind = 1;
9364       else
9365         {
9366           clib_warning ("parse error '%U'", format_unformat_error, i);
9367           return -99;
9368         }
9369     }
9370
9371   if (!address_set)
9372     {
9373       errmsg ("IP address not set");
9374       return -99;
9375     }
9376
9377   if (MPLS_LABEL_INVALID == local_label)
9378     {
9379       errmsg ("missing label");
9380       return -99;
9381     }
9382
9383   /* Construct the API message */
9384   M (MPLS_IP_BIND_UNBIND, mp);
9385
9386   mp->mb_is_bind = is_bind;
9387   mp->mb_is_ip4 = is_ip4;
9388   mp->mb_ip_table_id = ntohl (ip_table_id);
9389   mp->mb_mpls_table_id = 0;
9390   mp->mb_label = ntohl (local_label);
9391   mp->mb_address_length = address_length;
9392
9393   if (is_ip4)
9394     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9395   else
9396     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9397
9398   /* send it... */
9399   S (mp);
9400
9401   /* Wait for a reply... */
9402   W (ret);
9403   return ret;
9404 }
9405
9406 static int
9407 api_sr_mpls_policy_add (vat_main_t * vam)
9408 {
9409   unformat_input_t *i = vam->input;
9410   vl_api_sr_mpls_policy_add_t *mp;
9411   u32 bsid = 0;
9412   u32 weight = 1;
9413   u8 type = 0;
9414   u8 n_segments = 0;
9415   u32 sid;
9416   u32 *segments = NULL;
9417   int ret;
9418
9419   /* Parse args required to build the message */
9420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9421     {
9422       if (unformat (i, "bsid %d", &bsid))
9423         ;
9424       else if (unformat (i, "weight %d", &weight))
9425         ;
9426       else if (unformat (i, "spray"))
9427         type = 1;
9428       else if (unformat (i, "next %d", &sid))
9429         {
9430           n_segments += 1;
9431           vec_add1 (segments, htonl (sid));
9432         }
9433       else
9434         {
9435           clib_warning ("parse error '%U'", format_unformat_error, i);
9436           return -99;
9437         }
9438     }
9439
9440   if (bsid == 0)
9441     {
9442       errmsg ("bsid not set");
9443       return -99;
9444     }
9445
9446   if (n_segments == 0)
9447     {
9448       errmsg ("no sid in segment stack");
9449       return -99;
9450     }
9451
9452   /* Construct the API message */
9453   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9454
9455   mp->bsid = htonl (bsid);
9456   mp->weight = htonl (weight);
9457   mp->type = type;
9458   mp->n_segments = n_segments;
9459   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9460   vec_free (segments);
9461
9462   /* send it... */
9463   S (mp);
9464
9465   /* Wait for a reply... */
9466   W (ret);
9467   return ret;
9468 }
9469
9470 static int
9471 api_sr_mpls_policy_del (vat_main_t * vam)
9472 {
9473   unformat_input_t *i = vam->input;
9474   vl_api_sr_mpls_policy_del_t *mp;
9475   u32 bsid = 0;
9476   int ret;
9477
9478   /* Parse args required to build the message */
9479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9480     {
9481       if (unformat (i, "bsid %d", &bsid))
9482         ;
9483       else
9484         {
9485           clib_warning ("parse error '%U'", format_unformat_error, i);
9486           return -99;
9487         }
9488     }
9489
9490   if (bsid == 0)
9491     {
9492       errmsg ("bsid not set");
9493       return -99;
9494     }
9495
9496   /* Construct the API message */
9497   M (SR_MPLS_POLICY_DEL, mp);
9498
9499   mp->bsid = htonl (bsid);
9500
9501   /* send it... */
9502   S (mp);
9503
9504   /* Wait for a reply... */
9505   W (ret);
9506   return ret;
9507 }
9508
9509 static int
9510 api_bier_table_add_del (vat_main_t * vam)
9511 {
9512   unformat_input_t *i = vam->input;
9513   vl_api_bier_table_add_del_t *mp;
9514   u8 is_add = 1;
9515   u32 set = 0, sub_domain = 0, hdr_len = 3;
9516   mpls_label_t local_label = MPLS_LABEL_INVALID;
9517   int ret;
9518
9519   /* Parse args required to build the message */
9520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9521     {
9522       if (unformat (i, "sub-domain %d", &sub_domain))
9523         ;
9524       else if (unformat (i, "set %d", &set))
9525         ;
9526       else if (unformat (i, "label %d", &local_label))
9527         ;
9528       else if (unformat (i, "hdr-len %d", &hdr_len))
9529         ;
9530       else if (unformat (i, "add"))
9531         is_add = 1;
9532       else if (unformat (i, "del"))
9533         is_add = 0;
9534       else
9535         {
9536           clib_warning ("parse error '%U'", format_unformat_error, i);
9537           return -99;
9538         }
9539     }
9540
9541   if (MPLS_LABEL_INVALID == local_label)
9542     {
9543       errmsg ("missing label\n");
9544       return -99;
9545     }
9546
9547   /* Construct the API message */
9548   M (BIER_TABLE_ADD_DEL, mp);
9549
9550   mp->bt_is_add = is_add;
9551   mp->bt_label = ntohl (local_label);
9552   mp->bt_tbl_id.bt_set = set;
9553   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9554   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9555
9556   /* send it... */
9557   S (mp);
9558
9559   /* Wait for a reply... */
9560   W (ret);
9561
9562   return (ret);
9563 }
9564
9565 static int
9566 api_bier_route_add_del (vat_main_t * vam)
9567 {
9568   unformat_input_t *i = vam->input;
9569   vl_api_bier_route_add_del_t *mp;
9570   u8 is_add = 1;
9571   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9572   ip4_address_t v4_next_hop_address;
9573   ip6_address_t v6_next_hop_address;
9574   u8 next_hop_set = 0;
9575   u8 next_hop_proto_is_ip4 = 1;
9576   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9577   int ret;
9578
9579   /* Parse args required to build the message */
9580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9581     {
9582       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9583         {
9584           next_hop_proto_is_ip4 = 1;
9585           next_hop_set = 1;
9586         }
9587       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9588         {
9589           next_hop_proto_is_ip4 = 0;
9590           next_hop_set = 1;
9591         }
9592       if (unformat (i, "sub-domain %d", &sub_domain))
9593         ;
9594       else if (unformat (i, "set %d", &set))
9595         ;
9596       else if (unformat (i, "hdr-len %d", &hdr_len))
9597         ;
9598       else if (unformat (i, "bp %d", &bp))
9599         ;
9600       else if (unformat (i, "add"))
9601         is_add = 1;
9602       else if (unformat (i, "del"))
9603         is_add = 0;
9604       else if (unformat (i, "out-label %d", &next_hop_out_label))
9605         ;
9606       else
9607         {
9608           clib_warning ("parse error '%U'", format_unformat_error, i);
9609           return -99;
9610         }
9611     }
9612
9613   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9614     {
9615       errmsg ("next hop / label set\n");
9616       return -99;
9617     }
9618   if (0 == bp)
9619     {
9620       errmsg ("bit=position not set\n");
9621       return -99;
9622     }
9623
9624   /* Construct the API message */
9625   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9626
9627   mp->br_is_add = is_add;
9628   mp->br_tbl_id.bt_set = set;
9629   mp->br_tbl_id.bt_sub_domain = sub_domain;
9630   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9631   mp->br_bp = ntohs (bp);
9632   mp->br_n_paths = 1;
9633   mp->br_paths[0].n_labels = 1;
9634   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9635   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9636
9637   if (next_hop_proto_is_ip4)
9638     {
9639       clib_memcpy (mp->br_paths[0].next_hop,
9640                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9641     }
9642   else
9643     {
9644       clib_memcpy (mp->br_paths[0].next_hop,
9645                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9646     }
9647
9648   /* send it... */
9649   S (mp);
9650
9651   /* Wait for a reply... */
9652   W (ret);
9653
9654   return (ret);
9655 }
9656
9657 static int
9658 api_proxy_arp_add_del (vat_main_t * vam)
9659 {
9660   unformat_input_t *i = vam->input;
9661   vl_api_proxy_arp_add_del_t *mp;
9662   u32 vrf_id = 0;
9663   u8 is_add = 1;
9664   ip4_address_t lo, hi;
9665   u8 range_set = 0;
9666   int ret;
9667
9668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9669     {
9670       if (unformat (i, "vrf %d", &vrf_id))
9671         ;
9672       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9673                          unformat_ip4_address, &hi))
9674         range_set = 1;
9675       else if (unformat (i, "del"))
9676         is_add = 0;
9677       else
9678         {
9679           clib_warning ("parse error '%U'", format_unformat_error, i);
9680           return -99;
9681         }
9682     }
9683
9684   if (range_set == 0)
9685     {
9686       errmsg ("address range not set");
9687       return -99;
9688     }
9689
9690   M (PROXY_ARP_ADD_DEL, mp);
9691
9692   mp->proxy.vrf_id = ntohl (vrf_id);
9693   mp->is_add = is_add;
9694   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9695   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9696
9697   S (mp);
9698   W (ret);
9699   return ret;
9700 }
9701
9702 static int
9703 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9704 {
9705   unformat_input_t *i = vam->input;
9706   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9707   u32 sw_if_index;
9708   u8 enable = 1;
9709   u8 sw_if_index_set = 0;
9710   int ret;
9711
9712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9713     {
9714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9715         sw_if_index_set = 1;
9716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9717         sw_if_index_set = 1;
9718       else if (unformat (i, "enable"))
9719         enable = 1;
9720       else if (unformat (i, "disable"))
9721         enable = 0;
9722       else
9723         {
9724           clib_warning ("parse error '%U'", format_unformat_error, i);
9725           return -99;
9726         }
9727     }
9728
9729   if (sw_if_index_set == 0)
9730     {
9731       errmsg ("missing interface name or sw_if_index");
9732       return -99;
9733     }
9734
9735   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9736
9737   mp->sw_if_index = ntohl (sw_if_index);
9738   mp->enable_disable = enable;
9739
9740   S (mp);
9741   W (ret);
9742   return ret;
9743 }
9744
9745 static int
9746 api_mpls_tunnel_add_del (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   vl_api_mpls_tunnel_add_del_t *mp;
9750
9751   u8 is_add = 1;
9752   u8 l2_only = 0;
9753   u32 sw_if_index = ~0;
9754   u32 next_hop_sw_if_index = ~0;
9755   u32 next_hop_proto_is_ip4 = 1;
9756
9757   u32 next_hop_table_id = 0;
9758   ip4_address_t v4_next_hop_address = {
9759     .as_u32 = 0,
9760   };
9761   ip6_address_t v6_next_hop_address = { {0} };
9762   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9763   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9764   int ret;
9765
9766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9767     {
9768       if (unformat (i, "add"))
9769         is_add = 1;
9770       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9771         is_add = 0;
9772       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9773         ;
9774       else if (unformat (i, "via %U",
9775                          unformat_ip4_address, &v4_next_hop_address))
9776         {
9777           next_hop_proto_is_ip4 = 1;
9778         }
9779       else if (unformat (i, "via %U",
9780                          unformat_ip6_address, &v6_next_hop_address))
9781         {
9782           next_hop_proto_is_ip4 = 0;
9783         }
9784       else if (unformat (i, "via-label %d", &next_hop_via_label))
9785         ;
9786       else if (unformat (i, "l2-only"))
9787         l2_only = 1;
9788       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9789         ;
9790       else if (unformat (i, "out-label %d", &next_hop_out_label))
9791         vec_add1 (labels, ntohl (next_hop_out_label));
9792       else
9793         {
9794           clib_warning ("parse error '%U'", format_unformat_error, i);
9795           return -99;
9796         }
9797     }
9798
9799   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9800
9801   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9802   mp->mt_sw_if_index = ntohl (sw_if_index);
9803   mp->mt_is_add = is_add;
9804   mp->mt_l2_only = l2_only;
9805   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9806   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9807   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9808
9809   mp->mt_next_hop_n_out_labels = vec_len (labels);
9810
9811   if (0 != mp->mt_next_hop_n_out_labels)
9812     {
9813       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9814                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9815       vec_free (labels);
9816     }
9817
9818   if (next_hop_proto_is_ip4)
9819     {
9820       clib_memcpy (mp->mt_next_hop,
9821                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9822     }
9823   else
9824     {
9825       clib_memcpy (mp->mt_next_hop,
9826                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9827     }
9828
9829   S (mp);
9830   W (ret);
9831   return ret;
9832 }
9833
9834 static int
9835 api_sw_interface_set_unnumbered (vat_main_t * vam)
9836 {
9837   unformat_input_t *i = vam->input;
9838   vl_api_sw_interface_set_unnumbered_t *mp;
9839   u32 sw_if_index;
9840   u32 unnum_sw_index = ~0;
9841   u8 is_add = 1;
9842   u8 sw_if_index_set = 0;
9843   int ret;
9844
9845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9846     {
9847       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9848         sw_if_index_set = 1;
9849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9850         sw_if_index_set = 1;
9851       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9852         ;
9853       else if (unformat (i, "del"))
9854         is_add = 0;
9855       else
9856         {
9857           clib_warning ("parse error '%U'", format_unformat_error, i);
9858           return -99;
9859         }
9860     }
9861
9862   if (sw_if_index_set == 0)
9863     {
9864       errmsg ("missing interface name or sw_if_index");
9865       return -99;
9866     }
9867
9868   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9869
9870   mp->sw_if_index = ntohl (sw_if_index);
9871   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9872   mp->is_add = is_add;
9873
9874   S (mp);
9875   W (ret);
9876   return ret;
9877 }
9878
9879 static int
9880 api_ip_neighbor_add_del (vat_main_t * vam)
9881 {
9882   unformat_input_t *i = vam->input;
9883   vl_api_ip_neighbor_add_del_t *mp;
9884   u32 sw_if_index;
9885   u8 sw_if_index_set = 0;
9886   u8 is_add = 1;
9887   u8 is_static = 0;
9888   u8 is_no_fib_entry = 0;
9889   u8 mac_address[6];
9890   u8 mac_set = 0;
9891   u8 v4_address_set = 0;
9892   u8 v6_address_set = 0;
9893   ip4_address_t v4address;
9894   ip6_address_t v6address;
9895   int ret;
9896
9897   memset (mac_address, 0, sizeof (mac_address));
9898
9899   /* Parse args required to build the message */
9900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9901     {
9902       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9903         {
9904           mac_set = 1;
9905         }
9906       else if (unformat (i, "del"))
9907         is_add = 0;
9908       else
9909         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9910         sw_if_index_set = 1;
9911       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9912         sw_if_index_set = 1;
9913       else if (unformat (i, "is_static"))
9914         is_static = 1;
9915       else if (unformat (i, "no-fib-entry"))
9916         is_no_fib_entry = 1;
9917       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9918         v4_address_set = 1;
9919       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9920         v6_address_set = 1;
9921       else
9922         {
9923           clib_warning ("parse error '%U'", format_unformat_error, i);
9924           return -99;
9925         }
9926     }
9927
9928   if (sw_if_index_set == 0)
9929     {
9930       errmsg ("missing interface name or sw_if_index");
9931       return -99;
9932     }
9933   if (v4_address_set && v6_address_set)
9934     {
9935       errmsg ("both v4 and v6 addresses set");
9936       return -99;
9937     }
9938   if (!v4_address_set && !v6_address_set)
9939     {
9940       errmsg ("no address set");
9941       return -99;
9942     }
9943
9944   /* Construct the API message */
9945   M (IP_NEIGHBOR_ADD_DEL, mp);
9946
9947   mp->sw_if_index = ntohl (sw_if_index);
9948   mp->is_add = is_add;
9949   mp->is_static = is_static;
9950   mp->is_no_adj_fib = is_no_fib_entry;
9951   if (mac_set)
9952     clib_memcpy (mp->mac_address, mac_address, 6);
9953   if (v6_address_set)
9954     {
9955       mp->is_ipv6 = 1;
9956       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9957     }
9958   else
9959     {
9960       /* mp->is_ipv6 = 0; via memset in M macro above */
9961       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9962     }
9963
9964   /* send it... */
9965   S (mp);
9966
9967   /* Wait for a reply, return good/bad news  */
9968   W (ret);
9969   return ret;
9970 }
9971
9972 static int
9973 api_create_vlan_subif (vat_main_t * vam)
9974 {
9975   unformat_input_t *i = vam->input;
9976   vl_api_create_vlan_subif_t *mp;
9977   u32 sw_if_index;
9978   u8 sw_if_index_set = 0;
9979   u32 vlan_id;
9980   u8 vlan_id_set = 0;
9981   int ret;
9982
9983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9984     {
9985       if (unformat (i, "sw_if_index %d", &sw_if_index))
9986         sw_if_index_set = 1;
9987       else
9988         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9989         sw_if_index_set = 1;
9990       else if (unformat (i, "vlan %d", &vlan_id))
9991         vlan_id_set = 1;
9992       else
9993         {
9994           clib_warning ("parse error '%U'", format_unformat_error, i);
9995           return -99;
9996         }
9997     }
9998
9999   if (sw_if_index_set == 0)
10000     {
10001       errmsg ("missing interface name or sw_if_index");
10002       return -99;
10003     }
10004
10005   if (vlan_id_set == 0)
10006     {
10007       errmsg ("missing vlan_id");
10008       return -99;
10009     }
10010   M (CREATE_VLAN_SUBIF, mp);
10011
10012   mp->sw_if_index = ntohl (sw_if_index);
10013   mp->vlan_id = ntohl (vlan_id);
10014
10015   S (mp);
10016   W (ret);
10017   return ret;
10018 }
10019
10020 #define foreach_create_subif_bit                \
10021 _(no_tags)                                      \
10022 _(one_tag)                                      \
10023 _(two_tags)                                     \
10024 _(dot1ad)                                       \
10025 _(exact_match)                                  \
10026 _(default_sub)                                  \
10027 _(outer_vlan_id_any)                            \
10028 _(inner_vlan_id_any)
10029
10030 static int
10031 api_create_subif (vat_main_t * vam)
10032 {
10033   unformat_input_t *i = vam->input;
10034   vl_api_create_subif_t *mp;
10035   u32 sw_if_index;
10036   u8 sw_if_index_set = 0;
10037   u32 sub_id;
10038   u8 sub_id_set = 0;
10039   u32 no_tags = 0;
10040   u32 one_tag = 0;
10041   u32 two_tags = 0;
10042   u32 dot1ad = 0;
10043   u32 exact_match = 0;
10044   u32 default_sub = 0;
10045   u32 outer_vlan_id_any = 0;
10046   u32 inner_vlan_id_any = 0;
10047   u32 tmp;
10048   u16 outer_vlan_id = 0;
10049   u16 inner_vlan_id = 0;
10050   int ret;
10051
10052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10053     {
10054       if (unformat (i, "sw_if_index %d", &sw_if_index))
10055         sw_if_index_set = 1;
10056       else
10057         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10058         sw_if_index_set = 1;
10059       else if (unformat (i, "sub_id %d", &sub_id))
10060         sub_id_set = 1;
10061       else if (unformat (i, "outer_vlan_id %d", &tmp))
10062         outer_vlan_id = tmp;
10063       else if (unformat (i, "inner_vlan_id %d", &tmp))
10064         inner_vlan_id = tmp;
10065
10066 #define _(a) else if (unformat (i, #a)) a = 1 ;
10067       foreach_create_subif_bit
10068 #undef _
10069         else
10070         {
10071           clib_warning ("parse error '%U'", format_unformat_error, i);
10072           return -99;
10073         }
10074     }
10075
10076   if (sw_if_index_set == 0)
10077     {
10078       errmsg ("missing interface name or sw_if_index");
10079       return -99;
10080     }
10081
10082   if (sub_id_set == 0)
10083     {
10084       errmsg ("missing sub_id");
10085       return -99;
10086     }
10087   M (CREATE_SUBIF, mp);
10088
10089   mp->sw_if_index = ntohl (sw_if_index);
10090   mp->sub_id = ntohl (sub_id);
10091
10092 #define _(a) mp->a = a;
10093   foreach_create_subif_bit;
10094 #undef _
10095
10096   mp->outer_vlan_id = ntohs (outer_vlan_id);
10097   mp->inner_vlan_id = ntohs (inner_vlan_id);
10098
10099   S (mp);
10100   W (ret);
10101   return ret;
10102 }
10103
10104 static int
10105 api_oam_add_del (vat_main_t * vam)
10106 {
10107   unformat_input_t *i = vam->input;
10108   vl_api_oam_add_del_t *mp;
10109   u32 vrf_id = 0;
10110   u8 is_add = 1;
10111   ip4_address_t src, dst;
10112   u8 src_set = 0;
10113   u8 dst_set = 0;
10114   int ret;
10115
10116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10117     {
10118       if (unformat (i, "vrf %d", &vrf_id))
10119         ;
10120       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10121         src_set = 1;
10122       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10123         dst_set = 1;
10124       else if (unformat (i, "del"))
10125         is_add = 0;
10126       else
10127         {
10128           clib_warning ("parse error '%U'", format_unformat_error, i);
10129           return -99;
10130         }
10131     }
10132
10133   if (src_set == 0)
10134     {
10135       errmsg ("missing src addr");
10136       return -99;
10137     }
10138
10139   if (dst_set == 0)
10140     {
10141       errmsg ("missing dst addr");
10142       return -99;
10143     }
10144
10145   M (OAM_ADD_DEL, mp);
10146
10147   mp->vrf_id = ntohl (vrf_id);
10148   mp->is_add = is_add;
10149   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10150   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10151
10152   S (mp);
10153   W (ret);
10154   return ret;
10155 }
10156
10157 static int
10158 api_reset_fib (vat_main_t * vam)
10159 {
10160   unformat_input_t *i = vam->input;
10161   vl_api_reset_fib_t *mp;
10162   u32 vrf_id = 0;
10163   u8 is_ipv6 = 0;
10164   u8 vrf_id_set = 0;
10165
10166   int ret;
10167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10168     {
10169       if (unformat (i, "vrf %d", &vrf_id))
10170         vrf_id_set = 1;
10171       else if (unformat (i, "ipv6"))
10172         is_ipv6 = 1;
10173       else
10174         {
10175           clib_warning ("parse error '%U'", format_unformat_error, i);
10176           return -99;
10177         }
10178     }
10179
10180   if (vrf_id_set == 0)
10181     {
10182       errmsg ("missing vrf id");
10183       return -99;
10184     }
10185
10186   M (RESET_FIB, mp);
10187
10188   mp->vrf_id = ntohl (vrf_id);
10189   mp->is_ipv6 = is_ipv6;
10190
10191   S (mp);
10192   W (ret);
10193   return ret;
10194 }
10195
10196 static int
10197 api_dhcp_proxy_config (vat_main_t * vam)
10198 {
10199   unformat_input_t *i = vam->input;
10200   vl_api_dhcp_proxy_config_t *mp;
10201   u32 rx_vrf_id = 0;
10202   u32 server_vrf_id = 0;
10203   u8 is_add = 1;
10204   u8 v4_address_set = 0;
10205   u8 v6_address_set = 0;
10206   ip4_address_t v4address;
10207   ip6_address_t v6address;
10208   u8 v4_src_address_set = 0;
10209   u8 v6_src_address_set = 0;
10210   ip4_address_t v4srcaddress;
10211   ip6_address_t v6srcaddress;
10212   int ret;
10213
10214   /* Parse args required to build the message */
10215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10216     {
10217       if (unformat (i, "del"))
10218         is_add = 0;
10219       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10220         ;
10221       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10222         ;
10223       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10224         v4_address_set = 1;
10225       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10226         v6_address_set = 1;
10227       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10228         v4_src_address_set = 1;
10229       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10230         v6_src_address_set = 1;
10231       else
10232         break;
10233     }
10234
10235   if (v4_address_set && v6_address_set)
10236     {
10237       errmsg ("both v4 and v6 server addresses set");
10238       return -99;
10239     }
10240   if (!v4_address_set && !v6_address_set)
10241     {
10242       errmsg ("no server addresses set");
10243       return -99;
10244     }
10245
10246   if (v4_src_address_set && v6_src_address_set)
10247     {
10248       errmsg ("both v4 and v6  src addresses set");
10249       return -99;
10250     }
10251   if (!v4_src_address_set && !v6_src_address_set)
10252     {
10253       errmsg ("no src addresses set");
10254       return -99;
10255     }
10256
10257   if (!(v4_src_address_set && v4_address_set) &&
10258       !(v6_src_address_set && v6_address_set))
10259     {
10260       errmsg ("no matching server and src addresses set");
10261       return -99;
10262     }
10263
10264   /* Construct the API message */
10265   M (DHCP_PROXY_CONFIG, mp);
10266
10267   mp->is_add = is_add;
10268   mp->rx_vrf_id = ntohl (rx_vrf_id);
10269   mp->server_vrf_id = ntohl (server_vrf_id);
10270   if (v6_address_set)
10271     {
10272       mp->is_ipv6 = 1;
10273       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10274       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10275     }
10276   else
10277     {
10278       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10279       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10280     }
10281
10282   /* send it... */
10283   S (mp);
10284
10285   /* Wait for a reply, return good/bad news  */
10286   W (ret);
10287   return ret;
10288 }
10289
10290 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10291 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10292
10293 static void
10294 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10295 {
10296   vat_main_t *vam = &vat_main;
10297   u32 i, count = mp->count;
10298   vl_api_dhcp_server_t *s;
10299
10300   if (mp->is_ipv6)
10301     print (vam->ofp,
10302            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10303            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10304            ntohl (mp->rx_vrf_id),
10305            format_ip6_address, mp->dhcp_src_address,
10306            mp->vss_type, mp->vss_vpn_ascii_id,
10307            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10308   else
10309     print (vam->ofp,
10310            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10311            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10312            ntohl (mp->rx_vrf_id),
10313            format_ip4_address, mp->dhcp_src_address,
10314            mp->vss_type, mp->vss_vpn_ascii_id,
10315            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10316
10317   for (i = 0; i < count; i++)
10318     {
10319       s = &mp->servers[i];
10320
10321       if (mp->is_ipv6)
10322         print (vam->ofp,
10323                " Server Table-ID %d, Server Address %U",
10324                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10325       else
10326         print (vam->ofp,
10327                " Server Table-ID %d, Server Address %U",
10328                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10329     }
10330 }
10331
10332 static void vl_api_dhcp_proxy_details_t_handler_json
10333   (vl_api_dhcp_proxy_details_t * mp)
10334 {
10335   vat_main_t *vam = &vat_main;
10336   vat_json_node_t *node = NULL;
10337   u32 i, count = mp->count;
10338   struct in_addr ip4;
10339   struct in6_addr ip6;
10340   vl_api_dhcp_server_t *s;
10341
10342   if (VAT_JSON_ARRAY != vam->json_tree.type)
10343     {
10344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10345       vat_json_init_array (&vam->json_tree);
10346     }
10347   node = vat_json_array_add (&vam->json_tree);
10348
10349   vat_json_init_object (node);
10350   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10351   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10352                              sizeof (mp->vss_type));
10353   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10354                                    mp->vss_vpn_ascii_id);
10355   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10356   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10357
10358   if (mp->is_ipv6)
10359     {
10360       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10361       vat_json_object_add_ip6 (node, "src_address", ip6);
10362     }
10363   else
10364     {
10365       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10366       vat_json_object_add_ip4 (node, "src_address", ip4);
10367     }
10368
10369   for (i = 0; i < count; i++)
10370     {
10371       s = &mp->servers[i];
10372
10373       vat_json_object_add_uint (node, "server-table-id",
10374                                 ntohl (s->server_vrf_id));
10375
10376       if (mp->is_ipv6)
10377         {
10378           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10379           vat_json_object_add_ip4 (node, "src_address", ip4);
10380         }
10381       else
10382         {
10383           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10384           vat_json_object_add_ip6 (node, "server_address", ip6);
10385         }
10386     }
10387 }
10388
10389 static int
10390 api_dhcp_proxy_dump (vat_main_t * vam)
10391 {
10392   unformat_input_t *i = vam->input;
10393   vl_api_control_ping_t *mp_ping;
10394   vl_api_dhcp_proxy_dump_t *mp;
10395   u8 is_ipv6 = 0;
10396   int ret;
10397
10398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10399     {
10400       if (unformat (i, "ipv6"))
10401         is_ipv6 = 1;
10402       else
10403         {
10404           clib_warning ("parse error '%U'", format_unformat_error, i);
10405           return -99;
10406         }
10407     }
10408
10409   M (DHCP_PROXY_DUMP, mp);
10410
10411   mp->is_ip6 = is_ipv6;
10412   S (mp);
10413
10414   /* Use a control ping for synchronization */
10415   MPING (CONTROL_PING, mp_ping);
10416   S (mp_ping);
10417
10418   W (ret);
10419   return ret;
10420 }
10421
10422 static int
10423 api_dhcp_proxy_set_vss (vat_main_t * vam)
10424 {
10425   unformat_input_t *i = vam->input;
10426   vl_api_dhcp_proxy_set_vss_t *mp;
10427   u8 is_ipv6 = 0;
10428   u8 is_add = 1;
10429   u32 tbl_id = ~0;
10430   u8 vss_type = VSS_TYPE_DEFAULT;
10431   u8 *vpn_ascii_id = 0;
10432   u32 oui = 0;
10433   u32 fib_id = 0;
10434   int ret;
10435
10436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10437     {
10438       if (unformat (i, "tbl_id %d", &tbl_id))
10439         ;
10440       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10441         vss_type = VSS_TYPE_ASCII;
10442       else if (unformat (i, "fib_id %d", &fib_id))
10443         vss_type = VSS_TYPE_VPN_ID;
10444       else if (unformat (i, "oui %d", &oui))
10445         vss_type = VSS_TYPE_VPN_ID;
10446       else if (unformat (i, "ipv6"))
10447         is_ipv6 = 1;
10448       else if (unformat (i, "del"))
10449         is_add = 0;
10450       else
10451         break;
10452     }
10453
10454   if (tbl_id == ~0)
10455     {
10456       errmsg ("missing tbl_id ");
10457       vec_free (vpn_ascii_id);
10458       return -99;
10459     }
10460
10461   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10462     {
10463       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10464       vec_free (vpn_ascii_id);
10465       return -99;
10466     }
10467
10468   M (DHCP_PROXY_SET_VSS, mp);
10469   mp->tbl_id = ntohl (tbl_id);
10470   mp->vss_type = vss_type;
10471   if (vpn_ascii_id)
10472     {
10473       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10474       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10475     }
10476   mp->vpn_index = ntohl (fib_id);
10477   mp->oui = ntohl (oui);
10478   mp->is_ipv6 = is_ipv6;
10479   mp->is_add = is_add;
10480
10481   S (mp);
10482   W (ret);
10483
10484   vec_free (vpn_ascii_id);
10485   return ret;
10486 }
10487
10488 static int
10489 api_dhcp_client_config (vat_main_t * vam)
10490 {
10491   unformat_input_t *i = vam->input;
10492   vl_api_dhcp_client_config_t *mp;
10493   u32 sw_if_index;
10494   u8 sw_if_index_set = 0;
10495   u8 is_add = 1;
10496   u8 *hostname = 0;
10497   u8 disable_event = 0;
10498   int ret;
10499
10500   /* Parse args required to build the message */
10501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10502     {
10503       if (unformat (i, "del"))
10504         is_add = 0;
10505       else
10506         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10507         sw_if_index_set = 1;
10508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10509         sw_if_index_set = 1;
10510       else if (unformat (i, "hostname %s", &hostname))
10511         ;
10512       else if (unformat (i, "disable_event"))
10513         disable_event = 1;
10514       else
10515         break;
10516     }
10517
10518   if (sw_if_index_set == 0)
10519     {
10520       errmsg ("missing interface name or sw_if_index");
10521       return -99;
10522     }
10523
10524   if (vec_len (hostname) > 63)
10525     {
10526       errmsg ("hostname too long");
10527     }
10528   vec_add1 (hostname, 0);
10529
10530   /* Construct the API message */
10531   M (DHCP_CLIENT_CONFIG, mp);
10532
10533   mp->is_add = is_add;
10534   mp->client.sw_if_index = htonl (sw_if_index);
10535   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10536   vec_free (hostname);
10537   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10538   mp->client.pid = htonl (getpid ());
10539
10540   /* send it... */
10541   S (mp);
10542
10543   /* Wait for a reply, return good/bad news  */
10544   W (ret);
10545   return ret;
10546 }
10547
10548 static int
10549 api_set_ip_flow_hash (vat_main_t * vam)
10550 {
10551   unformat_input_t *i = vam->input;
10552   vl_api_set_ip_flow_hash_t *mp;
10553   u32 vrf_id = 0;
10554   u8 is_ipv6 = 0;
10555   u8 vrf_id_set = 0;
10556   u8 src = 0;
10557   u8 dst = 0;
10558   u8 sport = 0;
10559   u8 dport = 0;
10560   u8 proto = 0;
10561   u8 reverse = 0;
10562   int ret;
10563
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "vrf %d", &vrf_id))
10567         vrf_id_set = 1;
10568       else if (unformat (i, "ipv6"))
10569         is_ipv6 = 1;
10570       else if (unformat (i, "src"))
10571         src = 1;
10572       else if (unformat (i, "dst"))
10573         dst = 1;
10574       else if (unformat (i, "sport"))
10575         sport = 1;
10576       else if (unformat (i, "dport"))
10577         dport = 1;
10578       else if (unformat (i, "proto"))
10579         proto = 1;
10580       else if (unformat (i, "reverse"))
10581         reverse = 1;
10582
10583       else
10584         {
10585           clib_warning ("parse error '%U'", format_unformat_error, i);
10586           return -99;
10587         }
10588     }
10589
10590   if (vrf_id_set == 0)
10591     {
10592       errmsg ("missing vrf id");
10593       return -99;
10594     }
10595
10596   M (SET_IP_FLOW_HASH, mp);
10597   mp->src = src;
10598   mp->dst = dst;
10599   mp->sport = sport;
10600   mp->dport = dport;
10601   mp->proto = proto;
10602   mp->reverse = reverse;
10603   mp->vrf_id = ntohl (vrf_id);
10604   mp->is_ipv6 = is_ipv6;
10605
10606   S (mp);
10607   W (ret);
10608   return ret;
10609 }
10610
10611 static int
10612 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10613 {
10614   unformat_input_t *i = vam->input;
10615   vl_api_sw_interface_ip6_enable_disable_t *mp;
10616   u32 sw_if_index;
10617   u8 sw_if_index_set = 0;
10618   u8 enable = 0;
10619   int ret;
10620
10621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10624         sw_if_index_set = 1;
10625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10626         sw_if_index_set = 1;
10627       else if (unformat (i, "enable"))
10628         enable = 1;
10629       else if (unformat (i, "disable"))
10630         enable = 0;
10631       else
10632         {
10633           clib_warning ("parse error '%U'", format_unformat_error, i);
10634           return -99;
10635         }
10636     }
10637
10638   if (sw_if_index_set == 0)
10639     {
10640       errmsg ("missing interface name or sw_if_index");
10641       return -99;
10642     }
10643
10644   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10645
10646   mp->sw_if_index = ntohl (sw_if_index);
10647   mp->enable = enable;
10648
10649   S (mp);
10650   W (ret);
10651   return ret;
10652 }
10653
10654 static int
10655 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10656 {
10657   unformat_input_t *i = vam->input;
10658   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10659   u32 sw_if_index;
10660   u8 sw_if_index_set = 0;
10661   u8 v6_address_set = 0;
10662   ip6_address_t v6address;
10663   int ret;
10664
10665   /* Parse args required to build the message */
10666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10667     {
10668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10669         sw_if_index_set = 1;
10670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10671         sw_if_index_set = 1;
10672       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10673         v6_address_set = 1;
10674       else
10675         break;
10676     }
10677
10678   if (sw_if_index_set == 0)
10679     {
10680       errmsg ("missing interface name or sw_if_index");
10681       return -99;
10682     }
10683   if (!v6_address_set)
10684     {
10685       errmsg ("no address set");
10686       return -99;
10687     }
10688
10689   /* Construct the API message */
10690   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10691
10692   mp->sw_if_index = ntohl (sw_if_index);
10693   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10694
10695   /* send it... */
10696   S (mp);
10697
10698   /* Wait for a reply, return good/bad news  */
10699   W (ret);
10700   return ret;
10701 }
10702
10703 static int
10704 api_ip6nd_proxy_add_del (vat_main_t * vam)
10705 {
10706   unformat_input_t *i = vam->input;
10707   vl_api_ip6nd_proxy_add_del_t *mp;
10708   u32 sw_if_index = ~0;
10709   u8 v6_address_set = 0;
10710   ip6_address_t v6address;
10711   u8 is_del = 0;
10712   int ret;
10713
10714   /* Parse args required to build the message */
10715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10716     {
10717       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10718         ;
10719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10720         ;
10721       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10722         v6_address_set = 1;
10723       if (unformat (i, "del"))
10724         is_del = 1;
10725       else
10726         {
10727           clib_warning ("parse error '%U'", format_unformat_error, i);
10728           return -99;
10729         }
10730     }
10731
10732   if (sw_if_index == ~0)
10733     {
10734       errmsg ("missing interface name or sw_if_index");
10735       return -99;
10736     }
10737   if (!v6_address_set)
10738     {
10739       errmsg ("no address set");
10740       return -99;
10741     }
10742
10743   /* Construct the API message */
10744   M (IP6ND_PROXY_ADD_DEL, mp);
10745
10746   mp->is_del = is_del;
10747   mp->sw_if_index = ntohl (sw_if_index);
10748   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10749
10750   /* send it... */
10751   S (mp);
10752
10753   /* Wait for a reply, return good/bad news  */
10754   W (ret);
10755   return ret;
10756 }
10757
10758 static int
10759 api_ip6nd_proxy_dump (vat_main_t * vam)
10760 {
10761   vl_api_ip6nd_proxy_dump_t *mp;
10762   vl_api_control_ping_t *mp_ping;
10763   int ret;
10764
10765   M (IP6ND_PROXY_DUMP, mp);
10766
10767   S (mp);
10768
10769   /* Use a control ping for synchronization */
10770   MPING (CONTROL_PING, mp_ping);
10771   S (mp_ping);
10772
10773   W (ret);
10774   return ret;
10775 }
10776
10777 static void vl_api_ip6nd_proxy_details_t_handler
10778   (vl_api_ip6nd_proxy_details_t * mp)
10779 {
10780   vat_main_t *vam = &vat_main;
10781
10782   print (vam->ofp, "host %U sw_if_index %d",
10783          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10784 }
10785
10786 static void vl_api_ip6nd_proxy_details_t_handler_json
10787   (vl_api_ip6nd_proxy_details_t * mp)
10788 {
10789   vat_main_t *vam = &vat_main;
10790   struct in6_addr ip6;
10791   vat_json_node_t *node = NULL;
10792
10793   if (VAT_JSON_ARRAY != vam->json_tree.type)
10794     {
10795       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10796       vat_json_init_array (&vam->json_tree);
10797     }
10798   node = vat_json_array_add (&vam->json_tree);
10799
10800   vat_json_init_object (node);
10801   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10802
10803   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10804   vat_json_object_add_ip6 (node, "host", ip6);
10805 }
10806
10807 static int
10808 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10809 {
10810   unformat_input_t *i = vam->input;
10811   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10812   u32 sw_if_index;
10813   u8 sw_if_index_set = 0;
10814   u32 address_length = 0;
10815   u8 v6_address_set = 0;
10816   ip6_address_t v6address;
10817   u8 use_default = 0;
10818   u8 no_advertise = 0;
10819   u8 off_link = 0;
10820   u8 no_autoconfig = 0;
10821   u8 no_onlink = 0;
10822   u8 is_no = 0;
10823   u32 val_lifetime = 0;
10824   u32 pref_lifetime = 0;
10825   int ret;
10826
10827   /* Parse args required to build the message */
10828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10829     {
10830       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10831         sw_if_index_set = 1;
10832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10833         sw_if_index_set = 1;
10834       else if (unformat (i, "%U/%d",
10835                          unformat_ip6_address, &v6address, &address_length))
10836         v6_address_set = 1;
10837       else if (unformat (i, "val_life %d", &val_lifetime))
10838         ;
10839       else if (unformat (i, "pref_life %d", &pref_lifetime))
10840         ;
10841       else if (unformat (i, "def"))
10842         use_default = 1;
10843       else if (unformat (i, "noadv"))
10844         no_advertise = 1;
10845       else if (unformat (i, "offl"))
10846         off_link = 1;
10847       else if (unformat (i, "noauto"))
10848         no_autoconfig = 1;
10849       else if (unformat (i, "nolink"))
10850         no_onlink = 1;
10851       else if (unformat (i, "isno"))
10852         is_no = 1;
10853       else
10854         {
10855           clib_warning ("parse error '%U'", format_unformat_error, i);
10856           return -99;
10857         }
10858     }
10859
10860   if (sw_if_index_set == 0)
10861     {
10862       errmsg ("missing interface name or sw_if_index");
10863       return -99;
10864     }
10865   if (!v6_address_set)
10866     {
10867       errmsg ("no address set");
10868       return -99;
10869     }
10870
10871   /* Construct the API message */
10872   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10873
10874   mp->sw_if_index = ntohl (sw_if_index);
10875   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10876   mp->address_length = address_length;
10877   mp->use_default = use_default;
10878   mp->no_advertise = no_advertise;
10879   mp->off_link = off_link;
10880   mp->no_autoconfig = no_autoconfig;
10881   mp->no_onlink = no_onlink;
10882   mp->is_no = is_no;
10883   mp->val_lifetime = ntohl (val_lifetime);
10884   mp->pref_lifetime = ntohl (pref_lifetime);
10885
10886   /* send it... */
10887   S (mp);
10888
10889   /* Wait for a reply, return good/bad news  */
10890   W (ret);
10891   return ret;
10892 }
10893
10894 static int
10895 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10896 {
10897   unformat_input_t *i = vam->input;
10898   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10899   u32 sw_if_index;
10900   u8 sw_if_index_set = 0;
10901   u8 suppress = 0;
10902   u8 managed = 0;
10903   u8 other = 0;
10904   u8 ll_option = 0;
10905   u8 send_unicast = 0;
10906   u8 cease = 0;
10907   u8 is_no = 0;
10908   u8 default_router = 0;
10909   u32 max_interval = 0;
10910   u32 min_interval = 0;
10911   u32 lifetime = 0;
10912   u32 initial_count = 0;
10913   u32 initial_interval = 0;
10914   int ret;
10915
10916
10917   /* Parse args required to build the message */
10918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10921         sw_if_index_set = 1;
10922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10923         sw_if_index_set = 1;
10924       else if (unformat (i, "maxint %d", &max_interval))
10925         ;
10926       else if (unformat (i, "minint %d", &min_interval))
10927         ;
10928       else if (unformat (i, "life %d", &lifetime))
10929         ;
10930       else if (unformat (i, "count %d", &initial_count))
10931         ;
10932       else if (unformat (i, "interval %d", &initial_interval))
10933         ;
10934       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10935         suppress = 1;
10936       else if (unformat (i, "managed"))
10937         managed = 1;
10938       else if (unformat (i, "other"))
10939         other = 1;
10940       else if (unformat (i, "ll"))
10941         ll_option = 1;
10942       else if (unformat (i, "send"))
10943         send_unicast = 1;
10944       else if (unformat (i, "cease"))
10945         cease = 1;
10946       else if (unformat (i, "isno"))
10947         is_no = 1;
10948       else if (unformat (i, "def"))
10949         default_router = 1;
10950       else
10951         {
10952           clib_warning ("parse error '%U'", format_unformat_error, i);
10953           return -99;
10954         }
10955     }
10956
10957   if (sw_if_index_set == 0)
10958     {
10959       errmsg ("missing interface name or sw_if_index");
10960       return -99;
10961     }
10962
10963   /* Construct the API message */
10964   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10965
10966   mp->sw_if_index = ntohl (sw_if_index);
10967   mp->max_interval = ntohl (max_interval);
10968   mp->min_interval = ntohl (min_interval);
10969   mp->lifetime = ntohl (lifetime);
10970   mp->initial_count = ntohl (initial_count);
10971   mp->initial_interval = ntohl (initial_interval);
10972   mp->suppress = suppress;
10973   mp->managed = managed;
10974   mp->other = other;
10975   mp->ll_option = ll_option;
10976   mp->send_unicast = send_unicast;
10977   mp->cease = cease;
10978   mp->is_no = is_no;
10979   mp->default_router = default_router;
10980
10981   /* send it... */
10982   S (mp);
10983
10984   /* Wait for a reply, return good/bad news  */
10985   W (ret);
10986   return ret;
10987 }
10988
10989 static int
10990 api_set_arp_neighbor_limit (vat_main_t * vam)
10991 {
10992   unformat_input_t *i = vam->input;
10993   vl_api_set_arp_neighbor_limit_t *mp;
10994   u32 arp_nbr_limit;
10995   u8 limit_set = 0;
10996   u8 is_ipv6 = 0;
10997   int ret;
10998
10999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11000     {
11001       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11002         limit_set = 1;
11003       else if (unformat (i, "ipv6"))
11004         is_ipv6 = 1;
11005       else
11006         {
11007           clib_warning ("parse error '%U'", format_unformat_error, i);
11008           return -99;
11009         }
11010     }
11011
11012   if (limit_set == 0)
11013     {
11014       errmsg ("missing limit value");
11015       return -99;
11016     }
11017
11018   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11019
11020   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11021   mp->is_ipv6 = is_ipv6;
11022
11023   S (mp);
11024   W (ret);
11025   return ret;
11026 }
11027
11028 static int
11029 api_l2_patch_add_del (vat_main_t * vam)
11030 {
11031   unformat_input_t *i = vam->input;
11032   vl_api_l2_patch_add_del_t *mp;
11033   u32 rx_sw_if_index;
11034   u8 rx_sw_if_index_set = 0;
11035   u32 tx_sw_if_index;
11036   u8 tx_sw_if_index_set = 0;
11037   u8 is_add = 1;
11038   int ret;
11039
11040   /* Parse args required to build the message */
11041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11042     {
11043       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11044         rx_sw_if_index_set = 1;
11045       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11046         tx_sw_if_index_set = 1;
11047       else if (unformat (i, "rx"))
11048         {
11049           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11050             {
11051               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11052                             &rx_sw_if_index))
11053                 rx_sw_if_index_set = 1;
11054             }
11055           else
11056             break;
11057         }
11058       else if (unformat (i, "tx"))
11059         {
11060           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11061             {
11062               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11063                             &tx_sw_if_index))
11064                 tx_sw_if_index_set = 1;
11065             }
11066           else
11067             break;
11068         }
11069       else if (unformat (i, "del"))
11070         is_add = 0;
11071       else
11072         break;
11073     }
11074
11075   if (rx_sw_if_index_set == 0)
11076     {
11077       errmsg ("missing rx interface name or rx_sw_if_index");
11078       return -99;
11079     }
11080
11081   if (tx_sw_if_index_set == 0)
11082     {
11083       errmsg ("missing tx interface name or tx_sw_if_index");
11084       return -99;
11085     }
11086
11087   M (L2_PATCH_ADD_DEL, mp);
11088
11089   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11090   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11091   mp->is_add = is_add;
11092
11093   S (mp);
11094   W (ret);
11095   return ret;
11096 }
11097
11098 u8 is_del;
11099 u8 localsid_addr[16];
11100 u8 end_psp;
11101 u8 behavior;
11102 u32 sw_if_index;
11103 u32 vlan_index;
11104 u32 fib_table;
11105 u8 nh_addr[16];
11106
11107 static int
11108 api_sr_localsid_add_del (vat_main_t * vam)
11109 {
11110   unformat_input_t *i = vam->input;
11111   vl_api_sr_localsid_add_del_t *mp;
11112
11113   u8 is_del;
11114   ip6_address_t localsid;
11115   u8 end_psp = 0;
11116   u8 behavior = ~0;
11117   u32 sw_if_index;
11118   u32 fib_table = ~(u32) 0;
11119   ip6_address_t nh_addr6;
11120   ip4_address_t nh_addr4;
11121   memset (&nh_addr6, 0, sizeof (ip6_address_t));
11122   memset (&nh_addr4, 0, sizeof (ip4_address_t));
11123
11124   bool nexthop_set = 0;
11125
11126   int ret;
11127
11128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11129     {
11130       if (unformat (i, "del"))
11131         is_del = 1;
11132       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11133       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11134         nexthop_set = 1;
11135       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11136         nexthop_set = 1;
11137       else if (unformat (i, "behavior %u", &behavior));
11138       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11139       else if (unformat (i, "fib-table %u", &fib_table));
11140       else if (unformat (i, "end.psp %u", &behavior));
11141       else
11142         break;
11143     }
11144
11145   M (SR_LOCALSID_ADD_DEL, mp);
11146
11147   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11148   if (nexthop_set)
11149     {
11150       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11151       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11152     }
11153   mp->behavior = behavior;
11154   mp->sw_if_index = ntohl (sw_if_index);
11155   mp->fib_table = ntohl (fib_table);
11156   mp->end_psp = end_psp;
11157   mp->is_del = is_del;
11158
11159   S (mp);
11160   W (ret);
11161   return ret;
11162 }
11163
11164 static int
11165 api_ioam_enable (vat_main_t * vam)
11166 {
11167   unformat_input_t *input = vam->input;
11168   vl_api_ioam_enable_t *mp;
11169   u32 id = 0;
11170   int has_trace_option = 0;
11171   int has_pot_option = 0;
11172   int has_seqno_option = 0;
11173   int has_analyse_option = 0;
11174   int ret;
11175
11176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11177     {
11178       if (unformat (input, "trace"))
11179         has_trace_option = 1;
11180       else if (unformat (input, "pot"))
11181         has_pot_option = 1;
11182       else if (unformat (input, "seqno"))
11183         has_seqno_option = 1;
11184       else if (unformat (input, "analyse"))
11185         has_analyse_option = 1;
11186       else
11187         break;
11188     }
11189   M (IOAM_ENABLE, mp);
11190   mp->id = htons (id);
11191   mp->seqno = has_seqno_option;
11192   mp->analyse = has_analyse_option;
11193   mp->pot_enable = has_pot_option;
11194   mp->trace_enable = has_trace_option;
11195
11196   S (mp);
11197   W (ret);
11198   return ret;
11199 }
11200
11201
11202 static int
11203 api_ioam_disable (vat_main_t * vam)
11204 {
11205   vl_api_ioam_disable_t *mp;
11206   int ret;
11207
11208   M (IOAM_DISABLE, mp);
11209   S (mp);
11210   W (ret);
11211   return ret;
11212 }
11213
11214 #define foreach_tcp_proto_field                 \
11215 _(src_port)                                     \
11216 _(dst_port)
11217
11218 #define foreach_udp_proto_field                 \
11219 _(src_port)                                     \
11220 _(dst_port)
11221
11222 #define foreach_ip4_proto_field                 \
11223 _(src_address)                                  \
11224 _(dst_address)                                  \
11225 _(tos)                                          \
11226 _(length)                                       \
11227 _(fragment_id)                                  \
11228 _(ttl)                                          \
11229 _(protocol)                                     \
11230 _(checksum)
11231
11232 typedef struct
11233 {
11234   u16 src_port, dst_port;
11235 } tcpudp_header_t;
11236
11237 #if VPP_API_TEST_BUILTIN == 0
11238 uword
11239 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11240 {
11241   u8 **maskp = va_arg (*args, u8 **);
11242   u8 *mask = 0;
11243   u8 found_something = 0;
11244   tcp_header_t *tcp;
11245
11246 #define _(a) u8 a=0;
11247   foreach_tcp_proto_field;
11248 #undef _
11249
11250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11251     {
11252       if (0);
11253 #define _(a) else if (unformat (input, #a)) a=1;
11254       foreach_tcp_proto_field
11255 #undef _
11256         else
11257         break;
11258     }
11259
11260 #define _(a) found_something += a;
11261   foreach_tcp_proto_field;
11262 #undef _
11263
11264   if (found_something == 0)
11265     return 0;
11266
11267   vec_validate (mask, sizeof (*tcp) - 1);
11268
11269   tcp = (tcp_header_t *) mask;
11270
11271 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11272   foreach_tcp_proto_field;
11273 #undef _
11274
11275   *maskp = mask;
11276   return 1;
11277 }
11278
11279 uword
11280 unformat_udp_mask (unformat_input_t * input, va_list * args)
11281 {
11282   u8 **maskp = va_arg (*args, u8 **);
11283   u8 *mask = 0;
11284   u8 found_something = 0;
11285   udp_header_t *udp;
11286
11287 #define _(a) u8 a=0;
11288   foreach_udp_proto_field;
11289 #undef _
11290
11291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11292     {
11293       if (0);
11294 #define _(a) else if (unformat (input, #a)) a=1;
11295       foreach_udp_proto_field
11296 #undef _
11297         else
11298         break;
11299     }
11300
11301 #define _(a) found_something += a;
11302   foreach_udp_proto_field;
11303 #undef _
11304
11305   if (found_something == 0)
11306     return 0;
11307
11308   vec_validate (mask, sizeof (*udp) - 1);
11309
11310   udp = (udp_header_t *) mask;
11311
11312 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11313   foreach_udp_proto_field;
11314 #undef _
11315
11316   *maskp = mask;
11317   return 1;
11318 }
11319
11320 uword
11321 unformat_l4_mask (unformat_input_t * input, va_list * args)
11322 {
11323   u8 **maskp = va_arg (*args, u8 **);
11324   u16 src_port = 0, dst_port = 0;
11325   tcpudp_header_t *tcpudp;
11326
11327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11328     {
11329       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11330         return 1;
11331       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11332         return 1;
11333       else if (unformat (input, "src_port"))
11334         src_port = 0xFFFF;
11335       else if (unformat (input, "dst_port"))
11336         dst_port = 0xFFFF;
11337       else
11338         return 0;
11339     }
11340
11341   if (!src_port && !dst_port)
11342     return 0;
11343
11344   u8 *mask = 0;
11345   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11346
11347   tcpudp = (tcpudp_header_t *) mask;
11348   tcpudp->src_port = src_port;
11349   tcpudp->dst_port = dst_port;
11350
11351   *maskp = mask;
11352
11353   return 1;
11354 }
11355
11356 uword
11357 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11358 {
11359   u8 **maskp = va_arg (*args, u8 **);
11360   u8 *mask = 0;
11361   u8 found_something = 0;
11362   ip4_header_t *ip;
11363
11364 #define _(a) u8 a=0;
11365   foreach_ip4_proto_field;
11366 #undef _
11367   u8 version = 0;
11368   u8 hdr_length = 0;
11369
11370
11371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11372     {
11373       if (unformat (input, "version"))
11374         version = 1;
11375       else if (unformat (input, "hdr_length"))
11376         hdr_length = 1;
11377       else if (unformat (input, "src"))
11378         src_address = 1;
11379       else if (unformat (input, "dst"))
11380         dst_address = 1;
11381       else if (unformat (input, "proto"))
11382         protocol = 1;
11383
11384 #define _(a) else if (unformat (input, #a)) a=1;
11385       foreach_ip4_proto_field
11386 #undef _
11387         else
11388         break;
11389     }
11390
11391 #define _(a) found_something += a;
11392   foreach_ip4_proto_field;
11393 #undef _
11394
11395   if (found_something == 0)
11396     return 0;
11397
11398   vec_validate (mask, sizeof (*ip) - 1);
11399
11400   ip = (ip4_header_t *) mask;
11401
11402 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11403   foreach_ip4_proto_field;
11404 #undef _
11405
11406   ip->ip_version_and_header_length = 0;
11407
11408   if (version)
11409     ip->ip_version_and_header_length |= 0xF0;
11410
11411   if (hdr_length)
11412     ip->ip_version_and_header_length |= 0x0F;
11413
11414   *maskp = mask;
11415   return 1;
11416 }
11417
11418 #define foreach_ip6_proto_field                 \
11419 _(src_address)                                  \
11420 _(dst_address)                                  \
11421 _(payload_length)                               \
11422 _(hop_limit)                                    \
11423 _(protocol)
11424
11425 uword
11426 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11427 {
11428   u8 **maskp = va_arg (*args, u8 **);
11429   u8 *mask = 0;
11430   u8 found_something = 0;
11431   ip6_header_t *ip;
11432   u32 ip_version_traffic_class_and_flow_label;
11433
11434 #define _(a) u8 a=0;
11435   foreach_ip6_proto_field;
11436 #undef _
11437   u8 version = 0;
11438   u8 traffic_class = 0;
11439   u8 flow_label = 0;
11440
11441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11442     {
11443       if (unformat (input, "version"))
11444         version = 1;
11445       else if (unformat (input, "traffic-class"))
11446         traffic_class = 1;
11447       else if (unformat (input, "flow-label"))
11448         flow_label = 1;
11449       else if (unformat (input, "src"))
11450         src_address = 1;
11451       else if (unformat (input, "dst"))
11452         dst_address = 1;
11453       else if (unformat (input, "proto"))
11454         protocol = 1;
11455
11456 #define _(a) else if (unformat (input, #a)) a=1;
11457       foreach_ip6_proto_field
11458 #undef _
11459         else
11460         break;
11461     }
11462
11463 #define _(a) found_something += a;
11464   foreach_ip6_proto_field;
11465 #undef _
11466
11467   if (found_something == 0)
11468     return 0;
11469
11470   vec_validate (mask, sizeof (*ip) - 1);
11471
11472   ip = (ip6_header_t *) mask;
11473
11474 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11475   foreach_ip6_proto_field;
11476 #undef _
11477
11478   ip_version_traffic_class_and_flow_label = 0;
11479
11480   if (version)
11481     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11482
11483   if (traffic_class)
11484     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11485
11486   if (flow_label)
11487     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11488
11489   ip->ip_version_traffic_class_and_flow_label =
11490     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11491
11492   *maskp = mask;
11493   return 1;
11494 }
11495
11496 uword
11497 unformat_l3_mask (unformat_input_t * input, va_list * args)
11498 {
11499   u8 **maskp = va_arg (*args, u8 **);
11500
11501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11502     {
11503       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11504         return 1;
11505       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11506         return 1;
11507       else
11508         break;
11509     }
11510   return 0;
11511 }
11512
11513 uword
11514 unformat_l2_mask (unformat_input_t * input, va_list * args)
11515 {
11516   u8 **maskp = va_arg (*args, u8 **);
11517   u8 *mask = 0;
11518   u8 src = 0;
11519   u8 dst = 0;
11520   u8 proto = 0;
11521   u8 tag1 = 0;
11522   u8 tag2 = 0;
11523   u8 ignore_tag1 = 0;
11524   u8 ignore_tag2 = 0;
11525   u8 cos1 = 0;
11526   u8 cos2 = 0;
11527   u8 dot1q = 0;
11528   u8 dot1ad = 0;
11529   int len = 14;
11530
11531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (input, "src"))
11534         src = 1;
11535       else if (unformat (input, "dst"))
11536         dst = 1;
11537       else if (unformat (input, "proto"))
11538         proto = 1;
11539       else if (unformat (input, "tag1"))
11540         tag1 = 1;
11541       else if (unformat (input, "tag2"))
11542         tag2 = 1;
11543       else if (unformat (input, "ignore-tag1"))
11544         ignore_tag1 = 1;
11545       else if (unformat (input, "ignore-tag2"))
11546         ignore_tag2 = 1;
11547       else if (unformat (input, "cos1"))
11548         cos1 = 1;
11549       else if (unformat (input, "cos2"))
11550         cos2 = 1;
11551       else if (unformat (input, "dot1q"))
11552         dot1q = 1;
11553       else if (unformat (input, "dot1ad"))
11554         dot1ad = 1;
11555       else
11556         break;
11557     }
11558   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11559        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11560     return 0;
11561
11562   if (tag1 || ignore_tag1 || cos1 || dot1q)
11563     len = 18;
11564   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11565     len = 22;
11566
11567   vec_validate (mask, len - 1);
11568
11569   if (dst)
11570     memset (mask, 0xff, 6);
11571
11572   if (src)
11573     memset (mask + 6, 0xff, 6);
11574
11575   if (tag2 || dot1ad)
11576     {
11577       /* inner vlan tag */
11578       if (tag2)
11579         {
11580           mask[19] = 0xff;
11581           mask[18] = 0x0f;
11582         }
11583       if (cos2)
11584         mask[18] |= 0xe0;
11585       if (proto)
11586         mask[21] = mask[20] = 0xff;
11587       if (tag1)
11588         {
11589           mask[15] = 0xff;
11590           mask[14] = 0x0f;
11591         }
11592       if (cos1)
11593         mask[14] |= 0xe0;
11594       *maskp = mask;
11595       return 1;
11596     }
11597   if (tag1 | dot1q)
11598     {
11599       if (tag1)
11600         {
11601           mask[15] = 0xff;
11602           mask[14] = 0x0f;
11603         }
11604       if (cos1)
11605         mask[14] |= 0xe0;
11606       if (proto)
11607         mask[16] = mask[17] = 0xff;
11608
11609       *maskp = mask;
11610       return 1;
11611     }
11612   if (cos2)
11613     mask[18] |= 0xe0;
11614   if (cos1)
11615     mask[14] |= 0xe0;
11616   if (proto)
11617     mask[12] = mask[13] = 0xff;
11618
11619   *maskp = mask;
11620   return 1;
11621 }
11622
11623 uword
11624 unformat_classify_mask (unformat_input_t * input, va_list * args)
11625 {
11626   u8 **maskp = va_arg (*args, u8 **);
11627   u32 *skipp = va_arg (*args, u32 *);
11628   u32 *matchp = va_arg (*args, u32 *);
11629   u32 match;
11630   u8 *mask = 0;
11631   u8 *l2 = 0;
11632   u8 *l3 = 0;
11633   u8 *l4 = 0;
11634   int i;
11635
11636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11639         ;
11640       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11641         ;
11642       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11643         ;
11644       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11645         ;
11646       else
11647         break;
11648     }
11649
11650   if (l4 && !l3)
11651     {
11652       vec_free (mask);
11653       vec_free (l2);
11654       vec_free (l4);
11655       return 0;
11656     }
11657
11658   if (mask || l2 || l3 || l4)
11659     {
11660       if (l2 || l3 || l4)
11661         {
11662           /* "With a free Ethernet header in every package" */
11663           if (l2 == 0)
11664             vec_validate (l2, 13);
11665           mask = l2;
11666           if (vec_len (l3))
11667             {
11668               vec_append (mask, l3);
11669               vec_free (l3);
11670             }
11671           if (vec_len (l4))
11672             {
11673               vec_append (mask, l4);
11674               vec_free (l4);
11675             }
11676         }
11677
11678       /* Scan forward looking for the first significant mask octet */
11679       for (i = 0; i < vec_len (mask); i++)
11680         if (mask[i])
11681           break;
11682
11683       /* compute (skip, match) params */
11684       *skipp = i / sizeof (u32x4);
11685       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11686
11687       /* Pad mask to an even multiple of the vector size */
11688       while (vec_len (mask) % sizeof (u32x4))
11689         vec_add1 (mask, 0);
11690
11691       match = vec_len (mask) / sizeof (u32x4);
11692
11693       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11694         {
11695           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11696           if (*tmp || *(tmp + 1))
11697             break;
11698           match--;
11699         }
11700       if (match == 0)
11701         clib_warning ("BUG: match 0");
11702
11703       _vec_len (mask) = match * sizeof (u32x4);
11704
11705       *matchp = match;
11706       *maskp = mask;
11707
11708       return 1;
11709     }
11710
11711   return 0;
11712 }
11713 #endif /* VPP_API_TEST_BUILTIN */
11714
11715 #define foreach_l2_next                         \
11716 _(drop, DROP)                                   \
11717 _(ethernet, ETHERNET_INPUT)                     \
11718 _(ip4, IP4_INPUT)                               \
11719 _(ip6, IP6_INPUT)
11720
11721 uword
11722 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11723 {
11724   u32 *miss_next_indexp = va_arg (*args, u32 *);
11725   u32 next_index = 0;
11726   u32 tmp;
11727
11728 #define _(n,N) \
11729   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11730   foreach_l2_next;
11731 #undef _
11732
11733   if (unformat (input, "%d", &tmp))
11734     {
11735       next_index = tmp;
11736       goto out;
11737     }
11738
11739   return 0;
11740
11741 out:
11742   *miss_next_indexp = next_index;
11743   return 1;
11744 }
11745
11746 #define foreach_ip_next                         \
11747 _(drop, DROP)                                   \
11748 _(local, LOCAL)                                 \
11749 _(rewrite, REWRITE)
11750
11751 uword
11752 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11753 {
11754   u32 *miss_next_indexp = va_arg (*args, u32 *);
11755   u32 next_index = 0;
11756   u32 tmp;
11757
11758 #define _(n,N) \
11759   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11760   foreach_ip_next;
11761 #undef _
11762
11763   if (unformat (input, "%d", &tmp))
11764     {
11765       next_index = tmp;
11766       goto out;
11767     }
11768
11769   return 0;
11770
11771 out:
11772   *miss_next_indexp = next_index;
11773   return 1;
11774 }
11775
11776 #define foreach_acl_next                        \
11777 _(deny, DENY)
11778
11779 uword
11780 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11781 {
11782   u32 *miss_next_indexp = va_arg (*args, u32 *);
11783   u32 next_index = 0;
11784   u32 tmp;
11785
11786 #define _(n,N) \
11787   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11788   foreach_acl_next;
11789 #undef _
11790
11791   if (unformat (input, "permit"))
11792     {
11793       next_index = ~0;
11794       goto out;
11795     }
11796   else if (unformat (input, "%d", &tmp))
11797     {
11798       next_index = tmp;
11799       goto out;
11800     }
11801
11802   return 0;
11803
11804 out:
11805   *miss_next_indexp = next_index;
11806   return 1;
11807 }
11808
11809 uword
11810 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11811 {
11812   u32 *r = va_arg (*args, u32 *);
11813
11814   if (unformat (input, "conform-color"))
11815     *r = POLICE_CONFORM;
11816   else if (unformat (input, "exceed-color"))
11817     *r = POLICE_EXCEED;
11818   else
11819     return 0;
11820
11821   return 1;
11822 }
11823
11824 static int
11825 api_classify_add_del_table (vat_main_t * vam)
11826 {
11827   unformat_input_t *i = vam->input;
11828   vl_api_classify_add_del_table_t *mp;
11829
11830   u32 nbuckets = 2;
11831   u32 skip = ~0;
11832   u32 match = ~0;
11833   int is_add = 1;
11834   int del_chain = 0;
11835   u32 table_index = ~0;
11836   u32 next_table_index = ~0;
11837   u32 miss_next_index = ~0;
11838   u32 memory_size = 32 << 20;
11839   u8 *mask = 0;
11840   u32 current_data_flag = 0;
11841   int current_data_offset = 0;
11842   int ret;
11843
11844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11845     {
11846       if (unformat (i, "del"))
11847         is_add = 0;
11848       else if (unformat (i, "del-chain"))
11849         {
11850           is_add = 0;
11851           del_chain = 1;
11852         }
11853       else if (unformat (i, "buckets %d", &nbuckets))
11854         ;
11855       else if (unformat (i, "memory_size %d", &memory_size))
11856         ;
11857       else if (unformat (i, "skip %d", &skip))
11858         ;
11859       else if (unformat (i, "match %d", &match))
11860         ;
11861       else if (unformat (i, "table %d", &table_index))
11862         ;
11863       else if (unformat (i, "mask %U", unformat_classify_mask,
11864                          &mask, &skip, &match))
11865         ;
11866       else if (unformat (i, "next-table %d", &next_table_index))
11867         ;
11868       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11869                          &miss_next_index))
11870         ;
11871       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11872                          &miss_next_index))
11873         ;
11874       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11875                          &miss_next_index))
11876         ;
11877       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11878         ;
11879       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11880         ;
11881       else
11882         break;
11883     }
11884
11885   if (is_add && mask == 0)
11886     {
11887       errmsg ("Mask required");
11888       return -99;
11889     }
11890
11891   if (is_add && skip == ~0)
11892     {
11893       errmsg ("skip count required");
11894       return -99;
11895     }
11896
11897   if (is_add && match == ~0)
11898     {
11899       errmsg ("match count required");
11900       return -99;
11901     }
11902
11903   if (!is_add && table_index == ~0)
11904     {
11905       errmsg ("table index required for delete");
11906       return -99;
11907     }
11908
11909   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11910
11911   mp->is_add = is_add;
11912   mp->del_chain = del_chain;
11913   mp->table_index = ntohl (table_index);
11914   mp->nbuckets = ntohl (nbuckets);
11915   mp->memory_size = ntohl (memory_size);
11916   mp->skip_n_vectors = ntohl (skip);
11917   mp->match_n_vectors = ntohl (match);
11918   mp->next_table_index = ntohl (next_table_index);
11919   mp->miss_next_index = ntohl (miss_next_index);
11920   mp->current_data_flag = ntohl (current_data_flag);
11921   mp->current_data_offset = ntohl (current_data_offset);
11922   mp->mask_len = ntohl (vec_len (mask));
11923   clib_memcpy (mp->mask, mask, vec_len (mask));
11924
11925   vec_free (mask);
11926
11927   S (mp);
11928   W (ret);
11929   return ret;
11930 }
11931
11932 #if VPP_API_TEST_BUILTIN == 0
11933 uword
11934 unformat_l4_match (unformat_input_t * input, va_list * args)
11935 {
11936   u8 **matchp = va_arg (*args, u8 **);
11937
11938   u8 *proto_header = 0;
11939   int src_port = 0;
11940   int dst_port = 0;
11941
11942   tcpudp_header_t h;
11943
11944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11945     {
11946       if (unformat (input, "src_port %d", &src_port))
11947         ;
11948       else if (unformat (input, "dst_port %d", &dst_port))
11949         ;
11950       else
11951         return 0;
11952     }
11953
11954   h.src_port = clib_host_to_net_u16 (src_port);
11955   h.dst_port = clib_host_to_net_u16 (dst_port);
11956   vec_validate (proto_header, sizeof (h) - 1);
11957   memcpy (proto_header, &h, sizeof (h));
11958
11959   *matchp = proto_header;
11960
11961   return 1;
11962 }
11963
11964 uword
11965 unformat_ip4_match (unformat_input_t * input, va_list * args)
11966 {
11967   u8 **matchp = va_arg (*args, u8 **);
11968   u8 *match = 0;
11969   ip4_header_t *ip;
11970   int version = 0;
11971   u32 version_val;
11972   int hdr_length = 0;
11973   u32 hdr_length_val;
11974   int src = 0, dst = 0;
11975   ip4_address_t src_val, dst_val;
11976   int proto = 0;
11977   u32 proto_val;
11978   int tos = 0;
11979   u32 tos_val;
11980   int length = 0;
11981   u32 length_val;
11982   int fragment_id = 0;
11983   u32 fragment_id_val;
11984   int ttl = 0;
11985   int ttl_val;
11986   int checksum = 0;
11987   u32 checksum_val;
11988
11989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11990     {
11991       if (unformat (input, "version %d", &version_val))
11992         version = 1;
11993       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11994         hdr_length = 1;
11995       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11996         src = 1;
11997       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11998         dst = 1;
11999       else if (unformat (input, "proto %d", &proto_val))
12000         proto = 1;
12001       else if (unformat (input, "tos %d", &tos_val))
12002         tos = 1;
12003       else if (unformat (input, "length %d", &length_val))
12004         length = 1;
12005       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12006         fragment_id = 1;
12007       else if (unformat (input, "ttl %d", &ttl_val))
12008         ttl = 1;
12009       else if (unformat (input, "checksum %d", &checksum_val))
12010         checksum = 1;
12011       else
12012         break;
12013     }
12014
12015   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12016       + ttl + checksum == 0)
12017     return 0;
12018
12019   /*
12020    * Aligned because we use the real comparison functions
12021    */
12022   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12023
12024   ip = (ip4_header_t *) match;
12025
12026   /* These are realistically matched in practice */
12027   if (src)
12028     ip->src_address.as_u32 = src_val.as_u32;
12029
12030   if (dst)
12031     ip->dst_address.as_u32 = dst_val.as_u32;
12032
12033   if (proto)
12034     ip->protocol = proto_val;
12035
12036
12037   /* These are not, but they're included for completeness */
12038   if (version)
12039     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12040
12041   if (hdr_length)
12042     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12043
12044   if (tos)
12045     ip->tos = tos_val;
12046
12047   if (length)
12048     ip->length = clib_host_to_net_u16 (length_val);
12049
12050   if (ttl)
12051     ip->ttl = ttl_val;
12052
12053   if (checksum)
12054     ip->checksum = clib_host_to_net_u16 (checksum_val);
12055
12056   *matchp = match;
12057   return 1;
12058 }
12059
12060 uword
12061 unformat_ip6_match (unformat_input_t * input, va_list * args)
12062 {
12063   u8 **matchp = va_arg (*args, u8 **);
12064   u8 *match = 0;
12065   ip6_header_t *ip;
12066   int version = 0;
12067   u32 version_val;
12068   u8 traffic_class = 0;
12069   u32 traffic_class_val = 0;
12070   u8 flow_label = 0;
12071   u8 flow_label_val;
12072   int src = 0, dst = 0;
12073   ip6_address_t src_val, dst_val;
12074   int proto = 0;
12075   u32 proto_val;
12076   int payload_length = 0;
12077   u32 payload_length_val;
12078   int hop_limit = 0;
12079   int hop_limit_val;
12080   u32 ip_version_traffic_class_and_flow_label;
12081
12082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12083     {
12084       if (unformat (input, "version %d", &version_val))
12085         version = 1;
12086       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12087         traffic_class = 1;
12088       else if (unformat (input, "flow_label %d", &flow_label_val))
12089         flow_label = 1;
12090       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12091         src = 1;
12092       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12093         dst = 1;
12094       else if (unformat (input, "proto %d", &proto_val))
12095         proto = 1;
12096       else if (unformat (input, "payload_length %d", &payload_length_val))
12097         payload_length = 1;
12098       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12099         hop_limit = 1;
12100       else
12101         break;
12102     }
12103
12104   if (version + traffic_class + flow_label + src + dst + proto +
12105       payload_length + hop_limit == 0)
12106     return 0;
12107
12108   /*
12109    * Aligned because we use the real comparison functions
12110    */
12111   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12112
12113   ip = (ip6_header_t *) match;
12114
12115   if (src)
12116     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12117
12118   if (dst)
12119     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12120
12121   if (proto)
12122     ip->protocol = proto_val;
12123
12124   ip_version_traffic_class_and_flow_label = 0;
12125
12126   if (version)
12127     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12128
12129   if (traffic_class)
12130     ip_version_traffic_class_and_flow_label |=
12131       (traffic_class_val & 0xFF) << 20;
12132
12133   if (flow_label)
12134     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12135
12136   ip->ip_version_traffic_class_and_flow_label =
12137     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12138
12139   if (payload_length)
12140     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12141
12142   if (hop_limit)
12143     ip->hop_limit = hop_limit_val;
12144
12145   *matchp = match;
12146   return 1;
12147 }
12148
12149 uword
12150 unformat_l3_match (unformat_input_t * input, va_list * args)
12151 {
12152   u8 **matchp = va_arg (*args, u8 **);
12153
12154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12155     {
12156       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12157         return 1;
12158       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12159         return 1;
12160       else
12161         break;
12162     }
12163   return 0;
12164 }
12165
12166 uword
12167 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12168 {
12169   u8 *tagp = va_arg (*args, u8 *);
12170   u32 tag;
12171
12172   if (unformat (input, "%d", &tag))
12173     {
12174       tagp[0] = (tag >> 8) & 0x0F;
12175       tagp[1] = tag & 0xFF;
12176       return 1;
12177     }
12178
12179   return 0;
12180 }
12181
12182 uword
12183 unformat_l2_match (unformat_input_t * input, va_list * args)
12184 {
12185   u8 **matchp = va_arg (*args, u8 **);
12186   u8 *match = 0;
12187   u8 src = 0;
12188   u8 src_val[6];
12189   u8 dst = 0;
12190   u8 dst_val[6];
12191   u8 proto = 0;
12192   u16 proto_val;
12193   u8 tag1 = 0;
12194   u8 tag1_val[2];
12195   u8 tag2 = 0;
12196   u8 tag2_val[2];
12197   int len = 14;
12198   u8 ignore_tag1 = 0;
12199   u8 ignore_tag2 = 0;
12200   u8 cos1 = 0;
12201   u8 cos2 = 0;
12202   u32 cos1_val = 0;
12203   u32 cos2_val = 0;
12204
12205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12206     {
12207       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12208         src = 1;
12209       else
12210         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12211         dst = 1;
12212       else if (unformat (input, "proto %U",
12213                          unformat_ethernet_type_host_byte_order, &proto_val))
12214         proto = 1;
12215       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12216         tag1 = 1;
12217       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12218         tag2 = 1;
12219       else if (unformat (input, "ignore-tag1"))
12220         ignore_tag1 = 1;
12221       else if (unformat (input, "ignore-tag2"))
12222         ignore_tag2 = 1;
12223       else if (unformat (input, "cos1 %d", &cos1_val))
12224         cos1 = 1;
12225       else if (unformat (input, "cos2 %d", &cos2_val))
12226         cos2 = 1;
12227       else
12228         break;
12229     }
12230   if ((src + dst + proto + tag1 + tag2 +
12231        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12232     return 0;
12233
12234   if (tag1 || ignore_tag1 || cos1)
12235     len = 18;
12236   if (tag2 || ignore_tag2 || cos2)
12237     len = 22;
12238
12239   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12240
12241   if (dst)
12242     clib_memcpy (match, dst_val, 6);
12243
12244   if (src)
12245     clib_memcpy (match + 6, src_val, 6);
12246
12247   if (tag2)
12248     {
12249       /* inner vlan tag */
12250       match[19] = tag2_val[1];
12251       match[18] = tag2_val[0];
12252       if (cos2)
12253         match[18] |= (cos2_val & 0x7) << 5;
12254       if (proto)
12255         {
12256           match[21] = proto_val & 0xff;
12257           match[20] = proto_val >> 8;
12258         }
12259       if (tag1)
12260         {
12261           match[15] = tag1_val[1];
12262           match[14] = tag1_val[0];
12263         }
12264       if (cos1)
12265         match[14] |= (cos1_val & 0x7) << 5;
12266       *matchp = match;
12267       return 1;
12268     }
12269   if (tag1)
12270     {
12271       match[15] = tag1_val[1];
12272       match[14] = tag1_val[0];
12273       if (proto)
12274         {
12275           match[17] = proto_val & 0xff;
12276           match[16] = proto_val >> 8;
12277         }
12278       if (cos1)
12279         match[14] |= (cos1_val & 0x7) << 5;
12280
12281       *matchp = match;
12282       return 1;
12283     }
12284   if (cos2)
12285     match[18] |= (cos2_val & 0x7) << 5;
12286   if (cos1)
12287     match[14] |= (cos1_val & 0x7) << 5;
12288   if (proto)
12289     {
12290       match[13] = proto_val & 0xff;
12291       match[12] = proto_val >> 8;
12292     }
12293
12294   *matchp = match;
12295   return 1;
12296 }
12297
12298 uword
12299 unformat_qos_source (unformat_input_t * input, va_list * args)
12300 {
12301   int *qs = va_arg (*args, int *);
12302
12303   if (unformat (input, "ip"))
12304     *qs = QOS_SOURCE_IP;
12305   else if (unformat (input, "mpls"))
12306     *qs = QOS_SOURCE_MPLS;
12307   else if (unformat (input, "ext"))
12308     *qs = QOS_SOURCE_EXT;
12309   else if (unformat (input, "vlan"))
12310     *qs = QOS_SOURCE_VLAN;
12311   else
12312     return 0;
12313
12314   return 1;
12315 }
12316 #endif
12317
12318 uword
12319 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12320 {
12321   u8 **matchp = va_arg (*args, u8 **);
12322   u32 skip_n_vectors = va_arg (*args, u32);
12323   u32 match_n_vectors = va_arg (*args, u32);
12324
12325   u8 *match = 0;
12326   u8 *l2 = 0;
12327   u8 *l3 = 0;
12328   u8 *l4 = 0;
12329
12330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (input, "hex %U", unformat_hex_string, &match))
12333         ;
12334       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12335         ;
12336       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12337         ;
12338       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12339         ;
12340       else
12341         break;
12342     }
12343
12344   if (l4 && !l3)
12345     {
12346       vec_free (match);
12347       vec_free (l2);
12348       vec_free (l4);
12349       return 0;
12350     }
12351
12352   if (match || l2 || l3 || l4)
12353     {
12354       if (l2 || l3 || l4)
12355         {
12356           /* "Win a free Ethernet header in every packet" */
12357           if (l2 == 0)
12358             vec_validate_aligned (l2, 13, sizeof (u32x4));
12359           match = l2;
12360           if (vec_len (l3))
12361             {
12362               vec_append_aligned (match, l3, sizeof (u32x4));
12363               vec_free (l3);
12364             }
12365           if (vec_len (l4))
12366             {
12367               vec_append_aligned (match, l4, sizeof (u32x4));
12368               vec_free (l4);
12369             }
12370         }
12371
12372       /* Make sure the vector is big enough even if key is all 0's */
12373       vec_validate_aligned
12374         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12375          sizeof (u32x4));
12376
12377       /* Set size, include skipped vectors */
12378       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12379
12380       *matchp = match;
12381
12382       return 1;
12383     }
12384
12385   return 0;
12386 }
12387
12388 static int
12389 api_classify_add_del_session (vat_main_t * vam)
12390 {
12391   unformat_input_t *i = vam->input;
12392   vl_api_classify_add_del_session_t *mp;
12393   int is_add = 1;
12394   u32 table_index = ~0;
12395   u32 hit_next_index = ~0;
12396   u32 opaque_index = ~0;
12397   u8 *match = 0;
12398   i32 advance = 0;
12399   u32 skip_n_vectors = 0;
12400   u32 match_n_vectors = 0;
12401   u32 action = 0;
12402   u32 metadata = 0;
12403   int ret;
12404
12405   /*
12406    * Warning: you have to supply skip_n and match_n
12407    * because the API client cant simply look at the classify
12408    * table object.
12409    */
12410
12411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12412     {
12413       if (unformat (i, "del"))
12414         is_add = 0;
12415       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12416                          &hit_next_index))
12417         ;
12418       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12419                          &hit_next_index))
12420         ;
12421       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12422                          &hit_next_index))
12423         ;
12424       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12425         ;
12426       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12427         ;
12428       else if (unformat (i, "opaque-index %d", &opaque_index))
12429         ;
12430       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12431         ;
12432       else if (unformat (i, "match_n %d", &match_n_vectors))
12433         ;
12434       else if (unformat (i, "match %U", api_unformat_classify_match,
12435                          &match, skip_n_vectors, match_n_vectors))
12436         ;
12437       else if (unformat (i, "advance %d", &advance))
12438         ;
12439       else if (unformat (i, "table-index %d", &table_index))
12440         ;
12441       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12442         action = 1;
12443       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12444         action = 2;
12445       else if (unformat (i, "action %d", &action))
12446         ;
12447       else if (unformat (i, "metadata %d", &metadata))
12448         ;
12449       else
12450         break;
12451     }
12452
12453   if (table_index == ~0)
12454     {
12455       errmsg ("Table index required");
12456       return -99;
12457     }
12458
12459   if (is_add && match == 0)
12460     {
12461       errmsg ("Match value required");
12462       return -99;
12463     }
12464
12465   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12466
12467   mp->is_add = is_add;
12468   mp->table_index = ntohl (table_index);
12469   mp->hit_next_index = ntohl (hit_next_index);
12470   mp->opaque_index = ntohl (opaque_index);
12471   mp->advance = ntohl (advance);
12472   mp->action = action;
12473   mp->metadata = ntohl (metadata);
12474   mp->match_len = ntohl (vec_len (match));
12475   clib_memcpy (mp->match, match, vec_len (match));
12476   vec_free (match);
12477
12478   S (mp);
12479   W (ret);
12480   return ret;
12481 }
12482
12483 static int
12484 api_classify_set_interface_ip_table (vat_main_t * vam)
12485 {
12486   unformat_input_t *i = vam->input;
12487   vl_api_classify_set_interface_ip_table_t *mp;
12488   u32 sw_if_index;
12489   int sw_if_index_set;
12490   u32 table_index = ~0;
12491   u8 is_ipv6 = 0;
12492   int ret;
12493
12494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12495     {
12496       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12497         sw_if_index_set = 1;
12498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12499         sw_if_index_set = 1;
12500       else if (unformat (i, "table %d", &table_index))
12501         ;
12502       else
12503         {
12504           clib_warning ("parse error '%U'", format_unformat_error, i);
12505           return -99;
12506         }
12507     }
12508
12509   if (sw_if_index_set == 0)
12510     {
12511       errmsg ("missing interface name or sw_if_index");
12512       return -99;
12513     }
12514
12515
12516   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12517
12518   mp->sw_if_index = ntohl (sw_if_index);
12519   mp->table_index = ntohl (table_index);
12520   mp->is_ipv6 = is_ipv6;
12521
12522   S (mp);
12523   W (ret);
12524   return ret;
12525 }
12526
12527 static int
12528 api_classify_set_interface_l2_tables (vat_main_t * vam)
12529 {
12530   unformat_input_t *i = vam->input;
12531   vl_api_classify_set_interface_l2_tables_t *mp;
12532   u32 sw_if_index;
12533   int sw_if_index_set;
12534   u32 ip4_table_index = ~0;
12535   u32 ip6_table_index = ~0;
12536   u32 other_table_index = ~0;
12537   u32 is_input = 1;
12538   int ret;
12539
12540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12541     {
12542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12543         sw_if_index_set = 1;
12544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12545         sw_if_index_set = 1;
12546       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12547         ;
12548       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12549         ;
12550       else if (unformat (i, "other-table %d", &other_table_index))
12551         ;
12552       else if (unformat (i, "is-input %d", &is_input))
12553         ;
12554       else
12555         {
12556           clib_warning ("parse error '%U'", format_unformat_error, i);
12557           return -99;
12558         }
12559     }
12560
12561   if (sw_if_index_set == 0)
12562     {
12563       errmsg ("missing interface name or sw_if_index");
12564       return -99;
12565     }
12566
12567
12568   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12569
12570   mp->sw_if_index = ntohl (sw_if_index);
12571   mp->ip4_table_index = ntohl (ip4_table_index);
12572   mp->ip6_table_index = ntohl (ip6_table_index);
12573   mp->other_table_index = ntohl (other_table_index);
12574   mp->is_input = (u8) is_input;
12575
12576   S (mp);
12577   W (ret);
12578   return ret;
12579 }
12580
12581 static int
12582 api_set_ipfix_exporter (vat_main_t * vam)
12583 {
12584   unformat_input_t *i = vam->input;
12585   vl_api_set_ipfix_exporter_t *mp;
12586   ip4_address_t collector_address;
12587   u8 collector_address_set = 0;
12588   u32 collector_port = ~0;
12589   ip4_address_t src_address;
12590   u8 src_address_set = 0;
12591   u32 vrf_id = ~0;
12592   u32 path_mtu = ~0;
12593   u32 template_interval = ~0;
12594   u8 udp_checksum = 0;
12595   int ret;
12596
12597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12598     {
12599       if (unformat (i, "collector_address %U", unformat_ip4_address,
12600                     &collector_address))
12601         collector_address_set = 1;
12602       else if (unformat (i, "collector_port %d", &collector_port))
12603         ;
12604       else if (unformat (i, "src_address %U", unformat_ip4_address,
12605                          &src_address))
12606         src_address_set = 1;
12607       else if (unformat (i, "vrf_id %d", &vrf_id))
12608         ;
12609       else if (unformat (i, "path_mtu %d", &path_mtu))
12610         ;
12611       else if (unformat (i, "template_interval %d", &template_interval))
12612         ;
12613       else if (unformat (i, "udp_checksum"))
12614         udp_checksum = 1;
12615       else
12616         break;
12617     }
12618
12619   if (collector_address_set == 0)
12620     {
12621       errmsg ("collector_address required");
12622       return -99;
12623     }
12624
12625   if (src_address_set == 0)
12626     {
12627       errmsg ("src_address required");
12628       return -99;
12629     }
12630
12631   M (SET_IPFIX_EXPORTER, mp);
12632
12633   memcpy (mp->collector_address, collector_address.data,
12634           sizeof (collector_address.data));
12635   mp->collector_port = htons ((u16) collector_port);
12636   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12637   mp->vrf_id = htonl (vrf_id);
12638   mp->path_mtu = htonl (path_mtu);
12639   mp->template_interval = htonl (template_interval);
12640   mp->udp_checksum = udp_checksum;
12641
12642   S (mp);
12643   W (ret);
12644   return ret;
12645 }
12646
12647 static int
12648 api_set_ipfix_classify_stream (vat_main_t * vam)
12649 {
12650   unformat_input_t *i = vam->input;
12651   vl_api_set_ipfix_classify_stream_t *mp;
12652   u32 domain_id = 0;
12653   u32 src_port = UDP_DST_PORT_ipfix;
12654   int ret;
12655
12656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12657     {
12658       if (unformat (i, "domain %d", &domain_id))
12659         ;
12660       else if (unformat (i, "src_port %d", &src_port))
12661         ;
12662       else
12663         {
12664           errmsg ("unknown input `%U'", format_unformat_error, i);
12665           return -99;
12666         }
12667     }
12668
12669   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12670
12671   mp->domain_id = htonl (domain_id);
12672   mp->src_port = htons ((u16) src_port);
12673
12674   S (mp);
12675   W (ret);
12676   return ret;
12677 }
12678
12679 static int
12680 api_ipfix_classify_table_add_del (vat_main_t * vam)
12681 {
12682   unformat_input_t *i = vam->input;
12683   vl_api_ipfix_classify_table_add_del_t *mp;
12684   int is_add = -1;
12685   u32 classify_table_index = ~0;
12686   u8 ip_version = 0;
12687   u8 transport_protocol = 255;
12688   int ret;
12689
12690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12691     {
12692       if (unformat (i, "add"))
12693         is_add = 1;
12694       else if (unformat (i, "del"))
12695         is_add = 0;
12696       else if (unformat (i, "table %d", &classify_table_index))
12697         ;
12698       else if (unformat (i, "ip4"))
12699         ip_version = 4;
12700       else if (unformat (i, "ip6"))
12701         ip_version = 6;
12702       else if (unformat (i, "tcp"))
12703         transport_protocol = 6;
12704       else if (unformat (i, "udp"))
12705         transport_protocol = 17;
12706       else
12707         {
12708           errmsg ("unknown input `%U'", format_unformat_error, i);
12709           return -99;
12710         }
12711     }
12712
12713   if (is_add == -1)
12714     {
12715       errmsg ("expecting: add|del");
12716       return -99;
12717     }
12718   if (classify_table_index == ~0)
12719     {
12720       errmsg ("classifier table not specified");
12721       return -99;
12722     }
12723   if (ip_version == 0)
12724     {
12725       errmsg ("IP version not specified");
12726       return -99;
12727     }
12728
12729   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12730
12731   mp->is_add = is_add;
12732   mp->table_id = htonl (classify_table_index);
12733   mp->ip_version = ip_version;
12734   mp->transport_protocol = transport_protocol;
12735
12736   S (mp);
12737   W (ret);
12738   return ret;
12739 }
12740
12741 static int
12742 api_get_node_index (vat_main_t * vam)
12743 {
12744   unformat_input_t *i = vam->input;
12745   vl_api_get_node_index_t *mp;
12746   u8 *name = 0;
12747   int ret;
12748
12749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12750     {
12751       if (unformat (i, "node %s", &name))
12752         ;
12753       else
12754         break;
12755     }
12756   if (name == 0)
12757     {
12758       errmsg ("node name required");
12759       return -99;
12760     }
12761   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12762     {
12763       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12764       return -99;
12765     }
12766
12767   M (GET_NODE_INDEX, mp);
12768   clib_memcpy (mp->node_name, name, vec_len (name));
12769   vec_free (name);
12770
12771   S (mp);
12772   W (ret);
12773   return ret;
12774 }
12775
12776 static int
12777 api_get_next_index (vat_main_t * vam)
12778 {
12779   unformat_input_t *i = vam->input;
12780   vl_api_get_next_index_t *mp;
12781   u8 *node_name = 0, *next_node_name = 0;
12782   int ret;
12783
12784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12785     {
12786       if (unformat (i, "node-name %s", &node_name))
12787         ;
12788       else if (unformat (i, "next-node-name %s", &next_node_name))
12789         break;
12790     }
12791
12792   if (node_name == 0)
12793     {
12794       errmsg ("node name required");
12795       return -99;
12796     }
12797   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12798     {
12799       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12800       return -99;
12801     }
12802
12803   if (next_node_name == 0)
12804     {
12805       errmsg ("next node name required");
12806       return -99;
12807     }
12808   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12809     {
12810       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12811       return -99;
12812     }
12813
12814   M (GET_NEXT_INDEX, mp);
12815   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12816   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12817   vec_free (node_name);
12818   vec_free (next_node_name);
12819
12820   S (mp);
12821   W (ret);
12822   return ret;
12823 }
12824
12825 static int
12826 api_add_node_next (vat_main_t * vam)
12827 {
12828   unformat_input_t *i = vam->input;
12829   vl_api_add_node_next_t *mp;
12830   u8 *name = 0;
12831   u8 *next = 0;
12832   int ret;
12833
12834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12835     {
12836       if (unformat (i, "node %s", &name))
12837         ;
12838       else if (unformat (i, "next %s", &next))
12839         ;
12840       else
12841         break;
12842     }
12843   if (name == 0)
12844     {
12845       errmsg ("node name required");
12846       return -99;
12847     }
12848   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12849     {
12850       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12851       return -99;
12852     }
12853   if (next == 0)
12854     {
12855       errmsg ("next node required");
12856       return -99;
12857     }
12858   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12859     {
12860       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12861       return -99;
12862     }
12863
12864   M (ADD_NODE_NEXT, mp);
12865   clib_memcpy (mp->node_name, name, vec_len (name));
12866   clib_memcpy (mp->next_name, next, vec_len (next));
12867   vec_free (name);
12868   vec_free (next);
12869
12870   S (mp);
12871   W (ret);
12872   return ret;
12873 }
12874
12875 static int
12876 api_l2tpv3_create_tunnel (vat_main_t * vam)
12877 {
12878   unformat_input_t *i = vam->input;
12879   ip6_address_t client_address, our_address;
12880   int client_address_set = 0;
12881   int our_address_set = 0;
12882   u32 local_session_id = 0;
12883   u32 remote_session_id = 0;
12884   u64 local_cookie = 0;
12885   u64 remote_cookie = 0;
12886   u8 l2_sublayer_present = 0;
12887   vl_api_l2tpv3_create_tunnel_t *mp;
12888   int ret;
12889
12890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12891     {
12892       if (unformat (i, "client_address %U", unformat_ip6_address,
12893                     &client_address))
12894         client_address_set = 1;
12895       else if (unformat (i, "our_address %U", unformat_ip6_address,
12896                          &our_address))
12897         our_address_set = 1;
12898       else if (unformat (i, "local_session_id %d", &local_session_id))
12899         ;
12900       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12901         ;
12902       else if (unformat (i, "local_cookie %lld", &local_cookie))
12903         ;
12904       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12905         ;
12906       else if (unformat (i, "l2-sublayer-present"))
12907         l2_sublayer_present = 1;
12908       else
12909         break;
12910     }
12911
12912   if (client_address_set == 0)
12913     {
12914       errmsg ("client_address required");
12915       return -99;
12916     }
12917
12918   if (our_address_set == 0)
12919     {
12920       errmsg ("our_address required");
12921       return -99;
12922     }
12923
12924   M (L2TPV3_CREATE_TUNNEL, mp);
12925
12926   clib_memcpy (mp->client_address, client_address.as_u8,
12927                sizeof (mp->client_address));
12928
12929   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12930
12931   mp->local_session_id = ntohl (local_session_id);
12932   mp->remote_session_id = ntohl (remote_session_id);
12933   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12934   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12935   mp->l2_sublayer_present = l2_sublayer_present;
12936   mp->is_ipv6 = 1;
12937
12938   S (mp);
12939   W (ret);
12940   return ret;
12941 }
12942
12943 static int
12944 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12945 {
12946   unformat_input_t *i = vam->input;
12947   u32 sw_if_index;
12948   u8 sw_if_index_set = 0;
12949   u64 new_local_cookie = 0;
12950   u64 new_remote_cookie = 0;
12951   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12952   int ret;
12953
12954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12955     {
12956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12957         sw_if_index_set = 1;
12958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12959         sw_if_index_set = 1;
12960       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12961         ;
12962       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12963         ;
12964       else
12965         break;
12966     }
12967
12968   if (sw_if_index_set == 0)
12969     {
12970       errmsg ("missing interface name or sw_if_index");
12971       return -99;
12972     }
12973
12974   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12975
12976   mp->sw_if_index = ntohl (sw_if_index);
12977   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12978   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12979
12980   S (mp);
12981   W (ret);
12982   return ret;
12983 }
12984
12985 static int
12986 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12987 {
12988   unformat_input_t *i = vam->input;
12989   vl_api_l2tpv3_interface_enable_disable_t *mp;
12990   u32 sw_if_index;
12991   u8 sw_if_index_set = 0;
12992   u8 enable_disable = 1;
12993   int ret;
12994
12995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12996     {
12997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12998         sw_if_index_set = 1;
12999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13000         sw_if_index_set = 1;
13001       else if (unformat (i, "enable"))
13002         enable_disable = 1;
13003       else if (unformat (i, "disable"))
13004         enable_disable = 0;
13005       else
13006         break;
13007     }
13008
13009   if (sw_if_index_set == 0)
13010     {
13011       errmsg ("missing interface name or sw_if_index");
13012       return -99;
13013     }
13014
13015   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13016
13017   mp->sw_if_index = ntohl (sw_if_index);
13018   mp->enable_disable = enable_disable;
13019
13020   S (mp);
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static int
13026 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13027 {
13028   unformat_input_t *i = vam->input;
13029   vl_api_l2tpv3_set_lookup_key_t *mp;
13030   u8 key = ~0;
13031   int ret;
13032
13033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13034     {
13035       if (unformat (i, "lookup_v6_src"))
13036         key = L2T_LOOKUP_SRC_ADDRESS;
13037       else if (unformat (i, "lookup_v6_dst"))
13038         key = L2T_LOOKUP_DST_ADDRESS;
13039       else if (unformat (i, "lookup_session_id"))
13040         key = L2T_LOOKUP_SESSION_ID;
13041       else
13042         break;
13043     }
13044
13045   if (key == (u8) ~ 0)
13046     {
13047       errmsg ("l2tp session lookup key unset");
13048       return -99;
13049     }
13050
13051   M (L2TPV3_SET_LOOKUP_KEY, mp);
13052
13053   mp->key = key;
13054
13055   S (mp);
13056   W (ret);
13057   return ret;
13058 }
13059
13060 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13061   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13062 {
13063   vat_main_t *vam = &vat_main;
13064
13065   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13066          format_ip6_address, mp->our_address,
13067          format_ip6_address, mp->client_address,
13068          clib_net_to_host_u32 (mp->sw_if_index));
13069
13070   print (vam->ofp,
13071          "   local cookies %016llx %016llx remote cookie %016llx",
13072          clib_net_to_host_u64 (mp->local_cookie[0]),
13073          clib_net_to_host_u64 (mp->local_cookie[1]),
13074          clib_net_to_host_u64 (mp->remote_cookie));
13075
13076   print (vam->ofp, "   local session-id %d remote session-id %d",
13077          clib_net_to_host_u32 (mp->local_session_id),
13078          clib_net_to_host_u32 (mp->remote_session_id));
13079
13080   print (vam->ofp, "   l2 specific sublayer %s\n",
13081          mp->l2_sublayer_present ? "preset" : "absent");
13082
13083 }
13084
13085 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13086   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13087 {
13088   vat_main_t *vam = &vat_main;
13089   vat_json_node_t *node = NULL;
13090   struct in6_addr addr;
13091
13092   if (VAT_JSON_ARRAY != vam->json_tree.type)
13093     {
13094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13095       vat_json_init_array (&vam->json_tree);
13096     }
13097   node = vat_json_array_add (&vam->json_tree);
13098
13099   vat_json_init_object (node);
13100
13101   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13102   vat_json_object_add_ip6 (node, "our_address", addr);
13103   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13104   vat_json_object_add_ip6 (node, "client_address", addr);
13105
13106   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13107   vat_json_init_array (lc);
13108   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13109   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13110   vat_json_object_add_uint (node, "remote_cookie",
13111                             clib_net_to_host_u64 (mp->remote_cookie));
13112
13113   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13114   vat_json_object_add_uint (node, "local_session_id",
13115                             clib_net_to_host_u32 (mp->local_session_id));
13116   vat_json_object_add_uint (node, "remote_session_id",
13117                             clib_net_to_host_u32 (mp->remote_session_id));
13118   vat_json_object_add_string_copy (node, "l2_sublayer",
13119                                    mp->l2_sublayer_present ? (u8 *) "present"
13120                                    : (u8 *) "absent");
13121 }
13122
13123 static int
13124 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13125 {
13126   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13127   vl_api_control_ping_t *mp_ping;
13128   int ret;
13129
13130   /* Get list of l2tpv3-tunnel interfaces */
13131   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13132   S (mp);
13133
13134   /* Use a control ping for synchronization */
13135   MPING (CONTROL_PING, mp_ping);
13136   S (mp_ping);
13137
13138   W (ret);
13139   return ret;
13140 }
13141
13142
13143 static void vl_api_sw_interface_tap_details_t_handler
13144   (vl_api_sw_interface_tap_details_t * mp)
13145 {
13146   vat_main_t *vam = &vat_main;
13147
13148   print (vam->ofp, "%-16s %d",
13149          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13150 }
13151
13152 static void vl_api_sw_interface_tap_details_t_handler_json
13153   (vl_api_sw_interface_tap_details_t * mp)
13154 {
13155   vat_main_t *vam = &vat_main;
13156   vat_json_node_t *node = NULL;
13157
13158   if (VAT_JSON_ARRAY != vam->json_tree.type)
13159     {
13160       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13161       vat_json_init_array (&vam->json_tree);
13162     }
13163   node = vat_json_array_add (&vam->json_tree);
13164
13165   vat_json_init_object (node);
13166   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13167   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13168 }
13169
13170 static int
13171 api_sw_interface_tap_dump (vat_main_t * vam)
13172 {
13173   vl_api_sw_interface_tap_dump_t *mp;
13174   vl_api_control_ping_t *mp_ping;
13175   int ret;
13176
13177   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13178   /* Get list of tap interfaces */
13179   M (SW_INTERFACE_TAP_DUMP, mp);
13180   S (mp);
13181
13182   /* Use a control ping for synchronization */
13183   MPING (CONTROL_PING, mp_ping);
13184   S (mp_ping);
13185
13186   W (ret);
13187   return ret;
13188 }
13189
13190 static void vl_api_sw_interface_tap_v2_details_t_handler
13191   (vl_api_sw_interface_tap_v2_details_t * mp)
13192 {
13193   vat_main_t *vam = &vat_main;
13194
13195   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13196                     mp->host_ip4_prefix_len);
13197   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13198                     mp->host_ip6_prefix_len);
13199
13200   print (vam->ofp,
13201          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13202          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13203          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13204          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13205          mp->host_bridge, ip4, ip6);
13206
13207   vec_free (ip4);
13208   vec_free (ip6);
13209 }
13210
13211 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13212   (vl_api_sw_interface_tap_v2_details_t * mp)
13213 {
13214   vat_main_t *vam = &vat_main;
13215   vat_json_node_t *node = NULL;
13216
13217   if (VAT_JSON_ARRAY != vam->json_tree.type)
13218     {
13219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13220       vat_json_init_array (&vam->json_tree);
13221     }
13222   node = vat_json_array_add (&vam->json_tree);
13223
13224   vat_json_init_object (node);
13225   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13226   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13227   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13228   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13229   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13230   vat_json_object_add_string_copy (node, "host_mac_addr",
13231                                    format (0, "%U", format_ethernet_address,
13232                                            &mp->host_mac_addr));
13233   vat_json_object_add_string_copy (node, "host_namespace",
13234                                    mp->host_namespace);
13235   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13236   vat_json_object_add_string_copy (node, "host_ip4_addr",
13237                                    format (0, "%U/%d", format_ip4_address,
13238                                            mp->host_ip4_addr,
13239                                            mp->host_ip4_prefix_len));
13240   vat_json_object_add_string_copy (node, "host_ip6_addr",
13241                                    format (0, "%U/%d", format_ip6_address,
13242                                            mp->host_ip6_addr,
13243                                            mp->host_ip6_prefix_len));
13244
13245 }
13246
13247 static int
13248 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13249 {
13250   vl_api_sw_interface_tap_v2_dump_t *mp;
13251   vl_api_control_ping_t *mp_ping;
13252   int ret;
13253
13254   print (vam->ofp,
13255          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13256          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13257          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13258          "host_ip6_addr");
13259
13260   /* Get list of tap interfaces */
13261   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13262   S (mp);
13263
13264   /* Use a control ping for synchronization */
13265   MPING (CONTROL_PING, mp_ping);
13266   S (mp_ping);
13267
13268   W (ret);
13269   return ret;
13270 }
13271
13272 static int
13273 api_vxlan_offload_rx (vat_main_t * vam)
13274 {
13275   unformat_input_t *line_input = vam->input;
13276   vl_api_vxlan_offload_rx_t *mp;
13277   u32 hw_if_index = ~0, rx_if_index = ~0;
13278   u8 is_add = 1;
13279   int ret;
13280
13281   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13282     {
13283       if (unformat (line_input, "del"))
13284         is_add = 0;
13285       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13286                          &hw_if_index))
13287         ;
13288       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13289         ;
13290       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13291                          &rx_if_index))
13292         ;
13293       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13294         ;
13295       else
13296         {
13297           errmsg ("parse error '%U'", format_unformat_error, line_input);
13298           return -99;
13299         }
13300     }
13301
13302   if (hw_if_index == ~0)
13303     {
13304       errmsg ("no hw interface");
13305       return -99;
13306     }
13307
13308   if (rx_if_index == ~0)
13309     {
13310       errmsg ("no rx tunnel");
13311       return -99;
13312     }
13313
13314   M (VXLAN_OFFLOAD_RX, mp);
13315
13316   mp->hw_if_index = ntohl (hw_if_index);
13317   mp->sw_if_index = ntohl (rx_if_index);
13318   mp->enable = is_add;
13319
13320   S (mp);
13321   W (ret);
13322   return ret;
13323 }
13324
13325 static uword unformat_vxlan_decap_next
13326   (unformat_input_t * input, va_list * args)
13327 {
13328   u32 *result = va_arg (*args, u32 *);
13329   u32 tmp;
13330
13331   if (unformat (input, "l2"))
13332     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13333   else if (unformat (input, "%d", &tmp))
13334     *result = tmp;
13335   else
13336     return 0;
13337   return 1;
13338 }
13339
13340 static int
13341 api_vxlan_add_del_tunnel (vat_main_t * vam)
13342 {
13343   unformat_input_t *line_input = vam->input;
13344   vl_api_vxlan_add_del_tunnel_t *mp;
13345   ip46_address_t src, dst;
13346   u8 is_add = 1;
13347   u8 ipv4_set = 0, ipv6_set = 0;
13348   u8 src_set = 0;
13349   u8 dst_set = 0;
13350   u8 grp_set = 0;
13351   u32 instance = ~0;
13352   u32 mcast_sw_if_index = ~0;
13353   u32 encap_vrf_id = 0;
13354   u32 decap_next_index = ~0;
13355   u32 vni = 0;
13356   int ret;
13357
13358   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13359   memset (&src, 0, sizeof src);
13360   memset (&dst, 0, sizeof dst);
13361
13362   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13363     {
13364       if (unformat (line_input, "del"))
13365         is_add = 0;
13366       else if (unformat (line_input, "instance %d", &instance))
13367         ;
13368       else
13369         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13370         {
13371           ipv4_set = 1;
13372           src_set = 1;
13373         }
13374       else
13375         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13376         {
13377           ipv4_set = 1;
13378           dst_set = 1;
13379         }
13380       else
13381         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13382         {
13383           ipv6_set = 1;
13384           src_set = 1;
13385         }
13386       else
13387         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13388         {
13389           ipv6_set = 1;
13390           dst_set = 1;
13391         }
13392       else if (unformat (line_input, "group %U %U",
13393                          unformat_ip4_address, &dst.ip4,
13394                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13395         {
13396           grp_set = dst_set = 1;
13397           ipv4_set = 1;
13398         }
13399       else if (unformat (line_input, "group %U",
13400                          unformat_ip4_address, &dst.ip4))
13401         {
13402           grp_set = dst_set = 1;
13403           ipv4_set = 1;
13404         }
13405       else if (unformat (line_input, "group %U %U",
13406                          unformat_ip6_address, &dst.ip6,
13407                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13408         {
13409           grp_set = dst_set = 1;
13410           ipv6_set = 1;
13411         }
13412       else if (unformat (line_input, "group %U",
13413                          unformat_ip6_address, &dst.ip6))
13414         {
13415           grp_set = dst_set = 1;
13416           ipv6_set = 1;
13417         }
13418       else
13419         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13420         ;
13421       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13422         ;
13423       else if (unformat (line_input, "decap-next %U",
13424                          unformat_vxlan_decap_next, &decap_next_index))
13425         ;
13426       else if (unformat (line_input, "vni %d", &vni))
13427         ;
13428       else
13429         {
13430           errmsg ("parse error '%U'", format_unformat_error, line_input);
13431           return -99;
13432         }
13433     }
13434
13435   if (src_set == 0)
13436     {
13437       errmsg ("tunnel src address not specified");
13438       return -99;
13439     }
13440   if (dst_set == 0)
13441     {
13442       errmsg ("tunnel dst address not specified");
13443       return -99;
13444     }
13445
13446   if (grp_set && !ip46_address_is_multicast (&dst))
13447     {
13448       errmsg ("tunnel group address not multicast");
13449       return -99;
13450     }
13451   if (grp_set && mcast_sw_if_index == ~0)
13452     {
13453       errmsg ("tunnel nonexistent multicast device");
13454       return -99;
13455     }
13456   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13457     {
13458       errmsg ("tunnel dst address must be unicast");
13459       return -99;
13460     }
13461
13462
13463   if (ipv4_set && ipv6_set)
13464     {
13465       errmsg ("both IPv4 and IPv6 addresses specified");
13466       return -99;
13467     }
13468
13469   if ((vni == 0) || (vni >> 24))
13470     {
13471       errmsg ("vni not specified or out of range");
13472       return -99;
13473     }
13474
13475   M (VXLAN_ADD_DEL_TUNNEL, mp);
13476
13477   if (ipv6_set)
13478     {
13479       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13480       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13481     }
13482   else
13483     {
13484       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13485       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13486     }
13487
13488   mp->instance = htonl (instance);
13489   mp->encap_vrf_id = ntohl (encap_vrf_id);
13490   mp->decap_next_index = ntohl (decap_next_index);
13491   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13492   mp->vni = ntohl (vni);
13493   mp->is_add = is_add;
13494   mp->is_ipv6 = ipv6_set;
13495
13496   S (mp);
13497   W (ret);
13498   return ret;
13499 }
13500
13501 static void vl_api_vxlan_tunnel_details_t_handler
13502   (vl_api_vxlan_tunnel_details_t * mp)
13503 {
13504   vat_main_t *vam = &vat_main;
13505   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13506   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13507
13508   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13509          ntohl (mp->sw_if_index),
13510          ntohl (mp->instance),
13511          format_ip46_address, &src, IP46_TYPE_ANY,
13512          format_ip46_address, &dst, IP46_TYPE_ANY,
13513          ntohl (mp->encap_vrf_id),
13514          ntohl (mp->decap_next_index), ntohl (mp->vni),
13515          ntohl (mp->mcast_sw_if_index));
13516 }
13517
13518 static void vl_api_vxlan_tunnel_details_t_handler_json
13519   (vl_api_vxlan_tunnel_details_t * mp)
13520 {
13521   vat_main_t *vam = &vat_main;
13522   vat_json_node_t *node = NULL;
13523
13524   if (VAT_JSON_ARRAY != vam->json_tree.type)
13525     {
13526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13527       vat_json_init_array (&vam->json_tree);
13528     }
13529   node = vat_json_array_add (&vam->json_tree);
13530
13531   vat_json_init_object (node);
13532   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13533
13534   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13535
13536   if (mp->is_ipv6)
13537     {
13538       struct in6_addr ip6;
13539
13540       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13541       vat_json_object_add_ip6 (node, "src_address", ip6);
13542       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13543       vat_json_object_add_ip6 (node, "dst_address", ip6);
13544     }
13545   else
13546     {
13547       struct in_addr ip4;
13548
13549       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13550       vat_json_object_add_ip4 (node, "src_address", ip4);
13551       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13552       vat_json_object_add_ip4 (node, "dst_address", ip4);
13553     }
13554   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13555   vat_json_object_add_uint (node, "decap_next_index",
13556                             ntohl (mp->decap_next_index));
13557   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13558   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13559   vat_json_object_add_uint (node, "mcast_sw_if_index",
13560                             ntohl (mp->mcast_sw_if_index));
13561 }
13562
13563 static int
13564 api_vxlan_tunnel_dump (vat_main_t * vam)
13565 {
13566   unformat_input_t *i = vam->input;
13567   vl_api_vxlan_tunnel_dump_t *mp;
13568   vl_api_control_ping_t *mp_ping;
13569   u32 sw_if_index;
13570   u8 sw_if_index_set = 0;
13571   int ret;
13572
13573   /* Parse args required to build the message */
13574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13575     {
13576       if (unformat (i, "sw_if_index %d", &sw_if_index))
13577         sw_if_index_set = 1;
13578       else
13579         break;
13580     }
13581
13582   if (sw_if_index_set == 0)
13583     {
13584       sw_if_index = ~0;
13585     }
13586
13587   if (!vam->json_output)
13588     {
13589       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13590              "sw_if_index", "instance", "src_address", "dst_address",
13591              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13592     }
13593
13594   /* Get list of vxlan-tunnel interfaces */
13595   M (VXLAN_TUNNEL_DUMP, mp);
13596
13597   mp->sw_if_index = htonl (sw_if_index);
13598
13599   S (mp);
13600
13601   /* Use a control ping for synchronization */
13602   MPING (CONTROL_PING, mp_ping);
13603   S (mp_ping);
13604
13605   W (ret);
13606   return ret;
13607 }
13608
13609 static uword unformat_geneve_decap_next
13610   (unformat_input_t * input, va_list * args)
13611 {
13612   u32 *result = va_arg (*args, u32 *);
13613   u32 tmp;
13614
13615   if (unformat (input, "l2"))
13616     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13617   else if (unformat (input, "%d", &tmp))
13618     *result = tmp;
13619   else
13620     return 0;
13621   return 1;
13622 }
13623
13624 static int
13625 api_geneve_add_del_tunnel (vat_main_t * vam)
13626 {
13627   unformat_input_t *line_input = vam->input;
13628   vl_api_geneve_add_del_tunnel_t *mp;
13629   ip46_address_t src, dst;
13630   u8 is_add = 1;
13631   u8 ipv4_set = 0, ipv6_set = 0;
13632   u8 src_set = 0;
13633   u8 dst_set = 0;
13634   u8 grp_set = 0;
13635   u32 mcast_sw_if_index = ~0;
13636   u32 encap_vrf_id = 0;
13637   u32 decap_next_index = ~0;
13638   u32 vni = 0;
13639   int ret;
13640
13641   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13642   memset (&src, 0, sizeof src);
13643   memset (&dst, 0, sizeof dst);
13644
13645   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13646     {
13647       if (unformat (line_input, "del"))
13648         is_add = 0;
13649       else
13650         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13651         {
13652           ipv4_set = 1;
13653           src_set = 1;
13654         }
13655       else
13656         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13657         {
13658           ipv4_set = 1;
13659           dst_set = 1;
13660         }
13661       else
13662         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13663         {
13664           ipv6_set = 1;
13665           src_set = 1;
13666         }
13667       else
13668         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13669         {
13670           ipv6_set = 1;
13671           dst_set = 1;
13672         }
13673       else if (unformat (line_input, "group %U %U",
13674                          unformat_ip4_address, &dst.ip4,
13675                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13676         {
13677           grp_set = dst_set = 1;
13678           ipv4_set = 1;
13679         }
13680       else if (unformat (line_input, "group %U",
13681                          unformat_ip4_address, &dst.ip4))
13682         {
13683           grp_set = dst_set = 1;
13684           ipv4_set = 1;
13685         }
13686       else if (unformat (line_input, "group %U %U",
13687                          unformat_ip6_address, &dst.ip6,
13688                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13689         {
13690           grp_set = dst_set = 1;
13691           ipv6_set = 1;
13692         }
13693       else if (unformat (line_input, "group %U",
13694                          unformat_ip6_address, &dst.ip6))
13695         {
13696           grp_set = dst_set = 1;
13697           ipv6_set = 1;
13698         }
13699       else
13700         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13701         ;
13702       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13703         ;
13704       else if (unformat (line_input, "decap-next %U",
13705                          unformat_geneve_decap_next, &decap_next_index))
13706         ;
13707       else if (unformat (line_input, "vni %d", &vni))
13708         ;
13709       else
13710         {
13711           errmsg ("parse error '%U'", format_unformat_error, line_input);
13712           return -99;
13713         }
13714     }
13715
13716   if (src_set == 0)
13717     {
13718       errmsg ("tunnel src address not specified");
13719       return -99;
13720     }
13721   if (dst_set == 0)
13722     {
13723       errmsg ("tunnel dst address not specified");
13724       return -99;
13725     }
13726
13727   if (grp_set && !ip46_address_is_multicast (&dst))
13728     {
13729       errmsg ("tunnel group address not multicast");
13730       return -99;
13731     }
13732   if (grp_set && mcast_sw_if_index == ~0)
13733     {
13734       errmsg ("tunnel nonexistent multicast device");
13735       return -99;
13736     }
13737   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13738     {
13739       errmsg ("tunnel dst address must be unicast");
13740       return -99;
13741     }
13742
13743
13744   if (ipv4_set && ipv6_set)
13745     {
13746       errmsg ("both IPv4 and IPv6 addresses specified");
13747       return -99;
13748     }
13749
13750   if ((vni == 0) || (vni >> 24))
13751     {
13752       errmsg ("vni not specified or out of range");
13753       return -99;
13754     }
13755
13756   M (GENEVE_ADD_DEL_TUNNEL, mp);
13757
13758   if (ipv6_set)
13759     {
13760       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13761       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13762     }
13763   else
13764     {
13765       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13766       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13767     }
13768   mp->encap_vrf_id = ntohl (encap_vrf_id);
13769   mp->decap_next_index = ntohl (decap_next_index);
13770   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13771   mp->vni = ntohl (vni);
13772   mp->is_add = is_add;
13773   mp->is_ipv6 = ipv6_set;
13774
13775   S (mp);
13776   W (ret);
13777   return ret;
13778 }
13779
13780 static void vl_api_geneve_tunnel_details_t_handler
13781   (vl_api_geneve_tunnel_details_t * mp)
13782 {
13783   vat_main_t *vam = &vat_main;
13784   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13785   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13786
13787   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13788          ntohl (mp->sw_if_index),
13789          format_ip46_address, &src, IP46_TYPE_ANY,
13790          format_ip46_address, &dst, IP46_TYPE_ANY,
13791          ntohl (mp->encap_vrf_id),
13792          ntohl (mp->decap_next_index), ntohl (mp->vni),
13793          ntohl (mp->mcast_sw_if_index));
13794 }
13795
13796 static void vl_api_geneve_tunnel_details_t_handler_json
13797   (vl_api_geneve_tunnel_details_t * mp)
13798 {
13799   vat_main_t *vam = &vat_main;
13800   vat_json_node_t *node = NULL;
13801
13802   if (VAT_JSON_ARRAY != vam->json_tree.type)
13803     {
13804       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13805       vat_json_init_array (&vam->json_tree);
13806     }
13807   node = vat_json_array_add (&vam->json_tree);
13808
13809   vat_json_init_object (node);
13810   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13811   if (mp->is_ipv6)
13812     {
13813       struct in6_addr ip6;
13814
13815       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13816       vat_json_object_add_ip6 (node, "src_address", ip6);
13817       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13818       vat_json_object_add_ip6 (node, "dst_address", ip6);
13819     }
13820   else
13821     {
13822       struct in_addr ip4;
13823
13824       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13825       vat_json_object_add_ip4 (node, "src_address", ip4);
13826       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13827       vat_json_object_add_ip4 (node, "dst_address", ip4);
13828     }
13829   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13830   vat_json_object_add_uint (node, "decap_next_index",
13831                             ntohl (mp->decap_next_index));
13832   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13833   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13834   vat_json_object_add_uint (node, "mcast_sw_if_index",
13835                             ntohl (mp->mcast_sw_if_index));
13836 }
13837
13838 static int
13839 api_geneve_tunnel_dump (vat_main_t * vam)
13840 {
13841   unformat_input_t *i = vam->input;
13842   vl_api_geneve_tunnel_dump_t *mp;
13843   vl_api_control_ping_t *mp_ping;
13844   u32 sw_if_index;
13845   u8 sw_if_index_set = 0;
13846   int ret;
13847
13848   /* Parse args required to build the message */
13849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13850     {
13851       if (unformat (i, "sw_if_index %d", &sw_if_index))
13852         sw_if_index_set = 1;
13853       else
13854         break;
13855     }
13856
13857   if (sw_if_index_set == 0)
13858     {
13859       sw_if_index = ~0;
13860     }
13861
13862   if (!vam->json_output)
13863     {
13864       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13865              "sw_if_index", "local_address", "remote_address",
13866              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13867     }
13868
13869   /* Get list of geneve-tunnel interfaces */
13870   M (GENEVE_TUNNEL_DUMP, mp);
13871
13872   mp->sw_if_index = htonl (sw_if_index);
13873
13874   S (mp);
13875
13876   /* Use a control ping for synchronization */
13877   M (CONTROL_PING, mp_ping);
13878   S (mp_ping);
13879
13880   W (ret);
13881   return ret;
13882 }
13883
13884 static int
13885 api_gre_add_del_tunnel (vat_main_t * vam)
13886 {
13887   unformat_input_t *line_input = vam->input;
13888   vl_api_gre_add_del_tunnel_t *mp;
13889   ip4_address_t src4, dst4;
13890   ip6_address_t src6, dst6;
13891   u8 is_add = 1;
13892   u8 ipv4_set = 0;
13893   u8 ipv6_set = 0;
13894   u8 t_type = GRE_TUNNEL_TYPE_L3;
13895   u8 src_set = 0;
13896   u8 dst_set = 0;
13897   u32 outer_fib_id = 0;
13898   u32 session_id = 0;
13899   u32 instance = ~0;
13900   int ret;
13901
13902   memset (&src4, 0, sizeof src4);
13903   memset (&dst4, 0, sizeof dst4);
13904   memset (&src6, 0, sizeof src6);
13905   memset (&dst6, 0, sizeof dst6);
13906
13907   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13908     {
13909       if (unformat (line_input, "del"))
13910         is_add = 0;
13911       else if (unformat (line_input, "instance %d", &instance))
13912         ;
13913       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13914         {
13915           src_set = 1;
13916           ipv4_set = 1;
13917         }
13918       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13919         {
13920           dst_set = 1;
13921           ipv4_set = 1;
13922         }
13923       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13924         {
13925           src_set = 1;
13926           ipv6_set = 1;
13927         }
13928       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13929         {
13930           dst_set = 1;
13931           ipv6_set = 1;
13932         }
13933       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13934         ;
13935       else if (unformat (line_input, "teb"))
13936         t_type = GRE_TUNNEL_TYPE_TEB;
13937       else if (unformat (line_input, "erspan %d", &session_id))
13938         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13939       else
13940         {
13941           errmsg ("parse error '%U'", format_unformat_error, line_input);
13942           return -99;
13943         }
13944     }
13945
13946   if (src_set == 0)
13947     {
13948       errmsg ("tunnel src address not specified");
13949       return -99;
13950     }
13951   if (dst_set == 0)
13952     {
13953       errmsg ("tunnel dst address not specified");
13954       return -99;
13955     }
13956   if (ipv4_set && ipv6_set)
13957     {
13958       errmsg ("both IPv4 and IPv6 addresses specified");
13959       return -99;
13960     }
13961
13962
13963   M (GRE_ADD_DEL_TUNNEL, mp);
13964
13965   if (ipv4_set)
13966     {
13967       clib_memcpy (&mp->src_address, &src4, 4);
13968       clib_memcpy (&mp->dst_address, &dst4, 4);
13969     }
13970   else
13971     {
13972       clib_memcpy (&mp->src_address, &src6, 16);
13973       clib_memcpy (&mp->dst_address, &dst6, 16);
13974     }
13975   mp->instance = htonl (instance);
13976   mp->outer_fib_id = htonl (outer_fib_id);
13977   mp->is_add = is_add;
13978   mp->session_id = htons ((u16) session_id);
13979   mp->tunnel_type = t_type;
13980   mp->is_ipv6 = ipv6_set;
13981
13982   S (mp);
13983   W (ret);
13984   return ret;
13985 }
13986
13987 static void vl_api_gre_tunnel_details_t_handler
13988   (vl_api_gre_tunnel_details_t * mp)
13989 {
13990   vat_main_t *vam = &vat_main;
13991   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13992   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13993
13994   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13995          ntohl (mp->sw_if_index),
13996          ntohl (mp->instance),
13997          format_ip46_address, &src, IP46_TYPE_ANY,
13998          format_ip46_address, &dst, IP46_TYPE_ANY,
13999          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14000 }
14001
14002 static void vl_api_gre_tunnel_details_t_handler_json
14003   (vl_api_gre_tunnel_details_t * mp)
14004 {
14005   vat_main_t *vam = &vat_main;
14006   vat_json_node_t *node = NULL;
14007   struct in_addr ip4;
14008   struct in6_addr ip6;
14009
14010   if (VAT_JSON_ARRAY != vam->json_tree.type)
14011     {
14012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14013       vat_json_init_array (&vam->json_tree);
14014     }
14015   node = vat_json_array_add (&vam->json_tree);
14016
14017   vat_json_init_object (node);
14018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14019   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14020   if (!mp->is_ipv6)
14021     {
14022       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14023       vat_json_object_add_ip4 (node, "src_address", ip4);
14024       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14025       vat_json_object_add_ip4 (node, "dst_address", ip4);
14026     }
14027   else
14028     {
14029       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14030       vat_json_object_add_ip6 (node, "src_address", ip6);
14031       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14032       vat_json_object_add_ip6 (node, "dst_address", ip6);
14033     }
14034   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14035   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14036   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14037   vat_json_object_add_uint (node, "session_id", mp->session_id);
14038 }
14039
14040 static int
14041 api_gre_tunnel_dump (vat_main_t * vam)
14042 {
14043   unformat_input_t *i = vam->input;
14044   vl_api_gre_tunnel_dump_t *mp;
14045   vl_api_control_ping_t *mp_ping;
14046   u32 sw_if_index;
14047   u8 sw_if_index_set = 0;
14048   int ret;
14049
14050   /* Parse args required to build the message */
14051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14052     {
14053       if (unformat (i, "sw_if_index %d", &sw_if_index))
14054         sw_if_index_set = 1;
14055       else
14056         break;
14057     }
14058
14059   if (sw_if_index_set == 0)
14060     {
14061       sw_if_index = ~0;
14062     }
14063
14064   if (!vam->json_output)
14065     {
14066       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14067              "sw_if_index", "instance", "src_address", "dst_address",
14068              "tunnel_type", "outer_fib_id", "session_id");
14069     }
14070
14071   /* Get list of gre-tunnel interfaces */
14072   M (GRE_TUNNEL_DUMP, mp);
14073
14074   mp->sw_if_index = htonl (sw_if_index);
14075
14076   S (mp);
14077
14078   /* Use a control ping for synchronization */
14079   MPING (CONTROL_PING, mp_ping);
14080   S (mp_ping);
14081
14082   W (ret);
14083   return ret;
14084 }
14085
14086 static int
14087 api_l2_fib_clear_table (vat_main_t * vam)
14088 {
14089 //  unformat_input_t * i = vam->input;
14090   vl_api_l2_fib_clear_table_t *mp;
14091   int ret;
14092
14093   M (L2_FIB_CLEAR_TABLE, mp);
14094
14095   S (mp);
14096   W (ret);
14097   return ret;
14098 }
14099
14100 static int
14101 api_l2_interface_efp_filter (vat_main_t * vam)
14102 {
14103   unformat_input_t *i = vam->input;
14104   vl_api_l2_interface_efp_filter_t *mp;
14105   u32 sw_if_index;
14106   u8 enable = 1;
14107   u8 sw_if_index_set = 0;
14108   int ret;
14109
14110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14111     {
14112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14113         sw_if_index_set = 1;
14114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14115         sw_if_index_set = 1;
14116       else if (unformat (i, "enable"))
14117         enable = 1;
14118       else if (unformat (i, "disable"))
14119         enable = 0;
14120       else
14121         {
14122           clib_warning ("parse error '%U'", format_unformat_error, i);
14123           return -99;
14124         }
14125     }
14126
14127   if (sw_if_index_set == 0)
14128     {
14129       errmsg ("missing sw_if_index");
14130       return -99;
14131     }
14132
14133   M (L2_INTERFACE_EFP_FILTER, mp);
14134
14135   mp->sw_if_index = ntohl (sw_if_index);
14136   mp->enable_disable = enable;
14137
14138   S (mp);
14139   W (ret);
14140   return ret;
14141 }
14142
14143 #define foreach_vtr_op                          \
14144 _("disable",  L2_VTR_DISABLED)                  \
14145 _("push-1",  L2_VTR_PUSH_1)                     \
14146 _("push-2",  L2_VTR_PUSH_2)                     \
14147 _("pop-1",  L2_VTR_POP_1)                       \
14148 _("pop-2",  L2_VTR_POP_2)                       \
14149 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14150 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14151 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14152 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14153
14154 static int
14155 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14156 {
14157   unformat_input_t *i = vam->input;
14158   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14159   u32 sw_if_index;
14160   u8 sw_if_index_set = 0;
14161   u8 vtr_op_set = 0;
14162   u32 vtr_op = 0;
14163   u32 push_dot1q = 1;
14164   u32 tag1 = ~0;
14165   u32 tag2 = ~0;
14166   int ret;
14167
14168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14169     {
14170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14171         sw_if_index_set = 1;
14172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14173         sw_if_index_set = 1;
14174       else if (unformat (i, "vtr_op %d", &vtr_op))
14175         vtr_op_set = 1;
14176 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14177       foreach_vtr_op
14178 #undef _
14179         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14180         ;
14181       else if (unformat (i, "tag1 %d", &tag1))
14182         ;
14183       else if (unformat (i, "tag2 %d", &tag2))
14184         ;
14185       else
14186         {
14187           clib_warning ("parse error '%U'", format_unformat_error, i);
14188           return -99;
14189         }
14190     }
14191
14192   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14193     {
14194       errmsg ("missing vtr operation or sw_if_index");
14195       return -99;
14196     }
14197
14198   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14199   mp->sw_if_index = ntohl (sw_if_index);
14200   mp->vtr_op = ntohl (vtr_op);
14201   mp->push_dot1q = ntohl (push_dot1q);
14202   mp->tag1 = ntohl (tag1);
14203   mp->tag2 = ntohl (tag2);
14204
14205   S (mp);
14206   W (ret);
14207   return ret;
14208 }
14209
14210 static int
14211 api_create_vhost_user_if (vat_main_t * vam)
14212 {
14213   unformat_input_t *i = vam->input;
14214   vl_api_create_vhost_user_if_t *mp;
14215   u8 *file_name;
14216   u8 is_server = 0;
14217   u8 file_name_set = 0;
14218   u32 custom_dev_instance = ~0;
14219   u8 hwaddr[6];
14220   u8 use_custom_mac = 0;
14221   u8 disable_mrg_rxbuf = 0;
14222   u8 disable_indirect_desc = 0;
14223   u8 *tag = 0;
14224   int ret;
14225
14226   /* Shut up coverity */
14227   memset (hwaddr, 0, sizeof (hwaddr));
14228
14229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14230     {
14231       if (unformat (i, "socket %s", &file_name))
14232         {
14233           file_name_set = 1;
14234         }
14235       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14236         ;
14237       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14238         use_custom_mac = 1;
14239       else if (unformat (i, "server"))
14240         is_server = 1;
14241       else if (unformat (i, "disable_mrg_rxbuf"))
14242         disable_mrg_rxbuf = 1;
14243       else if (unformat (i, "disable_indirect_desc"))
14244         disable_indirect_desc = 1;
14245       else if (unformat (i, "tag %s", &tag))
14246         ;
14247       else
14248         break;
14249     }
14250
14251   if (file_name_set == 0)
14252     {
14253       errmsg ("missing socket file name");
14254       return -99;
14255     }
14256
14257   if (vec_len (file_name) > 255)
14258     {
14259       errmsg ("socket file name too long");
14260       return -99;
14261     }
14262   vec_add1 (file_name, 0);
14263
14264   M (CREATE_VHOST_USER_IF, mp);
14265
14266   mp->is_server = is_server;
14267   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14268   mp->disable_indirect_desc = disable_indirect_desc;
14269   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14270   vec_free (file_name);
14271   if (custom_dev_instance != ~0)
14272     {
14273       mp->renumber = 1;
14274       mp->custom_dev_instance = ntohl (custom_dev_instance);
14275     }
14276
14277   mp->use_custom_mac = use_custom_mac;
14278   clib_memcpy (mp->mac_address, hwaddr, 6);
14279   if (tag)
14280     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14281   vec_free (tag);
14282
14283   S (mp);
14284   W (ret);
14285   return ret;
14286 }
14287
14288 static int
14289 api_modify_vhost_user_if (vat_main_t * vam)
14290 {
14291   unformat_input_t *i = vam->input;
14292   vl_api_modify_vhost_user_if_t *mp;
14293   u8 *file_name;
14294   u8 is_server = 0;
14295   u8 file_name_set = 0;
14296   u32 custom_dev_instance = ~0;
14297   u8 sw_if_index_set = 0;
14298   u32 sw_if_index = (u32) ~ 0;
14299   int ret;
14300
14301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14302     {
14303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14304         sw_if_index_set = 1;
14305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14306         sw_if_index_set = 1;
14307       else if (unformat (i, "socket %s", &file_name))
14308         {
14309           file_name_set = 1;
14310         }
14311       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14312         ;
14313       else if (unformat (i, "server"))
14314         is_server = 1;
14315       else
14316         break;
14317     }
14318
14319   if (sw_if_index_set == 0)
14320     {
14321       errmsg ("missing sw_if_index or interface name");
14322       return -99;
14323     }
14324
14325   if (file_name_set == 0)
14326     {
14327       errmsg ("missing socket file name");
14328       return -99;
14329     }
14330
14331   if (vec_len (file_name) > 255)
14332     {
14333       errmsg ("socket file name too long");
14334       return -99;
14335     }
14336   vec_add1 (file_name, 0);
14337
14338   M (MODIFY_VHOST_USER_IF, mp);
14339
14340   mp->sw_if_index = ntohl (sw_if_index);
14341   mp->is_server = is_server;
14342   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14343   vec_free (file_name);
14344   if (custom_dev_instance != ~0)
14345     {
14346       mp->renumber = 1;
14347       mp->custom_dev_instance = ntohl (custom_dev_instance);
14348     }
14349
14350   S (mp);
14351   W (ret);
14352   return ret;
14353 }
14354
14355 static int
14356 api_delete_vhost_user_if (vat_main_t * vam)
14357 {
14358   unformat_input_t *i = vam->input;
14359   vl_api_delete_vhost_user_if_t *mp;
14360   u32 sw_if_index = ~0;
14361   u8 sw_if_index_set = 0;
14362   int ret;
14363
14364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14365     {
14366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14367         sw_if_index_set = 1;
14368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14369         sw_if_index_set = 1;
14370       else
14371         break;
14372     }
14373
14374   if (sw_if_index_set == 0)
14375     {
14376       errmsg ("missing sw_if_index or interface name");
14377       return -99;
14378     }
14379
14380
14381   M (DELETE_VHOST_USER_IF, mp);
14382
14383   mp->sw_if_index = ntohl (sw_if_index);
14384
14385   S (mp);
14386   W (ret);
14387   return ret;
14388 }
14389
14390 static void vl_api_sw_interface_vhost_user_details_t_handler
14391   (vl_api_sw_interface_vhost_user_details_t * mp)
14392 {
14393   vat_main_t *vam = &vat_main;
14394
14395   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14396          (char *) mp->interface_name,
14397          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14398          clib_net_to_host_u64 (mp->features), mp->is_server,
14399          ntohl (mp->num_regions), (char *) mp->sock_filename);
14400   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14401 }
14402
14403 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14404   (vl_api_sw_interface_vhost_user_details_t * mp)
14405 {
14406   vat_main_t *vam = &vat_main;
14407   vat_json_node_t *node = NULL;
14408
14409   if (VAT_JSON_ARRAY != vam->json_tree.type)
14410     {
14411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14412       vat_json_init_array (&vam->json_tree);
14413     }
14414   node = vat_json_array_add (&vam->json_tree);
14415
14416   vat_json_init_object (node);
14417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14418   vat_json_object_add_string_copy (node, "interface_name",
14419                                    mp->interface_name);
14420   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14421                             ntohl (mp->virtio_net_hdr_sz));
14422   vat_json_object_add_uint (node, "features",
14423                             clib_net_to_host_u64 (mp->features));
14424   vat_json_object_add_uint (node, "is_server", mp->is_server);
14425   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14426   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14427   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14428 }
14429
14430 static int
14431 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14432 {
14433   vl_api_sw_interface_vhost_user_dump_t *mp;
14434   vl_api_control_ping_t *mp_ping;
14435   int ret;
14436   print (vam->ofp,
14437          "Interface name            idx hdr_sz features server regions filename");
14438
14439   /* Get list of vhost-user interfaces */
14440   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14441   S (mp);
14442
14443   /* Use a control ping for synchronization */
14444   MPING (CONTROL_PING, mp_ping);
14445   S (mp_ping);
14446
14447   W (ret);
14448   return ret;
14449 }
14450
14451 static int
14452 api_show_version (vat_main_t * vam)
14453 {
14454   vl_api_show_version_t *mp;
14455   int ret;
14456
14457   M (SHOW_VERSION, mp);
14458
14459   S (mp);
14460   W (ret);
14461   return ret;
14462 }
14463
14464
14465 static int
14466 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14467 {
14468   unformat_input_t *line_input = vam->input;
14469   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14470   ip4_address_t local4, remote4;
14471   ip6_address_t local6, remote6;
14472   u8 is_add = 1;
14473   u8 ipv4_set = 0, ipv6_set = 0;
14474   u8 local_set = 0;
14475   u8 remote_set = 0;
14476   u8 grp_set = 0;
14477   u32 mcast_sw_if_index = ~0;
14478   u32 encap_vrf_id = 0;
14479   u32 decap_vrf_id = 0;
14480   u8 protocol = ~0;
14481   u32 vni;
14482   u8 vni_set = 0;
14483   int ret;
14484
14485   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14486   memset (&local4, 0, sizeof local4);
14487   memset (&remote4, 0, sizeof remote4);
14488   memset (&local6, 0, sizeof local6);
14489   memset (&remote6, 0, sizeof remote6);
14490
14491   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14492     {
14493       if (unformat (line_input, "del"))
14494         is_add = 0;
14495       else if (unformat (line_input, "local %U",
14496                          unformat_ip4_address, &local4))
14497         {
14498           local_set = 1;
14499           ipv4_set = 1;
14500         }
14501       else if (unformat (line_input, "remote %U",
14502                          unformat_ip4_address, &remote4))
14503         {
14504           remote_set = 1;
14505           ipv4_set = 1;
14506         }
14507       else if (unformat (line_input, "local %U",
14508                          unformat_ip6_address, &local6))
14509         {
14510           local_set = 1;
14511           ipv6_set = 1;
14512         }
14513       else if (unformat (line_input, "remote %U",
14514                          unformat_ip6_address, &remote6))
14515         {
14516           remote_set = 1;
14517           ipv6_set = 1;
14518         }
14519       else if (unformat (line_input, "group %U %U",
14520                          unformat_ip4_address, &remote4,
14521                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14522         {
14523           grp_set = remote_set = 1;
14524           ipv4_set = 1;
14525         }
14526       else if (unformat (line_input, "group %U",
14527                          unformat_ip4_address, &remote4))
14528         {
14529           grp_set = remote_set = 1;
14530           ipv4_set = 1;
14531         }
14532       else if (unformat (line_input, "group %U %U",
14533                          unformat_ip6_address, &remote6,
14534                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14535         {
14536           grp_set = remote_set = 1;
14537           ipv6_set = 1;
14538         }
14539       else if (unformat (line_input, "group %U",
14540                          unformat_ip6_address, &remote6))
14541         {
14542           grp_set = remote_set = 1;
14543           ipv6_set = 1;
14544         }
14545       else
14546         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14547         ;
14548       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14549         ;
14550       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14551         ;
14552       else if (unformat (line_input, "vni %d", &vni))
14553         vni_set = 1;
14554       else if (unformat (line_input, "next-ip4"))
14555         protocol = 1;
14556       else if (unformat (line_input, "next-ip6"))
14557         protocol = 2;
14558       else if (unformat (line_input, "next-ethernet"))
14559         protocol = 3;
14560       else if (unformat (line_input, "next-nsh"))
14561         protocol = 4;
14562       else
14563         {
14564           errmsg ("parse error '%U'", format_unformat_error, line_input);
14565           return -99;
14566         }
14567     }
14568
14569   if (local_set == 0)
14570     {
14571       errmsg ("tunnel local address not specified");
14572       return -99;
14573     }
14574   if (remote_set == 0)
14575     {
14576       errmsg ("tunnel remote address not specified");
14577       return -99;
14578     }
14579   if (grp_set && mcast_sw_if_index == ~0)
14580     {
14581       errmsg ("tunnel nonexistent multicast device");
14582       return -99;
14583     }
14584   if (ipv4_set && ipv6_set)
14585     {
14586       errmsg ("both IPv4 and IPv6 addresses specified");
14587       return -99;
14588     }
14589
14590   if (vni_set == 0)
14591     {
14592       errmsg ("vni not specified");
14593       return -99;
14594     }
14595
14596   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14597
14598
14599   if (ipv6_set)
14600     {
14601       clib_memcpy (&mp->local, &local6, sizeof (local6));
14602       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14603     }
14604   else
14605     {
14606       clib_memcpy (&mp->local, &local4, sizeof (local4));
14607       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14608     }
14609
14610   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14611   mp->encap_vrf_id = ntohl (encap_vrf_id);
14612   mp->decap_vrf_id = ntohl (decap_vrf_id);
14613   mp->protocol = protocol;
14614   mp->vni = ntohl (vni);
14615   mp->is_add = is_add;
14616   mp->is_ipv6 = ipv6_set;
14617
14618   S (mp);
14619   W (ret);
14620   return ret;
14621 }
14622
14623 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14624   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14625 {
14626   vat_main_t *vam = &vat_main;
14627   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14628   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14629
14630   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14631          ntohl (mp->sw_if_index),
14632          format_ip46_address, &local, IP46_TYPE_ANY,
14633          format_ip46_address, &remote, IP46_TYPE_ANY,
14634          ntohl (mp->vni), mp->protocol,
14635          ntohl (mp->mcast_sw_if_index),
14636          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14637 }
14638
14639
14640 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14641   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14642 {
14643   vat_main_t *vam = &vat_main;
14644   vat_json_node_t *node = NULL;
14645   struct in_addr ip4;
14646   struct in6_addr ip6;
14647
14648   if (VAT_JSON_ARRAY != vam->json_tree.type)
14649     {
14650       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14651       vat_json_init_array (&vam->json_tree);
14652     }
14653   node = vat_json_array_add (&vam->json_tree);
14654
14655   vat_json_init_object (node);
14656   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14657   if (mp->is_ipv6)
14658     {
14659       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14660       vat_json_object_add_ip6 (node, "local", ip6);
14661       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14662       vat_json_object_add_ip6 (node, "remote", ip6);
14663     }
14664   else
14665     {
14666       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14667       vat_json_object_add_ip4 (node, "local", ip4);
14668       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14669       vat_json_object_add_ip4 (node, "remote", ip4);
14670     }
14671   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14672   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14673   vat_json_object_add_uint (node, "mcast_sw_if_index",
14674                             ntohl (mp->mcast_sw_if_index));
14675   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14676   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14677   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14678 }
14679
14680 static int
14681 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14682 {
14683   unformat_input_t *i = vam->input;
14684   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14685   vl_api_control_ping_t *mp_ping;
14686   u32 sw_if_index;
14687   u8 sw_if_index_set = 0;
14688   int ret;
14689
14690   /* Parse args required to build the message */
14691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14692     {
14693       if (unformat (i, "sw_if_index %d", &sw_if_index))
14694         sw_if_index_set = 1;
14695       else
14696         break;
14697     }
14698
14699   if (sw_if_index_set == 0)
14700     {
14701       sw_if_index = ~0;
14702     }
14703
14704   if (!vam->json_output)
14705     {
14706       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14707              "sw_if_index", "local", "remote", "vni",
14708              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14709     }
14710
14711   /* Get list of vxlan-tunnel interfaces */
14712   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14713
14714   mp->sw_if_index = htonl (sw_if_index);
14715
14716   S (mp);
14717
14718   /* Use a control ping for synchronization */
14719   MPING (CONTROL_PING, mp_ping);
14720   S (mp_ping);
14721
14722   W (ret);
14723   return ret;
14724 }
14725
14726 static void vl_api_l2_fib_table_details_t_handler
14727   (vl_api_l2_fib_table_details_t * mp)
14728 {
14729   vat_main_t *vam = &vat_main;
14730
14731   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14732          "       %d       %d     %d",
14733          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14734          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14735          mp->bvi_mac);
14736 }
14737
14738 static void vl_api_l2_fib_table_details_t_handler_json
14739   (vl_api_l2_fib_table_details_t * mp)
14740 {
14741   vat_main_t *vam = &vat_main;
14742   vat_json_node_t *node = NULL;
14743
14744   if (VAT_JSON_ARRAY != vam->json_tree.type)
14745     {
14746       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14747       vat_json_init_array (&vam->json_tree);
14748     }
14749   node = vat_json_array_add (&vam->json_tree);
14750
14751   vat_json_init_object (node);
14752   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14753   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14754   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14755   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14756   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14757   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14758 }
14759
14760 static int
14761 api_l2_fib_table_dump (vat_main_t * vam)
14762 {
14763   unformat_input_t *i = vam->input;
14764   vl_api_l2_fib_table_dump_t *mp;
14765   vl_api_control_ping_t *mp_ping;
14766   u32 bd_id;
14767   u8 bd_id_set = 0;
14768   int ret;
14769
14770   /* Parse args required to build the message */
14771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14772     {
14773       if (unformat (i, "bd_id %d", &bd_id))
14774         bd_id_set = 1;
14775       else
14776         break;
14777     }
14778
14779   if (bd_id_set == 0)
14780     {
14781       errmsg ("missing bridge domain");
14782       return -99;
14783     }
14784
14785   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14786
14787   /* Get list of l2 fib entries */
14788   M (L2_FIB_TABLE_DUMP, mp);
14789
14790   mp->bd_id = ntohl (bd_id);
14791   S (mp);
14792
14793   /* Use a control ping for synchronization */
14794   MPING (CONTROL_PING, mp_ping);
14795   S (mp_ping);
14796
14797   W (ret);
14798   return ret;
14799 }
14800
14801
14802 static int
14803 api_interface_name_renumber (vat_main_t * vam)
14804 {
14805   unformat_input_t *line_input = vam->input;
14806   vl_api_interface_name_renumber_t *mp;
14807   u32 sw_if_index = ~0;
14808   u32 new_show_dev_instance = ~0;
14809   int ret;
14810
14811   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14812     {
14813       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14814                     &sw_if_index))
14815         ;
14816       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14817         ;
14818       else if (unformat (line_input, "new_show_dev_instance %d",
14819                          &new_show_dev_instance))
14820         ;
14821       else
14822         break;
14823     }
14824
14825   if (sw_if_index == ~0)
14826     {
14827       errmsg ("missing interface name or sw_if_index");
14828       return -99;
14829     }
14830
14831   if (new_show_dev_instance == ~0)
14832     {
14833       errmsg ("missing new_show_dev_instance");
14834       return -99;
14835     }
14836
14837   M (INTERFACE_NAME_RENUMBER, mp);
14838
14839   mp->sw_if_index = ntohl (sw_if_index);
14840   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14841
14842   S (mp);
14843   W (ret);
14844   return ret;
14845 }
14846
14847 static int
14848 api_ip_probe_neighbor (vat_main_t * vam)
14849 {
14850   unformat_input_t *i = vam->input;
14851   vl_api_ip_probe_neighbor_t *mp;
14852   u8 int_set = 0;
14853   u8 adr_set = 0;
14854   u8 is_ipv6 = 0;
14855   u8 dst_adr[16];
14856   u32 sw_if_index;
14857   int ret;
14858
14859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14860     {
14861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14862         int_set = 1;
14863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14864         int_set = 1;
14865       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14866         adr_set = 1;
14867       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14868         {
14869           adr_set = 1;
14870           is_ipv6 = 1;
14871         }
14872       else
14873         break;
14874     }
14875
14876   if (int_set == 0)
14877     {
14878       errmsg ("missing interface");
14879       return -99;
14880     }
14881
14882   if (adr_set == 0)
14883     {
14884       errmsg ("missing addresses");
14885       return -99;
14886     }
14887
14888   M (IP_PROBE_NEIGHBOR, mp);
14889
14890   mp->sw_if_index = ntohl (sw_if_index);
14891   mp->is_ipv6 = is_ipv6;
14892   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14893
14894   S (mp);
14895   W (ret);
14896   return ret;
14897 }
14898
14899 static int
14900 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14901 {
14902   unformat_input_t *i = vam->input;
14903   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14904   u8 mode = IP_SCAN_V46_NEIGHBORS;
14905   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14906   int ret;
14907
14908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14909     {
14910       if (unformat (i, "ip4"))
14911         mode = IP_SCAN_V4_NEIGHBORS;
14912       else if (unformat (i, "ip6"))
14913         mode = IP_SCAN_V6_NEIGHBORS;
14914       if (unformat (i, "both"))
14915         mode = IP_SCAN_V46_NEIGHBORS;
14916       else if (unformat (i, "disable"))
14917         mode = IP_SCAN_DISABLED;
14918       else if (unformat (i, "interval %d", &interval))
14919         ;
14920       else if (unformat (i, "max-time %d", &time))
14921         ;
14922       else if (unformat (i, "max-update %d", &update))
14923         ;
14924       else if (unformat (i, "delay %d", &delay))
14925         ;
14926       else if (unformat (i, "stale %d", &stale))
14927         ;
14928       else
14929         break;
14930     }
14931
14932   if (interval > 255)
14933     {
14934       errmsg ("interval cannot exceed 255 minutes.");
14935       return -99;
14936     }
14937   if (time > 255)
14938     {
14939       errmsg ("max-time cannot exceed 255 usec.");
14940       return -99;
14941     }
14942   if (update > 255)
14943     {
14944       errmsg ("max-update cannot exceed 255.");
14945       return -99;
14946     }
14947   if (delay > 255)
14948     {
14949       errmsg ("delay cannot exceed 255 msec.");
14950       return -99;
14951     }
14952   if (stale > 255)
14953     {
14954       errmsg ("stale cannot exceed 255 minutes.");
14955       return -99;
14956     }
14957
14958   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14959   mp->mode = mode;
14960   mp->scan_interval = interval;
14961   mp->max_proc_time = time;
14962   mp->max_update = update;
14963   mp->scan_int_delay = delay;
14964   mp->stale_threshold = stale;
14965
14966   S (mp);
14967   W (ret);
14968   return ret;
14969 }
14970
14971 static int
14972 api_want_ip4_arp_events (vat_main_t * vam)
14973 {
14974   unformat_input_t *line_input = vam->input;
14975   vl_api_want_ip4_arp_events_t *mp;
14976   ip4_address_t address;
14977   int address_set = 0;
14978   u32 enable_disable = 1;
14979   int ret;
14980
14981   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14982     {
14983       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14984         address_set = 1;
14985       else if (unformat (line_input, "del"))
14986         enable_disable = 0;
14987       else
14988         break;
14989     }
14990
14991   if (address_set == 0)
14992     {
14993       errmsg ("missing addresses");
14994       return -99;
14995     }
14996
14997   M (WANT_IP4_ARP_EVENTS, mp);
14998   mp->enable_disable = enable_disable;
14999   mp->pid = htonl (getpid ());
15000   mp->address = address.as_u32;
15001
15002   S (mp);
15003   W (ret);
15004   return ret;
15005 }
15006
15007 static int
15008 api_want_ip6_nd_events (vat_main_t * vam)
15009 {
15010   unformat_input_t *line_input = vam->input;
15011   vl_api_want_ip6_nd_events_t *mp;
15012   ip6_address_t address;
15013   int address_set = 0;
15014   u32 enable_disable = 1;
15015   int ret;
15016
15017   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15018     {
15019       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15020         address_set = 1;
15021       else if (unformat (line_input, "del"))
15022         enable_disable = 0;
15023       else
15024         break;
15025     }
15026
15027   if (address_set == 0)
15028     {
15029       errmsg ("missing addresses");
15030       return -99;
15031     }
15032
15033   M (WANT_IP6_ND_EVENTS, mp);
15034   mp->enable_disable = enable_disable;
15035   mp->pid = htonl (getpid ());
15036   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15037
15038   S (mp);
15039   W (ret);
15040   return ret;
15041 }
15042
15043 static int
15044 api_want_l2_macs_events (vat_main_t * vam)
15045 {
15046   unformat_input_t *line_input = vam->input;
15047   vl_api_want_l2_macs_events_t *mp;
15048   u8 enable_disable = 1;
15049   u32 scan_delay = 0;
15050   u32 max_macs_in_event = 0;
15051   u32 learn_limit = 0;
15052   int ret;
15053
15054   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15055     {
15056       if (unformat (line_input, "learn-limit %d", &learn_limit))
15057         ;
15058       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15059         ;
15060       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15061         ;
15062       else if (unformat (line_input, "disable"))
15063         enable_disable = 0;
15064       else
15065         break;
15066     }
15067
15068   M (WANT_L2_MACS_EVENTS, mp);
15069   mp->enable_disable = enable_disable;
15070   mp->pid = htonl (getpid ());
15071   mp->learn_limit = htonl (learn_limit);
15072   mp->scan_delay = (u8) scan_delay;
15073   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15074   S (mp);
15075   W (ret);
15076   return ret;
15077 }
15078
15079 static int
15080 api_input_acl_set_interface (vat_main_t * vam)
15081 {
15082   unformat_input_t *i = vam->input;
15083   vl_api_input_acl_set_interface_t *mp;
15084   u32 sw_if_index;
15085   int sw_if_index_set;
15086   u32 ip4_table_index = ~0;
15087   u32 ip6_table_index = ~0;
15088   u32 l2_table_index = ~0;
15089   u8 is_add = 1;
15090   int ret;
15091
15092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15093     {
15094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15095         sw_if_index_set = 1;
15096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15097         sw_if_index_set = 1;
15098       else if (unformat (i, "del"))
15099         is_add = 0;
15100       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15101         ;
15102       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15103         ;
15104       else if (unformat (i, "l2-table %d", &l2_table_index))
15105         ;
15106       else
15107         {
15108           clib_warning ("parse error '%U'", format_unformat_error, i);
15109           return -99;
15110         }
15111     }
15112
15113   if (sw_if_index_set == 0)
15114     {
15115       errmsg ("missing interface name or sw_if_index");
15116       return -99;
15117     }
15118
15119   M (INPUT_ACL_SET_INTERFACE, mp);
15120
15121   mp->sw_if_index = ntohl (sw_if_index);
15122   mp->ip4_table_index = ntohl (ip4_table_index);
15123   mp->ip6_table_index = ntohl (ip6_table_index);
15124   mp->l2_table_index = ntohl (l2_table_index);
15125   mp->is_add = is_add;
15126
15127   S (mp);
15128   W (ret);
15129   return ret;
15130 }
15131
15132 static int
15133 api_output_acl_set_interface (vat_main_t * vam)
15134 {
15135   unformat_input_t *i = vam->input;
15136   vl_api_output_acl_set_interface_t *mp;
15137   u32 sw_if_index;
15138   int sw_if_index_set;
15139   u32 ip4_table_index = ~0;
15140   u32 ip6_table_index = ~0;
15141   u32 l2_table_index = ~0;
15142   u8 is_add = 1;
15143   int ret;
15144
15145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15146     {
15147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15148         sw_if_index_set = 1;
15149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15150         sw_if_index_set = 1;
15151       else if (unformat (i, "del"))
15152         is_add = 0;
15153       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15154         ;
15155       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15156         ;
15157       else if (unformat (i, "l2-table %d", &l2_table_index))
15158         ;
15159       else
15160         {
15161           clib_warning ("parse error '%U'", format_unformat_error, i);
15162           return -99;
15163         }
15164     }
15165
15166   if (sw_if_index_set == 0)
15167     {
15168       errmsg ("missing interface name or sw_if_index");
15169       return -99;
15170     }
15171
15172   M (OUTPUT_ACL_SET_INTERFACE, mp);
15173
15174   mp->sw_if_index = ntohl (sw_if_index);
15175   mp->ip4_table_index = ntohl (ip4_table_index);
15176   mp->ip6_table_index = ntohl (ip6_table_index);
15177   mp->l2_table_index = ntohl (l2_table_index);
15178   mp->is_add = is_add;
15179
15180   S (mp);
15181   W (ret);
15182   return ret;
15183 }
15184
15185 static int
15186 api_ip_address_dump (vat_main_t * vam)
15187 {
15188   unformat_input_t *i = vam->input;
15189   vl_api_ip_address_dump_t *mp;
15190   vl_api_control_ping_t *mp_ping;
15191   u32 sw_if_index = ~0;
15192   u8 sw_if_index_set = 0;
15193   u8 ipv4_set = 0;
15194   u8 ipv6_set = 0;
15195   int ret;
15196
15197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15198     {
15199       if (unformat (i, "sw_if_index %d", &sw_if_index))
15200         sw_if_index_set = 1;
15201       else
15202         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15203         sw_if_index_set = 1;
15204       else if (unformat (i, "ipv4"))
15205         ipv4_set = 1;
15206       else if (unformat (i, "ipv6"))
15207         ipv6_set = 1;
15208       else
15209         break;
15210     }
15211
15212   if (ipv4_set && ipv6_set)
15213     {
15214       errmsg ("ipv4 and ipv6 flags cannot be both set");
15215       return -99;
15216     }
15217
15218   if ((!ipv4_set) && (!ipv6_set))
15219     {
15220       errmsg ("no ipv4 nor ipv6 flag set");
15221       return -99;
15222     }
15223
15224   if (sw_if_index_set == 0)
15225     {
15226       errmsg ("missing interface name or sw_if_index");
15227       return -99;
15228     }
15229
15230   vam->current_sw_if_index = sw_if_index;
15231   vam->is_ipv6 = ipv6_set;
15232
15233   M (IP_ADDRESS_DUMP, mp);
15234   mp->sw_if_index = ntohl (sw_if_index);
15235   mp->is_ipv6 = ipv6_set;
15236   S (mp);
15237
15238   /* Use a control ping for synchronization */
15239   MPING (CONTROL_PING, mp_ping);
15240   S (mp_ping);
15241
15242   W (ret);
15243   return ret;
15244 }
15245
15246 static int
15247 api_ip_dump (vat_main_t * vam)
15248 {
15249   vl_api_ip_dump_t *mp;
15250   vl_api_control_ping_t *mp_ping;
15251   unformat_input_t *in = vam->input;
15252   int ipv4_set = 0;
15253   int ipv6_set = 0;
15254   int is_ipv6;
15255   int i;
15256   int ret;
15257
15258   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15259     {
15260       if (unformat (in, "ipv4"))
15261         ipv4_set = 1;
15262       else if (unformat (in, "ipv6"))
15263         ipv6_set = 1;
15264       else
15265         break;
15266     }
15267
15268   if (ipv4_set && ipv6_set)
15269     {
15270       errmsg ("ipv4 and ipv6 flags cannot be both set");
15271       return -99;
15272     }
15273
15274   if ((!ipv4_set) && (!ipv6_set))
15275     {
15276       errmsg ("no ipv4 nor ipv6 flag set");
15277       return -99;
15278     }
15279
15280   is_ipv6 = ipv6_set;
15281   vam->is_ipv6 = is_ipv6;
15282
15283   /* free old data */
15284   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15285     {
15286       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15287     }
15288   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15289
15290   M (IP_DUMP, mp);
15291   mp->is_ipv6 = ipv6_set;
15292   S (mp);
15293
15294   /* Use a control ping for synchronization */
15295   MPING (CONTROL_PING, mp_ping);
15296   S (mp_ping);
15297
15298   W (ret);
15299   return ret;
15300 }
15301
15302 static int
15303 api_ipsec_spd_add_del (vat_main_t * vam)
15304 {
15305   unformat_input_t *i = vam->input;
15306   vl_api_ipsec_spd_add_del_t *mp;
15307   u32 spd_id = ~0;
15308   u8 is_add = 1;
15309   int ret;
15310
15311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15312     {
15313       if (unformat (i, "spd_id %d", &spd_id))
15314         ;
15315       else if (unformat (i, "del"))
15316         is_add = 0;
15317       else
15318         {
15319           clib_warning ("parse error '%U'", format_unformat_error, i);
15320           return -99;
15321         }
15322     }
15323   if (spd_id == ~0)
15324     {
15325       errmsg ("spd_id must be set");
15326       return -99;
15327     }
15328
15329   M (IPSEC_SPD_ADD_DEL, mp);
15330
15331   mp->spd_id = ntohl (spd_id);
15332   mp->is_add = is_add;
15333
15334   S (mp);
15335   W (ret);
15336   return ret;
15337 }
15338
15339 static int
15340 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15341 {
15342   unformat_input_t *i = vam->input;
15343   vl_api_ipsec_interface_add_del_spd_t *mp;
15344   u32 sw_if_index;
15345   u8 sw_if_index_set = 0;
15346   u32 spd_id = (u32) ~ 0;
15347   u8 is_add = 1;
15348   int ret;
15349
15350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (i, "del"))
15353         is_add = 0;
15354       else if (unformat (i, "spd_id %d", &spd_id))
15355         ;
15356       else
15357         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15358         sw_if_index_set = 1;
15359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15360         sw_if_index_set = 1;
15361       else
15362         {
15363           clib_warning ("parse error '%U'", format_unformat_error, i);
15364           return -99;
15365         }
15366
15367     }
15368
15369   if (spd_id == (u32) ~ 0)
15370     {
15371       errmsg ("spd_id must be set");
15372       return -99;
15373     }
15374
15375   if (sw_if_index_set == 0)
15376     {
15377       errmsg ("missing interface name or sw_if_index");
15378       return -99;
15379     }
15380
15381   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15382
15383   mp->spd_id = ntohl (spd_id);
15384   mp->sw_if_index = ntohl (sw_if_index);
15385   mp->is_add = is_add;
15386
15387   S (mp);
15388   W (ret);
15389   return ret;
15390 }
15391
15392 static int
15393 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15394 {
15395   unformat_input_t *i = vam->input;
15396   vl_api_ipsec_spd_add_del_entry_t *mp;
15397   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15398   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15399   i32 priority = 0;
15400   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15401   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15402   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15403   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15404   int ret;
15405
15406   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15407   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15408   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15409   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15410   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15411   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15412
15413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15414     {
15415       if (unformat (i, "del"))
15416         is_add = 0;
15417       if (unformat (i, "outbound"))
15418         is_outbound = 1;
15419       if (unformat (i, "inbound"))
15420         is_outbound = 0;
15421       else if (unformat (i, "spd_id %d", &spd_id))
15422         ;
15423       else if (unformat (i, "sa_id %d", &sa_id))
15424         ;
15425       else if (unformat (i, "priority %d", &priority))
15426         ;
15427       else if (unformat (i, "protocol %d", &protocol))
15428         ;
15429       else if (unformat (i, "lport_start %d", &lport_start))
15430         ;
15431       else if (unformat (i, "lport_stop %d", &lport_stop))
15432         ;
15433       else if (unformat (i, "rport_start %d", &rport_start))
15434         ;
15435       else if (unformat (i, "rport_stop %d", &rport_stop))
15436         ;
15437       else
15438         if (unformat
15439             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15440         {
15441           is_ipv6 = 0;
15442           is_ip_any = 0;
15443         }
15444       else
15445         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15446         {
15447           is_ipv6 = 0;
15448           is_ip_any = 0;
15449         }
15450       else
15451         if (unformat
15452             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15453         {
15454           is_ipv6 = 0;
15455           is_ip_any = 0;
15456         }
15457       else
15458         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15459         {
15460           is_ipv6 = 0;
15461           is_ip_any = 0;
15462         }
15463       else
15464         if (unformat
15465             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15466         {
15467           is_ipv6 = 1;
15468           is_ip_any = 0;
15469         }
15470       else
15471         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15472         {
15473           is_ipv6 = 1;
15474           is_ip_any = 0;
15475         }
15476       else
15477         if (unformat
15478             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15479         {
15480           is_ipv6 = 1;
15481           is_ip_any = 0;
15482         }
15483       else
15484         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15485         {
15486           is_ipv6 = 1;
15487           is_ip_any = 0;
15488         }
15489       else
15490         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15491         {
15492           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15493             {
15494               clib_warning ("unsupported action: 'resolve'");
15495               return -99;
15496             }
15497         }
15498       else
15499         {
15500           clib_warning ("parse error '%U'", format_unformat_error, i);
15501           return -99;
15502         }
15503
15504     }
15505
15506   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15507
15508   mp->spd_id = ntohl (spd_id);
15509   mp->priority = ntohl (priority);
15510   mp->is_outbound = is_outbound;
15511
15512   mp->is_ipv6 = is_ipv6;
15513   if (is_ipv6 || is_ip_any)
15514     {
15515       clib_memcpy (mp->remote_address_start, &raddr6_start,
15516                    sizeof (ip6_address_t));
15517       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15518                    sizeof (ip6_address_t));
15519       clib_memcpy (mp->local_address_start, &laddr6_start,
15520                    sizeof (ip6_address_t));
15521       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15522                    sizeof (ip6_address_t));
15523     }
15524   else
15525     {
15526       clib_memcpy (mp->remote_address_start, &raddr4_start,
15527                    sizeof (ip4_address_t));
15528       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15529                    sizeof (ip4_address_t));
15530       clib_memcpy (mp->local_address_start, &laddr4_start,
15531                    sizeof (ip4_address_t));
15532       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15533                    sizeof (ip4_address_t));
15534     }
15535   mp->protocol = (u8) protocol;
15536   mp->local_port_start = ntohs ((u16) lport_start);
15537   mp->local_port_stop = ntohs ((u16) lport_stop);
15538   mp->remote_port_start = ntohs ((u16) rport_start);
15539   mp->remote_port_stop = ntohs ((u16) rport_stop);
15540   mp->policy = (u8) policy;
15541   mp->sa_id = ntohl (sa_id);
15542   mp->is_add = is_add;
15543   mp->is_ip_any = is_ip_any;
15544   S (mp);
15545   W (ret);
15546   return ret;
15547 }
15548
15549 static int
15550 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15551 {
15552   unformat_input_t *i = vam->input;
15553   vl_api_ipsec_sad_add_del_entry_t *mp;
15554   u32 sad_id = 0, spi = 0;
15555   u8 *ck = 0, *ik = 0;
15556   u8 is_add = 1;
15557
15558   u8 protocol = IPSEC_PROTOCOL_AH;
15559   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15560   u32 crypto_alg = 0, integ_alg = 0;
15561   ip4_address_t tun_src4;
15562   ip4_address_t tun_dst4;
15563   ip6_address_t tun_src6;
15564   ip6_address_t tun_dst6;
15565   int ret;
15566
15567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15568     {
15569       if (unformat (i, "del"))
15570         is_add = 0;
15571       else if (unformat (i, "sad_id %d", &sad_id))
15572         ;
15573       else if (unformat (i, "spi %d", &spi))
15574         ;
15575       else if (unformat (i, "esp"))
15576         protocol = IPSEC_PROTOCOL_ESP;
15577       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15578         {
15579           is_tunnel = 1;
15580           is_tunnel_ipv6 = 0;
15581         }
15582       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15583         {
15584           is_tunnel = 1;
15585           is_tunnel_ipv6 = 0;
15586         }
15587       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15588         {
15589           is_tunnel = 1;
15590           is_tunnel_ipv6 = 1;
15591         }
15592       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15593         {
15594           is_tunnel = 1;
15595           is_tunnel_ipv6 = 1;
15596         }
15597       else
15598         if (unformat
15599             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15600         {
15601           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15602             {
15603               clib_warning ("unsupported crypto-alg: '%U'",
15604                             format_ipsec_crypto_alg, crypto_alg);
15605               return -99;
15606             }
15607         }
15608       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15609         ;
15610       else
15611         if (unformat
15612             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15613         {
15614           if (integ_alg >= IPSEC_INTEG_N_ALG)
15615             {
15616               clib_warning ("unsupported integ-alg: '%U'",
15617                             format_ipsec_integ_alg, integ_alg);
15618               return -99;
15619             }
15620         }
15621       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15622         ;
15623       else
15624         {
15625           clib_warning ("parse error '%U'", format_unformat_error, i);
15626           return -99;
15627         }
15628
15629     }
15630
15631   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15632
15633   mp->sad_id = ntohl (sad_id);
15634   mp->is_add = is_add;
15635   mp->protocol = protocol;
15636   mp->spi = ntohl (spi);
15637   mp->is_tunnel = is_tunnel;
15638   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15639   mp->crypto_algorithm = crypto_alg;
15640   mp->integrity_algorithm = integ_alg;
15641   mp->crypto_key_length = vec_len (ck);
15642   mp->integrity_key_length = vec_len (ik);
15643
15644   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15645     mp->crypto_key_length = sizeof (mp->crypto_key);
15646
15647   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15648     mp->integrity_key_length = sizeof (mp->integrity_key);
15649
15650   if (ck)
15651     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15652   if (ik)
15653     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15654
15655   if (is_tunnel)
15656     {
15657       if (is_tunnel_ipv6)
15658         {
15659           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15660                        sizeof (ip6_address_t));
15661           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15662                        sizeof (ip6_address_t));
15663         }
15664       else
15665         {
15666           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15667                        sizeof (ip4_address_t));
15668           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15669                        sizeof (ip4_address_t));
15670         }
15671     }
15672
15673   S (mp);
15674   W (ret);
15675   return ret;
15676 }
15677
15678 static int
15679 api_ipsec_sa_set_key (vat_main_t * vam)
15680 {
15681   unformat_input_t *i = vam->input;
15682   vl_api_ipsec_sa_set_key_t *mp;
15683   u32 sa_id;
15684   u8 *ck = 0, *ik = 0;
15685   int ret;
15686
15687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15688     {
15689       if (unformat (i, "sa_id %d", &sa_id))
15690         ;
15691       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15692         ;
15693       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15694         ;
15695       else
15696         {
15697           clib_warning ("parse error '%U'", format_unformat_error, i);
15698           return -99;
15699         }
15700     }
15701
15702   M (IPSEC_SA_SET_KEY, mp);
15703
15704   mp->sa_id = ntohl (sa_id);
15705   mp->crypto_key_length = vec_len (ck);
15706   mp->integrity_key_length = vec_len (ik);
15707
15708   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15709     mp->crypto_key_length = sizeof (mp->crypto_key);
15710
15711   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15712     mp->integrity_key_length = sizeof (mp->integrity_key);
15713
15714   if (ck)
15715     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15716   if (ik)
15717     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15718
15719   S (mp);
15720   W (ret);
15721   return ret;
15722 }
15723
15724 static int
15725 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15726 {
15727   unformat_input_t *i = vam->input;
15728   vl_api_ipsec_tunnel_if_add_del_t *mp;
15729   u32 local_spi = 0, remote_spi = 0;
15730   u32 crypto_alg = 0, integ_alg = 0;
15731   u8 *lck = NULL, *rck = NULL;
15732   u8 *lik = NULL, *rik = NULL;
15733   ip4_address_t local_ip = { {0} };
15734   ip4_address_t remote_ip = { {0} };
15735   u8 is_add = 1;
15736   u8 esn = 0;
15737   u8 anti_replay = 0;
15738   u8 renumber = 0;
15739   u32 instance = ~0;
15740   int ret;
15741
15742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15743     {
15744       if (unformat (i, "del"))
15745         is_add = 0;
15746       else if (unformat (i, "esn"))
15747         esn = 1;
15748       else if (unformat (i, "anti_replay"))
15749         anti_replay = 1;
15750       else if (unformat (i, "local_spi %d", &local_spi))
15751         ;
15752       else if (unformat (i, "remote_spi %d", &remote_spi))
15753         ;
15754       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15755         ;
15756       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15757         ;
15758       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15759         ;
15760       else
15761         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15762         ;
15763       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15764         ;
15765       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15766         ;
15767       else
15768         if (unformat
15769             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15770         {
15771           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15772             {
15773               errmsg ("unsupported crypto-alg: '%U'\n",
15774                       format_ipsec_crypto_alg, crypto_alg);
15775               return -99;
15776             }
15777         }
15778       else
15779         if (unformat
15780             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15781         {
15782           if (integ_alg >= IPSEC_INTEG_N_ALG)
15783             {
15784               errmsg ("unsupported integ-alg: '%U'\n",
15785                       format_ipsec_integ_alg, integ_alg);
15786               return -99;
15787             }
15788         }
15789       else if (unformat (i, "instance %u", &instance))
15790         renumber = 1;
15791       else
15792         {
15793           errmsg ("parse error '%U'\n", format_unformat_error, i);
15794           return -99;
15795         }
15796     }
15797
15798   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15799
15800   mp->is_add = is_add;
15801   mp->esn = esn;
15802   mp->anti_replay = anti_replay;
15803
15804   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15805   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15806
15807   mp->local_spi = htonl (local_spi);
15808   mp->remote_spi = htonl (remote_spi);
15809   mp->crypto_alg = (u8) crypto_alg;
15810
15811   mp->local_crypto_key_len = 0;
15812   if (lck)
15813     {
15814       mp->local_crypto_key_len = vec_len (lck);
15815       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15816         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15817       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15818     }
15819
15820   mp->remote_crypto_key_len = 0;
15821   if (rck)
15822     {
15823       mp->remote_crypto_key_len = vec_len (rck);
15824       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15825         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15826       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15827     }
15828
15829   mp->integ_alg = (u8) integ_alg;
15830
15831   mp->local_integ_key_len = 0;
15832   if (lik)
15833     {
15834       mp->local_integ_key_len = vec_len (lik);
15835       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15836         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15837       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15838     }
15839
15840   mp->remote_integ_key_len = 0;
15841   if (rik)
15842     {
15843       mp->remote_integ_key_len = vec_len (rik);
15844       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15845         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15846       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15847     }
15848
15849   if (renumber)
15850     {
15851       mp->renumber = renumber;
15852       mp->show_instance = ntohl (instance);
15853     }
15854
15855   S (mp);
15856   W (ret);
15857   return ret;
15858 }
15859
15860 static void
15861 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15862 {
15863   vat_main_t *vam = &vat_main;
15864
15865   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15866          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15867          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15868          "tunnel_src_addr %U tunnel_dst_addr %U "
15869          "salt %u seq_outbound %lu last_seq_inbound %lu "
15870          "replay_window %lu total_data_size %lu\n",
15871          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15872          mp->protocol,
15873          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15874          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15875          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15876          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15877          mp->tunnel_src_addr,
15878          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15879          mp->tunnel_dst_addr,
15880          ntohl (mp->salt),
15881          clib_net_to_host_u64 (mp->seq_outbound),
15882          clib_net_to_host_u64 (mp->last_seq_inbound),
15883          clib_net_to_host_u64 (mp->replay_window),
15884          clib_net_to_host_u64 (mp->total_data_size));
15885 }
15886
15887 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15888 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15889
15890 static void vl_api_ipsec_sa_details_t_handler_json
15891   (vl_api_ipsec_sa_details_t * mp)
15892 {
15893   vat_main_t *vam = &vat_main;
15894   vat_json_node_t *node = NULL;
15895   struct in_addr src_ip4, dst_ip4;
15896   struct in6_addr src_ip6, dst_ip6;
15897
15898   if (VAT_JSON_ARRAY != vam->json_tree.type)
15899     {
15900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15901       vat_json_init_array (&vam->json_tree);
15902     }
15903   node = vat_json_array_add (&vam->json_tree);
15904
15905   vat_json_init_object (node);
15906   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15907   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15908   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15909   vat_json_object_add_uint (node, "proto", mp->protocol);
15910   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15911   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15912   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15913   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15914   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15915   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15916   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15917                              mp->crypto_key_len);
15918   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15919                              mp->integ_key_len);
15920   if (mp->is_tunnel_ip6)
15921     {
15922       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15923       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15924       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15925       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15926     }
15927   else
15928     {
15929       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15930       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15931       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15932       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15933     }
15934   vat_json_object_add_uint (node, "replay_window",
15935                             clib_net_to_host_u64 (mp->replay_window));
15936   vat_json_object_add_uint (node, "total_data_size",
15937                             clib_net_to_host_u64 (mp->total_data_size));
15938
15939 }
15940
15941 static int
15942 api_ipsec_sa_dump (vat_main_t * vam)
15943 {
15944   unformat_input_t *i = vam->input;
15945   vl_api_ipsec_sa_dump_t *mp;
15946   vl_api_control_ping_t *mp_ping;
15947   u32 sa_id = ~0;
15948   int ret;
15949
15950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat (i, "sa_id %d", &sa_id))
15953         ;
15954       else
15955         {
15956           clib_warning ("parse error '%U'", format_unformat_error, i);
15957           return -99;
15958         }
15959     }
15960
15961   M (IPSEC_SA_DUMP, mp);
15962
15963   mp->sa_id = ntohl (sa_id);
15964
15965   S (mp);
15966
15967   /* Use a control ping for synchronization */
15968   M (CONTROL_PING, mp_ping);
15969   S (mp_ping);
15970
15971   W (ret);
15972   return ret;
15973 }
15974
15975 static int
15976 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15977 {
15978   unformat_input_t *i = vam->input;
15979   vl_api_ipsec_tunnel_if_set_key_t *mp;
15980   u32 sw_if_index = ~0;
15981   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15982   u8 *key = 0;
15983   u32 alg = ~0;
15984   int ret;
15985
15986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15987     {
15988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15989         ;
15990       else
15991         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15992         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15993       else
15994         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15995         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15996       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15997         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15998       else
15999         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16000         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16001       else if (unformat (i, "%U", unformat_hex_string, &key))
16002         ;
16003       else
16004         {
16005           clib_warning ("parse error '%U'", format_unformat_error, i);
16006           return -99;
16007         }
16008     }
16009
16010   if (sw_if_index == ~0)
16011     {
16012       errmsg ("interface must be specified");
16013       return -99;
16014     }
16015
16016   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16017     {
16018       errmsg ("key type must be specified");
16019       return -99;
16020     }
16021
16022   if (alg == ~0)
16023     {
16024       errmsg ("algorithm must be specified");
16025       return -99;
16026     }
16027
16028   if (vec_len (key) == 0)
16029     {
16030       errmsg ("key must be specified");
16031       return -99;
16032     }
16033
16034   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16035
16036   mp->sw_if_index = htonl (sw_if_index);
16037   mp->alg = alg;
16038   mp->key_type = key_type;
16039   mp->key_len = vec_len (key);
16040   clib_memcpy (mp->key, key, vec_len (key));
16041
16042   S (mp);
16043   W (ret);
16044
16045   return ret;
16046 }
16047
16048 static int
16049 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16050 {
16051   unformat_input_t *i = vam->input;
16052   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16053   u32 sw_if_index = ~0;
16054   u32 sa_id = ~0;
16055   u8 is_outbound = (u8) ~ 0;
16056   int ret;
16057
16058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16059     {
16060       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16061         ;
16062       else if (unformat (i, "sa_id %d", &sa_id))
16063         ;
16064       else if (unformat (i, "outbound"))
16065         is_outbound = 1;
16066       else if (unformat (i, "inbound"))
16067         is_outbound = 0;
16068       else
16069         {
16070           clib_warning ("parse error '%U'", format_unformat_error, i);
16071           return -99;
16072         }
16073     }
16074
16075   if (sw_if_index == ~0)
16076     {
16077       errmsg ("interface must be specified");
16078       return -99;
16079     }
16080
16081   if (sa_id == ~0)
16082     {
16083       errmsg ("SA ID must be specified");
16084       return -99;
16085     }
16086
16087   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16088
16089   mp->sw_if_index = htonl (sw_if_index);
16090   mp->sa_id = htonl (sa_id);
16091   mp->is_outbound = is_outbound;
16092
16093   S (mp);
16094   W (ret);
16095
16096   return ret;
16097 }
16098
16099 static int
16100 api_ikev2_profile_add_del (vat_main_t * vam)
16101 {
16102   unformat_input_t *i = vam->input;
16103   vl_api_ikev2_profile_add_del_t *mp;
16104   u8 is_add = 1;
16105   u8 *name = 0;
16106   int ret;
16107
16108   const char *valid_chars = "a-zA-Z0-9_";
16109
16110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16111     {
16112       if (unformat (i, "del"))
16113         is_add = 0;
16114       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16115         vec_add1 (name, 0);
16116       else
16117         {
16118           errmsg ("parse error '%U'", format_unformat_error, i);
16119           return -99;
16120         }
16121     }
16122
16123   if (!vec_len (name))
16124     {
16125       errmsg ("profile name must be specified");
16126       return -99;
16127     }
16128
16129   if (vec_len (name) > 64)
16130     {
16131       errmsg ("profile name too long");
16132       return -99;
16133     }
16134
16135   M (IKEV2_PROFILE_ADD_DEL, mp);
16136
16137   clib_memcpy (mp->name, name, vec_len (name));
16138   mp->is_add = is_add;
16139   vec_free (name);
16140
16141   S (mp);
16142   W (ret);
16143   return ret;
16144 }
16145
16146 static int
16147 api_ikev2_profile_set_auth (vat_main_t * vam)
16148 {
16149   unformat_input_t *i = vam->input;
16150   vl_api_ikev2_profile_set_auth_t *mp;
16151   u8 *name = 0;
16152   u8 *data = 0;
16153   u32 auth_method = 0;
16154   u8 is_hex = 0;
16155   int ret;
16156
16157   const char *valid_chars = "a-zA-Z0-9_";
16158
16159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16160     {
16161       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16162         vec_add1 (name, 0);
16163       else if (unformat (i, "auth_method %U",
16164                          unformat_ikev2_auth_method, &auth_method))
16165         ;
16166       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16167         is_hex = 1;
16168       else if (unformat (i, "auth_data %v", &data))
16169         ;
16170       else
16171         {
16172           errmsg ("parse error '%U'", format_unformat_error, i);
16173           return -99;
16174         }
16175     }
16176
16177   if (!vec_len (name))
16178     {
16179       errmsg ("profile name must be specified");
16180       return -99;
16181     }
16182
16183   if (vec_len (name) > 64)
16184     {
16185       errmsg ("profile name too long");
16186       return -99;
16187     }
16188
16189   if (!vec_len (data))
16190     {
16191       errmsg ("auth_data must be specified");
16192       return -99;
16193     }
16194
16195   if (!auth_method)
16196     {
16197       errmsg ("auth_method must be specified");
16198       return -99;
16199     }
16200
16201   M (IKEV2_PROFILE_SET_AUTH, mp);
16202
16203   mp->is_hex = is_hex;
16204   mp->auth_method = (u8) auth_method;
16205   mp->data_len = vec_len (data);
16206   clib_memcpy (mp->name, name, vec_len (name));
16207   clib_memcpy (mp->data, data, vec_len (data));
16208   vec_free (name);
16209   vec_free (data);
16210
16211   S (mp);
16212   W (ret);
16213   return ret;
16214 }
16215
16216 static int
16217 api_ikev2_profile_set_id (vat_main_t * vam)
16218 {
16219   unformat_input_t *i = vam->input;
16220   vl_api_ikev2_profile_set_id_t *mp;
16221   u8 *name = 0;
16222   u8 *data = 0;
16223   u8 is_local = 0;
16224   u32 id_type = 0;
16225   ip4_address_t ip4;
16226   int ret;
16227
16228   const char *valid_chars = "a-zA-Z0-9_";
16229
16230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16231     {
16232       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16233         vec_add1 (name, 0);
16234       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16235         ;
16236       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16237         {
16238           data = vec_new (u8, 4);
16239           clib_memcpy (data, ip4.as_u8, 4);
16240         }
16241       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16242         ;
16243       else if (unformat (i, "id_data %v", &data))
16244         ;
16245       else if (unformat (i, "local"))
16246         is_local = 1;
16247       else if (unformat (i, "remote"))
16248         is_local = 0;
16249       else
16250         {
16251           errmsg ("parse error '%U'", format_unformat_error, i);
16252           return -99;
16253         }
16254     }
16255
16256   if (!vec_len (name))
16257     {
16258       errmsg ("profile name must be specified");
16259       return -99;
16260     }
16261
16262   if (vec_len (name) > 64)
16263     {
16264       errmsg ("profile name too long");
16265       return -99;
16266     }
16267
16268   if (!vec_len (data))
16269     {
16270       errmsg ("id_data must be specified");
16271       return -99;
16272     }
16273
16274   if (!id_type)
16275     {
16276       errmsg ("id_type must be specified");
16277       return -99;
16278     }
16279
16280   M (IKEV2_PROFILE_SET_ID, mp);
16281
16282   mp->is_local = is_local;
16283   mp->id_type = (u8) id_type;
16284   mp->data_len = vec_len (data);
16285   clib_memcpy (mp->name, name, vec_len (name));
16286   clib_memcpy (mp->data, data, vec_len (data));
16287   vec_free (name);
16288   vec_free (data);
16289
16290   S (mp);
16291   W (ret);
16292   return ret;
16293 }
16294
16295 static int
16296 api_ikev2_profile_set_ts (vat_main_t * vam)
16297 {
16298   unformat_input_t *i = vam->input;
16299   vl_api_ikev2_profile_set_ts_t *mp;
16300   u8 *name = 0;
16301   u8 is_local = 0;
16302   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16303   ip4_address_t start_addr, end_addr;
16304
16305   const char *valid_chars = "a-zA-Z0-9_";
16306   int ret;
16307
16308   start_addr.as_u32 = 0;
16309   end_addr.as_u32 = (u32) ~ 0;
16310
16311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16312     {
16313       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16314         vec_add1 (name, 0);
16315       else if (unformat (i, "protocol %d", &proto))
16316         ;
16317       else if (unformat (i, "start_port %d", &start_port))
16318         ;
16319       else if (unformat (i, "end_port %d", &end_port))
16320         ;
16321       else
16322         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16323         ;
16324       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16325         ;
16326       else if (unformat (i, "local"))
16327         is_local = 1;
16328       else if (unformat (i, "remote"))
16329         is_local = 0;
16330       else
16331         {
16332           errmsg ("parse error '%U'", format_unformat_error, i);
16333           return -99;
16334         }
16335     }
16336
16337   if (!vec_len (name))
16338     {
16339       errmsg ("profile name must be specified");
16340       return -99;
16341     }
16342
16343   if (vec_len (name) > 64)
16344     {
16345       errmsg ("profile name too long");
16346       return -99;
16347     }
16348
16349   M (IKEV2_PROFILE_SET_TS, mp);
16350
16351   mp->is_local = is_local;
16352   mp->proto = (u8) proto;
16353   mp->start_port = (u16) start_port;
16354   mp->end_port = (u16) end_port;
16355   mp->start_addr = start_addr.as_u32;
16356   mp->end_addr = end_addr.as_u32;
16357   clib_memcpy (mp->name, name, vec_len (name));
16358   vec_free (name);
16359
16360   S (mp);
16361   W (ret);
16362   return ret;
16363 }
16364
16365 static int
16366 api_ikev2_set_local_key (vat_main_t * vam)
16367 {
16368   unformat_input_t *i = vam->input;
16369   vl_api_ikev2_set_local_key_t *mp;
16370   u8 *file = 0;
16371   int ret;
16372
16373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16374     {
16375       if (unformat (i, "file %v", &file))
16376         vec_add1 (file, 0);
16377       else
16378         {
16379           errmsg ("parse error '%U'", format_unformat_error, i);
16380           return -99;
16381         }
16382     }
16383
16384   if (!vec_len (file))
16385     {
16386       errmsg ("RSA key file must be specified");
16387       return -99;
16388     }
16389
16390   if (vec_len (file) > 256)
16391     {
16392       errmsg ("file name too long");
16393       return -99;
16394     }
16395
16396   M (IKEV2_SET_LOCAL_KEY, mp);
16397
16398   clib_memcpy (mp->key_file, file, vec_len (file));
16399   vec_free (file);
16400
16401   S (mp);
16402   W (ret);
16403   return ret;
16404 }
16405
16406 static int
16407 api_ikev2_set_responder (vat_main_t * vam)
16408 {
16409   unformat_input_t *i = vam->input;
16410   vl_api_ikev2_set_responder_t *mp;
16411   int ret;
16412   u8 *name = 0;
16413   u32 sw_if_index = ~0;
16414   ip4_address_t address;
16415
16416   const char *valid_chars = "a-zA-Z0-9_";
16417
16418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16419     {
16420       if (unformat
16421           (i, "%U interface %d address %U", unformat_token, valid_chars,
16422            &name, &sw_if_index, unformat_ip4_address, &address))
16423         vec_add1 (name, 0);
16424       else
16425         {
16426           errmsg ("parse error '%U'", format_unformat_error, i);
16427           return -99;
16428         }
16429     }
16430
16431   if (!vec_len (name))
16432     {
16433       errmsg ("profile name must be specified");
16434       return -99;
16435     }
16436
16437   if (vec_len (name) > 64)
16438     {
16439       errmsg ("profile name too long");
16440       return -99;
16441     }
16442
16443   M (IKEV2_SET_RESPONDER, mp);
16444
16445   clib_memcpy (mp->name, name, vec_len (name));
16446   vec_free (name);
16447
16448   mp->sw_if_index = sw_if_index;
16449   clib_memcpy (mp->address, &address, sizeof (address));
16450
16451   S (mp);
16452   W (ret);
16453   return ret;
16454 }
16455
16456 static int
16457 api_ikev2_set_ike_transforms (vat_main_t * vam)
16458 {
16459   unformat_input_t *i = vam->input;
16460   vl_api_ikev2_set_ike_transforms_t *mp;
16461   int ret;
16462   u8 *name = 0;
16463   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16464
16465   const char *valid_chars = "a-zA-Z0-9_";
16466
16467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16468     {
16469       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16470                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16471         vec_add1 (name, 0);
16472       else
16473         {
16474           errmsg ("parse error '%U'", format_unformat_error, i);
16475           return -99;
16476         }
16477     }
16478
16479   if (!vec_len (name))
16480     {
16481       errmsg ("profile name must be specified");
16482       return -99;
16483     }
16484
16485   if (vec_len (name) > 64)
16486     {
16487       errmsg ("profile name too long");
16488       return -99;
16489     }
16490
16491   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16492
16493   clib_memcpy (mp->name, name, vec_len (name));
16494   vec_free (name);
16495   mp->crypto_alg = crypto_alg;
16496   mp->crypto_key_size = crypto_key_size;
16497   mp->integ_alg = integ_alg;
16498   mp->dh_group = dh_group;
16499
16500   S (mp);
16501   W (ret);
16502   return ret;
16503 }
16504
16505
16506 static int
16507 api_ikev2_set_esp_transforms (vat_main_t * vam)
16508 {
16509   unformat_input_t *i = vam->input;
16510   vl_api_ikev2_set_esp_transforms_t *mp;
16511   int ret;
16512   u8 *name = 0;
16513   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16514
16515   const char *valid_chars = "a-zA-Z0-9_";
16516
16517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16518     {
16519       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16520                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16521         vec_add1 (name, 0);
16522       else
16523         {
16524           errmsg ("parse error '%U'", format_unformat_error, i);
16525           return -99;
16526         }
16527     }
16528
16529   if (!vec_len (name))
16530     {
16531       errmsg ("profile name must be specified");
16532       return -99;
16533     }
16534
16535   if (vec_len (name) > 64)
16536     {
16537       errmsg ("profile name too long");
16538       return -99;
16539     }
16540
16541   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16542
16543   clib_memcpy (mp->name, name, vec_len (name));
16544   vec_free (name);
16545   mp->crypto_alg = crypto_alg;
16546   mp->crypto_key_size = crypto_key_size;
16547   mp->integ_alg = integ_alg;
16548   mp->dh_group = dh_group;
16549
16550   S (mp);
16551   W (ret);
16552   return ret;
16553 }
16554
16555 static int
16556 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16557 {
16558   unformat_input_t *i = vam->input;
16559   vl_api_ikev2_set_sa_lifetime_t *mp;
16560   int ret;
16561   u8 *name = 0;
16562   u64 lifetime, lifetime_maxdata;
16563   u32 lifetime_jitter, handover;
16564
16565   const char *valid_chars = "a-zA-Z0-9_";
16566
16567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16568     {
16569       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16570                     &lifetime, &lifetime_jitter, &handover,
16571                     &lifetime_maxdata))
16572         vec_add1 (name, 0);
16573       else
16574         {
16575           errmsg ("parse error '%U'", format_unformat_error, i);
16576           return -99;
16577         }
16578     }
16579
16580   if (!vec_len (name))
16581     {
16582       errmsg ("profile name must be specified");
16583       return -99;
16584     }
16585
16586   if (vec_len (name) > 64)
16587     {
16588       errmsg ("profile name too long");
16589       return -99;
16590     }
16591
16592   M (IKEV2_SET_SA_LIFETIME, mp);
16593
16594   clib_memcpy (mp->name, name, vec_len (name));
16595   vec_free (name);
16596   mp->lifetime = lifetime;
16597   mp->lifetime_jitter = lifetime_jitter;
16598   mp->handover = handover;
16599   mp->lifetime_maxdata = lifetime_maxdata;
16600
16601   S (mp);
16602   W (ret);
16603   return ret;
16604 }
16605
16606 static int
16607 api_ikev2_initiate_sa_init (vat_main_t * vam)
16608 {
16609   unformat_input_t *i = vam->input;
16610   vl_api_ikev2_initiate_sa_init_t *mp;
16611   int ret;
16612   u8 *name = 0;
16613
16614   const char *valid_chars = "a-zA-Z0-9_";
16615
16616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16617     {
16618       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16619         vec_add1 (name, 0);
16620       else
16621         {
16622           errmsg ("parse error '%U'", format_unformat_error, i);
16623           return -99;
16624         }
16625     }
16626
16627   if (!vec_len (name))
16628     {
16629       errmsg ("profile name must be specified");
16630       return -99;
16631     }
16632
16633   if (vec_len (name) > 64)
16634     {
16635       errmsg ("profile name too long");
16636       return -99;
16637     }
16638
16639   M (IKEV2_INITIATE_SA_INIT, mp);
16640
16641   clib_memcpy (mp->name, name, vec_len (name));
16642   vec_free (name);
16643
16644   S (mp);
16645   W (ret);
16646   return ret;
16647 }
16648
16649 static int
16650 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16651 {
16652   unformat_input_t *i = vam->input;
16653   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16654   int ret;
16655   u64 ispi;
16656
16657
16658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16659     {
16660       if (unformat (i, "%lx", &ispi))
16661         ;
16662       else
16663         {
16664           errmsg ("parse error '%U'", format_unformat_error, i);
16665           return -99;
16666         }
16667     }
16668
16669   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16670
16671   mp->ispi = ispi;
16672
16673   S (mp);
16674   W (ret);
16675   return ret;
16676 }
16677
16678 static int
16679 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16680 {
16681   unformat_input_t *i = vam->input;
16682   vl_api_ikev2_initiate_del_child_sa_t *mp;
16683   int ret;
16684   u32 ispi;
16685
16686
16687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16688     {
16689       if (unformat (i, "%x", &ispi))
16690         ;
16691       else
16692         {
16693           errmsg ("parse error '%U'", format_unformat_error, i);
16694           return -99;
16695         }
16696     }
16697
16698   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16699
16700   mp->ispi = ispi;
16701
16702   S (mp);
16703   W (ret);
16704   return ret;
16705 }
16706
16707 static int
16708 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16709 {
16710   unformat_input_t *i = vam->input;
16711   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16712   int ret;
16713   u32 ispi;
16714
16715
16716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16717     {
16718       if (unformat (i, "%x", &ispi))
16719         ;
16720       else
16721         {
16722           errmsg ("parse error '%U'", format_unformat_error, i);
16723           return -99;
16724         }
16725     }
16726
16727   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16728
16729   mp->ispi = ispi;
16730
16731   S (mp);
16732   W (ret);
16733   return ret;
16734 }
16735
16736 static int
16737 api_get_first_msg_id (vat_main_t * vam)
16738 {
16739   vl_api_get_first_msg_id_t *mp;
16740   unformat_input_t *i = vam->input;
16741   u8 *name;
16742   u8 name_set = 0;
16743   int ret;
16744
16745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16746     {
16747       if (unformat (i, "client %s", &name))
16748         name_set = 1;
16749       else
16750         break;
16751     }
16752
16753   if (name_set == 0)
16754     {
16755       errmsg ("missing client name");
16756       return -99;
16757     }
16758   vec_add1 (name, 0);
16759
16760   if (vec_len (name) > 63)
16761     {
16762       errmsg ("client name too long");
16763       return -99;
16764     }
16765
16766   M (GET_FIRST_MSG_ID, mp);
16767   clib_memcpy (mp->name, name, vec_len (name));
16768   S (mp);
16769   W (ret);
16770   return ret;
16771 }
16772
16773 static int
16774 api_cop_interface_enable_disable (vat_main_t * vam)
16775 {
16776   unformat_input_t *line_input = vam->input;
16777   vl_api_cop_interface_enable_disable_t *mp;
16778   u32 sw_if_index = ~0;
16779   u8 enable_disable = 1;
16780   int ret;
16781
16782   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16783     {
16784       if (unformat (line_input, "disable"))
16785         enable_disable = 0;
16786       if (unformat (line_input, "enable"))
16787         enable_disable = 1;
16788       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16789                          vam, &sw_if_index))
16790         ;
16791       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16792         ;
16793       else
16794         break;
16795     }
16796
16797   if (sw_if_index == ~0)
16798     {
16799       errmsg ("missing interface name or sw_if_index");
16800       return -99;
16801     }
16802
16803   /* Construct the API message */
16804   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16805   mp->sw_if_index = ntohl (sw_if_index);
16806   mp->enable_disable = enable_disable;
16807
16808   /* send it... */
16809   S (mp);
16810   /* Wait for the reply */
16811   W (ret);
16812   return ret;
16813 }
16814
16815 static int
16816 api_cop_whitelist_enable_disable (vat_main_t * vam)
16817 {
16818   unformat_input_t *line_input = vam->input;
16819   vl_api_cop_whitelist_enable_disable_t *mp;
16820   u32 sw_if_index = ~0;
16821   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16822   u32 fib_id = 0;
16823   int ret;
16824
16825   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16826     {
16827       if (unformat (line_input, "ip4"))
16828         ip4 = 1;
16829       else if (unformat (line_input, "ip6"))
16830         ip6 = 1;
16831       else if (unformat (line_input, "default"))
16832         default_cop = 1;
16833       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16834                          vam, &sw_if_index))
16835         ;
16836       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16837         ;
16838       else if (unformat (line_input, "fib-id %d", &fib_id))
16839         ;
16840       else
16841         break;
16842     }
16843
16844   if (sw_if_index == ~0)
16845     {
16846       errmsg ("missing interface name or sw_if_index");
16847       return -99;
16848     }
16849
16850   /* Construct the API message */
16851   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16852   mp->sw_if_index = ntohl (sw_if_index);
16853   mp->fib_id = ntohl (fib_id);
16854   mp->ip4 = ip4;
16855   mp->ip6 = ip6;
16856   mp->default_cop = default_cop;
16857
16858   /* send it... */
16859   S (mp);
16860   /* Wait for the reply */
16861   W (ret);
16862   return ret;
16863 }
16864
16865 static int
16866 api_get_node_graph (vat_main_t * vam)
16867 {
16868   vl_api_get_node_graph_t *mp;
16869   int ret;
16870
16871   M (GET_NODE_GRAPH, mp);
16872
16873   /* send it... */
16874   S (mp);
16875   /* Wait for the reply */
16876   W (ret);
16877   return ret;
16878 }
16879
16880 /* *INDENT-OFF* */
16881 /** Used for parsing LISP eids */
16882 typedef CLIB_PACKED(struct{
16883   u8 addr[16];   /**< eid address */
16884   u32 len;       /**< prefix length if IP */
16885   u8 type;      /**< type of eid */
16886 }) lisp_eid_vat_t;
16887 /* *INDENT-ON* */
16888
16889 static uword
16890 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16891 {
16892   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16893
16894   memset (a, 0, sizeof (a[0]));
16895
16896   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16897     {
16898       a->type = 0;              /* ipv4 type */
16899     }
16900   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16901     {
16902       a->type = 1;              /* ipv6 type */
16903     }
16904   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16905     {
16906       a->type = 2;              /* mac type */
16907     }
16908   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16909     {
16910       a->type = 3;              /* NSH type */
16911       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16912       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16913     }
16914   else
16915     {
16916       return 0;
16917     }
16918
16919   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16920     {
16921       return 0;
16922     }
16923
16924   return 1;
16925 }
16926
16927 static int
16928 lisp_eid_size_vat (u8 type)
16929 {
16930   switch (type)
16931     {
16932     case 0:
16933       return 4;
16934     case 1:
16935       return 16;
16936     case 2:
16937       return 6;
16938     case 3:
16939       return 5;
16940     }
16941   return 0;
16942 }
16943
16944 static void
16945 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16946 {
16947   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16948 }
16949
16950 static int
16951 api_one_add_del_locator_set (vat_main_t * vam)
16952 {
16953   unformat_input_t *input = vam->input;
16954   vl_api_one_add_del_locator_set_t *mp;
16955   u8 is_add = 1;
16956   u8 *locator_set_name = NULL;
16957   u8 locator_set_name_set = 0;
16958   vl_api_local_locator_t locator, *locators = 0;
16959   u32 sw_if_index, priority, weight;
16960   u32 data_len = 0;
16961
16962   int ret;
16963   /* Parse args required to build the message */
16964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16965     {
16966       if (unformat (input, "del"))
16967         {
16968           is_add = 0;
16969         }
16970       else if (unformat (input, "locator-set %s", &locator_set_name))
16971         {
16972           locator_set_name_set = 1;
16973         }
16974       else if (unformat (input, "sw_if_index %u p %u w %u",
16975                          &sw_if_index, &priority, &weight))
16976         {
16977           locator.sw_if_index = htonl (sw_if_index);
16978           locator.priority = priority;
16979           locator.weight = weight;
16980           vec_add1 (locators, locator);
16981         }
16982       else
16983         if (unformat
16984             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16985              &sw_if_index, &priority, &weight))
16986         {
16987           locator.sw_if_index = htonl (sw_if_index);
16988           locator.priority = priority;
16989           locator.weight = weight;
16990           vec_add1 (locators, locator);
16991         }
16992       else
16993         break;
16994     }
16995
16996   if (locator_set_name_set == 0)
16997     {
16998       errmsg ("missing locator-set name");
16999       vec_free (locators);
17000       return -99;
17001     }
17002
17003   if (vec_len (locator_set_name) > 64)
17004     {
17005       errmsg ("locator-set name too long");
17006       vec_free (locator_set_name);
17007       vec_free (locators);
17008       return -99;
17009     }
17010   vec_add1 (locator_set_name, 0);
17011
17012   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17013
17014   /* Construct the API message */
17015   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17016
17017   mp->is_add = is_add;
17018   clib_memcpy (mp->locator_set_name, locator_set_name,
17019                vec_len (locator_set_name));
17020   vec_free (locator_set_name);
17021
17022   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17023   if (locators)
17024     clib_memcpy (mp->locators, locators, data_len);
17025   vec_free (locators);
17026
17027   /* send it... */
17028   S (mp);
17029
17030   /* Wait for a reply... */
17031   W (ret);
17032   return ret;
17033 }
17034
17035 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17036
17037 static int
17038 api_one_add_del_locator (vat_main_t * vam)
17039 {
17040   unformat_input_t *input = vam->input;
17041   vl_api_one_add_del_locator_t *mp;
17042   u32 tmp_if_index = ~0;
17043   u32 sw_if_index = ~0;
17044   u8 sw_if_index_set = 0;
17045   u8 sw_if_index_if_name_set = 0;
17046   u32 priority = ~0;
17047   u8 priority_set = 0;
17048   u32 weight = ~0;
17049   u8 weight_set = 0;
17050   u8 is_add = 1;
17051   u8 *locator_set_name = NULL;
17052   u8 locator_set_name_set = 0;
17053   int ret;
17054
17055   /* Parse args required to build the message */
17056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17057     {
17058       if (unformat (input, "del"))
17059         {
17060           is_add = 0;
17061         }
17062       else if (unformat (input, "locator-set %s", &locator_set_name))
17063         {
17064           locator_set_name_set = 1;
17065         }
17066       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17067                          &tmp_if_index))
17068         {
17069           sw_if_index_if_name_set = 1;
17070           sw_if_index = tmp_if_index;
17071         }
17072       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17073         {
17074           sw_if_index_set = 1;
17075           sw_if_index = tmp_if_index;
17076         }
17077       else if (unformat (input, "p %d", &priority))
17078         {
17079           priority_set = 1;
17080         }
17081       else if (unformat (input, "w %d", &weight))
17082         {
17083           weight_set = 1;
17084         }
17085       else
17086         break;
17087     }
17088
17089   if (locator_set_name_set == 0)
17090     {
17091       errmsg ("missing locator-set name");
17092       return -99;
17093     }
17094
17095   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17096     {
17097       errmsg ("missing sw_if_index");
17098       vec_free (locator_set_name);
17099       return -99;
17100     }
17101
17102   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17103     {
17104       errmsg ("cannot use both params interface name and sw_if_index");
17105       vec_free (locator_set_name);
17106       return -99;
17107     }
17108
17109   if (priority_set == 0)
17110     {
17111       errmsg ("missing locator-set priority");
17112       vec_free (locator_set_name);
17113       return -99;
17114     }
17115
17116   if (weight_set == 0)
17117     {
17118       errmsg ("missing locator-set weight");
17119       vec_free (locator_set_name);
17120       return -99;
17121     }
17122
17123   if (vec_len (locator_set_name) > 64)
17124     {
17125       errmsg ("locator-set name too long");
17126       vec_free (locator_set_name);
17127       return -99;
17128     }
17129   vec_add1 (locator_set_name, 0);
17130
17131   /* Construct the API message */
17132   M (ONE_ADD_DEL_LOCATOR, mp);
17133
17134   mp->is_add = is_add;
17135   mp->sw_if_index = ntohl (sw_if_index);
17136   mp->priority = priority;
17137   mp->weight = weight;
17138   clib_memcpy (mp->locator_set_name, locator_set_name,
17139                vec_len (locator_set_name));
17140   vec_free (locator_set_name);
17141
17142   /* send it... */
17143   S (mp);
17144
17145   /* Wait for a reply... */
17146   W (ret);
17147   return ret;
17148 }
17149
17150 #define api_lisp_add_del_locator api_one_add_del_locator
17151
17152 uword
17153 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17154 {
17155   u32 *key_id = va_arg (*args, u32 *);
17156   u8 *s = 0;
17157
17158   if (unformat (input, "%s", &s))
17159     {
17160       if (!strcmp ((char *) s, "sha1"))
17161         key_id[0] = HMAC_SHA_1_96;
17162       else if (!strcmp ((char *) s, "sha256"))
17163         key_id[0] = HMAC_SHA_256_128;
17164       else
17165         {
17166           clib_warning ("invalid key_id: '%s'", s);
17167           key_id[0] = HMAC_NO_KEY;
17168         }
17169     }
17170   else
17171     return 0;
17172
17173   vec_free (s);
17174   return 1;
17175 }
17176
17177 static int
17178 api_one_add_del_local_eid (vat_main_t * vam)
17179 {
17180   unformat_input_t *input = vam->input;
17181   vl_api_one_add_del_local_eid_t *mp;
17182   u8 is_add = 1;
17183   u8 eid_set = 0;
17184   lisp_eid_vat_t _eid, *eid = &_eid;
17185   u8 *locator_set_name = 0;
17186   u8 locator_set_name_set = 0;
17187   u32 vni = 0;
17188   u16 key_id = 0;
17189   u8 *key = 0;
17190   int ret;
17191
17192   /* Parse args required to build the message */
17193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17194     {
17195       if (unformat (input, "del"))
17196         {
17197           is_add = 0;
17198         }
17199       else if (unformat (input, "vni %d", &vni))
17200         {
17201           ;
17202         }
17203       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17204         {
17205           eid_set = 1;
17206         }
17207       else if (unformat (input, "locator-set %s", &locator_set_name))
17208         {
17209           locator_set_name_set = 1;
17210         }
17211       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17212         ;
17213       else if (unformat (input, "secret-key %_%v%_", &key))
17214         ;
17215       else
17216         break;
17217     }
17218
17219   if (locator_set_name_set == 0)
17220     {
17221       errmsg ("missing locator-set name");
17222       return -99;
17223     }
17224
17225   if (0 == eid_set)
17226     {
17227       errmsg ("EID address not set!");
17228       vec_free (locator_set_name);
17229       return -99;
17230     }
17231
17232   if (key && (0 == key_id))
17233     {
17234       errmsg ("invalid key_id!");
17235       return -99;
17236     }
17237
17238   if (vec_len (key) > 64)
17239     {
17240       errmsg ("key too long");
17241       vec_free (key);
17242       return -99;
17243     }
17244
17245   if (vec_len (locator_set_name) > 64)
17246     {
17247       errmsg ("locator-set name too long");
17248       vec_free (locator_set_name);
17249       return -99;
17250     }
17251   vec_add1 (locator_set_name, 0);
17252
17253   /* Construct the API message */
17254   M (ONE_ADD_DEL_LOCAL_EID, mp);
17255
17256   mp->is_add = is_add;
17257   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17258   mp->eid_type = eid->type;
17259   mp->prefix_len = eid->len;
17260   mp->vni = clib_host_to_net_u32 (vni);
17261   mp->key_id = clib_host_to_net_u16 (key_id);
17262   clib_memcpy (mp->locator_set_name, locator_set_name,
17263                vec_len (locator_set_name));
17264   clib_memcpy (mp->key, key, vec_len (key));
17265
17266   vec_free (locator_set_name);
17267   vec_free (key);
17268
17269   /* send it... */
17270   S (mp);
17271
17272   /* Wait for a reply... */
17273   W (ret);
17274   return ret;
17275 }
17276
17277 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17278
17279 static int
17280 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17281 {
17282   u32 dp_table = 0, vni = 0;;
17283   unformat_input_t *input = vam->input;
17284   vl_api_gpe_add_del_fwd_entry_t *mp;
17285   u8 is_add = 1;
17286   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17287   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17288   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17289   u32 action = ~0, w;
17290   ip4_address_t rmt_rloc4, lcl_rloc4;
17291   ip6_address_t rmt_rloc6, lcl_rloc6;
17292   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17293   int ret;
17294
17295   memset (&rloc, 0, sizeof (rloc));
17296
17297   /* Parse args required to build the message */
17298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17299     {
17300       if (unformat (input, "del"))
17301         is_add = 0;
17302       else if (unformat (input, "add"))
17303         is_add = 1;
17304       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17305         {
17306           rmt_eid_set = 1;
17307         }
17308       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17309         {
17310           lcl_eid_set = 1;
17311         }
17312       else if (unformat (input, "vrf %d", &dp_table))
17313         ;
17314       else if (unformat (input, "bd %d", &dp_table))
17315         ;
17316       else if (unformat (input, "vni %d", &vni))
17317         ;
17318       else if (unformat (input, "w %d", &w))
17319         {
17320           if (!curr_rloc)
17321             {
17322               errmsg ("No RLOC configured for setting priority/weight!");
17323               return -99;
17324             }
17325           curr_rloc->weight = w;
17326         }
17327       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17328                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17329         {
17330           rloc.is_ip4 = 1;
17331
17332           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17333           rloc.weight = 0;
17334           vec_add1 (lcl_locs, rloc);
17335
17336           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17337           vec_add1 (rmt_locs, rloc);
17338           /* weight saved in rmt loc */
17339           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17340         }
17341       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17342                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17343         {
17344           rloc.is_ip4 = 0;
17345           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17346           rloc.weight = 0;
17347           vec_add1 (lcl_locs, rloc);
17348
17349           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17350           vec_add1 (rmt_locs, rloc);
17351           /* weight saved in rmt loc */
17352           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17353         }
17354       else if (unformat (input, "action %d", &action))
17355         {
17356           ;
17357         }
17358       else
17359         {
17360           clib_warning ("parse error '%U'", format_unformat_error, input);
17361           return -99;
17362         }
17363     }
17364
17365   if (!rmt_eid_set)
17366     {
17367       errmsg ("remote eid addresses not set");
17368       return -99;
17369     }
17370
17371   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17372     {
17373       errmsg ("eid types don't match");
17374       return -99;
17375     }
17376
17377   if (0 == rmt_locs && (u32) ~ 0 == action)
17378     {
17379       errmsg ("action not set for negative mapping");
17380       return -99;
17381     }
17382
17383   /* Construct the API message */
17384   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17385       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17386
17387   mp->is_add = is_add;
17388   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17389   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17390   mp->eid_type = rmt_eid->type;
17391   mp->dp_table = clib_host_to_net_u32 (dp_table);
17392   mp->vni = clib_host_to_net_u32 (vni);
17393   mp->rmt_len = rmt_eid->len;
17394   mp->lcl_len = lcl_eid->len;
17395   mp->action = action;
17396
17397   if (0 != rmt_locs && 0 != lcl_locs)
17398     {
17399       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17400       clib_memcpy (mp->locs, lcl_locs,
17401                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17402
17403       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17404       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17405                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17406     }
17407   vec_free (lcl_locs);
17408   vec_free (rmt_locs);
17409
17410   /* send it... */
17411   S (mp);
17412
17413   /* Wait for a reply... */
17414   W (ret);
17415   return ret;
17416 }
17417
17418 static int
17419 api_one_add_del_map_server (vat_main_t * vam)
17420 {
17421   unformat_input_t *input = vam->input;
17422   vl_api_one_add_del_map_server_t *mp;
17423   u8 is_add = 1;
17424   u8 ipv4_set = 0;
17425   u8 ipv6_set = 0;
17426   ip4_address_t ipv4;
17427   ip6_address_t ipv6;
17428   int ret;
17429
17430   /* Parse args required to build the message */
17431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17432     {
17433       if (unformat (input, "del"))
17434         {
17435           is_add = 0;
17436         }
17437       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17438         {
17439           ipv4_set = 1;
17440         }
17441       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17442         {
17443           ipv6_set = 1;
17444         }
17445       else
17446         break;
17447     }
17448
17449   if (ipv4_set && ipv6_set)
17450     {
17451       errmsg ("both eid v4 and v6 addresses set");
17452       return -99;
17453     }
17454
17455   if (!ipv4_set && !ipv6_set)
17456     {
17457       errmsg ("eid addresses not set");
17458       return -99;
17459     }
17460
17461   /* Construct the API message */
17462   M (ONE_ADD_DEL_MAP_SERVER, mp);
17463
17464   mp->is_add = is_add;
17465   if (ipv6_set)
17466     {
17467       mp->is_ipv6 = 1;
17468       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17469     }
17470   else
17471     {
17472       mp->is_ipv6 = 0;
17473       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17474     }
17475
17476   /* send it... */
17477   S (mp);
17478
17479   /* Wait for a reply... */
17480   W (ret);
17481   return ret;
17482 }
17483
17484 #define api_lisp_add_del_map_server api_one_add_del_map_server
17485
17486 static int
17487 api_one_add_del_map_resolver (vat_main_t * vam)
17488 {
17489   unformat_input_t *input = vam->input;
17490   vl_api_one_add_del_map_resolver_t *mp;
17491   u8 is_add = 1;
17492   u8 ipv4_set = 0;
17493   u8 ipv6_set = 0;
17494   ip4_address_t ipv4;
17495   ip6_address_t ipv6;
17496   int ret;
17497
17498   /* Parse args required to build the message */
17499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17500     {
17501       if (unformat (input, "del"))
17502         {
17503           is_add = 0;
17504         }
17505       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17506         {
17507           ipv4_set = 1;
17508         }
17509       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17510         {
17511           ipv6_set = 1;
17512         }
17513       else
17514         break;
17515     }
17516
17517   if (ipv4_set && ipv6_set)
17518     {
17519       errmsg ("both eid v4 and v6 addresses set");
17520       return -99;
17521     }
17522
17523   if (!ipv4_set && !ipv6_set)
17524     {
17525       errmsg ("eid addresses not set");
17526       return -99;
17527     }
17528
17529   /* Construct the API message */
17530   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17531
17532   mp->is_add = is_add;
17533   if (ipv6_set)
17534     {
17535       mp->is_ipv6 = 1;
17536       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17537     }
17538   else
17539     {
17540       mp->is_ipv6 = 0;
17541       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17542     }
17543
17544   /* send it... */
17545   S (mp);
17546
17547   /* Wait for a reply... */
17548   W (ret);
17549   return ret;
17550 }
17551
17552 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17553
17554 static int
17555 api_lisp_gpe_enable_disable (vat_main_t * vam)
17556 {
17557   unformat_input_t *input = vam->input;
17558   vl_api_gpe_enable_disable_t *mp;
17559   u8 is_set = 0;
17560   u8 is_en = 1;
17561   int ret;
17562
17563   /* Parse args required to build the message */
17564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17565     {
17566       if (unformat (input, "enable"))
17567         {
17568           is_set = 1;
17569           is_en = 1;
17570         }
17571       else if (unformat (input, "disable"))
17572         {
17573           is_set = 1;
17574           is_en = 0;
17575         }
17576       else
17577         break;
17578     }
17579
17580   if (is_set == 0)
17581     {
17582       errmsg ("Value not set");
17583       return -99;
17584     }
17585
17586   /* Construct the API message */
17587   M (GPE_ENABLE_DISABLE, mp);
17588
17589   mp->is_en = is_en;
17590
17591   /* send it... */
17592   S (mp);
17593
17594   /* Wait for a reply... */
17595   W (ret);
17596   return ret;
17597 }
17598
17599 static int
17600 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17601 {
17602   unformat_input_t *input = vam->input;
17603   vl_api_one_rloc_probe_enable_disable_t *mp;
17604   u8 is_set = 0;
17605   u8 is_en = 0;
17606   int ret;
17607
17608   /* Parse args required to build the message */
17609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17610     {
17611       if (unformat (input, "enable"))
17612         {
17613           is_set = 1;
17614           is_en = 1;
17615         }
17616       else if (unformat (input, "disable"))
17617         is_set = 1;
17618       else
17619         break;
17620     }
17621
17622   if (!is_set)
17623     {
17624       errmsg ("Value not set");
17625       return -99;
17626     }
17627
17628   /* Construct the API message */
17629   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17630
17631   mp->is_enabled = is_en;
17632
17633   /* send it... */
17634   S (mp);
17635
17636   /* Wait for a reply... */
17637   W (ret);
17638   return ret;
17639 }
17640
17641 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17642
17643 static int
17644 api_one_map_register_enable_disable (vat_main_t * vam)
17645 {
17646   unformat_input_t *input = vam->input;
17647   vl_api_one_map_register_enable_disable_t *mp;
17648   u8 is_set = 0;
17649   u8 is_en = 0;
17650   int ret;
17651
17652   /* Parse args required to build the message */
17653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17654     {
17655       if (unformat (input, "enable"))
17656         {
17657           is_set = 1;
17658           is_en = 1;
17659         }
17660       else if (unformat (input, "disable"))
17661         is_set = 1;
17662       else
17663         break;
17664     }
17665
17666   if (!is_set)
17667     {
17668       errmsg ("Value not set");
17669       return -99;
17670     }
17671
17672   /* Construct the API message */
17673   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17674
17675   mp->is_enabled = is_en;
17676
17677   /* send it... */
17678   S (mp);
17679
17680   /* Wait for a reply... */
17681   W (ret);
17682   return ret;
17683 }
17684
17685 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17686
17687 static int
17688 api_one_enable_disable (vat_main_t * vam)
17689 {
17690   unformat_input_t *input = vam->input;
17691   vl_api_one_enable_disable_t *mp;
17692   u8 is_set = 0;
17693   u8 is_en = 0;
17694   int ret;
17695
17696   /* Parse args required to build the message */
17697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17698     {
17699       if (unformat (input, "enable"))
17700         {
17701           is_set = 1;
17702           is_en = 1;
17703         }
17704       else if (unformat (input, "disable"))
17705         {
17706           is_set = 1;
17707         }
17708       else
17709         break;
17710     }
17711
17712   if (!is_set)
17713     {
17714       errmsg ("Value not set");
17715       return -99;
17716     }
17717
17718   /* Construct the API message */
17719   M (ONE_ENABLE_DISABLE, mp);
17720
17721   mp->is_en = is_en;
17722
17723   /* send it... */
17724   S (mp);
17725
17726   /* Wait for a reply... */
17727   W (ret);
17728   return ret;
17729 }
17730
17731 #define api_lisp_enable_disable api_one_enable_disable
17732
17733 static int
17734 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17735 {
17736   unformat_input_t *input = vam->input;
17737   vl_api_one_enable_disable_xtr_mode_t *mp;
17738   u8 is_set = 0;
17739   u8 is_en = 0;
17740   int ret;
17741
17742   /* Parse args required to build the message */
17743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17744     {
17745       if (unformat (input, "enable"))
17746         {
17747           is_set = 1;
17748           is_en = 1;
17749         }
17750       else if (unformat (input, "disable"))
17751         {
17752           is_set = 1;
17753         }
17754       else
17755         break;
17756     }
17757
17758   if (!is_set)
17759     {
17760       errmsg ("Value not set");
17761       return -99;
17762     }
17763
17764   /* Construct the API message */
17765   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17766
17767   mp->is_en = is_en;
17768
17769   /* send it... */
17770   S (mp);
17771
17772   /* Wait for a reply... */
17773   W (ret);
17774   return ret;
17775 }
17776
17777 static int
17778 api_one_show_xtr_mode (vat_main_t * vam)
17779 {
17780   vl_api_one_show_xtr_mode_t *mp;
17781   int ret;
17782
17783   /* Construct the API message */
17784   M (ONE_SHOW_XTR_MODE, mp);
17785
17786   /* send it... */
17787   S (mp);
17788
17789   /* Wait for a reply... */
17790   W (ret);
17791   return ret;
17792 }
17793
17794 static int
17795 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17796 {
17797   unformat_input_t *input = vam->input;
17798   vl_api_one_enable_disable_pitr_mode_t *mp;
17799   u8 is_set = 0;
17800   u8 is_en = 0;
17801   int ret;
17802
17803   /* Parse args required to build the message */
17804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17805     {
17806       if (unformat (input, "enable"))
17807         {
17808           is_set = 1;
17809           is_en = 1;
17810         }
17811       else if (unformat (input, "disable"))
17812         {
17813           is_set = 1;
17814         }
17815       else
17816         break;
17817     }
17818
17819   if (!is_set)
17820     {
17821       errmsg ("Value not set");
17822       return -99;
17823     }
17824
17825   /* Construct the API message */
17826   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17827
17828   mp->is_en = is_en;
17829
17830   /* send it... */
17831   S (mp);
17832
17833   /* Wait for a reply... */
17834   W (ret);
17835   return ret;
17836 }
17837
17838 static int
17839 api_one_show_pitr_mode (vat_main_t * vam)
17840 {
17841   vl_api_one_show_pitr_mode_t *mp;
17842   int ret;
17843
17844   /* Construct the API message */
17845   M (ONE_SHOW_PITR_MODE, mp);
17846
17847   /* send it... */
17848   S (mp);
17849
17850   /* Wait for a reply... */
17851   W (ret);
17852   return ret;
17853 }
17854
17855 static int
17856 api_one_enable_disable_petr_mode (vat_main_t * vam)
17857 {
17858   unformat_input_t *input = vam->input;
17859   vl_api_one_enable_disable_petr_mode_t *mp;
17860   u8 is_set = 0;
17861   u8 is_en = 0;
17862   int ret;
17863
17864   /* Parse args required to build the message */
17865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17866     {
17867       if (unformat (input, "enable"))
17868         {
17869           is_set = 1;
17870           is_en = 1;
17871         }
17872       else if (unformat (input, "disable"))
17873         {
17874           is_set = 1;
17875         }
17876       else
17877         break;
17878     }
17879
17880   if (!is_set)
17881     {
17882       errmsg ("Value not set");
17883       return -99;
17884     }
17885
17886   /* Construct the API message */
17887   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17888
17889   mp->is_en = is_en;
17890
17891   /* send it... */
17892   S (mp);
17893
17894   /* Wait for a reply... */
17895   W (ret);
17896   return ret;
17897 }
17898
17899 static int
17900 api_one_show_petr_mode (vat_main_t * vam)
17901 {
17902   vl_api_one_show_petr_mode_t *mp;
17903   int ret;
17904
17905   /* Construct the API message */
17906   M (ONE_SHOW_PETR_MODE, mp);
17907
17908   /* send it... */
17909   S (mp);
17910
17911   /* Wait for a reply... */
17912   W (ret);
17913   return ret;
17914 }
17915
17916 static int
17917 api_show_one_map_register_state (vat_main_t * vam)
17918 {
17919   vl_api_show_one_map_register_state_t *mp;
17920   int ret;
17921
17922   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17923
17924   /* send */
17925   S (mp);
17926
17927   /* wait for reply */
17928   W (ret);
17929   return ret;
17930 }
17931
17932 #define api_show_lisp_map_register_state api_show_one_map_register_state
17933
17934 static int
17935 api_show_one_rloc_probe_state (vat_main_t * vam)
17936 {
17937   vl_api_show_one_rloc_probe_state_t *mp;
17938   int ret;
17939
17940   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17941
17942   /* send */
17943   S (mp);
17944
17945   /* wait for reply */
17946   W (ret);
17947   return ret;
17948 }
17949
17950 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17951
17952 static int
17953 api_one_add_del_ndp_entry (vat_main_t * vam)
17954 {
17955   vl_api_one_add_del_ndp_entry_t *mp;
17956   unformat_input_t *input = vam->input;
17957   u8 is_add = 1;
17958   u8 mac_set = 0;
17959   u8 bd_set = 0;
17960   u8 ip_set = 0;
17961   u8 mac[6] = { 0, };
17962   u8 ip6[16] = { 0, };
17963   u32 bd = ~0;
17964   int ret;
17965
17966   /* Parse args required to build the message */
17967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17968     {
17969       if (unformat (input, "del"))
17970         is_add = 0;
17971       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17972         mac_set = 1;
17973       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17974         ip_set = 1;
17975       else if (unformat (input, "bd %d", &bd))
17976         bd_set = 1;
17977       else
17978         {
17979           errmsg ("parse error '%U'", format_unformat_error, input);
17980           return -99;
17981         }
17982     }
17983
17984   if (!bd_set || !ip_set || (!mac_set && is_add))
17985     {
17986       errmsg ("Missing BD, IP or MAC!");
17987       return -99;
17988     }
17989
17990   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17991   mp->is_add = is_add;
17992   clib_memcpy (mp->mac, mac, 6);
17993   mp->bd = clib_host_to_net_u32 (bd);
17994   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17995
17996   /* send */
17997   S (mp);
17998
17999   /* wait for reply */
18000   W (ret);
18001   return ret;
18002 }
18003
18004 static int
18005 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18006 {
18007   vl_api_one_add_del_l2_arp_entry_t *mp;
18008   unformat_input_t *input = vam->input;
18009   u8 is_add = 1;
18010   u8 mac_set = 0;
18011   u8 bd_set = 0;
18012   u8 ip_set = 0;
18013   u8 mac[6] = { 0, };
18014   u32 ip4 = 0, bd = ~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, "mac %U", unformat_ethernet_address, mac))
18023         mac_set = 1;
18024       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18025         ip_set = 1;
18026       else if (unformat (input, "bd %d", &bd))
18027         bd_set = 1;
18028       else
18029         {
18030           errmsg ("parse error '%U'", format_unformat_error, input);
18031           return -99;
18032         }
18033     }
18034
18035   if (!bd_set || !ip_set || (!mac_set && is_add))
18036     {
18037       errmsg ("Missing BD, IP or MAC!");
18038       return -99;
18039     }
18040
18041   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18042   mp->is_add = is_add;
18043   clib_memcpy (mp->mac, mac, 6);
18044   mp->bd = clib_host_to_net_u32 (bd);
18045   mp->ip4 = ip4;
18046
18047   /* send */
18048   S (mp);
18049
18050   /* wait for reply */
18051   W (ret);
18052   return ret;
18053 }
18054
18055 static int
18056 api_one_ndp_bd_get (vat_main_t * vam)
18057 {
18058   vl_api_one_ndp_bd_get_t *mp;
18059   int ret;
18060
18061   M (ONE_NDP_BD_GET, mp);
18062
18063   /* send */
18064   S (mp);
18065
18066   /* wait for reply */
18067   W (ret);
18068   return ret;
18069 }
18070
18071 static int
18072 api_one_ndp_entries_get (vat_main_t * vam)
18073 {
18074   vl_api_one_ndp_entries_get_t *mp;
18075   unformat_input_t *input = vam->input;
18076   u8 bd_set = 0;
18077   u32 bd = ~0;
18078   int ret;
18079
18080   /* Parse args required to build the message */
18081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18082     {
18083       if (unformat (input, "bd %d", &bd))
18084         bd_set = 1;
18085       else
18086         {
18087           errmsg ("parse error '%U'", format_unformat_error, input);
18088           return -99;
18089         }
18090     }
18091
18092   if (!bd_set)
18093     {
18094       errmsg ("Expected bridge domain!");
18095       return -99;
18096     }
18097
18098   M (ONE_NDP_ENTRIES_GET, mp);
18099   mp->bd = clib_host_to_net_u32 (bd);
18100
18101   /* send */
18102   S (mp);
18103
18104   /* wait for reply */
18105   W (ret);
18106   return ret;
18107 }
18108
18109 static int
18110 api_one_l2_arp_bd_get (vat_main_t * vam)
18111 {
18112   vl_api_one_l2_arp_bd_get_t *mp;
18113   int ret;
18114
18115   M (ONE_L2_ARP_BD_GET, mp);
18116
18117   /* send */
18118   S (mp);
18119
18120   /* wait for reply */
18121   W (ret);
18122   return ret;
18123 }
18124
18125 static int
18126 api_one_l2_arp_entries_get (vat_main_t * vam)
18127 {
18128   vl_api_one_l2_arp_entries_get_t *mp;
18129   unformat_input_t *input = vam->input;
18130   u8 bd_set = 0;
18131   u32 bd = ~0;
18132   int ret;
18133
18134   /* Parse args required to build the message */
18135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18136     {
18137       if (unformat (input, "bd %d", &bd))
18138         bd_set = 1;
18139       else
18140         {
18141           errmsg ("parse error '%U'", format_unformat_error, input);
18142           return -99;
18143         }
18144     }
18145
18146   if (!bd_set)
18147     {
18148       errmsg ("Expected bridge domain!");
18149       return -99;
18150     }
18151
18152   M (ONE_L2_ARP_ENTRIES_GET, mp);
18153   mp->bd = clib_host_to_net_u32 (bd);
18154
18155   /* send */
18156   S (mp);
18157
18158   /* wait for reply */
18159   W (ret);
18160   return ret;
18161 }
18162
18163 static int
18164 api_one_stats_enable_disable (vat_main_t * vam)
18165 {
18166   vl_api_one_stats_enable_disable_t *mp;
18167   unformat_input_t *input = vam->input;
18168   u8 is_set = 0;
18169   u8 is_en = 0;
18170   int ret;
18171
18172   /* Parse args required to build the message */
18173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18174     {
18175       if (unformat (input, "enable"))
18176         {
18177           is_set = 1;
18178           is_en = 1;
18179         }
18180       else if (unformat (input, "disable"))
18181         {
18182           is_set = 1;
18183         }
18184       else
18185         break;
18186     }
18187
18188   if (!is_set)
18189     {
18190       errmsg ("Value not set");
18191       return -99;
18192     }
18193
18194   M (ONE_STATS_ENABLE_DISABLE, mp);
18195   mp->is_en = is_en;
18196
18197   /* send */
18198   S (mp);
18199
18200   /* wait for reply */
18201   W (ret);
18202   return ret;
18203 }
18204
18205 static int
18206 api_show_one_stats_enable_disable (vat_main_t * vam)
18207 {
18208   vl_api_show_one_stats_enable_disable_t *mp;
18209   int ret;
18210
18211   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18212
18213   /* send */
18214   S (mp);
18215
18216   /* wait for reply */
18217   W (ret);
18218   return ret;
18219 }
18220
18221 static int
18222 api_show_one_map_request_mode (vat_main_t * vam)
18223 {
18224   vl_api_show_one_map_request_mode_t *mp;
18225   int ret;
18226
18227   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18228
18229   /* send */
18230   S (mp);
18231
18232   /* wait for reply */
18233   W (ret);
18234   return ret;
18235 }
18236
18237 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18238
18239 static int
18240 api_one_map_request_mode (vat_main_t * vam)
18241 {
18242   unformat_input_t *input = vam->input;
18243   vl_api_one_map_request_mode_t *mp;
18244   u8 mode = 0;
18245   int ret;
18246
18247   /* Parse args required to build the message */
18248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18249     {
18250       if (unformat (input, "dst-only"))
18251         mode = 0;
18252       else if (unformat (input, "src-dst"))
18253         mode = 1;
18254       else
18255         {
18256           errmsg ("parse error '%U'", format_unformat_error, input);
18257           return -99;
18258         }
18259     }
18260
18261   M (ONE_MAP_REQUEST_MODE, mp);
18262
18263   mp->mode = mode;
18264
18265   /* send */
18266   S (mp);
18267
18268   /* wait for reply */
18269   W (ret);
18270   return ret;
18271 }
18272
18273 #define api_lisp_map_request_mode api_one_map_request_mode
18274
18275 /**
18276  * Enable/disable ONE proxy ITR.
18277  *
18278  * @param vam vpp API test context
18279  * @return return code
18280  */
18281 static int
18282 api_one_pitr_set_locator_set (vat_main_t * vam)
18283 {
18284   u8 ls_name_set = 0;
18285   unformat_input_t *input = vam->input;
18286   vl_api_one_pitr_set_locator_set_t *mp;
18287   u8 is_add = 1;
18288   u8 *ls_name = 0;
18289   int ret;
18290
18291   /* Parse args required to build the message */
18292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18293     {
18294       if (unformat (input, "del"))
18295         is_add = 0;
18296       else if (unformat (input, "locator-set %s", &ls_name))
18297         ls_name_set = 1;
18298       else
18299         {
18300           errmsg ("parse error '%U'", format_unformat_error, input);
18301           return -99;
18302         }
18303     }
18304
18305   if (!ls_name_set)
18306     {
18307       errmsg ("locator-set name not set!");
18308       return -99;
18309     }
18310
18311   M (ONE_PITR_SET_LOCATOR_SET, mp);
18312
18313   mp->is_add = is_add;
18314   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18315   vec_free (ls_name);
18316
18317   /* send */
18318   S (mp);
18319
18320   /* wait for reply */
18321   W (ret);
18322   return ret;
18323 }
18324
18325 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18326
18327 static int
18328 api_one_nsh_set_locator_set (vat_main_t * vam)
18329 {
18330   u8 ls_name_set = 0;
18331   unformat_input_t *input = vam->input;
18332   vl_api_one_nsh_set_locator_set_t *mp;
18333   u8 is_add = 1;
18334   u8 *ls_name = 0;
18335   int ret;
18336
18337   /* Parse args required to build the message */
18338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18339     {
18340       if (unformat (input, "del"))
18341         is_add = 0;
18342       else if (unformat (input, "ls %s", &ls_name))
18343         ls_name_set = 1;
18344       else
18345         {
18346           errmsg ("parse error '%U'", format_unformat_error, input);
18347           return -99;
18348         }
18349     }
18350
18351   if (!ls_name_set && is_add)
18352     {
18353       errmsg ("locator-set name not set!");
18354       return -99;
18355     }
18356
18357   M (ONE_NSH_SET_LOCATOR_SET, mp);
18358
18359   mp->is_add = is_add;
18360   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18361   vec_free (ls_name);
18362
18363   /* send */
18364   S (mp);
18365
18366   /* wait for reply */
18367   W (ret);
18368   return ret;
18369 }
18370
18371 static int
18372 api_show_one_pitr (vat_main_t * vam)
18373 {
18374   vl_api_show_one_pitr_t *mp;
18375   int ret;
18376
18377   if (!vam->json_output)
18378     {
18379       print (vam->ofp, "%=20s", "lisp status:");
18380     }
18381
18382   M (SHOW_ONE_PITR, mp);
18383   /* send it... */
18384   S (mp);
18385
18386   /* Wait for a reply... */
18387   W (ret);
18388   return ret;
18389 }
18390
18391 #define api_show_lisp_pitr api_show_one_pitr
18392
18393 static int
18394 api_one_use_petr (vat_main_t * vam)
18395 {
18396   unformat_input_t *input = vam->input;
18397   vl_api_one_use_petr_t *mp;
18398   u8 is_add = 0;
18399   ip_address_t ip;
18400   int ret;
18401
18402   memset (&ip, 0, sizeof (ip));
18403
18404   /* Parse args required to build the message */
18405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18406     {
18407       if (unformat (input, "disable"))
18408         is_add = 0;
18409       else
18410         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18411         {
18412           is_add = 1;
18413           ip_addr_version (&ip) = IP4;
18414         }
18415       else
18416         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18417         {
18418           is_add = 1;
18419           ip_addr_version (&ip) = IP6;
18420         }
18421       else
18422         {
18423           errmsg ("parse error '%U'", format_unformat_error, input);
18424           return -99;
18425         }
18426     }
18427
18428   M (ONE_USE_PETR, mp);
18429
18430   mp->is_add = is_add;
18431   if (is_add)
18432     {
18433       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18434       if (mp->is_ip4)
18435         clib_memcpy (mp->address, &ip, 4);
18436       else
18437         clib_memcpy (mp->address, &ip, 16);
18438     }
18439
18440   /* send */
18441   S (mp);
18442
18443   /* wait for reply */
18444   W (ret);
18445   return ret;
18446 }
18447
18448 #define api_lisp_use_petr api_one_use_petr
18449
18450 static int
18451 api_show_one_nsh_mapping (vat_main_t * vam)
18452 {
18453   vl_api_show_one_use_petr_t *mp;
18454   int ret;
18455
18456   if (!vam->json_output)
18457     {
18458       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18459     }
18460
18461   M (SHOW_ONE_NSH_MAPPING, mp);
18462   /* send it... */
18463   S (mp);
18464
18465   /* Wait for a reply... */
18466   W (ret);
18467   return ret;
18468 }
18469
18470 static int
18471 api_show_one_use_petr (vat_main_t * vam)
18472 {
18473   vl_api_show_one_use_petr_t *mp;
18474   int ret;
18475
18476   if (!vam->json_output)
18477     {
18478       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18479     }
18480
18481   M (SHOW_ONE_USE_PETR, mp);
18482   /* send it... */
18483   S (mp);
18484
18485   /* Wait for a reply... */
18486   W (ret);
18487   return ret;
18488 }
18489
18490 #define api_show_lisp_use_petr api_show_one_use_petr
18491
18492 /**
18493  * Add/delete mapping between vni and vrf
18494  */
18495 static int
18496 api_one_eid_table_add_del_map (vat_main_t * vam)
18497 {
18498   unformat_input_t *input = vam->input;
18499   vl_api_one_eid_table_add_del_map_t *mp;
18500   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18501   u32 vni, vrf, bd_index;
18502   int ret;
18503
18504   /* Parse args required to build the message */
18505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18506     {
18507       if (unformat (input, "del"))
18508         is_add = 0;
18509       else if (unformat (input, "vrf %d", &vrf))
18510         vrf_set = 1;
18511       else if (unformat (input, "bd_index %d", &bd_index))
18512         bd_index_set = 1;
18513       else if (unformat (input, "vni %d", &vni))
18514         vni_set = 1;
18515       else
18516         break;
18517     }
18518
18519   if (!vni_set || (!vrf_set && !bd_index_set))
18520     {
18521       errmsg ("missing arguments!");
18522       return -99;
18523     }
18524
18525   if (vrf_set && bd_index_set)
18526     {
18527       errmsg ("error: both vrf and bd entered!");
18528       return -99;
18529     }
18530
18531   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18532
18533   mp->is_add = is_add;
18534   mp->vni = htonl (vni);
18535   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18536   mp->is_l2 = bd_index_set;
18537
18538   /* send */
18539   S (mp);
18540
18541   /* wait for reply */
18542   W (ret);
18543   return ret;
18544 }
18545
18546 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18547
18548 uword
18549 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18550 {
18551   u32 *action = va_arg (*args, u32 *);
18552   u8 *s = 0;
18553
18554   if (unformat (input, "%s", &s))
18555     {
18556       if (!strcmp ((char *) s, "no-action"))
18557         action[0] = 0;
18558       else if (!strcmp ((char *) s, "natively-forward"))
18559         action[0] = 1;
18560       else if (!strcmp ((char *) s, "send-map-request"))
18561         action[0] = 2;
18562       else if (!strcmp ((char *) s, "drop"))
18563         action[0] = 3;
18564       else
18565         {
18566           clib_warning ("invalid action: '%s'", s);
18567           action[0] = 3;
18568         }
18569     }
18570   else
18571     return 0;
18572
18573   vec_free (s);
18574   return 1;
18575 }
18576
18577 /**
18578  * Add/del remote mapping to/from ONE control plane
18579  *
18580  * @param vam vpp API test context
18581  * @return return code
18582  */
18583 static int
18584 api_one_add_del_remote_mapping (vat_main_t * vam)
18585 {
18586   unformat_input_t *input = vam->input;
18587   vl_api_one_add_del_remote_mapping_t *mp;
18588   u32 vni = 0;
18589   lisp_eid_vat_t _eid, *eid = &_eid;
18590   lisp_eid_vat_t _seid, *seid = &_seid;
18591   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18592   u32 action = ~0, p, w, data_len;
18593   ip4_address_t rloc4;
18594   ip6_address_t rloc6;
18595   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18596   int ret;
18597
18598   memset (&rloc, 0, sizeof (rloc));
18599
18600   /* Parse args required to build the message */
18601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18602     {
18603       if (unformat (input, "del-all"))
18604         {
18605           del_all = 1;
18606         }
18607       else if (unformat (input, "del"))
18608         {
18609           is_add = 0;
18610         }
18611       else if (unformat (input, "add"))
18612         {
18613           is_add = 1;
18614         }
18615       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18616         {
18617           eid_set = 1;
18618         }
18619       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18620         {
18621           seid_set = 1;
18622         }
18623       else if (unformat (input, "vni %d", &vni))
18624         {
18625           ;
18626         }
18627       else if (unformat (input, "p %d w %d", &p, &w))
18628         {
18629           if (!curr_rloc)
18630             {
18631               errmsg ("No RLOC configured for setting priority/weight!");
18632               return -99;
18633             }
18634           curr_rloc->priority = p;
18635           curr_rloc->weight = w;
18636         }
18637       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18638         {
18639           rloc.is_ip4 = 1;
18640           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18641           vec_add1 (rlocs, rloc);
18642           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18643         }
18644       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18645         {
18646           rloc.is_ip4 = 0;
18647           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18648           vec_add1 (rlocs, rloc);
18649           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18650         }
18651       else if (unformat (input, "action %U",
18652                          unformat_negative_mapping_action, &action))
18653         {
18654           ;
18655         }
18656       else
18657         {
18658           clib_warning ("parse error '%U'", format_unformat_error, input);
18659           return -99;
18660         }
18661     }
18662
18663   if (0 == eid_set)
18664     {
18665       errmsg ("missing params!");
18666       return -99;
18667     }
18668
18669   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18670     {
18671       errmsg ("no action set for negative map-reply!");
18672       return -99;
18673     }
18674
18675   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18676
18677   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18678   mp->is_add = is_add;
18679   mp->vni = htonl (vni);
18680   mp->action = (u8) action;
18681   mp->is_src_dst = seid_set;
18682   mp->eid_len = eid->len;
18683   mp->seid_len = seid->len;
18684   mp->del_all = del_all;
18685   mp->eid_type = eid->type;
18686   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18687   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18688
18689   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18690   clib_memcpy (mp->rlocs, rlocs, data_len);
18691   vec_free (rlocs);
18692
18693   /* send it... */
18694   S (mp);
18695
18696   /* Wait for a reply... */
18697   W (ret);
18698   return ret;
18699 }
18700
18701 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18702
18703 /**
18704  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18705  * forwarding entries in data-plane accordingly.
18706  *
18707  * @param vam vpp API test context
18708  * @return return code
18709  */
18710 static int
18711 api_one_add_del_adjacency (vat_main_t * vam)
18712 {
18713   unformat_input_t *input = vam->input;
18714   vl_api_one_add_del_adjacency_t *mp;
18715   u32 vni = 0;
18716   ip4_address_t leid4, reid4;
18717   ip6_address_t leid6, reid6;
18718   u8 reid_mac[6] = { 0 };
18719   u8 leid_mac[6] = { 0 };
18720   u8 reid_type, leid_type;
18721   u32 leid_len = 0, reid_len = 0, len;
18722   u8 is_add = 1;
18723   int ret;
18724
18725   leid_type = reid_type = (u8) ~ 0;
18726
18727   /* Parse args required to build the message */
18728   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18729     {
18730       if (unformat (input, "del"))
18731         {
18732           is_add = 0;
18733         }
18734       else if (unformat (input, "add"))
18735         {
18736           is_add = 1;
18737         }
18738       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18739                          &reid4, &len))
18740         {
18741           reid_type = 0;        /* ipv4 */
18742           reid_len = len;
18743         }
18744       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18745                          &reid6, &len))
18746         {
18747           reid_type = 1;        /* ipv6 */
18748           reid_len = len;
18749         }
18750       else if (unformat (input, "reid %U", unformat_ethernet_address,
18751                          reid_mac))
18752         {
18753           reid_type = 2;        /* mac */
18754         }
18755       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18756                          &leid4, &len))
18757         {
18758           leid_type = 0;        /* ipv4 */
18759           leid_len = len;
18760         }
18761       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18762                          &leid6, &len))
18763         {
18764           leid_type = 1;        /* ipv6 */
18765           leid_len = len;
18766         }
18767       else if (unformat (input, "leid %U", unformat_ethernet_address,
18768                          leid_mac))
18769         {
18770           leid_type = 2;        /* mac */
18771         }
18772       else if (unformat (input, "vni %d", &vni))
18773         {
18774           ;
18775         }
18776       else
18777         {
18778           errmsg ("parse error '%U'", format_unformat_error, input);
18779           return -99;
18780         }
18781     }
18782
18783   if ((u8) ~ 0 == reid_type)
18784     {
18785       errmsg ("missing params!");
18786       return -99;
18787     }
18788
18789   if (leid_type != reid_type)
18790     {
18791       errmsg ("remote and local EIDs are of different types!");
18792       return -99;
18793     }
18794
18795   M (ONE_ADD_DEL_ADJACENCY, mp);
18796   mp->is_add = is_add;
18797   mp->vni = htonl (vni);
18798   mp->leid_len = leid_len;
18799   mp->reid_len = reid_len;
18800   mp->eid_type = reid_type;
18801
18802   switch (mp->eid_type)
18803     {
18804     case 0:
18805       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18806       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18807       break;
18808     case 1:
18809       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18810       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18811       break;
18812     case 2:
18813       clib_memcpy (mp->leid, leid_mac, 6);
18814       clib_memcpy (mp->reid, reid_mac, 6);
18815       break;
18816     default:
18817       errmsg ("unknown EID type %d!", mp->eid_type);
18818       return 0;
18819     }
18820
18821   /* send it... */
18822   S (mp);
18823
18824   /* Wait for a reply... */
18825   W (ret);
18826   return ret;
18827 }
18828
18829 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18830
18831 uword
18832 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18833 {
18834   u32 *mode = va_arg (*args, u32 *);
18835
18836   if (unformat (input, "lisp"))
18837     *mode = 0;
18838   else if (unformat (input, "vxlan"))
18839     *mode = 1;
18840   else
18841     return 0;
18842
18843   return 1;
18844 }
18845
18846 static int
18847 api_gpe_get_encap_mode (vat_main_t * vam)
18848 {
18849   vl_api_gpe_get_encap_mode_t *mp;
18850   int ret;
18851
18852   /* Construct the API message */
18853   M (GPE_GET_ENCAP_MODE, mp);
18854
18855   /* send it... */
18856   S (mp);
18857
18858   /* Wait for a reply... */
18859   W (ret);
18860   return ret;
18861 }
18862
18863 static int
18864 api_gpe_set_encap_mode (vat_main_t * vam)
18865 {
18866   unformat_input_t *input = vam->input;
18867   vl_api_gpe_set_encap_mode_t *mp;
18868   int ret;
18869   u32 mode = 0;
18870
18871   /* Parse args required to build the message */
18872   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18873     {
18874       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18875         ;
18876       else
18877         break;
18878     }
18879
18880   /* Construct the API message */
18881   M (GPE_SET_ENCAP_MODE, mp);
18882
18883   mp->mode = mode;
18884
18885   /* send it... */
18886   S (mp);
18887
18888   /* Wait for a reply... */
18889   W (ret);
18890   return ret;
18891 }
18892
18893 static int
18894 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18895 {
18896   unformat_input_t *input = vam->input;
18897   vl_api_gpe_add_del_iface_t *mp;
18898   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18899   u32 dp_table = 0, vni = 0;
18900   int ret;
18901
18902   /* Parse args required to build the message */
18903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18904     {
18905       if (unformat (input, "up"))
18906         {
18907           action_set = 1;
18908           is_add = 1;
18909         }
18910       else if (unformat (input, "down"))
18911         {
18912           action_set = 1;
18913           is_add = 0;
18914         }
18915       else if (unformat (input, "table_id %d", &dp_table))
18916         {
18917           dp_table_set = 1;
18918         }
18919       else if (unformat (input, "bd_id %d", &dp_table))
18920         {
18921           dp_table_set = 1;
18922           is_l2 = 1;
18923         }
18924       else if (unformat (input, "vni %d", &vni))
18925         {
18926           vni_set = 1;
18927         }
18928       else
18929         break;
18930     }
18931
18932   if (action_set == 0)
18933     {
18934       errmsg ("Action not set");
18935       return -99;
18936     }
18937   if (dp_table_set == 0 || vni_set == 0)
18938     {
18939       errmsg ("vni and dp_table must be set");
18940       return -99;
18941     }
18942
18943   /* Construct the API message */
18944   M (GPE_ADD_DEL_IFACE, mp);
18945
18946   mp->is_add = is_add;
18947   mp->dp_table = clib_host_to_net_u32 (dp_table);
18948   mp->is_l2 = is_l2;
18949   mp->vni = clib_host_to_net_u32 (vni);
18950
18951   /* send it... */
18952   S (mp);
18953
18954   /* Wait for a reply... */
18955   W (ret);
18956   return ret;
18957 }
18958
18959 static int
18960 api_one_map_register_fallback_threshold (vat_main_t * vam)
18961 {
18962   unformat_input_t *input = vam->input;
18963   vl_api_one_map_register_fallback_threshold_t *mp;
18964   u32 value = 0;
18965   u8 is_set = 0;
18966   int ret;
18967
18968   /* Parse args required to build the message */
18969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18970     {
18971       if (unformat (input, "%u", &value))
18972         is_set = 1;
18973       else
18974         {
18975           clib_warning ("parse error '%U'", format_unformat_error, input);
18976           return -99;
18977         }
18978     }
18979
18980   if (!is_set)
18981     {
18982       errmsg ("fallback threshold value is missing!");
18983       return -99;
18984     }
18985
18986   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18987   mp->value = clib_host_to_net_u32 (value);
18988
18989   /* send it... */
18990   S (mp);
18991
18992   /* Wait for a reply... */
18993   W (ret);
18994   return ret;
18995 }
18996
18997 static int
18998 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18999 {
19000   vl_api_show_one_map_register_fallback_threshold_t *mp;
19001   int ret;
19002
19003   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19004
19005   /* send it... */
19006   S (mp);
19007
19008   /* Wait for a reply... */
19009   W (ret);
19010   return ret;
19011 }
19012
19013 uword
19014 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19015 {
19016   u32 *proto = va_arg (*args, u32 *);
19017
19018   if (unformat (input, "udp"))
19019     *proto = 1;
19020   else if (unformat (input, "api"))
19021     *proto = 2;
19022   else
19023     return 0;
19024
19025   return 1;
19026 }
19027
19028 static int
19029 api_one_set_transport_protocol (vat_main_t * vam)
19030 {
19031   unformat_input_t *input = vam->input;
19032   vl_api_one_set_transport_protocol_t *mp;
19033   u8 is_set = 0;
19034   u32 protocol = 0;
19035   int ret;
19036
19037   /* Parse args required to build the message */
19038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19039     {
19040       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19041         is_set = 1;
19042       else
19043         {
19044           clib_warning ("parse error '%U'", format_unformat_error, input);
19045           return -99;
19046         }
19047     }
19048
19049   if (!is_set)
19050     {
19051       errmsg ("Transport protocol missing!");
19052       return -99;
19053     }
19054
19055   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19056   mp->protocol = (u8) protocol;
19057
19058   /* send it... */
19059   S (mp);
19060
19061   /* Wait for a reply... */
19062   W (ret);
19063   return ret;
19064 }
19065
19066 static int
19067 api_one_get_transport_protocol (vat_main_t * vam)
19068 {
19069   vl_api_one_get_transport_protocol_t *mp;
19070   int ret;
19071
19072   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19073
19074   /* send it... */
19075   S (mp);
19076
19077   /* Wait for a reply... */
19078   W (ret);
19079   return ret;
19080 }
19081
19082 static int
19083 api_one_map_register_set_ttl (vat_main_t * vam)
19084 {
19085   unformat_input_t *input = vam->input;
19086   vl_api_one_map_register_set_ttl_t *mp;
19087   u32 ttl = 0;
19088   u8 is_set = 0;
19089   int ret;
19090
19091   /* Parse args required to build the message */
19092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19093     {
19094       if (unformat (input, "%u", &ttl))
19095         is_set = 1;
19096       else
19097         {
19098           clib_warning ("parse error '%U'", format_unformat_error, input);
19099           return -99;
19100         }
19101     }
19102
19103   if (!is_set)
19104     {
19105       errmsg ("TTL value missing!");
19106       return -99;
19107     }
19108
19109   M (ONE_MAP_REGISTER_SET_TTL, mp);
19110   mp->ttl = clib_host_to_net_u32 (ttl);
19111
19112   /* send it... */
19113   S (mp);
19114
19115   /* Wait for a reply... */
19116   W (ret);
19117   return ret;
19118 }
19119
19120 static int
19121 api_show_one_map_register_ttl (vat_main_t * vam)
19122 {
19123   vl_api_show_one_map_register_ttl_t *mp;
19124   int ret;
19125
19126   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19127
19128   /* send it... */
19129   S (mp);
19130
19131   /* Wait for a reply... */
19132   W (ret);
19133   return ret;
19134 }
19135
19136 /**
19137  * Add/del map request itr rlocs from ONE control plane and updates
19138  *
19139  * @param vam vpp API test context
19140  * @return return code
19141  */
19142 static int
19143 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19144 {
19145   unformat_input_t *input = vam->input;
19146   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19147   u8 *locator_set_name = 0;
19148   u8 locator_set_name_set = 0;
19149   u8 is_add = 1;
19150   int ret;
19151
19152   /* Parse args required to build the message */
19153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19154     {
19155       if (unformat (input, "del"))
19156         {
19157           is_add = 0;
19158         }
19159       else if (unformat (input, "%_%v%_", &locator_set_name))
19160         {
19161           locator_set_name_set = 1;
19162         }
19163       else
19164         {
19165           clib_warning ("parse error '%U'", format_unformat_error, input);
19166           return -99;
19167         }
19168     }
19169
19170   if (is_add && !locator_set_name_set)
19171     {
19172       errmsg ("itr-rloc is not set!");
19173       return -99;
19174     }
19175
19176   if (is_add && vec_len (locator_set_name) > 64)
19177     {
19178       errmsg ("itr-rloc locator-set name too long");
19179       vec_free (locator_set_name);
19180       return -99;
19181     }
19182
19183   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19184   mp->is_add = is_add;
19185   if (is_add)
19186     {
19187       clib_memcpy (mp->locator_set_name, locator_set_name,
19188                    vec_len (locator_set_name));
19189     }
19190   else
19191     {
19192       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19193     }
19194   vec_free (locator_set_name);
19195
19196   /* send it... */
19197   S (mp);
19198
19199   /* Wait for a reply... */
19200   W (ret);
19201   return ret;
19202 }
19203
19204 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19205
19206 static int
19207 api_one_locator_dump (vat_main_t * vam)
19208 {
19209   unformat_input_t *input = vam->input;
19210   vl_api_one_locator_dump_t *mp;
19211   vl_api_control_ping_t *mp_ping;
19212   u8 is_index_set = 0, is_name_set = 0;
19213   u8 *ls_name = 0;
19214   u32 ls_index = ~0;
19215   int ret;
19216
19217   /* Parse args required to build the message */
19218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19219     {
19220       if (unformat (input, "ls_name %_%v%_", &ls_name))
19221         {
19222           is_name_set = 1;
19223         }
19224       else if (unformat (input, "ls_index %d", &ls_index))
19225         {
19226           is_index_set = 1;
19227         }
19228       else
19229         {
19230           errmsg ("parse error '%U'", format_unformat_error, input);
19231           return -99;
19232         }
19233     }
19234
19235   if (!is_index_set && !is_name_set)
19236     {
19237       errmsg ("error: expected one of index or name!");
19238       return -99;
19239     }
19240
19241   if (is_index_set && is_name_set)
19242     {
19243       errmsg ("error: only one param expected!");
19244       return -99;
19245     }
19246
19247   if (vec_len (ls_name) > 62)
19248     {
19249       errmsg ("error: locator set name too long!");
19250       return -99;
19251     }
19252
19253   if (!vam->json_output)
19254     {
19255       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19256     }
19257
19258   M (ONE_LOCATOR_DUMP, mp);
19259   mp->is_index_set = is_index_set;
19260
19261   if (is_index_set)
19262     mp->ls_index = clib_host_to_net_u32 (ls_index);
19263   else
19264     {
19265       vec_add1 (ls_name, 0);
19266       strncpy ((char *) mp->ls_name, (char *) ls_name,
19267                sizeof (mp->ls_name) - 1);
19268     }
19269
19270   /* send it... */
19271   S (mp);
19272
19273   /* Use a control ping for synchronization */
19274   MPING (CONTROL_PING, mp_ping);
19275   S (mp_ping);
19276
19277   /* Wait for a reply... */
19278   W (ret);
19279   return ret;
19280 }
19281
19282 #define api_lisp_locator_dump api_one_locator_dump
19283
19284 static int
19285 api_one_locator_set_dump (vat_main_t * vam)
19286 {
19287   vl_api_one_locator_set_dump_t *mp;
19288   vl_api_control_ping_t *mp_ping;
19289   unformat_input_t *input = vam->input;
19290   u8 filter = 0;
19291   int ret;
19292
19293   /* Parse args required to build the message */
19294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19295     {
19296       if (unformat (input, "local"))
19297         {
19298           filter = 1;
19299         }
19300       else if (unformat (input, "remote"))
19301         {
19302           filter = 2;
19303         }
19304       else
19305         {
19306           errmsg ("parse error '%U'", format_unformat_error, input);
19307           return -99;
19308         }
19309     }
19310
19311   if (!vam->json_output)
19312     {
19313       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19314     }
19315
19316   M (ONE_LOCATOR_SET_DUMP, mp);
19317
19318   mp->filter = filter;
19319
19320   /* send it... */
19321   S (mp);
19322
19323   /* Use a control ping for synchronization */
19324   MPING (CONTROL_PING, mp_ping);
19325   S (mp_ping);
19326
19327   /* Wait for a reply... */
19328   W (ret);
19329   return ret;
19330 }
19331
19332 #define api_lisp_locator_set_dump api_one_locator_set_dump
19333
19334 static int
19335 api_one_eid_table_map_dump (vat_main_t * vam)
19336 {
19337   u8 is_l2 = 0;
19338   u8 mode_set = 0;
19339   unformat_input_t *input = vam->input;
19340   vl_api_one_eid_table_map_dump_t *mp;
19341   vl_api_control_ping_t *mp_ping;
19342   int ret;
19343
19344   /* Parse args required to build the message */
19345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19346     {
19347       if (unformat (input, "l2"))
19348         {
19349           is_l2 = 1;
19350           mode_set = 1;
19351         }
19352       else if (unformat (input, "l3"))
19353         {
19354           is_l2 = 0;
19355           mode_set = 1;
19356         }
19357       else
19358         {
19359           errmsg ("parse error '%U'", format_unformat_error, input);
19360           return -99;
19361         }
19362     }
19363
19364   if (!mode_set)
19365     {
19366       errmsg ("expected one of 'l2' or 'l3' parameter!");
19367       return -99;
19368     }
19369
19370   if (!vam->json_output)
19371     {
19372       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19373     }
19374
19375   M (ONE_EID_TABLE_MAP_DUMP, mp);
19376   mp->is_l2 = is_l2;
19377
19378   /* send it... */
19379   S (mp);
19380
19381   /* Use a control ping for synchronization */
19382   MPING (CONTROL_PING, mp_ping);
19383   S (mp_ping);
19384
19385   /* Wait for a reply... */
19386   W (ret);
19387   return ret;
19388 }
19389
19390 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19391
19392 static int
19393 api_one_eid_table_vni_dump (vat_main_t * vam)
19394 {
19395   vl_api_one_eid_table_vni_dump_t *mp;
19396   vl_api_control_ping_t *mp_ping;
19397   int ret;
19398
19399   if (!vam->json_output)
19400     {
19401       print (vam->ofp, "VNI");
19402     }
19403
19404   M (ONE_EID_TABLE_VNI_DUMP, mp);
19405
19406   /* send it... */
19407   S (mp);
19408
19409   /* Use a control ping for synchronization */
19410   MPING (CONTROL_PING, mp_ping);
19411   S (mp_ping);
19412
19413   /* Wait for a reply... */
19414   W (ret);
19415   return ret;
19416 }
19417
19418 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19419
19420 static int
19421 api_one_eid_table_dump (vat_main_t * vam)
19422 {
19423   unformat_input_t *i = vam->input;
19424   vl_api_one_eid_table_dump_t *mp;
19425   vl_api_control_ping_t *mp_ping;
19426   struct in_addr ip4;
19427   struct in6_addr ip6;
19428   u8 mac[6];
19429   u8 eid_type = ~0, eid_set = 0;
19430   u32 prefix_length = ~0, t, vni = 0;
19431   u8 filter = 0;
19432   int ret;
19433   lisp_nsh_api_t nsh;
19434
19435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19436     {
19437       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19438         {
19439           eid_set = 1;
19440           eid_type = 0;
19441           prefix_length = t;
19442         }
19443       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19444         {
19445           eid_set = 1;
19446           eid_type = 1;
19447           prefix_length = t;
19448         }
19449       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19450         {
19451           eid_set = 1;
19452           eid_type = 2;
19453         }
19454       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19455         {
19456           eid_set = 1;
19457           eid_type = 3;
19458         }
19459       else if (unformat (i, "vni %d", &t))
19460         {
19461           vni = t;
19462         }
19463       else if (unformat (i, "local"))
19464         {
19465           filter = 1;
19466         }
19467       else if (unformat (i, "remote"))
19468         {
19469           filter = 2;
19470         }
19471       else
19472         {
19473           errmsg ("parse error '%U'", format_unformat_error, i);
19474           return -99;
19475         }
19476     }
19477
19478   if (!vam->json_output)
19479     {
19480       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19481              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19482     }
19483
19484   M (ONE_EID_TABLE_DUMP, mp);
19485
19486   mp->filter = filter;
19487   if (eid_set)
19488     {
19489       mp->eid_set = 1;
19490       mp->vni = htonl (vni);
19491       mp->eid_type = eid_type;
19492       switch (eid_type)
19493         {
19494         case 0:
19495           mp->prefix_length = prefix_length;
19496           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19497           break;
19498         case 1:
19499           mp->prefix_length = prefix_length;
19500           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19501           break;
19502         case 2:
19503           clib_memcpy (mp->eid, mac, sizeof (mac));
19504           break;
19505         case 3:
19506           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19507           break;
19508         default:
19509           errmsg ("unknown EID type %d!", eid_type);
19510           return -99;
19511         }
19512     }
19513
19514   /* send it... */
19515   S (mp);
19516
19517   /* Use a control ping for synchronization */
19518   MPING (CONTROL_PING, mp_ping);
19519   S (mp_ping);
19520
19521   /* Wait for a reply... */
19522   W (ret);
19523   return ret;
19524 }
19525
19526 #define api_lisp_eid_table_dump api_one_eid_table_dump
19527
19528 static int
19529 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19530 {
19531   unformat_input_t *i = vam->input;
19532   vl_api_gpe_fwd_entries_get_t *mp;
19533   u8 vni_set = 0;
19534   u32 vni = ~0;
19535   int ret;
19536
19537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19538     {
19539       if (unformat (i, "vni %d", &vni))
19540         {
19541           vni_set = 1;
19542         }
19543       else
19544         {
19545           errmsg ("parse error '%U'", format_unformat_error, i);
19546           return -99;
19547         }
19548     }
19549
19550   if (!vni_set)
19551     {
19552       errmsg ("vni not set!");
19553       return -99;
19554     }
19555
19556   if (!vam->json_output)
19557     {
19558       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19559              "leid", "reid");
19560     }
19561
19562   M (GPE_FWD_ENTRIES_GET, mp);
19563   mp->vni = clib_host_to_net_u32 (vni);
19564
19565   /* send it... */
19566   S (mp);
19567
19568   /* Wait for a reply... */
19569   W (ret);
19570   return ret;
19571 }
19572
19573 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19574 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19575 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19576 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19577 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19578 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19579 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19580 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19581
19582 static int
19583 api_one_adjacencies_get (vat_main_t * vam)
19584 {
19585   unformat_input_t *i = vam->input;
19586   vl_api_one_adjacencies_get_t *mp;
19587   u8 vni_set = 0;
19588   u32 vni = ~0;
19589   int ret;
19590
19591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19592     {
19593       if (unformat (i, "vni %d", &vni))
19594         {
19595           vni_set = 1;
19596         }
19597       else
19598         {
19599           errmsg ("parse error '%U'", format_unformat_error, i);
19600           return -99;
19601         }
19602     }
19603
19604   if (!vni_set)
19605     {
19606       errmsg ("vni not set!");
19607       return -99;
19608     }
19609
19610   if (!vam->json_output)
19611     {
19612       print (vam->ofp, "%s %40s", "leid", "reid");
19613     }
19614
19615   M (ONE_ADJACENCIES_GET, mp);
19616   mp->vni = clib_host_to_net_u32 (vni);
19617
19618   /* send it... */
19619   S (mp);
19620
19621   /* Wait for a reply... */
19622   W (ret);
19623   return ret;
19624 }
19625
19626 #define api_lisp_adjacencies_get api_one_adjacencies_get
19627
19628 static int
19629 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19630 {
19631   unformat_input_t *i = vam->input;
19632   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19633   int ret;
19634   u8 ip_family_set = 0, is_ip4 = 1;
19635
19636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19637     {
19638       if (unformat (i, "ip4"))
19639         {
19640           ip_family_set = 1;
19641           is_ip4 = 1;
19642         }
19643       else if (unformat (i, "ip6"))
19644         {
19645           ip_family_set = 1;
19646           is_ip4 = 0;
19647         }
19648       else
19649         {
19650           errmsg ("parse error '%U'", format_unformat_error, i);
19651           return -99;
19652         }
19653     }
19654
19655   if (!ip_family_set)
19656     {
19657       errmsg ("ip family not set!");
19658       return -99;
19659     }
19660
19661   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19662   mp->is_ip4 = is_ip4;
19663
19664   /* send it... */
19665   S (mp);
19666
19667   /* Wait for a reply... */
19668   W (ret);
19669   return ret;
19670 }
19671
19672 static int
19673 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19674 {
19675   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19676   int ret;
19677
19678   if (!vam->json_output)
19679     {
19680       print (vam->ofp, "VNIs");
19681     }
19682
19683   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19684
19685   /* send it... */
19686   S (mp);
19687
19688   /* Wait for a reply... */
19689   W (ret);
19690   return ret;
19691 }
19692
19693 static int
19694 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19695 {
19696   unformat_input_t *i = vam->input;
19697   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19698   int ret = 0;
19699   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19700   struct in_addr ip4;
19701   struct in6_addr ip6;
19702   u32 table_id = 0, nh_sw_if_index = ~0;
19703
19704   memset (&ip4, 0, sizeof (ip4));
19705   memset (&ip6, 0, sizeof (ip6));
19706
19707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19708     {
19709       if (unformat (i, "del"))
19710         is_add = 0;
19711       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19712                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19713         {
19714           ip_set = 1;
19715           is_ip4 = 1;
19716         }
19717       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19718                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19719         {
19720           ip_set = 1;
19721           is_ip4 = 0;
19722         }
19723       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19724         {
19725           ip_set = 1;
19726           is_ip4 = 1;
19727           nh_sw_if_index = ~0;
19728         }
19729       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19730         {
19731           ip_set = 1;
19732           is_ip4 = 0;
19733           nh_sw_if_index = ~0;
19734         }
19735       else if (unformat (i, "table %d", &table_id))
19736         ;
19737       else
19738         {
19739           errmsg ("parse error '%U'", format_unformat_error, i);
19740           return -99;
19741         }
19742     }
19743
19744   if (!ip_set)
19745     {
19746       errmsg ("nh addr not set!");
19747       return -99;
19748     }
19749
19750   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19751   mp->is_add = is_add;
19752   mp->table_id = clib_host_to_net_u32 (table_id);
19753   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19754   mp->is_ip4 = is_ip4;
19755   if (is_ip4)
19756     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19757   else
19758     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19759
19760   /* send it... */
19761   S (mp);
19762
19763   /* Wait for a reply... */
19764   W (ret);
19765   return ret;
19766 }
19767
19768 static int
19769 api_one_map_server_dump (vat_main_t * vam)
19770 {
19771   vl_api_one_map_server_dump_t *mp;
19772   vl_api_control_ping_t *mp_ping;
19773   int ret;
19774
19775   if (!vam->json_output)
19776     {
19777       print (vam->ofp, "%=20s", "Map server");
19778     }
19779
19780   M (ONE_MAP_SERVER_DUMP, mp);
19781   /* send it... */
19782   S (mp);
19783
19784   /* Use a control ping for synchronization */
19785   MPING (CONTROL_PING, mp_ping);
19786   S (mp_ping);
19787
19788   /* Wait for a reply... */
19789   W (ret);
19790   return ret;
19791 }
19792
19793 #define api_lisp_map_server_dump api_one_map_server_dump
19794
19795 static int
19796 api_one_map_resolver_dump (vat_main_t * vam)
19797 {
19798   vl_api_one_map_resolver_dump_t *mp;
19799   vl_api_control_ping_t *mp_ping;
19800   int ret;
19801
19802   if (!vam->json_output)
19803     {
19804       print (vam->ofp, "%=20s", "Map resolver");
19805     }
19806
19807   M (ONE_MAP_RESOLVER_DUMP, mp);
19808   /* send it... */
19809   S (mp);
19810
19811   /* Use a control ping for synchronization */
19812   MPING (CONTROL_PING, mp_ping);
19813   S (mp_ping);
19814
19815   /* Wait for a reply... */
19816   W (ret);
19817   return ret;
19818 }
19819
19820 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19821
19822 static int
19823 api_one_stats_flush (vat_main_t * vam)
19824 {
19825   vl_api_one_stats_flush_t *mp;
19826   int ret = 0;
19827
19828   M (ONE_STATS_FLUSH, mp);
19829   S (mp);
19830   W (ret);
19831   return ret;
19832 }
19833
19834 static int
19835 api_one_stats_dump (vat_main_t * vam)
19836 {
19837   vl_api_one_stats_dump_t *mp;
19838   vl_api_control_ping_t *mp_ping;
19839   int ret;
19840
19841   M (ONE_STATS_DUMP, mp);
19842   /* send it... */
19843   S (mp);
19844
19845   /* Use a control ping for synchronization */
19846   MPING (CONTROL_PING, mp_ping);
19847   S (mp_ping);
19848
19849   /* Wait for a reply... */
19850   W (ret);
19851   return ret;
19852 }
19853
19854 static int
19855 api_show_one_status (vat_main_t * vam)
19856 {
19857   vl_api_show_one_status_t *mp;
19858   int ret;
19859
19860   if (!vam->json_output)
19861     {
19862       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19863     }
19864
19865   M (SHOW_ONE_STATUS, mp);
19866   /* send it... */
19867   S (mp);
19868   /* Wait for a reply... */
19869   W (ret);
19870   return ret;
19871 }
19872
19873 #define api_show_lisp_status api_show_one_status
19874
19875 static int
19876 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19877 {
19878   vl_api_gpe_fwd_entry_path_dump_t *mp;
19879   vl_api_control_ping_t *mp_ping;
19880   unformat_input_t *i = vam->input;
19881   u32 fwd_entry_index = ~0;
19882   int ret;
19883
19884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19885     {
19886       if (unformat (i, "index %d", &fwd_entry_index))
19887         ;
19888       else
19889         break;
19890     }
19891
19892   if (~0 == fwd_entry_index)
19893     {
19894       errmsg ("no index specified!");
19895       return -99;
19896     }
19897
19898   if (!vam->json_output)
19899     {
19900       print (vam->ofp, "first line");
19901     }
19902
19903   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19904
19905   /* send it... */
19906   S (mp);
19907   /* Use a control ping for synchronization */
19908   MPING (CONTROL_PING, mp_ping);
19909   S (mp_ping);
19910
19911   /* Wait for a reply... */
19912   W (ret);
19913   return ret;
19914 }
19915
19916 static int
19917 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19918 {
19919   vl_api_one_get_map_request_itr_rlocs_t *mp;
19920   int ret;
19921
19922   if (!vam->json_output)
19923     {
19924       print (vam->ofp, "%=20s", "itr-rlocs:");
19925     }
19926
19927   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19928   /* send it... */
19929   S (mp);
19930   /* Wait for a reply... */
19931   W (ret);
19932   return ret;
19933 }
19934
19935 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19936
19937 static int
19938 api_af_packet_create (vat_main_t * vam)
19939 {
19940   unformat_input_t *i = vam->input;
19941   vl_api_af_packet_create_t *mp;
19942   u8 *host_if_name = 0;
19943   u8 hw_addr[6];
19944   u8 random_hw_addr = 1;
19945   int ret;
19946
19947   memset (hw_addr, 0, sizeof (hw_addr));
19948
19949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19950     {
19951       if (unformat (i, "name %s", &host_if_name))
19952         vec_add1 (host_if_name, 0);
19953       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19954         random_hw_addr = 0;
19955       else
19956         break;
19957     }
19958
19959   if (!vec_len (host_if_name))
19960     {
19961       errmsg ("host-interface name must be specified");
19962       return -99;
19963     }
19964
19965   if (vec_len (host_if_name) > 64)
19966     {
19967       errmsg ("host-interface name too long");
19968       return -99;
19969     }
19970
19971   M (AF_PACKET_CREATE, mp);
19972
19973   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19974   clib_memcpy (mp->hw_addr, hw_addr, 6);
19975   mp->use_random_hw_addr = random_hw_addr;
19976   vec_free (host_if_name);
19977
19978   S (mp);
19979
19980   /* *INDENT-OFF* */
19981   W2 (ret,
19982       ({
19983         if (ret == 0)
19984           fprintf (vam->ofp ? vam->ofp : stderr,
19985                    " new sw_if_index = %d\n", vam->sw_if_index);
19986       }));
19987   /* *INDENT-ON* */
19988   return ret;
19989 }
19990
19991 static int
19992 api_af_packet_delete (vat_main_t * vam)
19993 {
19994   unformat_input_t *i = vam->input;
19995   vl_api_af_packet_delete_t *mp;
19996   u8 *host_if_name = 0;
19997   int ret;
19998
19999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20000     {
20001       if (unformat (i, "name %s", &host_if_name))
20002         vec_add1 (host_if_name, 0);
20003       else
20004         break;
20005     }
20006
20007   if (!vec_len (host_if_name))
20008     {
20009       errmsg ("host-interface name must be specified");
20010       return -99;
20011     }
20012
20013   if (vec_len (host_if_name) > 64)
20014     {
20015       errmsg ("host-interface name too long");
20016       return -99;
20017     }
20018
20019   M (AF_PACKET_DELETE, mp);
20020
20021   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20022   vec_free (host_if_name);
20023
20024   S (mp);
20025   W (ret);
20026   return ret;
20027 }
20028
20029 static void vl_api_af_packet_details_t_handler
20030   (vl_api_af_packet_details_t * mp)
20031 {
20032   vat_main_t *vam = &vat_main;
20033
20034   print (vam->ofp, "%-16s %d",
20035          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20036 }
20037
20038 static void vl_api_af_packet_details_t_handler_json
20039   (vl_api_af_packet_details_t * mp)
20040 {
20041   vat_main_t *vam = &vat_main;
20042   vat_json_node_t *node = NULL;
20043
20044   if (VAT_JSON_ARRAY != vam->json_tree.type)
20045     {
20046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20047       vat_json_init_array (&vam->json_tree);
20048     }
20049   node = vat_json_array_add (&vam->json_tree);
20050
20051   vat_json_init_object (node);
20052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20053   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20054 }
20055
20056 static int
20057 api_af_packet_dump (vat_main_t * vam)
20058 {
20059   vl_api_af_packet_dump_t *mp;
20060   vl_api_control_ping_t *mp_ping;
20061   int ret;
20062
20063   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20064   /* Get list of tap interfaces */
20065   M (AF_PACKET_DUMP, mp);
20066   S (mp);
20067
20068   /* Use a control ping for synchronization */
20069   MPING (CONTROL_PING, mp_ping);
20070   S (mp_ping);
20071
20072   W (ret);
20073   return ret;
20074 }
20075
20076 static int
20077 api_policer_add_del (vat_main_t * vam)
20078 {
20079   unformat_input_t *i = vam->input;
20080   vl_api_policer_add_del_t *mp;
20081   u8 is_add = 1;
20082   u8 *name = 0;
20083   u32 cir = 0;
20084   u32 eir = 0;
20085   u64 cb = 0;
20086   u64 eb = 0;
20087   u8 rate_type = 0;
20088   u8 round_type = 0;
20089   u8 type = 0;
20090   u8 color_aware = 0;
20091   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20092   int ret;
20093
20094   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20095   conform_action.dscp = 0;
20096   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20097   exceed_action.dscp = 0;
20098   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20099   violate_action.dscp = 0;
20100
20101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20102     {
20103       if (unformat (i, "del"))
20104         is_add = 0;
20105       else if (unformat (i, "name %s", &name))
20106         vec_add1 (name, 0);
20107       else if (unformat (i, "cir %u", &cir))
20108         ;
20109       else if (unformat (i, "eir %u", &eir))
20110         ;
20111       else if (unformat (i, "cb %u", &cb))
20112         ;
20113       else if (unformat (i, "eb %u", &eb))
20114         ;
20115       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20116                          &rate_type))
20117         ;
20118       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20119                          &round_type))
20120         ;
20121       else if (unformat (i, "type %U", unformat_policer_type, &type))
20122         ;
20123       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20124                          &conform_action))
20125         ;
20126       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20127                          &exceed_action))
20128         ;
20129       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20130                          &violate_action))
20131         ;
20132       else if (unformat (i, "color-aware"))
20133         color_aware = 1;
20134       else
20135         break;
20136     }
20137
20138   if (!vec_len (name))
20139     {
20140       errmsg ("policer name must be specified");
20141       return -99;
20142     }
20143
20144   if (vec_len (name) > 64)
20145     {
20146       errmsg ("policer name too long");
20147       return -99;
20148     }
20149
20150   M (POLICER_ADD_DEL, mp);
20151
20152   clib_memcpy (mp->name, name, vec_len (name));
20153   vec_free (name);
20154   mp->is_add = is_add;
20155   mp->cir = ntohl (cir);
20156   mp->eir = ntohl (eir);
20157   mp->cb = clib_net_to_host_u64 (cb);
20158   mp->eb = clib_net_to_host_u64 (eb);
20159   mp->rate_type = rate_type;
20160   mp->round_type = round_type;
20161   mp->type = type;
20162   mp->conform_action_type = conform_action.action_type;
20163   mp->conform_dscp = conform_action.dscp;
20164   mp->exceed_action_type = exceed_action.action_type;
20165   mp->exceed_dscp = exceed_action.dscp;
20166   mp->violate_action_type = violate_action.action_type;
20167   mp->violate_dscp = violate_action.dscp;
20168   mp->color_aware = color_aware;
20169
20170   S (mp);
20171   W (ret);
20172   return ret;
20173 }
20174
20175 static int
20176 api_policer_dump (vat_main_t * vam)
20177 {
20178   unformat_input_t *i = vam->input;
20179   vl_api_policer_dump_t *mp;
20180   vl_api_control_ping_t *mp_ping;
20181   u8 *match_name = 0;
20182   u8 match_name_valid = 0;
20183   int ret;
20184
20185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20186     {
20187       if (unformat (i, "name %s", &match_name))
20188         {
20189           vec_add1 (match_name, 0);
20190           match_name_valid = 1;
20191         }
20192       else
20193         break;
20194     }
20195
20196   M (POLICER_DUMP, mp);
20197   mp->match_name_valid = match_name_valid;
20198   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20199   vec_free (match_name);
20200   /* send it... */
20201   S (mp);
20202
20203   /* Use a control ping for synchronization */
20204   MPING (CONTROL_PING, mp_ping);
20205   S (mp_ping);
20206
20207   /* Wait for a reply... */
20208   W (ret);
20209   return ret;
20210 }
20211
20212 static int
20213 api_policer_classify_set_interface (vat_main_t * vam)
20214 {
20215   unformat_input_t *i = vam->input;
20216   vl_api_policer_classify_set_interface_t *mp;
20217   u32 sw_if_index;
20218   int sw_if_index_set;
20219   u32 ip4_table_index = ~0;
20220   u32 ip6_table_index = ~0;
20221   u32 l2_table_index = ~0;
20222   u8 is_add = 1;
20223   int ret;
20224
20225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20226     {
20227       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20228         sw_if_index_set = 1;
20229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20230         sw_if_index_set = 1;
20231       else if (unformat (i, "del"))
20232         is_add = 0;
20233       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20234         ;
20235       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20236         ;
20237       else if (unformat (i, "l2-table %d", &l2_table_index))
20238         ;
20239       else
20240         {
20241           clib_warning ("parse error '%U'", format_unformat_error, i);
20242           return -99;
20243         }
20244     }
20245
20246   if (sw_if_index_set == 0)
20247     {
20248       errmsg ("missing interface name or sw_if_index");
20249       return -99;
20250     }
20251
20252   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20253
20254   mp->sw_if_index = ntohl (sw_if_index);
20255   mp->ip4_table_index = ntohl (ip4_table_index);
20256   mp->ip6_table_index = ntohl (ip6_table_index);
20257   mp->l2_table_index = ntohl (l2_table_index);
20258   mp->is_add = is_add;
20259
20260   S (mp);
20261   W (ret);
20262   return ret;
20263 }
20264
20265 static int
20266 api_policer_classify_dump (vat_main_t * vam)
20267 {
20268   unformat_input_t *i = vam->input;
20269   vl_api_policer_classify_dump_t *mp;
20270   vl_api_control_ping_t *mp_ping;
20271   u8 type = POLICER_CLASSIFY_N_TABLES;
20272   int ret;
20273
20274   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20275     ;
20276   else
20277     {
20278       errmsg ("classify table type must be specified");
20279       return -99;
20280     }
20281
20282   if (!vam->json_output)
20283     {
20284       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20285     }
20286
20287   M (POLICER_CLASSIFY_DUMP, mp);
20288   mp->type = type;
20289   /* send it... */
20290   S (mp);
20291
20292   /* Use a control ping for synchronization */
20293   MPING (CONTROL_PING, mp_ping);
20294   S (mp_ping);
20295
20296   /* Wait for a reply... */
20297   W (ret);
20298   return ret;
20299 }
20300
20301 static int
20302 api_netmap_create (vat_main_t * vam)
20303 {
20304   unformat_input_t *i = vam->input;
20305   vl_api_netmap_create_t *mp;
20306   u8 *if_name = 0;
20307   u8 hw_addr[6];
20308   u8 random_hw_addr = 1;
20309   u8 is_pipe = 0;
20310   u8 is_master = 0;
20311   int ret;
20312
20313   memset (hw_addr, 0, sizeof (hw_addr));
20314
20315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20316     {
20317       if (unformat (i, "name %s", &if_name))
20318         vec_add1 (if_name, 0);
20319       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20320         random_hw_addr = 0;
20321       else if (unformat (i, "pipe"))
20322         is_pipe = 1;
20323       else if (unformat (i, "master"))
20324         is_master = 1;
20325       else if (unformat (i, "slave"))
20326         is_master = 0;
20327       else
20328         break;
20329     }
20330
20331   if (!vec_len (if_name))
20332     {
20333       errmsg ("interface name must be specified");
20334       return -99;
20335     }
20336
20337   if (vec_len (if_name) > 64)
20338     {
20339       errmsg ("interface name too long");
20340       return -99;
20341     }
20342
20343   M (NETMAP_CREATE, mp);
20344
20345   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20346   clib_memcpy (mp->hw_addr, hw_addr, 6);
20347   mp->use_random_hw_addr = random_hw_addr;
20348   mp->is_pipe = is_pipe;
20349   mp->is_master = is_master;
20350   vec_free (if_name);
20351
20352   S (mp);
20353   W (ret);
20354   return ret;
20355 }
20356
20357 static int
20358 api_netmap_delete (vat_main_t * vam)
20359 {
20360   unformat_input_t *i = vam->input;
20361   vl_api_netmap_delete_t *mp;
20362   u8 *if_name = 0;
20363   int ret;
20364
20365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20366     {
20367       if (unformat (i, "name %s", &if_name))
20368         vec_add1 (if_name, 0);
20369       else
20370         break;
20371     }
20372
20373   if (!vec_len (if_name))
20374     {
20375       errmsg ("interface name must be specified");
20376       return -99;
20377     }
20378
20379   if (vec_len (if_name) > 64)
20380     {
20381       errmsg ("interface name too long");
20382       return -99;
20383     }
20384
20385   M (NETMAP_DELETE, mp);
20386
20387   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20388   vec_free (if_name);
20389
20390   S (mp);
20391   W (ret);
20392   return ret;
20393 }
20394
20395 static void
20396 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20397 {
20398   if (fp->afi == IP46_TYPE_IP6)
20399     print (vam->ofp,
20400            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20401            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20402            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20403            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20404            format_ip6_address, fp->next_hop);
20405   else if (fp->afi == IP46_TYPE_IP4)
20406     print (vam->ofp,
20407            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20408            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20409            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20410            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20411            format_ip4_address, fp->next_hop);
20412 }
20413
20414 static void
20415 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20416                                  vl_api_fib_path_t * fp)
20417 {
20418   struct in_addr ip4;
20419   struct in6_addr ip6;
20420
20421   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20422   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20423   vat_json_object_add_uint (node, "is_local", fp->is_local);
20424   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20425   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20426   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20427   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20428   if (fp->afi == IP46_TYPE_IP4)
20429     {
20430       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20431       vat_json_object_add_ip4 (node, "next_hop", ip4);
20432     }
20433   else if (fp->afi == IP46_TYPE_IP6)
20434     {
20435       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20436       vat_json_object_add_ip6 (node, "next_hop", ip6);
20437     }
20438 }
20439
20440 static void
20441 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20442 {
20443   vat_main_t *vam = &vat_main;
20444   int count = ntohl (mp->mt_count);
20445   vl_api_fib_path_t *fp;
20446   i32 i;
20447
20448   print (vam->ofp, "[%d]: sw_if_index %d via:",
20449          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20450   fp = mp->mt_paths;
20451   for (i = 0; i < count; i++)
20452     {
20453       vl_api_mpls_fib_path_print (vam, fp);
20454       fp++;
20455     }
20456
20457   print (vam->ofp, "");
20458 }
20459
20460 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20461 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20462
20463 static void
20464 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20465 {
20466   vat_main_t *vam = &vat_main;
20467   vat_json_node_t *node = NULL;
20468   int count = ntohl (mp->mt_count);
20469   vl_api_fib_path_t *fp;
20470   i32 i;
20471
20472   if (VAT_JSON_ARRAY != vam->json_tree.type)
20473     {
20474       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20475       vat_json_init_array (&vam->json_tree);
20476     }
20477   node = vat_json_array_add (&vam->json_tree);
20478
20479   vat_json_init_object (node);
20480   vat_json_object_add_uint (node, "tunnel_index",
20481                             ntohl (mp->mt_tunnel_index));
20482   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20483
20484   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20485
20486   fp = mp->mt_paths;
20487   for (i = 0; i < count; i++)
20488     {
20489       vl_api_mpls_fib_path_json_print (node, fp);
20490       fp++;
20491     }
20492 }
20493
20494 static int
20495 api_mpls_tunnel_dump (vat_main_t * vam)
20496 {
20497   vl_api_mpls_tunnel_dump_t *mp;
20498   vl_api_control_ping_t *mp_ping;
20499   u32 sw_if_index = ~0;
20500   int ret;
20501
20502   /* Parse args required to build the message */
20503   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20504     {
20505       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20506         ;
20507     }
20508
20509   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20510
20511   M (MPLS_TUNNEL_DUMP, mp);
20512   mp->sw_if_index = htonl (sw_if_index);
20513   S (mp);
20514
20515   /* Use a control ping for synchronization */
20516   MPING (CONTROL_PING, mp_ping);
20517   S (mp_ping);
20518
20519   W (ret);
20520   return ret;
20521 }
20522
20523 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20524 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20525
20526
20527 static void
20528 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20529 {
20530   vat_main_t *vam = &vat_main;
20531   int count = ntohl (mp->count);
20532   vl_api_fib_path_t *fp;
20533   int i;
20534
20535   print (vam->ofp,
20536          "table-id %d, label %u, ess_bit %u",
20537          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20538   fp = mp->path;
20539   for (i = 0; i < count; i++)
20540     {
20541       vl_api_mpls_fib_path_print (vam, fp);
20542       fp++;
20543     }
20544 }
20545
20546 static void vl_api_mpls_fib_details_t_handler_json
20547   (vl_api_mpls_fib_details_t * mp)
20548 {
20549   vat_main_t *vam = &vat_main;
20550   int count = ntohl (mp->count);
20551   vat_json_node_t *node = NULL;
20552   vl_api_fib_path_t *fp;
20553   int i;
20554
20555   if (VAT_JSON_ARRAY != vam->json_tree.type)
20556     {
20557       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20558       vat_json_init_array (&vam->json_tree);
20559     }
20560   node = vat_json_array_add (&vam->json_tree);
20561
20562   vat_json_init_object (node);
20563   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20564   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20565   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20566   vat_json_object_add_uint (node, "path_count", count);
20567   fp = mp->path;
20568   for (i = 0; i < count; i++)
20569     {
20570       vl_api_mpls_fib_path_json_print (node, fp);
20571       fp++;
20572     }
20573 }
20574
20575 static int
20576 api_mpls_fib_dump (vat_main_t * vam)
20577 {
20578   vl_api_mpls_fib_dump_t *mp;
20579   vl_api_control_ping_t *mp_ping;
20580   int ret;
20581
20582   M (MPLS_FIB_DUMP, mp);
20583   S (mp);
20584
20585   /* Use a control ping for synchronization */
20586   MPING (CONTROL_PING, mp_ping);
20587   S (mp_ping);
20588
20589   W (ret);
20590   return ret;
20591 }
20592
20593 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20594 #define vl_api_ip_fib_details_t_print vl_noop_handler
20595
20596 static void
20597 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20598 {
20599   vat_main_t *vam = &vat_main;
20600   int count = ntohl (mp->count);
20601   vl_api_fib_path_t *fp;
20602   int i;
20603
20604   print (vam->ofp,
20605          "table-id %d, prefix %U/%d stats-index %d",
20606          ntohl (mp->table_id), format_ip4_address, mp->address,
20607          mp->address_length, ntohl (mp->stats_index));
20608   fp = mp->path;
20609   for (i = 0; i < count; i++)
20610     {
20611       if (fp->afi == IP46_TYPE_IP6)
20612         print (vam->ofp,
20613                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20614                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20615                "next_hop_table %d",
20616                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20617                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20618                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20619       else if (fp->afi == IP46_TYPE_IP4)
20620         print (vam->ofp,
20621                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20622                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20623                "next_hop_table %d",
20624                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20625                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20626                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20627       fp++;
20628     }
20629 }
20630
20631 static void vl_api_ip_fib_details_t_handler_json
20632   (vl_api_ip_fib_details_t * mp)
20633 {
20634   vat_main_t *vam = &vat_main;
20635   int count = ntohl (mp->count);
20636   vat_json_node_t *node = NULL;
20637   struct in_addr ip4;
20638   struct in6_addr ip6;
20639   vl_api_fib_path_t *fp;
20640   int i;
20641
20642   if (VAT_JSON_ARRAY != vam->json_tree.type)
20643     {
20644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20645       vat_json_init_array (&vam->json_tree);
20646     }
20647   node = vat_json_array_add (&vam->json_tree);
20648
20649   vat_json_init_object (node);
20650   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20651   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20652   vat_json_object_add_ip4 (node, "prefix", ip4);
20653   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20654   vat_json_object_add_uint (node, "path_count", count);
20655   fp = mp->path;
20656   for (i = 0; i < count; i++)
20657     {
20658       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20659       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20660       vat_json_object_add_uint (node, "is_local", fp->is_local);
20661       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20662       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20663       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20664       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20665       if (fp->afi == IP46_TYPE_IP4)
20666         {
20667           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20668           vat_json_object_add_ip4 (node, "next_hop", ip4);
20669         }
20670       else if (fp->afi == IP46_TYPE_IP6)
20671         {
20672           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20673           vat_json_object_add_ip6 (node, "next_hop", ip6);
20674         }
20675     }
20676 }
20677
20678 static int
20679 api_ip_fib_dump (vat_main_t * vam)
20680 {
20681   vl_api_ip_fib_dump_t *mp;
20682   vl_api_control_ping_t *mp_ping;
20683   int ret;
20684
20685   M (IP_FIB_DUMP, mp);
20686   S (mp);
20687
20688   /* Use a control ping for synchronization */
20689   MPING (CONTROL_PING, mp_ping);
20690   S (mp_ping);
20691
20692   W (ret);
20693   return ret;
20694 }
20695
20696 static int
20697 api_ip_mfib_dump (vat_main_t * vam)
20698 {
20699   vl_api_ip_mfib_dump_t *mp;
20700   vl_api_control_ping_t *mp_ping;
20701   int ret;
20702
20703   M (IP_MFIB_DUMP, mp);
20704   S (mp);
20705
20706   /* Use a control ping for synchronization */
20707   MPING (CONTROL_PING, mp_ping);
20708   S (mp_ping);
20709
20710   W (ret);
20711   return ret;
20712 }
20713
20714 static void vl_api_ip_neighbor_details_t_handler
20715   (vl_api_ip_neighbor_details_t * mp)
20716 {
20717   vat_main_t *vam = &vat_main;
20718
20719   print (vam->ofp, "%c %U %U",
20720          (mp->is_static) ? 'S' : 'D',
20721          format_ethernet_address, &mp->mac_address,
20722          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20723          &mp->ip_address);
20724 }
20725
20726 static void vl_api_ip_neighbor_details_t_handler_json
20727   (vl_api_ip_neighbor_details_t * mp)
20728 {
20729
20730   vat_main_t *vam = &vat_main;
20731   vat_json_node_t *node;
20732   struct in_addr ip4;
20733   struct in6_addr ip6;
20734
20735   if (VAT_JSON_ARRAY != vam->json_tree.type)
20736     {
20737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20738       vat_json_init_array (&vam->json_tree);
20739     }
20740   node = vat_json_array_add (&vam->json_tree);
20741
20742   vat_json_init_object (node);
20743   vat_json_object_add_string_copy (node, "flag",
20744                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20745                                    "dynamic");
20746
20747   vat_json_object_add_string_copy (node, "link_layer",
20748                                    format (0, "%U", format_ethernet_address,
20749                                            &mp->mac_address));
20750
20751   if (mp->is_ipv6)
20752     {
20753       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20754       vat_json_object_add_ip6 (node, "ip_address", ip6);
20755     }
20756   else
20757     {
20758       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20759       vat_json_object_add_ip4 (node, "ip_address", ip4);
20760     }
20761 }
20762
20763 static int
20764 api_ip_neighbor_dump (vat_main_t * vam)
20765 {
20766   unformat_input_t *i = vam->input;
20767   vl_api_ip_neighbor_dump_t *mp;
20768   vl_api_control_ping_t *mp_ping;
20769   u8 is_ipv6 = 0;
20770   u32 sw_if_index = ~0;
20771   int ret;
20772
20773   /* Parse args required to build the message */
20774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20775     {
20776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20777         ;
20778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20779         ;
20780       else if (unformat (i, "ip6"))
20781         is_ipv6 = 1;
20782       else
20783         break;
20784     }
20785
20786   if (sw_if_index == ~0)
20787     {
20788       errmsg ("missing interface name or sw_if_index");
20789       return -99;
20790     }
20791
20792   M (IP_NEIGHBOR_DUMP, mp);
20793   mp->is_ipv6 = (u8) is_ipv6;
20794   mp->sw_if_index = ntohl (sw_if_index);
20795   S (mp);
20796
20797   /* Use a control ping for synchronization */
20798   MPING (CONTROL_PING, mp_ping);
20799   S (mp_ping);
20800
20801   W (ret);
20802   return ret;
20803 }
20804
20805 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20806 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20807
20808 static void
20809 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20810 {
20811   vat_main_t *vam = &vat_main;
20812   int count = ntohl (mp->count);
20813   vl_api_fib_path_t *fp;
20814   int i;
20815
20816   print (vam->ofp,
20817          "table-id %d, prefix %U/%d stats-index %d",
20818          ntohl (mp->table_id), format_ip6_address, mp->address,
20819          mp->address_length, ntohl (mp->stats_index));
20820   fp = mp->path;
20821   for (i = 0; i < count; i++)
20822     {
20823       if (fp->afi == IP46_TYPE_IP6)
20824         print (vam->ofp,
20825                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20826                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20827                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20828                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20829                format_ip6_address, fp->next_hop);
20830       else if (fp->afi == IP46_TYPE_IP4)
20831         print (vam->ofp,
20832                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20833                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20834                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20835                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20836                format_ip4_address, fp->next_hop);
20837       fp++;
20838     }
20839 }
20840
20841 static void vl_api_ip6_fib_details_t_handler_json
20842   (vl_api_ip6_fib_details_t * mp)
20843 {
20844   vat_main_t *vam = &vat_main;
20845   int count = ntohl (mp->count);
20846   vat_json_node_t *node = NULL;
20847   struct in_addr ip4;
20848   struct in6_addr ip6;
20849   vl_api_fib_path_t *fp;
20850   int i;
20851
20852   if (VAT_JSON_ARRAY != vam->json_tree.type)
20853     {
20854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20855       vat_json_init_array (&vam->json_tree);
20856     }
20857   node = vat_json_array_add (&vam->json_tree);
20858
20859   vat_json_init_object (node);
20860   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20861   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20862   vat_json_object_add_ip6 (node, "prefix", ip6);
20863   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20864   vat_json_object_add_uint (node, "path_count", count);
20865   fp = mp->path;
20866   for (i = 0; i < count; i++)
20867     {
20868       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20869       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20870       vat_json_object_add_uint (node, "is_local", fp->is_local);
20871       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20872       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20873       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20874       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20875       if (fp->afi == IP46_TYPE_IP4)
20876         {
20877           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20878           vat_json_object_add_ip4 (node, "next_hop", ip4);
20879         }
20880       else if (fp->afi == IP46_TYPE_IP6)
20881         {
20882           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20883           vat_json_object_add_ip6 (node, "next_hop", ip6);
20884         }
20885     }
20886 }
20887
20888 static int
20889 api_ip6_fib_dump (vat_main_t * vam)
20890 {
20891   vl_api_ip6_fib_dump_t *mp;
20892   vl_api_control_ping_t *mp_ping;
20893   int ret;
20894
20895   M (IP6_FIB_DUMP, mp);
20896   S (mp);
20897
20898   /* Use a control ping for synchronization */
20899   MPING (CONTROL_PING, mp_ping);
20900   S (mp_ping);
20901
20902   W (ret);
20903   return ret;
20904 }
20905
20906 static int
20907 api_ip6_mfib_dump (vat_main_t * vam)
20908 {
20909   vl_api_ip6_mfib_dump_t *mp;
20910   vl_api_control_ping_t *mp_ping;
20911   int ret;
20912
20913   M (IP6_MFIB_DUMP, mp);
20914   S (mp);
20915
20916   /* Use a control ping for synchronization */
20917   MPING (CONTROL_PING, mp_ping);
20918   S (mp_ping);
20919
20920   W (ret);
20921   return ret;
20922 }
20923
20924 int
20925 api_classify_table_ids (vat_main_t * vam)
20926 {
20927   vl_api_classify_table_ids_t *mp;
20928   int ret;
20929
20930   /* Construct the API message */
20931   M (CLASSIFY_TABLE_IDS, mp);
20932   mp->context = 0;
20933
20934   S (mp);
20935   W (ret);
20936   return ret;
20937 }
20938
20939 int
20940 api_classify_table_by_interface (vat_main_t * vam)
20941 {
20942   unformat_input_t *input = vam->input;
20943   vl_api_classify_table_by_interface_t *mp;
20944
20945   u32 sw_if_index = ~0;
20946   int ret;
20947   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20948     {
20949       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20950         ;
20951       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20952         ;
20953       else
20954         break;
20955     }
20956   if (sw_if_index == ~0)
20957     {
20958       errmsg ("missing interface name or sw_if_index");
20959       return -99;
20960     }
20961
20962   /* Construct the API message */
20963   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20964   mp->context = 0;
20965   mp->sw_if_index = ntohl (sw_if_index);
20966
20967   S (mp);
20968   W (ret);
20969   return ret;
20970 }
20971
20972 int
20973 api_classify_table_info (vat_main_t * vam)
20974 {
20975   unformat_input_t *input = vam->input;
20976   vl_api_classify_table_info_t *mp;
20977
20978   u32 table_id = ~0;
20979   int ret;
20980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20981     {
20982       if (unformat (input, "table_id %d", &table_id))
20983         ;
20984       else
20985         break;
20986     }
20987   if (table_id == ~0)
20988     {
20989       errmsg ("missing table id");
20990       return -99;
20991     }
20992
20993   /* Construct the API message */
20994   M (CLASSIFY_TABLE_INFO, mp);
20995   mp->context = 0;
20996   mp->table_id = ntohl (table_id);
20997
20998   S (mp);
20999   W (ret);
21000   return ret;
21001 }
21002
21003 int
21004 api_classify_session_dump (vat_main_t * vam)
21005 {
21006   unformat_input_t *input = vam->input;
21007   vl_api_classify_session_dump_t *mp;
21008   vl_api_control_ping_t *mp_ping;
21009
21010   u32 table_id = ~0;
21011   int ret;
21012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21013     {
21014       if (unformat (input, "table_id %d", &table_id))
21015         ;
21016       else
21017         break;
21018     }
21019   if (table_id == ~0)
21020     {
21021       errmsg ("missing table id");
21022       return -99;
21023     }
21024
21025   /* Construct the API message */
21026   M (CLASSIFY_SESSION_DUMP, mp);
21027   mp->context = 0;
21028   mp->table_id = ntohl (table_id);
21029   S (mp);
21030
21031   /* Use a control ping for synchronization */
21032   MPING (CONTROL_PING, mp_ping);
21033   S (mp_ping);
21034
21035   W (ret);
21036   return ret;
21037 }
21038
21039 static void
21040 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21041 {
21042   vat_main_t *vam = &vat_main;
21043
21044   print (vam->ofp, "collector_address %U, collector_port %d, "
21045          "src_address %U, vrf_id %d, path_mtu %u, "
21046          "template_interval %u, udp_checksum %d",
21047          format_ip4_address, mp->collector_address,
21048          ntohs (mp->collector_port),
21049          format_ip4_address, mp->src_address,
21050          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21051          ntohl (mp->template_interval), mp->udp_checksum);
21052
21053   vam->retval = 0;
21054   vam->result_ready = 1;
21055 }
21056
21057 static void
21058   vl_api_ipfix_exporter_details_t_handler_json
21059   (vl_api_ipfix_exporter_details_t * mp)
21060 {
21061   vat_main_t *vam = &vat_main;
21062   vat_json_node_t node;
21063   struct in_addr collector_address;
21064   struct in_addr src_address;
21065
21066   vat_json_init_object (&node);
21067   clib_memcpy (&collector_address, &mp->collector_address,
21068                sizeof (collector_address));
21069   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21070   vat_json_object_add_uint (&node, "collector_port",
21071                             ntohs (mp->collector_port));
21072   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21073   vat_json_object_add_ip4 (&node, "src_address", src_address);
21074   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21075   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21076   vat_json_object_add_uint (&node, "template_interval",
21077                             ntohl (mp->template_interval));
21078   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21079
21080   vat_json_print (vam->ofp, &node);
21081   vat_json_free (&node);
21082   vam->retval = 0;
21083   vam->result_ready = 1;
21084 }
21085
21086 int
21087 api_ipfix_exporter_dump (vat_main_t * vam)
21088 {
21089   vl_api_ipfix_exporter_dump_t *mp;
21090   int ret;
21091
21092   /* Construct the API message */
21093   M (IPFIX_EXPORTER_DUMP, mp);
21094   mp->context = 0;
21095
21096   S (mp);
21097   W (ret);
21098   return ret;
21099 }
21100
21101 static int
21102 api_ipfix_classify_stream_dump (vat_main_t * vam)
21103 {
21104   vl_api_ipfix_classify_stream_dump_t *mp;
21105   int ret;
21106
21107   /* Construct the API message */
21108   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21109   mp->context = 0;
21110
21111   S (mp);
21112   W (ret);
21113   return ret;
21114   /* NOTREACHED */
21115   return 0;
21116 }
21117
21118 static void
21119   vl_api_ipfix_classify_stream_details_t_handler
21120   (vl_api_ipfix_classify_stream_details_t * mp)
21121 {
21122   vat_main_t *vam = &vat_main;
21123   print (vam->ofp, "domain_id %d, src_port %d",
21124          ntohl (mp->domain_id), ntohs (mp->src_port));
21125   vam->retval = 0;
21126   vam->result_ready = 1;
21127 }
21128
21129 static void
21130   vl_api_ipfix_classify_stream_details_t_handler_json
21131   (vl_api_ipfix_classify_stream_details_t * mp)
21132 {
21133   vat_main_t *vam = &vat_main;
21134   vat_json_node_t node;
21135
21136   vat_json_init_object (&node);
21137   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21138   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21139
21140   vat_json_print (vam->ofp, &node);
21141   vat_json_free (&node);
21142   vam->retval = 0;
21143   vam->result_ready = 1;
21144 }
21145
21146 static int
21147 api_ipfix_classify_table_dump (vat_main_t * vam)
21148 {
21149   vl_api_ipfix_classify_table_dump_t *mp;
21150   vl_api_control_ping_t *mp_ping;
21151   int ret;
21152
21153   if (!vam->json_output)
21154     {
21155       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21156              "transport_protocol");
21157     }
21158
21159   /* Construct the API message */
21160   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21161
21162   /* send it... */
21163   S (mp);
21164
21165   /* Use a control ping for synchronization */
21166   MPING (CONTROL_PING, mp_ping);
21167   S (mp_ping);
21168
21169   W (ret);
21170   return ret;
21171 }
21172
21173 static void
21174   vl_api_ipfix_classify_table_details_t_handler
21175   (vl_api_ipfix_classify_table_details_t * mp)
21176 {
21177   vat_main_t *vam = &vat_main;
21178   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21179          mp->transport_protocol);
21180 }
21181
21182 static void
21183   vl_api_ipfix_classify_table_details_t_handler_json
21184   (vl_api_ipfix_classify_table_details_t * mp)
21185 {
21186   vat_json_node_t *node = NULL;
21187   vat_main_t *vam = &vat_main;
21188
21189   if (VAT_JSON_ARRAY != vam->json_tree.type)
21190     {
21191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21192       vat_json_init_array (&vam->json_tree);
21193     }
21194
21195   node = vat_json_array_add (&vam->json_tree);
21196   vat_json_init_object (node);
21197
21198   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21199   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21200   vat_json_object_add_uint (node, "transport_protocol",
21201                             mp->transport_protocol);
21202 }
21203
21204 static int
21205 api_sw_interface_span_enable_disable (vat_main_t * vam)
21206 {
21207   unformat_input_t *i = vam->input;
21208   vl_api_sw_interface_span_enable_disable_t *mp;
21209   u32 src_sw_if_index = ~0;
21210   u32 dst_sw_if_index = ~0;
21211   u8 state = 3;
21212   int ret;
21213   u8 is_l2 = 0;
21214
21215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21216     {
21217       if (unformat
21218           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21219         ;
21220       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21221         ;
21222       else
21223         if (unformat
21224             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21225         ;
21226       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21227         ;
21228       else if (unformat (i, "disable"))
21229         state = 0;
21230       else if (unformat (i, "rx"))
21231         state = 1;
21232       else if (unformat (i, "tx"))
21233         state = 2;
21234       else if (unformat (i, "both"))
21235         state = 3;
21236       else if (unformat (i, "l2"))
21237         is_l2 = 1;
21238       else
21239         break;
21240     }
21241
21242   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21243
21244   mp->sw_if_index_from = htonl (src_sw_if_index);
21245   mp->sw_if_index_to = htonl (dst_sw_if_index);
21246   mp->state = state;
21247   mp->is_l2 = is_l2;
21248
21249   S (mp);
21250   W (ret);
21251   return ret;
21252 }
21253
21254 static void
21255 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21256                                             * mp)
21257 {
21258   vat_main_t *vam = &vat_main;
21259   u8 *sw_if_from_name = 0;
21260   u8 *sw_if_to_name = 0;
21261   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21262   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21263   char *states[] = { "none", "rx", "tx", "both" };
21264   hash_pair_t *p;
21265
21266   /* *INDENT-OFF* */
21267   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21268   ({
21269     if ((u32) p->value[0] == sw_if_index_from)
21270       {
21271         sw_if_from_name = (u8 *)(p->key);
21272         if (sw_if_to_name)
21273           break;
21274       }
21275     if ((u32) p->value[0] == sw_if_index_to)
21276       {
21277         sw_if_to_name = (u8 *)(p->key);
21278         if (sw_if_from_name)
21279           break;
21280       }
21281   }));
21282   /* *INDENT-ON* */
21283   print (vam->ofp, "%20s => %20s (%s) %s",
21284          sw_if_from_name, sw_if_to_name, states[mp->state],
21285          mp->is_l2 ? "l2" : "device");
21286 }
21287
21288 static void
21289   vl_api_sw_interface_span_details_t_handler_json
21290   (vl_api_sw_interface_span_details_t * mp)
21291 {
21292   vat_main_t *vam = &vat_main;
21293   vat_json_node_t *node = NULL;
21294   u8 *sw_if_from_name = 0;
21295   u8 *sw_if_to_name = 0;
21296   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21297   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21298   hash_pair_t *p;
21299
21300   /* *INDENT-OFF* */
21301   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21302   ({
21303     if ((u32) p->value[0] == sw_if_index_from)
21304       {
21305         sw_if_from_name = (u8 *)(p->key);
21306         if (sw_if_to_name)
21307           break;
21308       }
21309     if ((u32) p->value[0] == sw_if_index_to)
21310       {
21311         sw_if_to_name = (u8 *)(p->key);
21312         if (sw_if_from_name)
21313           break;
21314       }
21315   }));
21316   /* *INDENT-ON* */
21317
21318   if (VAT_JSON_ARRAY != vam->json_tree.type)
21319     {
21320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21321       vat_json_init_array (&vam->json_tree);
21322     }
21323   node = vat_json_array_add (&vam->json_tree);
21324
21325   vat_json_init_object (node);
21326   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21327   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21328   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21329   if (0 != sw_if_to_name)
21330     {
21331       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21332     }
21333   vat_json_object_add_uint (node, "state", mp->state);
21334   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21335 }
21336
21337 static int
21338 api_sw_interface_span_dump (vat_main_t * vam)
21339 {
21340   unformat_input_t *input = vam->input;
21341   vl_api_sw_interface_span_dump_t *mp;
21342   vl_api_control_ping_t *mp_ping;
21343   u8 is_l2 = 0;
21344   int ret;
21345
21346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21347     {
21348       if (unformat (input, "l2"))
21349         is_l2 = 1;
21350       else
21351         break;
21352     }
21353
21354   M (SW_INTERFACE_SPAN_DUMP, mp);
21355   mp->is_l2 = is_l2;
21356   S (mp);
21357
21358   /* Use a control ping for synchronization */
21359   MPING (CONTROL_PING, mp_ping);
21360   S (mp_ping);
21361
21362   W (ret);
21363   return ret;
21364 }
21365
21366 int
21367 api_pg_create_interface (vat_main_t * vam)
21368 {
21369   unformat_input_t *input = vam->input;
21370   vl_api_pg_create_interface_t *mp;
21371
21372   u32 if_id = ~0;
21373   int ret;
21374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21375     {
21376       if (unformat (input, "if_id %d", &if_id))
21377         ;
21378       else
21379         break;
21380     }
21381   if (if_id == ~0)
21382     {
21383       errmsg ("missing pg interface index");
21384       return -99;
21385     }
21386
21387   /* Construct the API message */
21388   M (PG_CREATE_INTERFACE, mp);
21389   mp->context = 0;
21390   mp->interface_id = ntohl (if_id);
21391
21392   S (mp);
21393   W (ret);
21394   return ret;
21395 }
21396
21397 int
21398 api_pg_capture (vat_main_t * vam)
21399 {
21400   unformat_input_t *input = vam->input;
21401   vl_api_pg_capture_t *mp;
21402
21403   u32 if_id = ~0;
21404   u8 enable = 1;
21405   u32 count = 1;
21406   u8 pcap_file_set = 0;
21407   u8 *pcap_file = 0;
21408   int ret;
21409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21410     {
21411       if (unformat (input, "if_id %d", &if_id))
21412         ;
21413       else if (unformat (input, "pcap %s", &pcap_file))
21414         pcap_file_set = 1;
21415       else if (unformat (input, "count %d", &count))
21416         ;
21417       else if (unformat (input, "disable"))
21418         enable = 0;
21419       else
21420         break;
21421     }
21422   if (if_id == ~0)
21423     {
21424       errmsg ("missing pg interface index");
21425       return -99;
21426     }
21427   if (pcap_file_set > 0)
21428     {
21429       if (vec_len (pcap_file) > 255)
21430         {
21431           errmsg ("pcap file name is too long");
21432           return -99;
21433         }
21434     }
21435
21436   u32 name_len = vec_len (pcap_file);
21437   /* Construct the API message */
21438   M (PG_CAPTURE, mp);
21439   mp->context = 0;
21440   mp->interface_id = ntohl (if_id);
21441   mp->is_enabled = enable;
21442   mp->count = ntohl (count);
21443   mp->pcap_name_length = ntohl (name_len);
21444   if (pcap_file_set != 0)
21445     {
21446       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21447     }
21448   vec_free (pcap_file);
21449
21450   S (mp);
21451   W (ret);
21452   return ret;
21453 }
21454
21455 int
21456 api_pg_enable_disable (vat_main_t * vam)
21457 {
21458   unformat_input_t *input = vam->input;
21459   vl_api_pg_enable_disable_t *mp;
21460
21461   u8 enable = 1;
21462   u8 stream_name_set = 0;
21463   u8 *stream_name = 0;
21464   int ret;
21465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21466     {
21467       if (unformat (input, "stream %s", &stream_name))
21468         stream_name_set = 1;
21469       else if (unformat (input, "disable"))
21470         enable = 0;
21471       else
21472         break;
21473     }
21474
21475   if (stream_name_set > 0)
21476     {
21477       if (vec_len (stream_name) > 255)
21478         {
21479           errmsg ("stream name too long");
21480           return -99;
21481         }
21482     }
21483
21484   u32 name_len = vec_len (stream_name);
21485   /* Construct the API message */
21486   M (PG_ENABLE_DISABLE, mp);
21487   mp->context = 0;
21488   mp->is_enabled = enable;
21489   if (stream_name_set != 0)
21490     {
21491       mp->stream_name_length = ntohl (name_len);
21492       clib_memcpy (mp->stream_name, stream_name, name_len);
21493     }
21494   vec_free (stream_name);
21495
21496   S (mp);
21497   W (ret);
21498   return ret;
21499 }
21500
21501 int
21502 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21503 {
21504   unformat_input_t *input = vam->input;
21505   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21506
21507   u16 *low_ports = 0;
21508   u16 *high_ports = 0;
21509   u16 this_low;
21510   u16 this_hi;
21511   ip4_address_t ip4_addr;
21512   ip6_address_t ip6_addr;
21513   u32 length;
21514   u32 tmp, tmp2;
21515   u8 prefix_set = 0;
21516   u32 vrf_id = ~0;
21517   u8 is_add = 1;
21518   u8 is_ipv6 = 0;
21519   int ret;
21520
21521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21522     {
21523       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21524         {
21525           prefix_set = 1;
21526         }
21527       else
21528         if (unformat
21529             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21530         {
21531           prefix_set = 1;
21532           is_ipv6 = 1;
21533         }
21534       else if (unformat (input, "vrf %d", &vrf_id))
21535         ;
21536       else if (unformat (input, "del"))
21537         is_add = 0;
21538       else if (unformat (input, "port %d", &tmp))
21539         {
21540           if (tmp == 0 || tmp > 65535)
21541             {
21542               errmsg ("port %d out of range", tmp);
21543               return -99;
21544             }
21545           this_low = tmp;
21546           this_hi = this_low + 1;
21547           vec_add1 (low_ports, this_low);
21548           vec_add1 (high_ports, this_hi);
21549         }
21550       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21551         {
21552           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21553             {
21554               errmsg ("incorrect range parameters");
21555               return -99;
21556             }
21557           this_low = tmp;
21558           /* Note: in debug CLI +1 is added to high before
21559              passing to real fn that does "the work"
21560              (ip_source_and_port_range_check_add_del).
21561              This fn is a wrapper around the binary API fn a
21562              control plane will call, which expects this increment
21563              to have occurred. Hence letting the binary API control
21564              plane fn do the increment for consistency between VAT
21565              and other control planes.
21566            */
21567           this_hi = tmp2;
21568           vec_add1 (low_ports, this_low);
21569           vec_add1 (high_ports, this_hi);
21570         }
21571       else
21572         break;
21573     }
21574
21575   if (prefix_set == 0)
21576     {
21577       errmsg ("<address>/<mask> not specified");
21578       return -99;
21579     }
21580
21581   if (vrf_id == ~0)
21582     {
21583       errmsg ("VRF ID required, not specified");
21584       return -99;
21585     }
21586
21587   if (vrf_id == 0)
21588     {
21589       errmsg
21590         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21591       return -99;
21592     }
21593
21594   if (vec_len (low_ports) == 0)
21595     {
21596       errmsg ("At least one port or port range required");
21597       return -99;
21598     }
21599
21600   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21601
21602   mp->is_add = is_add;
21603
21604   if (is_ipv6)
21605     {
21606       mp->is_ipv6 = 1;
21607       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21608     }
21609   else
21610     {
21611       mp->is_ipv6 = 0;
21612       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21613     }
21614
21615   mp->mask_length = length;
21616   mp->number_of_ranges = vec_len (low_ports);
21617
21618   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21619   vec_free (low_ports);
21620
21621   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21622   vec_free (high_ports);
21623
21624   mp->vrf_id = ntohl (vrf_id);
21625
21626   S (mp);
21627   W (ret);
21628   return ret;
21629 }
21630
21631 int
21632 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21633 {
21634   unformat_input_t *input = vam->input;
21635   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21636   u32 sw_if_index = ~0;
21637   int vrf_set = 0;
21638   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21639   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21640   u8 is_add = 1;
21641   int ret;
21642
21643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21644     {
21645       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21646         ;
21647       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21648         ;
21649       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21650         vrf_set = 1;
21651       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21652         vrf_set = 1;
21653       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21654         vrf_set = 1;
21655       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21656         vrf_set = 1;
21657       else if (unformat (input, "del"))
21658         is_add = 0;
21659       else
21660         break;
21661     }
21662
21663   if (sw_if_index == ~0)
21664     {
21665       errmsg ("Interface required but not specified");
21666       return -99;
21667     }
21668
21669   if (vrf_set == 0)
21670     {
21671       errmsg ("VRF ID required but not specified");
21672       return -99;
21673     }
21674
21675   if (tcp_out_vrf_id == 0
21676       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21677     {
21678       errmsg
21679         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21680       return -99;
21681     }
21682
21683   /* Construct the API message */
21684   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21685
21686   mp->sw_if_index = ntohl (sw_if_index);
21687   mp->is_add = is_add;
21688   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21689   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21690   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21691   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21692
21693   /* send it... */
21694   S (mp);
21695
21696   /* Wait for a reply... */
21697   W (ret);
21698   return ret;
21699 }
21700
21701 static int
21702 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21703 {
21704   unformat_input_t *i = vam->input;
21705   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21706   u32 local_sa_id = 0;
21707   u32 remote_sa_id = 0;
21708   ip4_address_t src_address;
21709   ip4_address_t dst_address;
21710   u8 is_add = 1;
21711   int ret;
21712
21713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21714     {
21715       if (unformat (i, "local_sa %d", &local_sa_id))
21716         ;
21717       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21718         ;
21719       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21720         ;
21721       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21722         ;
21723       else if (unformat (i, "del"))
21724         is_add = 0;
21725       else
21726         {
21727           clib_warning ("parse error '%U'", format_unformat_error, i);
21728           return -99;
21729         }
21730     }
21731
21732   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21733
21734   mp->local_sa_id = ntohl (local_sa_id);
21735   mp->remote_sa_id = ntohl (remote_sa_id);
21736   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21737   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21738   mp->is_add = is_add;
21739
21740   S (mp);
21741   W (ret);
21742   return ret;
21743 }
21744
21745 static int
21746 api_punt (vat_main_t * vam)
21747 {
21748   unformat_input_t *i = vam->input;
21749   vl_api_punt_t *mp;
21750   u32 ipv = ~0;
21751   u32 protocol = ~0;
21752   u32 port = ~0;
21753   int is_add = 1;
21754   int ret;
21755
21756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21757     {
21758       if (unformat (i, "ip %d", &ipv))
21759         ;
21760       else if (unformat (i, "protocol %d", &protocol))
21761         ;
21762       else if (unformat (i, "port %d", &port))
21763         ;
21764       else if (unformat (i, "del"))
21765         is_add = 0;
21766       else
21767         {
21768           clib_warning ("parse error '%U'", format_unformat_error, i);
21769           return -99;
21770         }
21771     }
21772
21773   M (PUNT, mp);
21774
21775   mp->is_add = (u8) is_add;
21776   mp->ipv = (u8) ipv;
21777   mp->l4_protocol = (u8) protocol;
21778   mp->l4_port = htons ((u16) port);
21779
21780   S (mp);
21781   W (ret);
21782   return ret;
21783 }
21784
21785 static void vl_api_ipsec_gre_tunnel_details_t_handler
21786   (vl_api_ipsec_gre_tunnel_details_t * mp)
21787 {
21788   vat_main_t *vam = &vat_main;
21789
21790   print (vam->ofp, "%11d%15U%15U%14d%14d",
21791          ntohl (mp->sw_if_index),
21792          format_ip4_address, &mp->src_address,
21793          format_ip4_address, &mp->dst_address,
21794          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21795 }
21796
21797 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21798   (vl_api_ipsec_gre_tunnel_details_t * mp)
21799 {
21800   vat_main_t *vam = &vat_main;
21801   vat_json_node_t *node = NULL;
21802   struct in_addr ip4;
21803
21804   if (VAT_JSON_ARRAY != vam->json_tree.type)
21805     {
21806       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21807       vat_json_init_array (&vam->json_tree);
21808     }
21809   node = vat_json_array_add (&vam->json_tree);
21810
21811   vat_json_init_object (node);
21812   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21813   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21814   vat_json_object_add_ip4 (node, "src_address", ip4);
21815   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21816   vat_json_object_add_ip4 (node, "dst_address", ip4);
21817   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21818   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21819 }
21820
21821 static int
21822 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21823 {
21824   unformat_input_t *i = vam->input;
21825   vl_api_ipsec_gre_tunnel_dump_t *mp;
21826   vl_api_control_ping_t *mp_ping;
21827   u32 sw_if_index;
21828   u8 sw_if_index_set = 0;
21829   int ret;
21830
21831   /* Parse args required to build the message */
21832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21833     {
21834       if (unformat (i, "sw_if_index %d", &sw_if_index))
21835         sw_if_index_set = 1;
21836       else
21837         break;
21838     }
21839
21840   if (sw_if_index_set == 0)
21841     {
21842       sw_if_index = ~0;
21843     }
21844
21845   if (!vam->json_output)
21846     {
21847       print (vam->ofp, "%11s%15s%15s%14s%14s",
21848              "sw_if_index", "src_address", "dst_address",
21849              "local_sa_id", "remote_sa_id");
21850     }
21851
21852   /* Get list of gre-tunnel interfaces */
21853   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21854
21855   mp->sw_if_index = htonl (sw_if_index);
21856
21857   S (mp);
21858
21859   /* Use a control ping for synchronization */
21860   MPING (CONTROL_PING, mp_ping);
21861   S (mp_ping);
21862
21863   W (ret);
21864   return ret;
21865 }
21866
21867 static int
21868 api_delete_subif (vat_main_t * vam)
21869 {
21870   unformat_input_t *i = vam->input;
21871   vl_api_delete_subif_t *mp;
21872   u32 sw_if_index = ~0;
21873   int ret;
21874
21875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21876     {
21877       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21878         ;
21879       if (unformat (i, "sw_if_index %d", &sw_if_index))
21880         ;
21881       else
21882         break;
21883     }
21884
21885   if (sw_if_index == ~0)
21886     {
21887       errmsg ("missing sw_if_index");
21888       return -99;
21889     }
21890
21891   /* Construct the API message */
21892   M (DELETE_SUBIF, mp);
21893   mp->sw_if_index = ntohl (sw_if_index);
21894
21895   S (mp);
21896   W (ret);
21897   return ret;
21898 }
21899
21900 #define foreach_pbb_vtr_op      \
21901 _("disable",  L2_VTR_DISABLED)  \
21902 _("pop",  L2_VTR_POP_2)         \
21903 _("push",  L2_VTR_PUSH_2)
21904
21905 static int
21906 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21907 {
21908   unformat_input_t *i = vam->input;
21909   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21910   u32 sw_if_index = ~0, vtr_op = ~0;
21911   u16 outer_tag = ~0;
21912   u8 dmac[6], smac[6];
21913   u8 dmac_set = 0, smac_set = 0;
21914   u16 vlanid = 0;
21915   u32 sid = ~0;
21916   u32 tmp;
21917   int ret;
21918
21919   /* Shut up coverity */
21920   memset (dmac, 0, sizeof (dmac));
21921   memset (smac, 0, sizeof (smac));
21922
21923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21924     {
21925       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21926         ;
21927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21928         ;
21929       else if (unformat (i, "vtr_op %d", &vtr_op))
21930         ;
21931 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21932       foreach_pbb_vtr_op
21933 #undef _
21934         else if (unformat (i, "translate_pbb_stag"))
21935         {
21936           if (unformat (i, "%d", &tmp))
21937             {
21938               vtr_op = L2_VTR_TRANSLATE_2_1;
21939               outer_tag = tmp;
21940             }
21941           else
21942             {
21943               errmsg
21944                 ("translate_pbb_stag operation requires outer tag definition");
21945               return -99;
21946             }
21947         }
21948       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21949         dmac_set++;
21950       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21951         smac_set++;
21952       else if (unformat (i, "sid %d", &sid))
21953         ;
21954       else if (unformat (i, "vlanid %d", &tmp))
21955         vlanid = tmp;
21956       else
21957         {
21958           clib_warning ("parse error '%U'", format_unformat_error, i);
21959           return -99;
21960         }
21961     }
21962
21963   if ((sw_if_index == ~0) || (vtr_op == ~0))
21964     {
21965       errmsg ("missing sw_if_index or vtr operation");
21966       return -99;
21967     }
21968   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21969       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21970     {
21971       errmsg
21972         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21973       return -99;
21974     }
21975
21976   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21977   mp->sw_if_index = ntohl (sw_if_index);
21978   mp->vtr_op = ntohl (vtr_op);
21979   mp->outer_tag = ntohs (outer_tag);
21980   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21981   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21982   mp->b_vlanid = ntohs (vlanid);
21983   mp->i_sid = ntohl (sid);
21984
21985   S (mp);
21986   W (ret);
21987   return ret;
21988 }
21989
21990 static int
21991 api_flow_classify_set_interface (vat_main_t * vam)
21992 {
21993   unformat_input_t *i = vam->input;
21994   vl_api_flow_classify_set_interface_t *mp;
21995   u32 sw_if_index;
21996   int sw_if_index_set;
21997   u32 ip4_table_index = ~0;
21998   u32 ip6_table_index = ~0;
21999   u8 is_add = 1;
22000   int ret;
22001
22002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22003     {
22004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22005         sw_if_index_set = 1;
22006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22007         sw_if_index_set = 1;
22008       else if (unformat (i, "del"))
22009         is_add = 0;
22010       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22011         ;
22012       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22013         ;
22014       else
22015         {
22016           clib_warning ("parse error '%U'", format_unformat_error, i);
22017           return -99;
22018         }
22019     }
22020
22021   if (sw_if_index_set == 0)
22022     {
22023       errmsg ("missing interface name or sw_if_index");
22024       return -99;
22025     }
22026
22027   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22028
22029   mp->sw_if_index = ntohl (sw_if_index);
22030   mp->ip4_table_index = ntohl (ip4_table_index);
22031   mp->ip6_table_index = ntohl (ip6_table_index);
22032   mp->is_add = is_add;
22033
22034   S (mp);
22035   W (ret);
22036   return ret;
22037 }
22038
22039 static int
22040 api_flow_classify_dump (vat_main_t * vam)
22041 {
22042   unformat_input_t *i = vam->input;
22043   vl_api_flow_classify_dump_t *mp;
22044   vl_api_control_ping_t *mp_ping;
22045   u8 type = FLOW_CLASSIFY_N_TABLES;
22046   int ret;
22047
22048   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22049     ;
22050   else
22051     {
22052       errmsg ("classify table type must be specified");
22053       return -99;
22054     }
22055
22056   if (!vam->json_output)
22057     {
22058       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22059     }
22060
22061   M (FLOW_CLASSIFY_DUMP, mp);
22062   mp->type = type;
22063   /* send it... */
22064   S (mp);
22065
22066   /* Use a control ping for synchronization */
22067   MPING (CONTROL_PING, mp_ping);
22068   S (mp_ping);
22069
22070   /* Wait for a reply... */
22071   W (ret);
22072   return ret;
22073 }
22074
22075 static int
22076 api_feature_enable_disable (vat_main_t * vam)
22077 {
22078   unformat_input_t *i = vam->input;
22079   vl_api_feature_enable_disable_t *mp;
22080   u8 *arc_name = 0;
22081   u8 *feature_name = 0;
22082   u32 sw_if_index = ~0;
22083   u8 enable = 1;
22084   int ret;
22085
22086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22087     {
22088       if (unformat (i, "arc_name %s", &arc_name))
22089         ;
22090       else if (unformat (i, "feature_name %s", &feature_name))
22091         ;
22092       else
22093         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22094         ;
22095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22096         ;
22097       else if (unformat (i, "disable"))
22098         enable = 0;
22099       else
22100         break;
22101     }
22102
22103   if (arc_name == 0)
22104     {
22105       errmsg ("missing arc name");
22106       return -99;
22107     }
22108   if (vec_len (arc_name) > 63)
22109     {
22110       errmsg ("arc name too long");
22111     }
22112
22113   if (feature_name == 0)
22114     {
22115       errmsg ("missing feature name");
22116       return -99;
22117     }
22118   if (vec_len (feature_name) > 63)
22119     {
22120       errmsg ("feature name too long");
22121     }
22122
22123   if (sw_if_index == ~0)
22124     {
22125       errmsg ("missing interface name or sw_if_index");
22126       return -99;
22127     }
22128
22129   /* Construct the API message */
22130   M (FEATURE_ENABLE_DISABLE, mp);
22131   mp->sw_if_index = ntohl (sw_if_index);
22132   mp->enable = enable;
22133   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22134   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22135   vec_free (arc_name);
22136   vec_free (feature_name);
22137
22138   S (mp);
22139   W (ret);
22140   return ret;
22141 }
22142
22143 static int
22144 api_sw_interface_tag_add_del (vat_main_t * vam)
22145 {
22146   unformat_input_t *i = vam->input;
22147   vl_api_sw_interface_tag_add_del_t *mp;
22148   u32 sw_if_index = ~0;
22149   u8 *tag = 0;
22150   u8 enable = 1;
22151   int ret;
22152
22153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22154     {
22155       if (unformat (i, "tag %s", &tag))
22156         ;
22157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22158         ;
22159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22160         ;
22161       else if (unformat (i, "del"))
22162         enable = 0;
22163       else
22164         break;
22165     }
22166
22167   if (sw_if_index == ~0)
22168     {
22169       errmsg ("missing interface name or sw_if_index");
22170       return -99;
22171     }
22172
22173   if (enable && (tag == 0))
22174     {
22175       errmsg ("no tag specified");
22176       return -99;
22177     }
22178
22179   /* Construct the API message */
22180   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22181   mp->sw_if_index = ntohl (sw_if_index);
22182   mp->is_add = enable;
22183   if (enable)
22184     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22185   vec_free (tag);
22186
22187   S (mp);
22188   W (ret);
22189   return ret;
22190 }
22191
22192 static void vl_api_l2_xconnect_details_t_handler
22193   (vl_api_l2_xconnect_details_t * mp)
22194 {
22195   vat_main_t *vam = &vat_main;
22196
22197   print (vam->ofp, "%15d%15d",
22198          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22199 }
22200
22201 static void vl_api_l2_xconnect_details_t_handler_json
22202   (vl_api_l2_xconnect_details_t * mp)
22203 {
22204   vat_main_t *vam = &vat_main;
22205   vat_json_node_t *node = NULL;
22206
22207   if (VAT_JSON_ARRAY != vam->json_tree.type)
22208     {
22209       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22210       vat_json_init_array (&vam->json_tree);
22211     }
22212   node = vat_json_array_add (&vam->json_tree);
22213
22214   vat_json_init_object (node);
22215   vat_json_object_add_uint (node, "rx_sw_if_index",
22216                             ntohl (mp->rx_sw_if_index));
22217   vat_json_object_add_uint (node, "tx_sw_if_index",
22218                             ntohl (mp->tx_sw_if_index));
22219 }
22220
22221 static int
22222 api_l2_xconnect_dump (vat_main_t * vam)
22223 {
22224   vl_api_l2_xconnect_dump_t *mp;
22225   vl_api_control_ping_t *mp_ping;
22226   int ret;
22227
22228   if (!vam->json_output)
22229     {
22230       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22231     }
22232
22233   M (L2_XCONNECT_DUMP, mp);
22234
22235   S (mp);
22236
22237   /* Use a control ping for synchronization */
22238   MPING (CONTROL_PING, mp_ping);
22239   S (mp_ping);
22240
22241   W (ret);
22242   return ret;
22243 }
22244
22245 static int
22246 api_hw_interface_set_mtu (vat_main_t * vam)
22247 {
22248   unformat_input_t *i = vam->input;
22249   vl_api_hw_interface_set_mtu_t *mp;
22250   u32 sw_if_index = ~0;
22251   u32 mtu = 0;
22252   int ret;
22253
22254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22255     {
22256       if (unformat (i, "mtu %d", &mtu))
22257         ;
22258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22259         ;
22260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22261         ;
22262       else
22263         break;
22264     }
22265
22266   if (sw_if_index == ~0)
22267     {
22268       errmsg ("missing interface name or sw_if_index");
22269       return -99;
22270     }
22271
22272   if (mtu == 0)
22273     {
22274       errmsg ("no mtu specified");
22275       return -99;
22276     }
22277
22278   /* Construct the API message */
22279   M (HW_INTERFACE_SET_MTU, mp);
22280   mp->sw_if_index = ntohl (sw_if_index);
22281   mp->mtu = ntohs ((u16) mtu);
22282
22283   S (mp);
22284   W (ret);
22285   return ret;
22286 }
22287
22288 static int
22289 api_p2p_ethernet_add (vat_main_t * vam)
22290 {
22291   unformat_input_t *i = vam->input;
22292   vl_api_p2p_ethernet_add_t *mp;
22293   u32 parent_if_index = ~0;
22294   u32 sub_id = ~0;
22295   u8 remote_mac[6];
22296   u8 mac_set = 0;
22297   int ret;
22298
22299   memset (remote_mac, 0, sizeof (remote_mac));
22300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22301     {
22302       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22303         ;
22304       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22305         ;
22306       else
22307         if (unformat
22308             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22309         mac_set++;
22310       else if (unformat (i, "sub_id %d", &sub_id))
22311         ;
22312       else
22313         {
22314           clib_warning ("parse error '%U'", format_unformat_error, i);
22315           return -99;
22316         }
22317     }
22318
22319   if (parent_if_index == ~0)
22320     {
22321       errmsg ("missing interface name or sw_if_index");
22322       return -99;
22323     }
22324   if (mac_set == 0)
22325     {
22326       errmsg ("missing remote mac address");
22327       return -99;
22328     }
22329   if (sub_id == ~0)
22330     {
22331       errmsg ("missing sub-interface id");
22332       return -99;
22333     }
22334
22335   M (P2P_ETHERNET_ADD, mp);
22336   mp->parent_if_index = ntohl (parent_if_index);
22337   mp->subif_id = ntohl (sub_id);
22338   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22339
22340   S (mp);
22341   W (ret);
22342   return ret;
22343 }
22344
22345 static int
22346 api_p2p_ethernet_del (vat_main_t * vam)
22347 {
22348   unformat_input_t *i = vam->input;
22349   vl_api_p2p_ethernet_del_t *mp;
22350   u32 parent_if_index = ~0;
22351   u8 remote_mac[6];
22352   u8 mac_set = 0;
22353   int ret;
22354
22355   memset (remote_mac, 0, sizeof (remote_mac));
22356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22357     {
22358       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22359         ;
22360       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22361         ;
22362       else
22363         if (unformat
22364             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22365         mac_set++;
22366       else
22367         {
22368           clib_warning ("parse error '%U'", format_unformat_error, i);
22369           return -99;
22370         }
22371     }
22372
22373   if (parent_if_index == ~0)
22374     {
22375       errmsg ("missing interface name or sw_if_index");
22376       return -99;
22377     }
22378   if (mac_set == 0)
22379     {
22380       errmsg ("missing remote mac address");
22381       return -99;
22382     }
22383
22384   M (P2P_ETHERNET_DEL, mp);
22385   mp->parent_if_index = ntohl (parent_if_index);
22386   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22387
22388   S (mp);
22389   W (ret);
22390   return ret;
22391 }
22392
22393 static int
22394 api_lldp_config (vat_main_t * vam)
22395 {
22396   unformat_input_t *i = vam->input;
22397   vl_api_lldp_config_t *mp;
22398   int tx_hold = 0;
22399   int tx_interval = 0;
22400   u8 *sys_name = NULL;
22401   int ret;
22402
22403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22404     {
22405       if (unformat (i, "system-name %s", &sys_name))
22406         ;
22407       else if (unformat (i, "tx-hold %d", &tx_hold))
22408         ;
22409       else if (unformat (i, "tx-interval %d", &tx_interval))
22410         ;
22411       else
22412         {
22413           clib_warning ("parse error '%U'", format_unformat_error, i);
22414           return -99;
22415         }
22416     }
22417
22418   vec_add1 (sys_name, 0);
22419
22420   M (LLDP_CONFIG, mp);
22421   mp->tx_hold = htonl (tx_hold);
22422   mp->tx_interval = htonl (tx_interval);
22423   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22424   vec_free (sys_name);
22425
22426   S (mp);
22427   W (ret);
22428   return ret;
22429 }
22430
22431 static int
22432 api_sw_interface_set_lldp (vat_main_t * vam)
22433 {
22434   unformat_input_t *i = vam->input;
22435   vl_api_sw_interface_set_lldp_t *mp;
22436   u32 sw_if_index = ~0;
22437   u32 enable = 1;
22438   u8 *port_desc = NULL, *mgmt_oid = NULL;
22439   ip4_address_t ip4_addr;
22440   ip6_address_t ip6_addr;
22441   int ret;
22442
22443   memset (&ip4_addr, 0, sizeof (ip4_addr));
22444   memset (&ip6_addr, 0, sizeof (ip6_addr));
22445
22446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22447     {
22448       if (unformat (i, "disable"))
22449         enable = 0;
22450       else
22451         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22452         ;
22453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22454         ;
22455       else if (unformat (i, "port-desc %s", &port_desc))
22456         ;
22457       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22458         ;
22459       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22460         ;
22461       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22462         ;
22463       else
22464         break;
22465     }
22466
22467   if (sw_if_index == ~0)
22468     {
22469       errmsg ("missing interface name or sw_if_index");
22470       return -99;
22471     }
22472
22473   /* Construct the API message */
22474   vec_add1 (port_desc, 0);
22475   vec_add1 (mgmt_oid, 0);
22476   M (SW_INTERFACE_SET_LLDP, mp);
22477   mp->sw_if_index = ntohl (sw_if_index);
22478   mp->enable = enable;
22479   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22480   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22481   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22482   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22483   vec_free (port_desc);
22484   vec_free (mgmt_oid);
22485
22486   S (mp);
22487   W (ret);
22488   return ret;
22489 }
22490
22491 static int
22492 api_tcp_configure_src_addresses (vat_main_t * vam)
22493 {
22494   vl_api_tcp_configure_src_addresses_t *mp;
22495   unformat_input_t *i = vam->input;
22496   ip4_address_t v4first, v4last;
22497   ip6_address_t v6first, v6last;
22498   u8 range_set = 0;
22499   u32 vrf_id = 0;
22500   int ret;
22501
22502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22503     {
22504       if (unformat (i, "%U - %U",
22505                     unformat_ip4_address, &v4first,
22506                     unformat_ip4_address, &v4last))
22507         {
22508           if (range_set)
22509             {
22510               errmsg ("one range per message (range already set)");
22511               return -99;
22512             }
22513           range_set = 1;
22514         }
22515       else if (unformat (i, "%U - %U",
22516                          unformat_ip6_address, &v6first,
22517                          unformat_ip6_address, &v6last))
22518         {
22519           if (range_set)
22520             {
22521               errmsg ("one range per message (range already set)");
22522               return -99;
22523             }
22524           range_set = 2;
22525         }
22526       else if (unformat (i, "vrf %d", &vrf_id))
22527         ;
22528       else
22529         break;
22530     }
22531
22532   if (range_set == 0)
22533     {
22534       errmsg ("address range not set");
22535       return -99;
22536     }
22537
22538   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22539   mp->vrf_id = ntohl (vrf_id);
22540   /* ipv6? */
22541   if (range_set == 2)
22542     {
22543       mp->is_ipv6 = 1;
22544       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22545       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22546     }
22547   else
22548     {
22549       mp->is_ipv6 = 0;
22550       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22551       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22552     }
22553   S (mp);
22554   W (ret);
22555   return ret;
22556 }
22557
22558 static void vl_api_app_namespace_add_del_reply_t_handler
22559   (vl_api_app_namespace_add_del_reply_t * mp)
22560 {
22561   vat_main_t *vam = &vat_main;
22562   i32 retval = ntohl (mp->retval);
22563   if (vam->async_mode)
22564     {
22565       vam->async_errors += (retval < 0);
22566     }
22567   else
22568     {
22569       vam->retval = retval;
22570       if (retval == 0)
22571         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22572       vam->result_ready = 1;
22573     }
22574 }
22575
22576 static void vl_api_app_namespace_add_del_reply_t_handler_json
22577   (vl_api_app_namespace_add_del_reply_t * mp)
22578 {
22579   vat_main_t *vam = &vat_main;
22580   vat_json_node_t node;
22581
22582   vat_json_init_object (&node);
22583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22584   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22585
22586   vat_json_print (vam->ofp, &node);
22587   vat_json_free (&node);
22588
22589   vam->retval = ntohl (mp->retval);
22590   vam->result_ready = 1;
22591 }
22592
22593 static int
22594 api_app_namespace_add_del (vat_main_t * vam)
22595 {
22596   vl_api_app_namespace_add_del_t *mp;
22597   unformat_input_t *i = vam->input;
22598   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22599   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22600   u64 secret;
22601   int ret;
22602
22603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22604     {
22605       if (unformat (i, "id %_%v%_", &ns_id))
22606         ;
22607       else if (unformat (i, "secret %lu", &secret))
22608         secret_set = 1;
22609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22610         sw_if_index_set = 1;
22611       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22612         ;
22613       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22614         ;
22615       else
22616         break;
22617     }
22618   if (!ns_id || !secret_set || !sw_if_index_set)
22619     {
22620       errmsg ("namespace id, secret and sw_if_index must be set");
22621       return -99;
22622     }
22623   if (vec_len (ns_id) > 64)
22624     {
22625       errmsg ("namespace id too long");
22626       return -99;
22627     }
22628   M (APP_NAMESPACE_ADD_DEL, mp);
22629
22630   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22631   mp->namespace_id_len = vec_len (ns_id);
22632   mp->secret = clib_host_to_net_u64 (secret);
22633   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22634   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22635   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22636   vec_free (ns_id);
22637   S (mp);
22638   W (ret);
22639   return ret;
22640 }
22641
22642 static int
22643 api_sock_init_shm (vat_main_t * vam)
22644 {
22645 #if VPP_API_TEST_BUILTIN == 0
22646   unformat_input_t *i = vam->input;
22647   vl_api_shm_elem_config_t *config = 0;
22648   u64 size = 64 << 20;
22649   int rv;
22650
22651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22652     {
22653       if (unformat (i, "size %U", unformat_memory_size, &size))
22654         ;
22655       else
22656         break;
22657     }
22658
22659   /*
22660    * Canned custom ring allocator config.
22661    * Should probably parse all of this
22662    */
22663   vec_validate (config, 6);
22664   config[0].type = VL_API_VLIB_RING;
22665   config[0].size = 256;
22666   config[0].count = 32;
22667
22668   config[1].type = VL_API_VLIB_RING;
22669   config[1].size = 1024;
22670   config[1].count = 16;
22671
22672   config[2].type = VL_API_VLIB_RING;
22673   config[2].size = 4096;
22674   config[2].count = 2;
22675
22676   config[3].type = VL_API_CLIENT_RING;
22677   config[3].size = 256;
22678   config[3].count = 32;
22679
22680   config[4].type = VL_API_CLIENT_RING;
22681   config[4].size = 1024;
22682   config[4].count = 16;
22683
22684   config[5].type = VL_API_CLIENT_RING;
22685   config[5].size = 4096;
22686   config[5].count = 2;
22687
22688   config[6].type = VL_API_QUEUE;
22689   config[6].count = 128;
22690   config[6].size = sizeof (uword);
22691
22692   rv = vl_socket_client_init_shm (config);
22693   if (!rv)
22694     vam->client_index_invalid = 1;
22695   return rv;
22696 #else
22697   return -99;
22698 #endif
22699 }
22700
22701 static int
22702 api_dns_enable_disable (vat_main_t * vam)
22703 {
22704   unformat_input_t *line_input = vam->input;
22705   vl_api_dns_enable_disable_t *mp;
22706   u8 enable_disable = 1;
22707   int ret;
22708
22709   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22710     {
22711       if (unformat (line_input, "disable"))
22712         enable_disable = 0;
22713       if (unformat (line_input, "enable"))
22714         enable_disable = 1;
22715       else
22716         break;
22717     }
22718
22719   /* Construct the API message */
22720   M (DNS_ENABLE_DISABLE, mp);
22721   mp->enable = enable_disable;
22722
22723   /* send it... */
22724   S (mp);
22725   /* Wait for the reply */
22726   W (ret);
22727   return ret;
22728 }
22729
22730 static int
22731 api_dns_resolve_name (vat_main_t * vam)
22732 {
22733   unformat_input_t *line_input = vam->input;
22734   vl_api_dns_resolve_name_t *mp;
22735   u8 *name = 0;
22736   int ret;
22737
22738   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22739     {
22740       if (unformat (line_input, "%s", &name))
22741         ;
22742       else
22743         break;
22744     }
22745
22746   if (vec_len (name) > 127)
22747     {
22748       errmsg ("name too long");
22749       return -99;
22750     }
22751
22752   /* Construct the API message */
22753   M (DNS_RESOLVE_NAME, mp);
22754   memcpy (mp->name, name, vec_len (name));
22755   vec_free (name);
22756
22757   /* send it... */
22758   S (mp);
22759   /* Wait for the reply */
22760   W (ret);
22761   return ret;
22762 }
22763
22764 static int
22765 api_dns_resolve_ip (vat_main_t * vam)
22766 {
22767   unformat_input_t *line_input = vam->input;
22768   vl_api_dns_resolve_ip_t *mp;
22769   int is_ip6 = -1;
22770   ip4_address_t addr4;
22771   ip6_address_t addr6;
22772   int ret;
22773
22774   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22775     {
22776       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22777         is_ip6 = 1;
22778       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22779         is_ip6 = 0;
22780       else
22781         break;
22782     }
22783
22784   if (is_ip6 == -1)
22785     {
22786       errmsg ("missing address");
22787       return -99;
22788     }
22789
22790   /* Construct the API message */
22791   M (DNS_RESOLVE_IP, mp);
22792   mp->is_ip6 = is_ip6;
22793   if (is_ip6)
22794     memcpy (mp->address, &addr6, sizeof (addr6));
22795   else
22796     memcpy (mp->address, &addr4, sizeof (addr4));
22797
22798   /* send it... */
22799   S (mp);
22800   /* Wait for the reply */
22801   W (ret);
22802   return ret;
22803 }
22804
22805 static int
22806 api_dns_name_server_add_del (vat_main_t * vam)
22807 {
22808   unformat_input_t *i = vam->input;
22809   vl_api_dns_name_server_add_del_t *mp;
22810   u8 is_add = 1;
22811   ip6_address_t ip6_server;
22812   ip4_address_t ip4_server;
22813   int ip6_set = 0;
22814   int ip4_set = 0;
22815   int ret = 0;
22816
22817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22818     {
22819       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22820         ip6_set = 1;
22821       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22822         ip4_set = 1;
22823       else if (unformat (i, "del"))
22824         is_add = 0;
22825       else
22826         {
22827           clib_warning ("parse error '%U'", format_unformat_error, i);
22828           return -99;
22829         }
22830     }
22831
22832   if (ip4_set && ip6_set)
22833     {
22834       errmsg ("Only one server address allowed per message");
22835       return -99;
22836     }
22837   if ((ip4_set + ip6_set) == 0)
22838     {
22839       errmsg ("Server address required");
22840       return -99;
22841     }
22842
22843   /* Construct the API message */
22844   M (DNS_NAME_SERVER_ADD_DEL, mp);
22845
22846   if (ip6_set)
22847     {
22848       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22849       mp->is_ip6 = 1;
22850     }
22851   else
22852     {
22853       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22854       mp->is_ip6 = 0;
22855     }
22856
22857   mp->is_add = is_add;
22858
22859   /* send it... */
22860   S (mp);
22861
22862   /* Wait for a reply, return good/bad news  */
22863   W (ret);
22864   return ret;
22865 }
22866
22867 static void
22868 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22869 {
22870   vat_main_t *vam = &vat_main;
22871
22872   if (mp->is_ip4)
22873     {
22874       print (vam->ofp,
22875              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22876              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22877              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22878              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22879              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22880              clib_net_to_host_u32 (mp->action_index), mp->tag);
22881     }
22882   else
22883     {
22884       print (vam->ofp,
22885              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22886              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22887              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22888              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22889              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22890              clib_net_to_host_u32 (mp->action_index), mp->tag);
22891     }
22892 }
22893
22894 static void
22895 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22896                                              mp)
22897 {
22898   vat_main_t *vam = &vat_main;
22899   vat_json_node_t *node = NULL;
22900   struct in6_addr ip6;
22901   struct in_addr ip4;
22902
22903   if (VAT_JSON_ARRAY != vam->json_tree.type)
22904     {
22905       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22906       vat_json_init_array (&vam->json_tree);
22907     }
22908   node = vat_json_array_add (&vam->json_tree);
22909   vat_json_init_object (node);
22910
22911   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22912   vat_json_object_add_uint (node, "appns_index",
22913                             clib_net_to_host_u32 (mp->appns_index));
22914   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22915   vat_json_object_add_uint (node, "scope", mp->scope);
22916   vat_json_object_add_uint (node, "action_index",
22917                             clib_net_to_host_u32 (mp->action_index));
22918   vat_json_object_add_uint (node, "lcl_port",
22919                             clib_net_to_host_u16 (mp->lcl_port));
22920   vat_json_object_add_uint (node, "rmt_port",
22921                             clib_net_to_host_u16 (mp->rmt_port));
22922   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22923   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22924   vat_json_object_add_string_copy (node, "tag", mp->tag);
22925   if (mp->is_ip4)
22926     {
22927       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22928       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22929       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22930       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22931     }
22932   else
22933     {
22934       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22935       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22936       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22937       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22938     }
22939 }
22940
22941 static int
22942 api_session_rule_add_del (vat_main_t * vam)
22943 {
22944   vl_api_session_rule_add_del_t *mp;
22945   unformat_input_t *i = vam->input;
22946   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22947   u32 appns_index = 0, scope = 0;
22948   ip4_address_t lcl_ip4, rmt_ip4;
22949   ip6_address_t lcl_ip6, rmt_ip6;
22950   u8 is_ip4 = 1, conn_set = 0;
22951   u8 is_add = 1, *tag = 0;
22952   int ret;
22953
22954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22955     {
22956       if (unformat (i, "del"))
22957         is_add = 0;
22958       else if (unformat (i, "add"))
22959         ;
22960       else if (unformat (i, "proto tcp"))
22961         proto = 0;
22962       else if (unformat (i, "proto udp"))
22963         proto = 1;
22964       else if (unformat (i, "appns %d", &appns_index))
22965         ;
22966       else if (unformat (i, "scope %d", &scope))
22967         ;
22968       else if (unformat (i, "tag %_%v%_", &tag))
22969         ;
22970       else
22971         if (unformat
22972             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22973              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22974              &rmt_port))
22975         {
22976           is_ip4 = 1;
22977           conn_set = 1;
22978         }
22979       else
22980         if (unformat
22981             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22982              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22983              &rmt_port))
22984         {
22985           is_ip4 = 0;
22986           conn_set = 1;
22987         }
22988       else if (unformat (i, "action %d", &action))
22989         ;
22990       else
22991         break;
22992     }
22993   if (proto == ~0 || !conn_set || action == ~0)
22994     {
22995       errmsg ("transport proto, connection and action must be set");
22996       return -99;
22997     }
22998
22999   if (scope > 3)
23000     {
23001       errmsg ("scope should be 0-3");
23002       return -99;
23003     }
23004
23005   M (SESSION_RULE_ADD_DEL, mp);
23006
23007   mp->is_ip4 = is_ip4;
23008   mp->transport_proto = proto;
23009   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23010   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23011   mp->lcl_plen = lcl_plen;
23012   mp->rmt_plen = rmt_plen;
23013   mp->action_index = clib_host_to_net_u32 (action);
23014   mp->appns_index = clib_host_to_net_u32 (appns_index);
23015   mp->scope = scope;
23016   mp->is_add = is_add;
23017   if (is_ip4)
23018     {
23019       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23020       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23021     }
23022   else
23023     {
23024       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23025       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23026     }
23027   if (tag)
23028     {
23029       clib_memcpy (mp->tag, tag, vec_len (tag));
23030       vec_free (tag);
23031     }
23032
23033   S (mp);
23034   W (ret);
23035   return ret;
23036 }
23037
23038 static int
23039 api_session_rules_dump (vat_main_t * vam)
23040 {
23041   vl_api_session_rules_dump_t *mp;
23042   vl_api_control_ping_t *mp_ping;
23043   int ret;
23044
23045   if (!vam->json_output)
23046     {
23047       print (vam->ofp, "%=20s", "Session Rules");
23048     }
23049
23050   M (SESSION_RULES_DUMP, mp);
23051   /* send it... */
23052   S (mp);
23053
23054   /* Use a control ping for synchronization */
23055   MPING (CONTROL_PING, mp_ping);
23056   S (mp_ping);
23057
23058   /* Wait for a reply... */
23059   W (ret);
23060   return ret;
23061 }
23062
23063 static int
23064 api_ip_container_proxy_add_del (vat_main_t * vam)
23065 {
23066   vl_api_ip_container_proxy_add_del_t *mp;
23067   unformat_input_t *i = vam->input;
23068   u32 plen = ~0, sw_if_index = ~0;
23069   ip4_address_t ip4;
23070   ip6_address_t ip6;
23071   u8 is_ip4 = 1;
23072   u8 is_add = 1;
23073   int ret;
23074
23075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23076     {
23077       if (unformat (i, "del"))
23078         is_add = 0;
23079       else if (unformat (i, "add"))
23080         ;
23081       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23082         {
23083           is_ip4 = 1;
23084           plen = 32;
23085         }
23086       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23087         {
23088           is_ip4 = 0;
23089           plen = 128;
23090         }
23091       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23092         ;
23093       else
23094         break;
23095     }
23096   if (sw_if_index == ~0 || plen == ~0)
23097     {
23098       errmsg ("address and sw_if_index must be set");
23099       return -99;
23100     }
23101
23102   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23103
23104   mp->is_ip4 = is_ip4;
23105   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23106   mp->plen = plen;
23107   mp->is_add = is_add;
23108   if (is_ip4)
23109     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23110   else
23111     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23112
23113   S (mp);
23114   W (ret);
23115   return ret;
23116 }
23117
23118 static int
23119 api_qos_record_enable_disable (vat_main_t * vam)
23120 {
23121   unformat_input_t *i = vam->input;
23122   vl_api_qos_record_enable_disable_t *mp;
23123   u32 sw_if_index, qs = 0xff;
23124   u8 sw_if_index_set = 0;
23125   u8 enable = 1;
23126   int ret;
23127
23128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23129     {
23130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23131         sw_if_index_set = 1;
23132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23133         sw_if_index_set = 1;
23134       else if (unformat (i, "%U", unformat_qos_source, &qs))
23135         ;
23136       else if (unformat (i, "disable"))
23137         enable = 0;
23138       else
23139         {
23140           clib_warning ("parse error '%U'", format_unformat_error, i);
23141           return -99;
23142         }
23143     }
23144
23145   if (sw_if_index_set == 0)
23146     {
23147       errmsg ("missing interface name or sw_if_index");
23148       return -99;
23149     }
23150   if (qs == 0xff)
23151     {
23152       errmsg ("input location must be specified");
23153       return -99;
23154     }
23155
23156   M (QOS_RECORD_ENABLE_DISABLE, mp);
23157
23158   mp->sw_if_index = ntohl (sw_if_index);
23159   mp->input_source = qs;
23160   mp->enable = enable;
23161
23162   S (mp);
23163   W (ret);
23164   return ret;
23165 }
23166
23167
23168 static int
23169 q_or_quit (vat_main_t * vam)
23170 {
23171 #if VPP_API_TEST_BUILTIN == 0
23172   longjmp (vam->jump_buf, 1);
23173 #endif
23174   return 0;                     /* not so much */
23175 }
23176
23177 static int
23178 q (vat_main_t * vam)
23179 {
23180   return q_or_quit (vam);
23181 }
23182
23183 static int
23184 quit (vat_main_t * vam)
23185 {
23186   return q_or_quit (vam);
23187 }
23188
23189 static int
23190 comment (vat_main_t * vam)
23191 {
23192   return 0;
23193 }
23194
23195 static int
23196 statseg (vat_main_t * vam)
23197 {
23198   ssvm_private_t *ssvmp = &vam->stat_segment;
23199   ssvm_shared_header_t *shared_header = ssvmp->sh;
23200   vlib_counter_t **counters;
23201   u64 thread0_index1_packets;
23202   u64 thread0_index1_bytes;
23203   f64 vector_rate, input_rate;
23204   uword *p;
23205
23206   uword *counter_vector_by_name;
23207   if (vam->stat_segment_lockp == 0)
23208     {
23209       errmsg ("Stat segment not mapped...");
23210       return -99;
23211     }
23212
23213   /* look up "/if/rx for sw_if_index 1 as a test */
23214
23215   clib_spinlock_lock (vam->stat_segment_lockp);
23216
23217   counter_vector_by_name = (uword *) shared_header->opaque[1];
23218
23219   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23220   if (p == 0)
23221     {
23222       clib_spinlock_unlock (vam->stat_segment_lockp);
23223       errmsg ("/if/tx not found?");
23224       return -99;
23225     }
23226
23227   /* Fish per-thread vector of combined counters from shared memory */
23228   counters = (vlib_counter_t **) p[0];
23229
23230   if (vec_len (counters[0]) < 2)
23231     {
23232       clib_spinlock_unlock (vam->stat_segment_lockp);
23233       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23234       return -99;
23235     }
23236
23237   /* Read thread 0 sw_if_index 1 counter */
23238   thread0_index1_packets = counters[0][1].packets;
23239   thread0_index1_bytes = counters[0][1].bytes;
23240
23241   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23242   if (p == 0)
23243     {
23244       clib_spinlock_unlock (vam->stat_segment_lockp);
23245       errmsg ("vector_rate not found?");
23246       return -99;
23247     }
23248
23249   vector_rate = *(f64 *) (p[0]);
23250   p = hash_get_mem (counter_vector_by_name, "input_rate");
23251   if (p == 0)
23252     {
23253       clib_spinlock_unlock (vam->stat_segment_lockp);
23254       errmsg ("input_rate not found?");
23255       return -99;
23256     }
23257   input_rate = *(f64 *) (p[0]);
23258
23259   clib_spinlock_unlock (vam->stat_segment_lockp);
23260
23261   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23262          vector_rate, input_rate);
23263   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23264          thread0_index1_packets, thread0_index1_bytes);
23265
23266   return 0;
23267 }
23268
23269 static int
23270 cmd_cmp (void *a1, void *a2)
23271 {
23272   u8 **c1 = a1;
23273   u8 **c2 = a2;
23274
23275   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23276 }
23277
23278 static int
23279 help (vat_main_t * vam)
23280 {
23281   u8 **cmds = 0;
23282   u8 *name = 0;
23283   hash_pair_t *p;
23284   unformat_input_t *i = vam->input;
23285   int j;
23286
23287   if (unformat (i, "%s", &name))
23288     {
23289       uword *hs;
23290
23291       vec_add1 (name, 0);
23292
23293       hs = hash_get_mem (vam->help_by_name, name);
23294       if (hs)
23295         print (vam->ofp, "usage: %s %s", name, hs[0]);
23296       else
23297         print (vam->ofp, "No such msg / command '%s'", name);
23298       vec_free (name);
23299       return 0;
23300     }
23301
23302   print (vam->ofp, "Help is available for the following:");
23303
23304     /* *INDENT-OFF* */
23305     hash_foreach_pair (p, vam->function_by_name,
23306     ({
23307       vec_add1 (cmds, (u8 *)(p->key));
23308     }));
23309     /* *INDENT-ON* */
23310
23311   vec_sort_with_function (cmds, cmd_cmp);
23312
23313   for (j = 0; j < vec_len (cmds); j++)
23314     print (vam->ofp, "%s", cmds[j]);
23315
23316   vec_free (cmds);
23317   return 0;
23318 }
23319
23320 static int
23321 set (vat_main_t * vam)
23322 {
23323   u8 *name = 0, *value = 0;
23324   unformat_input_t *i = vam->input;
23325
23326   if (unformat (i, "%s", &name))
23327     {
23328       /* The input buffer is a vector, not a string. */
23329       value = vec_dup (i->buffer);
23330       vec_delete (value, i->index, 0);
23331       /* Almost certainly has a trailing newline */
23332       if (value[vec_len (value) - 1] == '\n')
23333         value[vec_len (value) - 1] = 0;
23334       /* Make sure it's a proper string, one way or the other */
23335       vec_add1 (value, 0);
23336       (void) clib_macro_set_value (&vam->macro_main,
23337                                    (char *) name, (char *) value);
23338     }
23339   else
23340     errmsg ("usage: set <name> <value>");
23341
23342   vec_free (name);
23343   vec_free (value);
23344   return 0;
23345 }
23346
23347 static int
23348 unset (vat_main_t * vam)
23349 {
23350   u8 *name = 0;
23351
23352   if (unformat (vam->input, "%s", &name))
23353     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23354       errmsg ("unset: %s wasn't set", name);
23355   vec_free (name);
23356   return 0;
23357 }
23358
23359 typedef struct
23360 {
23361   u8 *name;
23362   u8 *value;
23363 } macro_sort_t;
23364
23365
23366 static int
23367 macro_sort_cmp (void *a1, void *a2)
23368 {
23369   macro_sort_t *s1 = a1;
23370   macro_sort_t *s2 = a2;
23371
23372   return strcmp ((char *) (s1->name), (char *) (s2->name));
23373 }
23374
23375 static int
23376 dump_macro_table (vat_main_t * vam)
23377 {
23378   macro_sort_t *sort_me = 0, *sm;
23379   int i;
23380   hash_pair_t *p;
23381
23382     /* *INDENT-OFF* */
23383     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23384     ({
23385       vec_add2 (sort_me, sm, 1);
23386       sm->name = (u8 *)(p->key);
23387       sm->value = (u8 *) (p->value[0]);
23388     }));
23389     /* *INDENT-ON* */
23390
23391   vec_sort_with_function (sort_me, macro_sort_cmp);
23392
23393   if (vec_len (sort_me))
23394     print (vam->ofp, "%-15s%s", "Name", "Value");
23395   else
23396     print (vam->ofp, "The macro table is empty...");
23397
23398   for (i = 0; i < vec_len (sort_me); i++)
23399     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23400   return 0;
23401 }
23402
23403 static int
23404 dump_node_table (vat_main_t * vam)
23405 {
23406   int i, j;
23407   vlib_node_t *node, *next_node;
23408
23409   if (vec_len (vam->graph_nodes) == 0)
23410     {
23411       print (vam->ofp, "Node table empty, issue get_node_graph...");
23412       return 0;
23413     }
23414
23415   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23416     {
23417       node = vam->graph_nodes[0][i];
23418       print (vam->ofp, "[%d] %s", i, node->name);
23419       for (j = 0; j < vec_len (node->next_nodes); j++)
23420         {
23421           if (node->next_nodes[j] != ~0)
23422             {
23423               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23424               print (vam->ofp, "  [%d] %s", j, next_node->name);
23425             }
23426         }
23427     }
23428   return 0;
23429 }
23430
23431 static int
23432 value_sort_cmp (void *a1, void *a2)
23433 {
23434   name_sort_t *n1 = a1;
23435   name_sort_t *n2 = a2;
23436
23437   if (n1->value < n2->value)
23438     return -1;
23439   if (n1->value > n2->value)
23440     return 1;
23441   return 0;
23442 }
23443
23444
23445 static int
23446 dump_msg_api_table (vat_main_t * vam)
23447 {
23448   api_main_t *am = &api_main;
23449   name_sort_t *nses = 0, *ns;
23450   hash_pair_t *hp;
23451   int i;
23452
23453   /* *INDENT-OFF* */
23454   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23455   ({
23456     vec_add2 (nses, ns, 1);
23457     ns->name = (u8 *)(hp->key);
23458     ns->value = (u32) hp->value[0];
23459   }));
23460   /* *INDENT-ON* */
23461
23462   vec_sort_with_function (nses, value_sort_cmp);
23463
23464   for (i = 0; i < vec_len (nses); i++)
23465     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23466   vec_free (nses);
23467   return 0;
23468 }
23469
23470 static int
23471 get_msg_id (vat_main_t * vam)
23472 {
23473   u8 *name_and_crc;
23474   u32 message_index;
23475
23476   if (unformat (vam->input, "%s", &name_and_crc))
23477     {
23478       message_index = vl_msg_api_get_msg_index (name_and_crc);
23479       if (message_index == ~0)
23480         {
23481           print (vam->ofp, " '%s' not found", name_and_crc);
23482           return 0;
23483         }
23484       print (vam->ofp, " '%s' has message index %d",
23485              name_and_crc, message_index);
23486       return 0;
23487     }
23488   errmsg ("name_and_crc required...");
23489   return 0;
23490 }
23491
23492 static int
23493 search_node_table (vat_main_t * vam)
23494 {
23495   unformat_input_t *line_input = vam->input;
23496   u8 *node_to_find;
23497   int j;
23498   vlib_node_t *node, *next_node;
23499   uword *p;
23500
23501   if (vam->graph_node_index_by_name == 0)
23502     {
23503       print (vam->ofp, "Node table empty, issue get_node_graph...");
23504       return 0;
23505     }
23506
23507   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23508     {
23509       if (unformat (line_input, "%s", &node_to_find))
23510         {
23511           vec_add1 (node_to_find, 0);
23512           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23513           if (p == 0)
23514             {
23515               print (vam->ofp, "%s not found...", node_to_find);
23516               goto out;
23517             }
23518           node = vam->graph_nodes[0][p[0]];
23519           print (vam->ofp, "[%d] %s", p[0], node->name);
23520           for (j = 0; j < vec_len (node->next_nodes); j++)
23521             {
23522               if (node->next_nodes[j] != ~0)
23523                 {
23524                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23525                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23526                 }
23527             }
23528         }
23529
23530       else
23531         {
23532           clib_warning ("parse error '%U'", format_unformat_error,
23533                         line_input);
23534           return -99;
23535         }
23536
23537     out:
23538       vec_free (node_to_find);
23539
23540     }
23541
23542   return 0;
23543 }
23544
23545
23546 static int
23547 script (vat_main_t * vam)
23548 {
23549 #if (VPP_API_TEST_BUILTIN==0)
23550   u8 *s = 0;
23551   char *save_current_file;
23552   unformat_input_t save_input;
23553   jmp_buf save_jump_buf;
23554   u32 save_line_number;
23555
23556   FILE *new_fp, *save_ifp;
23557
23558   if (unformat (vam->input, "%s", &s))
23559     {
23560       new_fp = fopen ((char *) s, "r");
23561       if (new_fp == 0)
23562         {
23563           errmsg ("Couldn't open script file %s", s);
23564           vec_free (s);
23565           return -99;
23566         }
23567     }
23568   else
23569     {
23570       errmsg ("Missing script name");
23571       return -99;
23572     }
23573
23574   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23575   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23576   save_ifp = vam->ifp;
23577   save_line_number = vam->input_line_number;
23578   save_current_file = (char *) vam->current_file;
23579
23580   vam->input_line_number = 0;
23581   vam->ifp = new_fp;
23582   vam->current_file = s;
23583   do_one_file (vam);
23584
23585   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23586   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23587   vam->ifp = save_ifp;
23588   vam->input_line_number = save_line_number;
23589   vam->current_file = (u8 *) save_current_file;
23590   vec_free (s);
23591
23592   return 0;
23593 #else
23594   clib_warning ("use the exec command...");
23595   return -99;
23596 #endif
23597 }
23598
23599 static int
23600 echo (vat_main_t * vam)
23601 {
23602   print (vam->ofp, "%v", vam->input->buffer);
23603   return 0;
23604 }
23605
23606 /* List of API message constructors, CLI names map to api_xxx */
23607 #define foreach_vpe_api_msg                                             \
23608 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23609 _(sw_interface_dump,"")                                                 \
23610 _(sw_interface_set_flags,                                               \
23611   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23612 _(sw_interface_add_del_address,                                         \
23613   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23614 _(sw_interface_set_rx_mode,                                             \
23615   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23616 _(sw_interface_set_rx_placement,                                        \
23617   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23618 _(sw_interface_rx_placement_dump,                                       \
23619   "[<intfc> | sw_if_index <id>]")                                         \
23620 _(sw_interface_set_table,                                               \
23621   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23622 _(sw_interface_set_mpls_enable,                                         \
23623   "<intfc> | sw_if_index [disable | dis]")                              \
23624 _(sw_interface_set_vpath,                                               \
23625   "<intfc> | sw_if_index <id> enable | disable")                        \
23626 _(sw_interface_set_vxlan_bypass,                                        \
23627   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23628 _(sw_interface_set_geneve_bypass,                                       \
23629   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23630 _(sw_interface_set_l2_xconnect,                                         \
23631   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23632   "enable | disable")                                                   \
23633 _(sw_interface_set_l2_bridge,                                           \
23634   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23635   "[shg <split-horizon-group>] [bvi]\n"                                 \
23636   "enable | disable")                                                   \
23637 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23638 _(bridge_domain_add_del,                                                \
23639   "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") \
23640 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23641 _(l2fib_add_del,                                                        \
23642   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23643 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23644 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23645 _(l2_flags,                                                             \
23646   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23647 _(bridge_flags,                                                         \
23648   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23649 _(tap_connect,                                                          \
23650   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23651 _(tap_modify,                                                           \
23652   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23653 _(tap_delete,                                                           \
23654   "<vpp-if-name> | sw_if_index <id>")                                   \
23655 _(sw_interface_tap_dump, "")                                            \
23656 _(tap_create_v2,                                                        \
23657   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23658 _(tap_delete_v2,                                                        \
23659   "<vpp-if-name> | sw_if_index <id>")                                   \
23660 _(sw_interface_tap_v2_dump, "")                                         \
23661 _(bond_create,                                                          \
23662   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23663   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23664 _(bond_delete,                                                          \
23665   "<vpp-if-name> | sw_if_index <id>")                                   \
23666 _(bond_enslave,                                                         \
23667   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23668 _(bond_detach_slave,                                                    \
23669   "sw_if_index <n>")                                                    \
23670 _(sw_interface_bond_dump, "")                                           \
23671 _(sw_interface_slave_dump,                                              \
23672   "<vpp-if-name> | sw_if_index <id>")                                   \
23673 _(ip_table_add_del,                                                     \
23674   "table <n> [ipv6] [add | del]\n")                                     \
23675 _(ip_add_del_route,                                                     \
23676   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23677   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23678   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23679   "[multipath] [count <n>]")                                            \
23680 _(ip_mroute_add_del,                                                    \
23681   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23682   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23683 _(mpls_table_add_del,                                                   \
23684   "table <n> [add | del]\n")                                            \
23685 _(mpls_route_add_del,                                                   \
23686   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23687   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23688   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23689   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23690   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23691 _(mpls_ip_bind_unbind,                                                  \
23692   "<label> <addr/len>")                                                 \
23693 _(mpls_tunnel_add_del,                                                  \
23694   " via <addr> [table-id <n>]\n"                                        \
23695   "sw_if_index <id>] [l2]  [del]")                                      \
23696 _(sr_mpls_policy_add,                                                   \
23697   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23698 _(sr_mpls_policy_del,                                                   \
23699   "bsid <id>")                                                          \
23700 _(bier_table_add_del,                                                   \
23701   "<label> <sub-domain> <set> <bsl> [del]")                             \
23702 _(bier_route_add_del,                                                   \
23703   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23704   "[<intfc> | sw_if_index <id>]"                                        \
23705   "[weight <n>] [del] [multipath]")                                     \
23706 _(proxy_arp_add_del,                                                    \
23707   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23708 _(proxy_arp_intfc_enable_disable,                                       \
23709   "<intfc> | sw_if_index <id> enable | disable")                        \
23710 _(sw_interface_set_unnumbered,                                          \
23711   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23712 _(ip_neighbor_add_del,                                                  \
23713   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23714   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23715 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23716 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23717   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23718   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23719   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23720 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23721 _(reset_fib, "vrf <n> [ipv6]")                                          \
23722 _(dhcp_proxy_config,                                                    \
23723   "svr <v46-address> src <v46-address>\n"                               \
23724    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23725 _(dhcp_proxy_set_vss,                                                   \
23726   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23727 _(dhcp_proxy_dump, "ip6")                                               \
23728 _(dhcp_client_config,                                                   \
23729   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23730 _(set_ip_flow_hash,                                                     \
23731   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23732 _(sw_interface_ip6_enable_disable,                                      \
23733   "<intfc> | sw_if_index <id> enable | disable")                        \
23734 _(sw_interface_ip6_set_link_local_address,                              \
23735   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23736 _(ip6nd_proxy_add_del,                                                  \
23737   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23738 _(ip6nd_proxy_dump, "")                                                 \
23739 _(sw_interface_ip6nd_ra_prefix,                                         \
23740   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23741   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23742   "[nolink] [isno]")                                                    \
23743 _(sw_interface_ip6nd_ra_config,                                         \
23744   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23745   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23746   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23747 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23748 _(l2_patch_add_del,                                                     \
23749   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23750   "enable | disable")                                                   \
23751 _(sr_localsid_add_del,                                                  \
23752   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23753   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23754 _(classify_add_del_table,                                               \
23755   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23756   " [del] [del-chain] mask <mask-value>\n"                              \
23757   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23758   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23759 _(classify_add_del_session,                                             \
23760   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23761   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23762   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23763   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23764 _(classify_set_interface_ip_table,                                      \
23765   "<intfc> | sw_if_index <nn> table <nn>")                              \
23766 _(classify_set_interface_l2_tables,                                     \
23767   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23768   "  [other-table <nn>]")                                               \
23769 _(get_node_index, "node <node-name")                                    \
23770 _(add_node_next, "node <node-name> next <next-node-name>")              \
23771 _(l2tpv3_create_tunnel,                                                 \
23772   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23773   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23774   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23775 _(l2tpv3_set_tunnel_cookies,                                            \
23776   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23777   "[new_remote_cookie <nn>]\n")                                         \
23778 _(l2tpv3_interface_enable_disable,                                      \
23779   "<intfc> | sw_if_index <nn> enable | disable")                        \
23780 _(l2tpv3_set_lookup_key,                                                \
23781   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23782 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23783 _(vxlan_offload_rx,                                                     \
23784   "hw { <interface name> | hw_if_index <nn>} "                          \
23785   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23786 _(vxlan_add_del_tunnel,                                                 \
23787   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23788   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23789   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23790 _(geneve_add_del_tunnel,                                                \
23791   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23792   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23793   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23794 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23795 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23796 _(gre_add_del_tunnel,                                                   \
23797   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23798   "[teb | erspan <session-id>] [del]")                                  \
23799 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23800 _(l2_fib_clear_table, "")                                               \
23801 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23802 _(l2_interface_vlan_tag_rewrite,                                        \
23803   "<intfc> | sw_if_index <nn> \n"                                       \
23804   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23805   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23806 _(create_vhost_user_if,                                                 \
23807         "socket <filename> [server] [renumber <dev_instance>] "         \
23808         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23809         "[mac <mac_address>]")                                          \
23810 _(modify_vhost_user_if,                                                 \
23811         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23812         "[server] [renumber <dev_instance>]")                           \
23813 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23814 _(sw_interface_vhost_user_dump, "")                                     \
23815 _(show_version, "")                                                     \
23816 _(show_threads, "")                                                     \
23817 _(vxlan_gpe_add_del_tunnel,                                             \
23818   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23819   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23820   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23821   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23822 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23823 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23824 _(interface_name_renumber,                                              \
23825   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23826 _(input_acl_set_interface,                                              \
23827   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23828   "  [l2-table <nn>] [del]")                                            \
23829 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23830 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23831   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23832 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23833 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23834 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23835 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23836 _(ip_dump, "ipv4 | ipv6")                                               \
23837 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23838 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23839   "  spid_id <n> ")                                                     \
23840 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23841   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23842   "  integ_alg <alg> integ_key <hex>")                                  \
23843 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23844   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23845   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23846   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23847 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23848 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23849   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23850   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23851   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23852   "  [instance <n>]")     \
23853 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23854 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23855   "  <alg> <hex>\n")                                                    \
23856 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23857 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23858 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23859   "(auth_data 0x<data> | auth_data <data>)")                            \
23860 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23861   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23862 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23863   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23864   "(local|remote)")                                                     \
23865 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23866 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23867 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23868 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23869 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23870 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23871 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23872 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23873 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23874 _(delete_loopback,"sw_if_index <nn>")                                   \
23875 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23876 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23877 _(want_interface_events,  "enable|disable")                             \
23878 _(want_stats,"enable|disable")                                          \
23879 _(get_first_msg_id, "client <name>")                                    \
23880 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23881 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23882   "fib-id <nn> [ip4][ip6][default]")                                    \
23883 _(get_node_graph, " ")                                                  \
23884 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23885 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23886 _(ioam_disable, "")                                                     \
23887 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23888                             " sw_if_index <sw_if_index> p <priority> "  \
23889                             "w <weight>] [del]")                        \
23890 _(one_add_del_locator, "locator-set <locator_name> "                    \
23891                         "iface <intf> | sw_if_index <sw_if_index> "     \
23892                         "p <priority> w <weight> [del]")                \
23893 _(one_add_del_local_eid,"vni <vni> eid "                                \
23894                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23895                          "locator-set <locator_name> [del]"             \
23896                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23897 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23898 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23899 _(one_enable_disable, "enable|disable")                                 \
23900 _(one_map_register_enable_disable, "enable|disable")                    \
23901 _(one_map_register_fallback_threshold, "<value>")                       \
23902 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23903 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23904                                "[seid <seid>] "                         \
23905                                "rloc <locator> p <prio> "               \
23906                                "w <weight> [rloc <loc> ... ] "          \
23907                                "action <action> [del-all]")             \
23908 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23909                           "<local-eid>")                                \
23910 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23911 _(one_use_petr, "ip-address> | disable")                                \
23912 _(one_map_request_mode, "src-dst|dst-only")                             \
23913 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23914 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23915 _(one_locator_set_dump, "[local | remote]")                             \
23916 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23917 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23918                        "[local] | [remote]")                            \
23919 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23920 _(one_ndp_bd_get, "")                                                   \
23921 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23922 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23923 _(one_l2_arp_bd_get, "")                                                \
23924 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23925 _(one_stats_enable_disable, "enable|disable")                           \
23926 _(show_one_stats_enable_disable, "")                                    \
23927 _(one_eid_table_vni_dump, "")                                           \
23928 _(one_eid_table_map_dump, "l2|l3")                                      \
23929 _(one_map_resolver_dump, "")                                            \
23930 _(one_map_server_dump, "")                                              \
23931 _(one_adjacencies_get, "vni <vni>")                                     \
23932 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23933 _(show_one_rloc_probe_state, "")                                        \
23934 _(show_one_map_register_state, "")                                      \
23935 _(show_one_status, "")                                                  \
23936 _(one_stats_dump, "")                                                   \
23937 _(one_stats_flush, "")                                                  \
23938 _(one_get_map_request_itr_rlocs, "")                                    \
23939 _(one_map_register_set_ttl, "<ttl>")                                    \
23940 _(one_set_transport_protocol, "udp|api")                                \
23941 _(one_get_transport_protocol, "")                                       \
23942 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23943 _(one_show_xtr_mode, "")                                                \
23944 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23945 _(one_show_pitr_mode, "")                                               \
23946 _(one_enable_disable_petr_mode, "enable|disable")                       \
23947 _(one_show_petr_mode, "")                                               \
23948 _(show_one_nsh_mapping, "")                                             \
23949 _(show_one_pitr, "")                                                    \
23950 _(show_one_use_petr, "")                                                \
23951 _(show_one_map_request_mode, "")                                        \
23952 _(show_one_map_register_ttl, "")                                        \
23953 _(show_one_map_register_fallback_threshold, "")                         \
23954 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23955                             " sw_if_index <sw_if_index> p <priority> "  \
23956                             "w <weight>] [del]")                        \
23957 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23958                         "iface <intf> | sw_if_index <sw_if_index> "     \
23959                         "p <priority> w <weight> [del]")                \
23960 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23961                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23962                          "locator-set <locator_name> [del]"             \
23963                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23964 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23965 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23966 _(lisp_enable_disable, "enable|disable")                                \
23967 _(lisp_map_register_enable_disable, "enable|disable")                   \
23968 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23969 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23970                                "[seid <seid>] "                         \
23971                                "rloc <locator> p <prio> "               \
23972                                "w <weight> [rloc <loc> ... ] "          \
23973                                "action <action> [del-all]")             \
23974 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23975                           "<local-eid>")                                \
23976 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23977 _(lisp_use_petr, "<ip-address> | disable")                              \
23978 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23979 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23980 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23981 _(lisp_locator_set_dump, "[local | remote]")                            \
23982 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23983 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23984                        "[local] | [remote]")                            \
23985 _(lisp_eid_table_vni_dump, "")                                          \
23986 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23987 _(lisp_map_resolver_dump, "")                                           \
23988 _(lisp_map_server_dump, "")                                             \
23989 _(lisp_adjacencies_get, "vni <vni>")                                    \
23990 _(gpe_fwd_entry_vnis_get, "")                                           \
23991 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23992 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23993                                 "[table <table-id>]")                   \
23994 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23995 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23996 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23997 _(gpe_get_encap_mode, "")                                               \
23998 _(lisp_gpe_add_del_iface, "up|down")                                    \
23999 _(lisp_gpe_enable_disable, "enable|disable")                            \
24000 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24001   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24002 _(show_lisp_rloc_probe_state, "")                                       \
24003 _(show_lisp_map_register_state, "")                                     \
24004 _(show_lisp_status, "")                                                 \
24005 _(lisp_get_map_request_itr_rlocs, "")                                   \
24006 _(show_lisp_pitr, "")                                                   \
24007 _(show_lisp_use_petr, "")                                               \
24008 _(show_lisp_map_request_mode, "")                                       \
24009 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24010 _(af_packet_delete, "name <host interface name>")                       \
24011 _(af_packet_dump, "")                                                   \
24012 _(policer_add_del, "name <policer name> <params> [del]")                \
24013 _(policer_dump, "[name <policer name>]")                                \
24014 _(policer_classify_set_interface,                                       \
24015   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24016   "  [l2-table <nn>] [del]")                                            \
24017 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24018 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24019     "[master|slave]")                                                   \
24020 _(netmap_delete, "name <interface name>")                               \
24021 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24022 _(mpls_fib_dump, "")                                                    \
24023 _(classify_table_ids, "")                                               \
24024 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24025 _(classify_table_info, "table_id <nn>")                                 \
24026 _(classify_session_dump, "table_id <nn>")                               \
24027 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24028     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24029     "[template_interval <nn>] [udp_checksum]")                          \
24030 _(ipfix_exporter_dump, "")                                              \
24031 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24032 _(ipfix_classify_stream_dump, "")                                       \
24033 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24034 _(ipfix_classify_table_dump, "")                                        \
24035 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24036 _(sw_interface_span_dump, "[l2]")                                           \
24037 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24038 _(pg_create_interface, "if_id <nn>")                                    \
24039 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24040 _(pg_enable_disable, "[stream <id>] disable")                           \
24041 _(ip_source_and_port_range_check_add_del,                               \
24042   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24043 _(ip_source_and_port_range_check_interface_add_del,                     \
24044   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24045   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24046 _(ipsec_gre_add_del_tunnel,                                             \
24047   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24048 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24049 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24050 _(l2_interface_pbb_tag_rewrite,                                         \
24051   "<intfc> | sw_if_index <nn> \n"                                       \
24052   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24053   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24054 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24055 _(flow_classify_set_interface,                                          \
24056   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24057 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24058 _(ip_fib_dump, "")                                                      \
24059 _(ip_mfib_dump, "")                                                     \
24060 _(ip6_fib_dump, "")                                                     \
24061 _(ip6_mfib_dump, "")                                                    \
24062 _(feature_enable_disable, "arc_name <arc_name> "                        \
24063   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24064 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24065 "[disable]")                                                            \
24066 _(l2_xconnect_dump, "")                                                 \
24067 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24068 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24069 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24070 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24071 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24072 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24073 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24074   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24075 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24076 _(sock_init_shm, "size <nnn>")                                          \
24077 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24078 _(dns_enable_disable, "[enable][disable]")                              \
24079 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24080 _(dns_resolve_name, "<hostname>")                                       \
24081 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24082 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24083 _(dns_resolve_name, "<hostname>")                                       \
24084 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24085   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24086 _(session_rules_dump, "")                                               \
24087 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24088 _(output_acl_set_interface,                                             \
24089   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24090   "  [l2-table <nn>] [del]")                                            \
24091 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24092
24093 /* List of command functions, CLI names map directly to functions */
24094 #define foreach_cli_function                                    \
24095 _(comment, "usage: comment <ignore-rest-of-line>")              \
24096 _(dump_interface_table, "usage: dump_interface_table")          \
24097 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24098 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24099 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24100 _(dump_stats_table, "usage: dump_stats_table")                  \
24101 _(dump_macro_table, "usage: dump_macro_table ")                 \
24102 _(dump_node_table, "usage: dump_node_table")                    \
24103 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24104 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24105 _(echo, "usage: echo <message>")                                \
24106 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24107 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24108 _(help, "usage: help")                                          \
24109 _(q, "usage: quit")                                             \
24110 _(quit, "usage: quit")                                          \
24111 _(search_node_table, "usage: search_node_table <name>...")      \
24112 _(set, "usage: set <variable-name> <value>")                    \
24113 _(script, "usage: script <file-name>")                          \
24114 _(statseg, "usage: statseg");                                   \
24115 _(unset, "usage: unset <variable-name>")
24116
24117 #define _(N,n)                                  \
24118     static void vl_api_##n##_t_handler_uni      \
24119     (vl_api_##n##_t * mp)                       \
24120     {                                           \
24121         vat_main_t * vam = &vat_main;           \
24122         if (vam->json_output) {                 \
24123             vl_api_##n##_t_handler_json(mp);    \
24124         } else {                                \
24125             vl_api_##n##_t_handler(mp);         \
24126         }                                       \
24127     }
24128 foreach_vpe_api_reply_msg;
24129 #if VPP_API_TEST_BUILTIN == 0
24130 foreach_standalone_reply_msg;
24131 #endif
24132 #undef _
24133
24134 void
24135 vat_api_hookup (vat_main_t * vam)
24136 {
24137 #define _(N,n)                                                  \
24138     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24139                            vl_api_##n##_t_handler_uni,          \
24140                            vl_noop_handler,                     \
24141                            vl_api_##n##_t_endian,               \
24142                            vl_api_##n##_t_print,                \
24143                            sizeof(vl_api_##n##_t), 1);
24144   foreach_vpe_api_reply_msg;
24145 #if VPP_API_TEST_BUILTIN == 0
24146   foreach_standalone_reply_msg;
24147 #endif
24148 #undef _
24149
24150 #if (VPP_API_TEST_BUILTIN==0)
24151   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24152
24153   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24154
24155   vam->function_by_name = hash_create_string (0, sizeof (uword));
24156
24157   vam->help_by_name = hash_create_string (0, sizeof (uword));
24158 #endif
24159
24160   /* API messages we can send */
24161 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24162   foreach_vpe_api_msg;
24163 #undef _
24164
24165   /* Help strings */
24166 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24167   foreach_vpe_api_msg;
24168 #undef _
24169
24170   /* CLI functions */
24171 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24172   foreach_cli_function;
24173 #undef _
24174
24175   /* Help strings */
24176 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24177   foreach_cli_function;
24178 #undef _
24179 }
24180
24181 #if VPP_API_TEST_BUILTIN
24182 static clib_error_t *
24183 vat_api_hookup_shim (vlib_main_t * vm)
24184 {
24185   vat_api_hookup (&vat_main);
24186   return 0;
24187 }
24188
24189 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24190 #endif
24191
24192 /*
24193  * fd.io coding-style-patch-verification: ON
24194  *
24195  * Local Variables:
24196  * eval: (c-set-style "gnu")
24197  * End:
24198  */