vhost-user: Add disable feature support in 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
1323 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1324 {
1325   u32 sw_if_index = ntohl (mp->sw_if_index);
1326   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1327           mp->mac_ip ? "mac/ip binding" : "address resolution",
1328           ntohl (mp->pid), format_ip4_address, &mp->address,
1329           format_ethernet_address, mp->new_mac, sw_if_index);
1330 }
1331
1332 static void
1333 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1334 {
1335   /* JSON output not supported */
1336 }
1337
1338 static void
1339 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1340 {
1341   u32 sw_if_index = ntohl (mp->sw_if_index);
1342   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1343           mp->mac_ip ? "mac/ip binding" : "address resolution",
1344           ntohl (mp->pid), format_ip6_address, mp->address,
1345           format_ethernet_address, mp->new_mac, sw_if_index);
1346 }
1347
1348 static void
1349 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1350 {
1351   /* JSON output not supported */
1352 }
1353
1354 static void
1355 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1356 {
1357   u32 n_macs = ntohl (mp->n_macs);
1358   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1359           ntohl (mp->pid), mp->client_index, n_macs);
1360   int i;
1361   for (i = 0; i < n_macs; i++)
1362     {
1363       vl_api_mac_entry_t *mac = &mp->mac[i];
1364       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1365               i + 1, ntohl (mac->sw_if_index),
1366               format_ethernet_address, mac->mac_addr, mac->action);
1367       if (i == 1000)
1368         break;
1369     }
1370 }
1371
1372 static void
1373 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1374 {
1375   /* JSON output not supported */
1376 }
1377
1378 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1379 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1380
1381 /*
1382  * Special-case: build the bridge domain table, maintain
1383  * the next bd id vbl.
1384  */
1385 static void vl_api_bridge_domain_details_t_handler
1386   (vl_api_bridge_domain_details_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1390   int i;
1391
1392   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1398
1399   if (n_sw_ifs)
1400     {
1401       vl_api_bridge_domain_sw_if_t *sw_ifs;
1402       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1403              "Interface Name");
1404
1405       sw_ifs = mp->sw_if_details;
1406       for (i = 0; i < n_sw_ifs; i++)
1407         {
1408           u8 *sw_if_name = 0;
1409           u32 sw_if_index;
1410           hash_pair_t *p;
1411
1412           sw_if_index = ntohl (sw_ifs->sw_if_index);
1413
1414           /* *INDENT-OFF* */
1415           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1416                              ({
1417                                if ((u32) p->value[0] == sw_if_index)
1418                                  {
1419                                    sw_if_name = (u8 *)(p->key);
1420                                    break;
1421                                  }
1422                              }));
1423           /* *INDENT-ON* */
1424           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1425                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1426                  "sw_if_index not found!");
1427
1428           sw_ifs++;
1429         }
1430     }
1431 }
1432
1433 static void vl_api_bridge_domain_details_t_handler_json
1434   (vl_api_bridge_domain_details_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   vat_json_node_t *node, *array = NULL;
1438   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1439
1440   if (VAT_JSON_ARRAY != vam->json_tree.type)
1441     {
1442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1443       vat_json_init_array (&vam->json_tree);
1444     }
1445   node = vat_json_array_add (&vam->json_tree);
1446
1447   vat_json_init_object (node);
1448   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1449   vat_json_object_add_uint (node, "flood", mp->flood);
1450   vat_json_object_add_uint (node, "forward", mp->forward);
1451   vat_json_object_add_uint (node, "learn", mp->learn);
1452   vat_json_object_add_uint (node, "bvi_sw_if_index",
1453                             ntohl (mp->bvi_sw_if_index));
1454   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1455   array = vat_json_object_add (node, "sw_if");
1456   vat_json_init_array (array);
1457
1458
1459
1460   if (n_sw_ifs)
1461     {
1462       vl_api_bridge_domain_sw_if_t *sw_ifs;
1463       int i;
1464
1465       sw_ifs = mp->sw_if_details;
1466       for (i = 0; i < n_sw_ifs; i++)
1467         {
1468           node = vat_json_array_add (array);
1469           vat_json_init_object (node);
1470           vat_json_object_add_uint (node, "sw_if_index",
1471                                     ntohl (sw_ifs->sw_if_index));
1472           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1473           sw_ifs++;
1474         }
1475     }
1476 }
1477
1478 static void vl_api_control_ping_reply_t_handler
1479   (vl_api_control_ping_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   i32 retval = ntohl (mp->retval);
1483   if (vam->async_mode)
1484     {
1485       vam->async_errors += (retval < 0);
1486     }
1487   else
1488     {
1489       vam->retval = retval;
1490       vam->result_ready = 1;
1491     }
1492   if (vam->socket_client_main)
1493     vam->socket_client_main->control_pings_outstanding--;
1494 }
1495
1496 static void vl_api_control_ping_reply_t_handler_json
1497   (vl_api_control_ping_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501
1502   if (VAT_JSON_NONE != vam->json_tree.type)
1503     {
1504       vat_json_print (vam->ofp, &vam->json_tree);
1505       vat_json_free (&vam->json_tree);
1506       vam->json_tree.type = VAT_JSON_NONE;
1507     }
1508   else
1509     {
1510       /* just print [] */
1511       vat_json_init_array (&vam->json_tree);
1512       vat_json_print (vam->ofp, &vam->json_tree);
1513       vam->json_tree.type = VAT_JSON_NONE;
1514     }
1515
1516   vam->retval = retval;
1517   vam->result_ready = 1;
1518 }
1519
1520 static void
1521   vl_api_bridge_domain_set_mac_age_reply_t_handler
1522   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   i32 retval = ntohl (mp->retval);
1526   if (vam->async_mode)
1527     {
1528       vam->async_errors += (retval < 0);
1529     }
1530   else
1531     {
1532       vam->retval = retval;
1533       vam->result_ready = 1;
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1538   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t node;
1542
1543   vat_json_init_object (&node);
1544   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1545
1546   vat_json_print (vam->ofp, &node);
1547   vat_json_free (&node);
1548
1549   vam->retval = ntohl (mp->retval);
1550   vam->result_ready = 1;
1551 }
1552
1553 static void
1554 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_l2_flags_reply_t_handler_json
1570   (vl_api_l2_flags_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1578                             ntohl (mp->resulting_feature_bitmap));
1579
1580   vat_json_print (vam->ofp, &node);
1581   vat_json_free (&node);
1582
1583   vam->retval = ntohl (mp->retval);
1584   vam->result_ready = 1;
1585 }
1586
1587 static void vl_api_bridge_flags_reply_t_handler
1588   (vl_api_bridge_flags_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_bridge_flags_reply_t_handler_json
1604   (vl_api_bridge_flags_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1612                             ntohl (mp->resulting_feature_bitmap));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void vl_api_tap_connect_reply_t_handler
1622   (vl_api_tap_connect_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->sw_if_index = ntohl (mp->sw_if_index);
1634       vam->result_ready = 1;
1635     }
1636
1637 }
1638
1639 static void vl_api_tap_connect_reply_t_handler_json
1640   (vl_api_tap_connect_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   vat_json_node_t node;
1644
1645   vat_json_init_object (&node);
1646   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654
1655 }
1656
1657 static void
1658 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->sw_if_index = ntohl (mp->sw_if_index);
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_tap_modify_reply_t_handler_json
1675   (vl_api_tap_modify_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void
1692 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_tap_delete_reply_t_handler_json
1708   (vl_api_tap_delete_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715
1716   vat_json_print (vam->ofp, &node);
1717   vat_json_free (&node);
1718
1719   vam->retval = ntohl (mp->retval);
1720   vam->result_ready = 1;
1721 }
1722
1723 static void
1724 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   i32 retval = ntohl (mp->retval);
1728   if (vam->async_mode)
1729     {
1730       vam->async_errors += (retval < 0);
1731     }
1732   else
1733     {
1734       vam->retval = retval;
1735       vam->sw_if_index = ntohl (mp->sw_if_index);
1736       vam->result_ready = 1;
1737     }
1738
1739 }
1740
1741 static void vl_api_tap_create_v2_reply_t_handler_json
1742   (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   vat_json_node_t node;
1746
1747   vat_json_init_object (&node);
1748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751   vat_json_print (vam->ofp, &node);
1752   vat_json_free (&node);
1753
1754   vam->retval = ntohl (mp->retval);
1755   vam->result_ready = 1;
1756
1757 }
1758
1759 static void
1760 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->result_ready = 1;
1772     }
1773 }
1774
1775 static void vl_api_tap_delete_v2_reply_t_handler_json
1776   (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   vat_json_node_t node;
1780
1781   vat_json_init_object (&node);
1782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784   vat_json_print (vam->ofp, &node);
1785   vat_json_free (&node);
1786
1787   vam->retval = ntohl (mp->retval);
1788   vam->result_ready = 1;
1789 }
1790
1791 static void
1792 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796
1797   if (vam->async_mode)
1798     {
1799       vam->async_errors += (retval < 0);
1800     }
1801   else
1802     {
1803       vam->retval = retval;
1804       vam->sw_if_index = ntohl (mp->sw_if_index);
1805       vam->result_ready = 1;
1806     }
1807 }
1808
1809 static void vl_api_bond_create_reply_t_handler_json
1810   (vl_api_bond_create_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   vat_json_node_t node;
1814
1815   vat_json_init_object (&node);
1816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819   vat_json_print (vam->ofp, &node);
1820   vat_json_free (&node);
1821
1822   vam->retval = ntohl (mp->retval);
1823   vam->result_ready = 1;
1824 }
1825
1826 static void
1827 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   i32 retval = ntohl (mp->retval);
1831
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->result_ready = 1;
1840     }
1841 }
1842
1843 static void vl_api_bond_delete_reply_t_handler_json
1844   (vl_api_bond_delete_reply_t * mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   vat_json_node_t node;
1848
1849   vat_json_init_object (&node);
1850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   i32 retval = ntohl (mp->retval);
1864
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_bond_enslave_reply_t_handler_json
1877   (vl_api_bond_enslave_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1894                                           mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   i32 retval = ntohl (mp->retval);
1898
1899   if (vam->async_mode)
1900     {
1901       vam->async_errors += (retval < 0);
1902     }
1903   else
1904     {
1905       vam->retval = retval;
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_detach_slave_reply_t_handler_json
1911   (vl_api_bond_detach_slave_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918
1919   vat_json_print (vam->ofp, &node);
1920   vat_json_free (&node);
1921
1922   vam->retval = ntohl (mp->retval);
1923   vam->result_ready = 1;
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   print (vam->ofp,
1932          "%-16s %-12d %-12U %-13U %-14u %-14u",
1933          mp->interface_name, ntohl (mp->sw_if_index),
1934          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1935          ntohl (mp->active_slaves), ntohl (mp->slaves));
1936 }
1937
1938 static void vl_api_sw_interface_bond_details_t_handler_json
1939   (vl_api_sw_interface_bond_details_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   vat_json_node_t *node = NULL;
1943
1944   if (VAT_JSON_ARRAY != vam->json_tree.type)
1945     {
1946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1947       vat_json_init_array (&vam->json_tree);
1948     }
1949   node = vat_json_array_add (&vam->json_tree);
1950
1951   vat_json_init_object (node);
1952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1953   vat_json_object_add_string_copy (node, "interface_name",
1954                                    mp->interface_name);
1955   vat_json_object_add_uint (node, "mode", mp->mode);
1956   vat_json_object_add_uint (node, "load_balance", mp->lb);
1957   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1958   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1959 }
1960
1961 static int
1962 api_sw_interface_bond_dump (vat_main_t * vam)
1963 {
1964   vl_api_sw_interface_bond_dump_t *mp;
1965   vl_api_control_ping_t *mp_ping;
1966   int ret;
1967
1968   print (vam->ofp,
1969          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1970          "interface name", "sw_if_index", "mode", "load balance",
1971          "active slaves", "slaves");
1972
1973   /* Get list of bond interfaces */
1974   M (SW_INTERFACE_BOND_DUMP, mp);
1975   S (mp);
1976
1977   /* Use a control ping for synchronization */
1978   MPING (CONTROL_PING, mp_ping);
1979   S (mp_ping);
1980
1981   W (ret);
1982   return ret;
1983 }
1984
1985 static void vl_api_sw_interface_slave_details_t_handler
1986   (vl_api_sw_interface_slave_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-25s %-12d %-12d %d", mp->interface_name,
1992          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1993 }
1994
1995 static void vl_api_sw_interface_slave_details_t_handler_json
1996   (vl_api_sw_interface_slave_details_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t *node = NULL;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006   node = vat_json_array_add (&vam->json_tree);
2007
2008   vat_json_init_object (node);
2009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2010   vat_json_object_add_string_copy (node, "interface_name",
2011                                    mp->interface_name);
2012   vat_json_object_add_uint (node, "passive", mp->is_passive);
2013   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2014 }
2015
2016 static int
2017 api_sw_interface_slave_dump (vat_main_t * vam)
2018 {
2019   unformat_input_t *i = vam->input;
2020   vl_api_sw_interface_slave_dump_t *mp;
2021   vl_api_control_ping_t *mp_ping;
2022   u32 sw_if_index = ~0;
2023   u8 sw_if_index_set = 0;
2024   int ret;
2025
2026   /* Parse args required to build the message */
2027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2028     {
2029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2030         sw_if_index_set = 1;
2031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2032         sw_if_index_set = 1;
2033       else
2034         break;
2035     }
2036
2037   if (sw_if_index_set == 0)
2038     {
2039       errmsg ("missing vpp interface name. ");
2040       return -99;
2041     }
2042
2043   print (vam->ofp,
2044          "\n%-25s %-12s %-12s %s",
2045          "slave interface name", "sw_if_index", "passive", "long_timeout");
2046
2047   /* Get list of bond interfaces */
2048   M (SW_INTERFACE_SLAVE_DUMP, mp);
2049   mp->sw_if_index = ntohl (sw_if_index);
2050   S (mp);
2051
2052   /* Use a control ping for synchronization */
2053   MPING (CONTROL_PING, mp_ping);
2054   S (mp_ping);
2055
2056   W (ret);
2057   return ret;
2058 }
2059
2060 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2061   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->result_ready = 1;
2073     }
2074 }
2075
2076 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2077   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   vat_json_node_t node;
2081
2082   vat_json_init_object (&node);
2083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2084   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2085                             ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2095   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2112   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2129   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   i32 retval = ntohl (mp->retval);
2133   if (vam->async_mode)
2134     {
2135       vam->async_errors += (retval < 0);
2136     }
2137   else
2138     {
2139       vam->retval = retval;
2140       vam->result_ready = 1;
2141     }
2142 }
2143
2144 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2145   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   vat_json_node_t node;
2149
2150   vat_json_init_object (&node);
2151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2152   vat_json_object_add_uint (&node, "fwd_entry_index",
2153                             clib_net_to_host_u32 (mp->fwd_entry_index));
2154
2155   vat_json_print (vam->ofp, &node);
2156   vat_json_free (&node);
2157
2158   vam->retval = ntohl (mp->retval);
2159   vam->result_ready = 1;
2160 }
2161
2162 u8 *
2163 format_lisp_transport_protocol (u8 * s, va_list * args)
2164 {
2165   u32 proto = va_arg (*args, u32);
2166
2167   switch (proto)
2168     {
2169     case 1:
2170       return format (s, "udp");
2171     case 2:
2172       return format (s, "api");
2173     default:
2174       return 0;
2175     }
2176   return 0;
2177 }
2178
2179 static void vl_api_one_get_transport_protocol_reply_t_handler
2180   (vl_api_one_get_transport_protocol_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       u32 proto = mp->protocol;
2191       print (vam->ofp, "Transport protocol: %U",
2192              format_lisp_transport_protocol, proto);
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2199   (vl_api_one_get_transport_protocol_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203   u8 *s;
2204
2205   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2206   vec_add1 (s, 0);
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2211
2212   vec_free (s);
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_one_add_del_locator_set_reply_t_handler
2221   (vl_api_one_add_del_locator_set_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2237   (vl_api_one_add_del_locator_set_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2254   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->sw_if_index = ntohl (mp->sw_if_index);
2266       vam->result_ready = 1;
2267     }
2268   vam->regenerate_interface_table = 1;
2269 }
2270
2271 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2272   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 static void vl_api_vxlan_offload_rx_reply_t_handler
2289   (vl_api_vxlan_offload_rx_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       vam->retval = retval;
2300       vam->result_ready = 1;
2301     }
2302 }
2303
2304 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2305   (vl_api_vxlan_offload_rx_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   vat_json_node_t node;
2309
2310   vat_json_init_object (&node);
2311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2312
2313   vat_json_print (vam->ofp, &node);
2314   vat_json_free (&node);
2315
2316   vam->retval = ntohl (mp->retval);
2317   vam->result_ready = 1;
2318 }
2319
2320 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2321   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325   if (vam->async_mode)
2326     {
2327       vam->async_errors += (retval < 0);
2328     }
2329   else
2330     {
2331       vam->retval = retval;
2332       vam->sw_if_index = ntohl (mp->sw_if_index);
2333       vam->result_ready = 1;
2334     }
2335 }
2336
2337 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2338   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   vat_json_node_t node;
2342
2343   vat_json_init_object (&node);
2344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2345   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2346
2347   vat_json_print (vam->ofp, &node);
2348   vat_json_free (&node);
2349
2350   vam->retval = ntohl (mp->retval);
2351   vam->result_ready = 1;
2352 }
2353
2354 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2355   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   i32 retval = ntohl (mp->retval);
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->sw_if_index = ntohl (mp->sw_if_index);
2367       vam->result_ready = 1;
2368     }
2369   vam->regenerate_interface_table = 1;
2370 }
2371
2372 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2373   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_gre_add_del_tunnel_reply_t_handler
2390   (vl_api_gre_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2407   (vl_api_gre_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_create_vhost_user_if_reply_t_handler
2424   (vl_api_create_vhost_user_if_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_create_vhost_user_if_reply_t_handler_json
2442   (vl_api_create_vhost_user_if_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_dns_resolve_name_reply_t_handler
2459   (vl_api_dns_resolve_name_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471
2472       if (retval == 0)
2473         {
2474           if (mp->ip4_set)
2475             clib_warning ("ip4 address %U", format_ip4_address,
2476                           (ip4_address_t *) mp->ip4_address);
2477           if (mp->ip6_set)
2478             clib_warning ("ip6 address %U", format_ip6_address,
2479                           (ip6_address_t *) mp->ip6_address);
2480         }
2481       else
2482         clib_warning ("retval %d", retval);
2483     }
2484 }
2485
2486 static void vl_api_dns_resolve_name_reply_t_handler_json
2487   (vl_api_dns_resolve_name_reply_t * mp)
2488 {
2489   clib_warning ("not implemented");
2490 }
2491
2492 static void vl_api_dns_resolve_ip_reply_t_handler
2493   (vl_api_dns_resolve_ip_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   i32 retval = ntohl (mp->retval);
2497   if (vam->async_mode)
2498     {
2499       vam->async_errors += (retval < 0);
2500     }
2501   else
2502     {
2503       vam->retval = retval;
2504       vam->result_ready = 1;
2505
2506       if (retval == 0)
2507         {
2508           clib_warning ("canonical name %s", mp->name);
2509         }
2510       else
2511         clib_warning ("retval %d", retval);
2512     }
2513 }
2514
2515 static void vl_api_dns_resolve_ip_reply_t_handler_json
2516   (vl_api_dns_resolve_ip_reply_t * mp)
2517 {
2518   clib_warning ("not implemented");
2519 }
2520
2521
2522 static void vl_api_ip_address_details_t_handler
2523   (vl_api_ip_address_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   static ip_address_details_t empty_ip_address_details = { {0} };
2527   ip_address_details_t *address = NULL;
2528   ip_details_t *current_ip_details = NULL;
2529   ip_details_t *details = NULL;
2530
2531   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2532
2533   if (!details || vam->current_sw_if_index >= vec_len (details)
2534       || !details[vam->current_sw_if_index].present)
2535     {
2536       errmsg ("ip address details arrived but not stored");
2537       errmsg ("ip_dump should be called first");
2538       return;
2539     }
2540
2541   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2542
2543 #define addresses (current_ip_details->addr)
2544
2545   vec_validate_init_empty (addresses, vec_len (addresses),
2546                            empty_ip_address_details);
2547
2548   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2549
2550   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2551   address->prefix_length = mp->prefix_length;
2552 #undef addresses
2553 }
2554
2555 static void vl_api_ip_address_details_t_handler_json
2556   (vl_api_ip_address_details_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t *node = NULL;
2560   struct in6_addr ip6;
2561   struct in_addr ip4;
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   if (vam->is_ipv6)
2572     {
2573       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2574       vat_json_object_add_ip6 (node, "ip", ip6);
2575     }
2576   else
2577     {
2578       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2579       vat_json_object_add_ip4 (node, "ip", ip4);
2580     }
2581   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2582 }
2583
2584 static void
2585 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_details_t empty_ip_details = { 0 };
2589   ip_details_t *ip = NULL;
2590   u32 sw_if_index = ~0;
2591
2592   sw_if_index = ntohl (mp->sw_if_index);
2593
2594   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2595                            sw_if_index, empty_ip_details);
2596
2597   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2598                          sw_if_index);
2599
2600   ip->present = 1;
2601 }
2602
2603 static void
2604 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607
2608   if (VAT_JSON_ARRAY != vam->json_tree.type)
2609     {
2610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611       vat_json_init_array (&vam->json_tree);
2612     }
2613   vat_json_array_add_uint (&vam->json_tree,
2614                            clib_net_to_host_u32 (mp->sw_if_index));
2615 }
2616
2617 static void
2618 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2619 {
2620   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2621           "router_addr %U host_mac %U",
2622           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2623           mp->lease.hostname,
2624           format_ip4_address, &mp->lease.host_address,
2625           format_ip4_address, &mp->lease.router_address,
2626           format_ethernet_address, mp->lease.host_mac);
2627 }
2628
2629 static void vl_api_dhcp_compl_event_t_handler_json
2630   (vl_api_dhcp_compl_event_t * mp)
2631 {
2632   /* JSON output not supported */
2633 }
2634
2635 static void
2636 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2637                               u32 counter)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static u64 default_counter = 0;
2641
2642   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2643                            NULL);
2644   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2645                            sw_if_index, default_counter);
2646   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2647 }
2648
2649 static void
2650 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2651                                 interface_counter_t counter)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   static interface_counter_t default_counter = { 0, };
2655
2656   vec_validate_init_empty (vam->combined_interface_counters,
2657                            vnet_counter_type, NULL);
2658   vec_validate_init_empty (vam->combined_interface_counters
2659                            [vnet_counter_type], sw_if_index, default_counter);
2660   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2661 }
2662
2663 static void vl_api_vnet_interface_simple_counters_t_handler
2664   (vl_api_vnet_interface_simple_counters_t * mp)
2665 {
2666   /* not supported */
2667 }
2668
2669 static void vl_api_vnet_interface_combined_counters_t_handler
2670   (vl_api_vnet_interface_combined_counters_t * mp)
2671 {
2672   /* not supported */
2673 }
2674
2675 static void vl_api_vnet_interface_simple_counters_t_handler_json
2676   (vl_api_vnet_interface_simple_counters_t * mp)
2677 {
2678   u64 *v_packets;
2679   u64 packets;
2680   u32 count;
2681   u32 first_sw_if_index;
2682   int i;
2683
2684   count = ntohl (mp->count);
2685   first_sw_if_index = ntohl (mp->first_sw_if_index);
2686
2687   v_packets = (u64 *) & mp->data;
2688   for (i = 0; i < count; i++)
2689     {
2690       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2691       set_simple_interface_counter (mp->vnet_counter_type,
2692                                     first_sw_if_index + i, packets);
2693       v_packets++;
2694     }
2695 }
2696
2697 static void vl_api_vnet_interface_combined_counters_t_handler_json
2698   (vl_api_vnet_interface_combined_counters_t * mp)
2699 {
2700   interface_counter_t counter;
2701   vlib_counter_t *v;
2702   u32 first_sw_if_index;
2703   int i;
2704   u32 count;
2705
2706   count = ntohl (mp->count);
2707   first_sw_if_index = ntohl (mp->first_sw_if_index);
2708
2709   v = (vlib_counter_t *) & mp->data;
2710   for (i = 0; i < count; i++)
2711     {
2712       counter.packets =
2713         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2714       counter.bytes =
2715         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2716       set_combined_interface_counter (mp->vnet_counter_type,
2717                                       first_sw_if_index + i, counter);
2718       v++;
2719     }
2720 }
2721
2722 static u32
2723 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   u32 i;
2727
2728   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2729     {
2730       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2731         {
2732           return i;
2733         }
2734     }
2735   return ~0;
2736 }
2737
2738 static u32
2739 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   u32 i;
2743
2744   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2745     {
2746       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2747         {
2748           return i;
2749         }
2750     }
2751   return ~0;
2752 }
2753
2754 static void vl_api_vnet_ip4_fib_counters_t_handler
2755   (vl_api_vnet_ip4_fib_counters_t * mp)
2756 {
2757   /* not supported */
2758 }
2759
2760 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2761   (vl_api_vnet_ip4_fib_counters_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vl_api_ip4_fib_counter_t *v;
2765   ip4_fib_counter_t *counter;
2766   struct in_addr ip4;
2767   u32 vrf_id;
2768   u32 vrf_index;
2769   u32 count;
2770   int i;
2771
2772   vrf_id = ntohl (mp->vrf_id);
2773   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2774   if (~0 == vrf_index)
2775     {
2776       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2777       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2778       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2779       vec_validate (vam->ip4_fib_counters, vrf_index);
2780       vam->ip4_fib_counters[vrf_index] = NULL;
2781     }
2782
2783   vec_free (vam->ip4_fib_counters[vrf_index]);
2784   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2785   count = ntohl (mp->count);
2786   for (i = 0; i < count; i++)
2787     {
2788       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2789       counter = &vam->ip4_fib_counters[vrf_index][i];
2790       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2791       counter->address = ip4;
2792       counter->address_length = v->address_length;
2793       counter->packets = clib_net_to_host_u64 (v->packets);
2794       counter->bytes = clib_net_to_host_u64 (v->bytes);
2795       v++;
2796     }
2797 }
2798
2799 static void vl_api_vnet_ip4_nbr_counters_t_handler
2800   (vl_api_vnet_ip4_nbr_counters_t * mp)
2801 {
2802   /* not supported */
2803 }
2804
2805 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2806   (vl_api_vnet_ip4_nbr_counters_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vl_api_ip4_nbr_counter_t *v;
2810   ip4_nbr_counter_t *counter;
2811   u32 sw_if_index;
2812   u32 count;
2813   int i;
2814
2815   sw_if_index = ntohl (mp->sw_if_index);
2816   count = ntohl (mp->count);
2817   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2818
2819   if (mp->begin)
2820     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2821
2822   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2823   for (i = 0; i < count; i++)
2824     {
2825       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2826       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2827       counter->address.s_addr = v->address;
2828       counter->packets = clib_net_to_host_u64 (v->packets);
2829       counter->bytes = clib_net_to_host_u64 (v->bytes);
2830       counter->linkt = v->link_type;
2831       v++;
2832     }
2833 }
2834
2835 static void vl_api_vnet_ip6_fib_counters_t_handler
2836   (vl_api_vnet_ip6_fib_counters_t * mp)
2837 {
2838   /* not supported */
2839 }
2840
2841 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2842   (vl_api_vnet_ip6_fib_counters_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   vl_api_ip6_fib_counter_t *v;
2846   ip6_fib_counter_t *counter;
2847   struct in6_addr ip6;
2848   u32 vrf_id;
2849   u32 vrf_index;
2850   u32 count;
2851   int i;
2852
2853   vrf_id = ntohl (mp->vrf_id);
2854   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2855   if (~0 == vrf_index)
2856     {
2857       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2858       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2859       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2860       vec_validate (vam->ip6_fib_counters, vrf_index);
2861       vam->ip6_fib_counters[vrf_index] = NULL;
2862     }
2863
2864   vec_free (vam->ip6_fib_counters[vrf_index]);
2865   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2866   count = ntohl (mp->count);
2867   for (i = 0; i < count; i++)
2868     {
2869       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2870       counter = &vam->ip6_fib_counters[vrf_index][i];
2871       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2872       counter->address = ip6;
2873       counter->address_length = v->address_length;
2874       counter->packets = clib_net_to_host_u64 (v->packets);
2875       counter->bytes = clib_net_to_host_u64 (v->bytes);
2876       v++;
2877     }
2878 }
2879
2880 static void vl_api_vnet_ip6_nbr_counters_t_handler
2881   (vl_api_vnet_ip6_nbr_counters_t * mp)
2882 {
2883   /* not supported */
2884 }
2885
2886 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2887   (vl_api_vnet_ip6_nbr_counters_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vl_api_ip6_nbr_counter_t *v;
2891   ip6_nbr_counter_t *counter;
2892   struct in6_addr ip6;
2893   u32 sw_if_index;
2894   u32 count;
2895   int i;
2896
2897   sw_if_index = ntohl (mp->sw_if_index);
2898   count = ntohl (mp->count);
2899   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2900
2901   if (mp->begin)
2902     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2903
2904   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2905   for (i = 0; i < count; i++)
2906     {
2907       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2908       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2909       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2910       counter->address = ip6;
2911       counter->packets = clib_net_to_host_u64 (v->packets);
2912       counter->bytes = clib_net_to_host_u64 (v->bytes);
2913       v++;
2914     }
2915 }
2916
2917 static void vl_api_get_first_msg_id_reply_t_handler
2918   (vl_api_get_first_msg_id_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   i32 retval = ntohl (mp->retval);
2922
2923   if (vam->async_mode)
2924     {
2925       vam->async_errors += (retval < 0);
2926     }
2927   else
2928     {
2929       vam->retval = retval;
2930       vam->result_ready = 1;
2931     }
2932   if (retval >= 0)
2933     {
2934       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2935     }
2936 }
2937
2938 static void vl_api_get_first_msg_id_reply_t_handler_json
2939   (vl_api_get_first_msg_id_reply_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942   vat_json_node_t node;
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2946   vat_json_object_add_uint (&node, "first_msg_id",
2947                             (uint) ntohs (mp->first_msg_id));
2948
2949   vat_json_print (vam->ofp, &node);
2950   vat_json_free (&node);
2951
2952   vam->retval = ntohl (mp->retval);
2953   vam->result_ready = 1;
2954 }
2955
2956 static void vl_api_get_node_graph_reply_t_handler
2957   (vl_api_get_node_graph_reply_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   api_main_t *am = &api_main;
2961   i32 retval = ntohl (mp->retval);
2962   u8 *pvt_copy, *reply;
2963   void *oldheap;
2964   vlib_node_t *node;
2965   int i;
2966
2967   if (vam->async_mode)
2968     {
2969       vam->async_errors += (retval < 0);
2970     }
2971   else
2972     {
2973       vam->retval = retval;
2974       vam->result_ready = 1;
2975     }
2976
2977   /* "Should never happen..." */
2978   if (retval != 0)
2979     return;
2980
2981   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2982   pvt_copy = vec_dup (reply);
2983
2984   /* Toss the shared-memory original... */
2985   pthread_mutex_lock (&am->vlib_rp->mutex);
2986   oldheap = svm_push_data_heap (am->vlib_rp);
2987
2988   vec_free (reply);
2989
2990   svm_pop_heap (oldheap);
2991   pthread_mutex_unlock (&am->vlib_rp->mutex);
2992
2993   if (vam->graph_nodes)
2994     {
2995       hash_free (vam->graph_node_index_by_name);
2996
2997       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2998         {
2999           node = vam->graph_nodes[0][i];
3000           vec_free (node->name);
3001           vec_free (node->next_nodes);
3002           vec_free (node);
3003         }
3004       vec_free (vam->graph_nodes[0]);
3005       vec_free (vam->graph_nodes);
3006     }
3007
3008   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3009   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3010   vec_free (pvt_copy);
3011
3012   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3013     {
3014       node = vam->graph_nodes[0][i];
3015       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3016     }
3017 }
3018
3019 static void vl_api_get_node_graph_reply_t_handler_json
3020   (vl_api_get_node_graph_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   api_main_t *am = &api_main;
3024   void *oldheap;
3025   vat_json_node_t node;
3026   u8 *reply;
3027
3028   /* $$$$ make this real? */
3029   vat_json_init_object (&node);
3030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3031   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3032
3033   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3034
3035   /* Toss the shared-memory original... */
3036   pthread_mutex_lock (&am->vlib_rp->mutex);
3037   oldheap = svm_push_data_heap (am->vlib_rp);
3038
3039   vec_free (reply);
3040
3041   svm_pop_heap (oldheap);
3042   pthread_mutex_unlock (&am->vlib_rp->mutex);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   u8 *s = 0;
3056
3057   if (mp->local)
3058     {
3059       s = format (s, "%=16d%=16d%=16d",
3060                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3061     }
3062   else
3063     {
3064       s = format (s, "%=16U%=16d%=16d",
3065                   mp->is_ipv6 ? format_ip6_address :
3066                   format_ip4_address,
3067                   mp->ip_address, mp->priority, mp->weight);
3068     }
3069
3070   print (vam->ofp, "%v", s);
3071   vec_free (s);
3072 }
3073
3074 static void
3075 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = NULL;
3079   struct in6_addr ip6;
3080   struct in_addr ip4;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088   vat_json_init_object (node);
3089
3090   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3091   vat_json_object_add_uint (node, "priority", mp->priority);
3092   vat_json_object_add_uint (node, "weight", mp->weight);
3093
3094   if (mp->local)
3095     vat_json_object_add_uint (node, "sw_if_index",
3096                               clib_net_to_host_u32 (mp->sw_if_index));
3097   else
3098     {
3099       if (mp->is_ipv6)
3100         {
3101           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3102           vat_json_object_add_ip6 (node, "address", ip6);
3103         }
3104       else
3105         {
3106           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3107           vat_json_object_add_ip4 (node, "address", ip4);
3108         }
3109     }
3110 }
3111
3112 static void
3113 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3114                                           mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   u8 *ls_name = 0;
3118
3119   ls_name = format (0, "%s", mp->ls_name);
3120
3121   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3122          ls_name);
3123   vec_free (ls_name);
3124 }
3125
3126 static void
3127   vl_api_one_locator_set_details_t_handler_json
3128   (vl_api_one_locator_set_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = 0;
3132   u8 *ls_name = 0;
3133
3134   ls_name = format (0, "%s", mp->ls_name);
3135   vec_add1 (ls_name, 0);
3136
3137   if (VAT_JSON_ARRAY != vam->json_tree.type)
3138     {
3139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3140       vat_json_init_array (&vam->json_tree);
3141     }
3142   node = vat_json_array_add (&vam->json_tree);
3143
3144   vat_json_init_object (node);
3145   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3146   vat_json_object_add_uint (node, "ls_index",
3147                             clib_net_to_host_u32 (mp->ls_index));
3148   vec_free (ls_name);
3149 }
3150
3151 typedef struct
3152 {
3153   u32 spi;
3154   u8 si;
3155 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3156
3157 uword
3158 unformat_nsh_address (unformat_input_t * input, va_list * args)
3159 {
3160   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3161   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3162 }
3163
3164 u8 *
3165 format_nsh_address_vat (u8 * s, va_list * args)
3166 {
3167   nsh_t *a = va_arg (*args, nsh_t *);
3168   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3169 }
3170
3171 static u8 *
3172 format_lisp_flat_eid (u8 * s, va_list * args)
3173 {
3174   u32 type = va_arg (*args, u32);
3175   u8 *eid = va_arg (*args, u8 *);
3176   u32 eid_len = va_arg (*args, u32);
3177
3178   switch (type)
3179     {
3180     case 0:
3181       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3182     case 1:
3183       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3184     case 2:
3185       return format (s, "%U", format_ethernet_address, eid);
3186     case 3:
3187       return format (s, "%U", format_nsh_address_vat, eid);
3188     }
3189   return 0;
3190 }
3191
3192 static u8 *
3193 format_lisp_eid_vat (u8 * s, va_list * args)
3194 {
3195   u32 type = va_arg (*args, u32);
3196   u8 *eid = va_arg (*args, u8 *);
3197   u32 eid_len = va_arg (*args, u32);
3198   u8 *seid = va_arg (*args, u8 *);
3199   u32 seid_len = va_arg (*args, u32);
3200   u32 is_src_dst = va_arg (*args, u32);
3201
3202   if (is_src_dst)
3203     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3204
3205   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   u8 *s = 0, *eid = 0;
3215
3216   if (~0 == mp->locator_set_index)
3217     s = format (0, "action: %d", mp->action);
3218   else
3219     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3220
3221   eid = format (0, "%U", format_lisp_eid_vat,
3222                 mp->eid_type,
3223                 mp->eid,
3224                 mp->eid_prefix_len,
3225                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3226   vec_add1 (eid, 0);
3227
3228   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3229          clib_net_to_host_u32 (mp->vni),
3230          eid,
3231          mp->is_local ? "local" : "remote",
3232          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3233          clib_net_to_host_u16 (mp->key_id), mp->key);
3234
3235   vec_free (s);
3236   vec_free (eid);
3237 }
3238
3239 static void
3240 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3241                                              * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t *node = 0;
3245   u8 *eid = 0;
3246
3247   if (VAT_JSON_ARRAY != vam->json_tree.type)
3248     {
3249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3250       vat_json_init_array (&vam->json_tree);
3251     }
3252   node = vat_json_array_add (&vam->json_tree);
3253
3254   vat_json_init_object (node);
3255   if (~0 == mp->locator_set_index)
3256     vat_json_object_add_uint (node, "action", mp->action);
3257   else
3258     vat_json_object_add_uint (node, "locator_set_index",
3259                               clib_net_to_host_u32 (mp->locator_set_index));
3260
3261   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3262   if (mp->eid_type == 3)
3263     {
3264       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3265       vat_json_init_object (nsh_json);
3266       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3267       vat_json_object_add_uint (nsh_json, "spi",
3268                                 clib_net_to_host_u32 (nsh->spi));
3269       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3270     }
3271   else
3272     {
3273       eid = format (0, "%U", format_lisp_eid_vat,
3274                     mp->eid_type,
3275                     mp->eid,
3276                     mp->eid_prefix_len,
3277                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3278       vec_add1 (eid, 0);
3279       vat_json_object_add_string_copy (node, "eid", eid);
3280       vec_free (eid);
3281     }
3282   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3283   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3284   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3285
3286   if (mp->key_id)
3287     {
3288       vat_json_object_add_uint (node, "key_id",
3289                                 clib_net_to_host_u16 (mp->key_id));
3290       vat_json_object_add_string_copy (node, "key", mp->key);
3291     }
3292 }
3293
3294 static void
3295 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   u8 *seid = 0, *deid = 0;
3299   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3300
3301   deid = format (0, "%U", format_lisp_eid_vat,
3302                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3303
3304   seid = format (0, "%U", format_lisp_eid_vat,
3305                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3306
3307   vec_add1 (deid, 0);
3308   vec_add1 (seid, 0);
3309
3310   if (mp->is_ip4)
3311     format_ip_address_fcn = format_ip4_address;
3312   else
3313     format_ip_address_fcn = format_ip6_address;
3314
3315
3316   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3317          clib_net_to_host_u32 (mp->vni),
3318          seid, deid,
3319          format_ip_address_fcn, mp->lloc,
3320          format_ip_address_fcn, mp->rloc,
3321          clib_net_to_host_u32 (mp->pkt_count),
3322          clib_net_to_host_u32 (mp->bytes));
3323
3324   vec_free (deid);
3325   vec_free (seid);
3326 }
3327
3328 static void
3329 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3330 {
3331   struct in6_addr ip6;
3332   struct in_addr ip4;
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = 0;
3335   u8 *deid = 0, *seid = 0;
3336
3337   if (VAT_JSON_ARRAY != vam->json_tree.type)
3338     {
3339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3340       vat_json_init_array (&vam->json_tree);
3341     }
3342   node = vat_json_array_add (&vam->json_tree);
3343
3344   vat_json_init_object (node);
3345   deid = format (0, "%U", format_lisp_eid_vat,
3346                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3347
3348   seid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3350
3351   vec_add1 (deid, 0);
3352   vec_add1 (seid, 0);
3353
3354   vat_json_object_add_string_copy (node, "seid", seid);
3355   vat_json_object_add_string_copy (node, "deid", deid);
3356   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3357
3358   if (mp->is_ip4)
3359     {
3360       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3361       vat_json_object_add_ip4 (node, "lloc", ip4);
3362       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3363       vat_json_object_add_ip4 (node, "rloc", ip4);
3364     }
3365   else
3366     {
3367       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3368       vat_json_object_add_ip6 (node, "lloc", ip6);
3369       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3370       vat_json_object_add_ip6 (node, "rloc", ip6);
3371     }
3372   vat_json_object_add_uint (node, "pkt_count",
3373                             clib_net_to_host_u32 (mp->pkt_count));
3374   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3375
3376   vec_free (deid);
3377   vec_free (seid);
3378 }
3379
3380 static void
3381   vl_api_one_eid_table_map_details_t_handler
3382   (vl_api_one_eid_table_map_details_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385
3386   u8 *line = format (0, "%=10d%=10d",
3387                      clib_net_to_host_u32 (mp->vni),
3388                      clib_net_to_host_u32 (mp->dp_table));
3389   print (vam->ofp, "%v", line);
3390   vec_free (line);
3391 }
3392
3393 static void
3394   vl_api_one_eid_table_map_details_t_handler_json
3395   (vl_api_one_eid_table_map_details_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398   vat_json_node_t *node = NULL;
3399
3400   if (VAT_JSON_ARRAY != vam->json_tree.type)
3401     {
3402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3403       vat_json_init_array (&vam->json_tree);
3404     }
3405   node = vat_json_array_add (&vam->json_tree);
3406   vat_json_init_object (node);
3407   vat_json_object_add_uint (node, "dp_table",
3408                             clib_net_to_host_u32 (mp->dp_table));
3409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3410 }
3411
3412 static void
3413   vl_api_one_eid_table_vni_details_t_handler
3414   (vl_api_one_eid_table_vni_details_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417
3418   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3419   print (vam->ofp, "%v", line);
3420   vec_free (line);
3421 }
3422
3423 static void
3424   vl_api_one_eid_table_vni_details_t_handler_json
3425   (vl_api_one_eid_table_vni_details_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = NULL;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436   vat_json_init_object (node);
3437   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3438 }
3439
3440 static void
3441   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3442   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   int retval = clib_net_to_host_u32 (mp->retval);
3446
3447   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3448   print (vam->ofp, "fallback threshold value: %d", mp->value);
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3456   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3463   vat_json_init_object (node);
3464   vat_json_object_add_uint (node, "value", mp->value);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_show_one_map_register_state_reply_t_handler
3475   (vl_api_show_one_map_register_state_reply_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479
3480   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3481
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_show_one_map_register_state_reply_t_handler_json
3488   (vl_api_show_one_map_register_state_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t _node, *node = &_node;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3495
3496   vat_json_init_object (node);
3497   vat_json_object_add_string_copy (node, "state", s);
3498
3499   vat_json_print (vam->ofp, node);
3500   vat_json_free (node);
3501
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504   vec_free (s);
3505 }
3506
3507 static void
3508   vl_api_show_one_rloc_probe_state_reply_t_handler
3509   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513
3514   if (retval)
3515     goto end;
3516
3517   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3518 end:
3519   vam->retval = retval;
3520   vam->result_ready = 1;
3521 }
3522
3523 static void
3524   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3525   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t _node, *node = &_node;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530
3531   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3532   vat_json_init_object (node);
3533   vat_json_object_add_string_copy (node, "state", s);
3534
3535   vat_json_print (vam->ofp, node);
3536   vat_json_free (node);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540   vec_free (s);
3541 }
3542
3543 static void
3544   vl_api_show_one_stats_enable_disable_reply_t_handler
3545   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   if (retval)
3551     goto end;
3552
3553   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3561   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t _node, *node = &_node;
3565   int retval = clib_net_to_host_u32 (mp->retval);
3566
3567   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3568   vat_json_init_object (node);
3569   vat_json_object_add_string_copy (node, "state", s);
3570
3571   vat_json_print (vam->ofp, node);
3572   vat_json_free (node);
3573
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576   vec_free (s);
3577 }
3578
3579 static void
3580 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3581 {
3582   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3583   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3584   e->vni = clib_net_to_host_u32 (e->vni);
3585 }
3586
3587 static void
3588   gpe_fwd_entries_get_reply_t_net_to_host
3589   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3590 {
3591   u32 i;
3592
3593   mp->count = clib_net_to_host_u32 (mp->count);
3594   for (i = 0; i < mp->count; i++)
3595     {
3596       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3597     }
3598 }
3599
3600 static u8 *
3601 format_gpe_encap_mode (u8 * s, va_list * args)
3602 {
3603   u32 mode = va_arg (*args, u32);
3604
3605   switch (mode)
3606     {
3607     case 0:
3608       return format (s, "lisp");
3609     case 1:
3610       return format (s, "vxlan");
3611     }
3612   return 0;
3613 }
3614
3615 static void
3616   vl_api_gpe_get_encap_mode_reply_t_handler
3617   (vl_api_gpe_get_encap_mode_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620
3621   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3622   vam->retval = ntohl (mp->retval);
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_get_encap_mode_reply_t_handler_json
3628   (vl_api_gpe_get_encap_mode_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t node;
3632
3633   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3634   vec_add1 (encap_mode, 0);
3635
3636   vat_json_init_object (&node);
3637   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3638
3639   vec_free (encap_mode);
3640   vat_json_print (vam->ofp, &node);
3641   vat_json_free (&node);
3642
3643   vam->retval = ntohl (mp->retval);
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_fwd_entry_path_details_t_handler
3649   (vl_api_gpe_fwd_entry_path_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3653
3654   if (mp->lcl_loc.is_ip4)
3655     format_ip_address_fcn = format_ip4_address;
3656   else
3657     format_ip_address_fcn = format_ip6_address;
3658
3659   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3660          format_ip_address_fcn, &mp->lcl_loc,
3661          format_ip_address_fcn, &mp->rmt_loc);
3662 }
3663
3664 static void
3665 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3666 {
3667   struct in6_addr ip6;
3668   struct in_addr ip4;
3669
3670   if (loc->is_ip4)
3671     {
3672       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3673       vat_json_object_add_ip4 (n, "address", ip4);
3674     }
3675   else
3676     {
3677       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3678       vat_json_object_add_ip6 (n, "address", ip6);
3679     }
3680   vat_json_object_add_uint (n, "weight", loc->weight);
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_path_details_t_handler_json
3685   (vl_api_gpe_fwd_entry_path_details_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t *node = NULL;
3689   vat_json_node_t *loc_node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697   vat_json_init_object (node);
3698
3699   loc_node = vat_json_object_add (node, "local_locator");
3700   vat_json_init_object (loc_node);
3701   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3702
3703   loc_node = vat_json_object_add (node, "remote_locator");
3704   vat_json_init_object (loc_node);
3705   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entries_get_reply_t_handler
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_fwd_entry_t *e;
3716
3717   if (retval)
3718     goto end;
3719
3720   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3721
3722   for (i = 0; i < mp->count; i++)
3723     {
3724       e = &mp->entries[i];
3725       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3726              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3727              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3728     }
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3737   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3738 {
3739   u8 *s = 0;
3740   vat_main_t *vam = &vat_main;
3741   vat_json_node_t *e = 0, root;
3742   u32 i;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744   vl_api_gpe_fwd_entry_t *fwd;
3745
3746   if (retval)
3747     goto end;
3748
3749   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3750   vat_json_init_array (&root);
3751
3752   for (i = 0; i < mp->count; i++)
3753     {
3754       e = vat_json_array_add (&root);
3755       fwd = &mp->entries[i];
3756
3757       vat_json_init_object (e);
3758       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3759       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3760       vat_json_object_add_int (e, "vni", fwd->vni);
3761       vat_json_object_add_int (e, "action", fwd->action);
3762
3763       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3764                   fwd->leid_prefix_len);
3765       vec_add1 (s, 0);
3766       vat_json_object_add_string_copy (e, "leid", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3770                   fwd->reid_prefix_len);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "reid", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3786   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_native_fwd_rpath_t *r;
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     {
3800       r = &mp->entries[i];
3801       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3802              clib_net_to_host_u32 (r->fib_index),
3803              clib_net_to_host_u32 (r->nh_sw_if_index),
3804              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3814   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   vat_json_node_t root, *e;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820   vl_api_gpe_native_fwd_rpath_t *r;
3821   u8 *s;
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       vat_json_init_object (e);
3833       r = &mp->entries[i];
3834       s =
3835         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3836                 r->nh_addr);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840
3841       vat_json_object_add_uint (e, "fib_index",
3842                                 clib_net_to_host_u32 (r->fib_index));
3843       vat_json_object_add_uint (e, "nh_sw_if_index",
3844                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3845     }
3846
3847   vat_json_print (vam->ofp, &root);
3848   vat_json_free (&root);
3849
3850 end:
3851   vam->retval = retval;
3852   vam->result_ready = 1;
3853 }
3854
3855 static void
3856   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3857   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3858 {
3859   vat_main_t *vam = &vat_main;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867
3868   for (i = 0; i < n; i++)
3869     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3878   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   vat_json_node_t root;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_one_ndp_entries_get_reply_t_handler
3904   (vl_api_one_ndp_entries_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3917            format_ethernet_address, mp->entries[i].mac);
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_ndp_entries_get_reply_t_handler_json
3926   (vl_api_one_ndp_entries_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_ndp_entry_t *arp_entry;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       arp_entry = &mp->entries[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3948       vec_add1 (s, 0);
3949
3950       vat_json_object_add_string_copy (e, "mac", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3954       vec_add1 (s, 0);
3955       vat_json_object_add_string_copy (e, "ip6", s);
3956       vec_free (s);
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_l2_arp_entries_get_reply_t_handler
3969   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3982            format_ethernet_address, mp->entries[i].mac);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3992 {
3993   u8 *s = 0;
3994   vat_main_t *vam = &vat_main;
3995   vat_json_node_t *e = 0, root;
3996   u32 i, n;
3997   int retval = clib_net_to_host_u32 (mp->retval);
3998   vl_api_one_l2_arp_entry_t *arp_entry;
3999
4000   if (retval)
4001     goto end;
4002
4003   n = clib_net_to_host_u32 (mp->count);
4004   vat_json_init_array (&root);
4005
4006   for (i = 0; i < n; i++)
4007     {
4008       e = vat_json_array_add (&root);
4009       arp_entry = &mp->entries[i];
4010
4011       vat_json_init_object (e);
4012       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4013       vec_add1 (s, 0);
4014
4015       vat_json_object_add_string_copy (e, "mac", s);
4016       vec_free (s);
4017
4018       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "ip4", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4047     }
4048
4049 end:
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_one_ndp_bd_get_reply_t_handler_json
4056   (vl_api_one_ndp_bd_get_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t root;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067   vat_json_init_array (&root);
4068
4069   for (i = 0; i < n; i++)
4070     {
4071       vat_json_array_add_uint (&root,
4072                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4073     }
4074
4075   vat_json_print (vam->ofp, &root);
4076   vat_json_free (&root);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_bd_get_reply_t_handler
4085   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   u32 i, n;
4089   int retval = clib_net_to_host_u32 (mp->retval);
4090
4091   if (retval)
4092     goto end;
4093
4094   n = clib_net_to_host_u32 (mp->count);
4095
4096   for (i = 0; i < n; i++)
4097     {
4098       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4099     }
4100
4101 end:
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4108   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t root;
4112   u32 i, n;
4113   int retval = clib_net_to_host_u32 (mp->retval);
4114
4115   if (retval)
4116     goto end;
4117
4118   n = clib_net_to_host_u32 (mp->count);
4119   vat_json_init_array (&root);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       vat_json_array_add_uint (&root,
4124                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_adjacencies_get_reply_t_handler
4137   (vl_api_one_adjacencies_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142   vl_api_one_adjacency_t *a;
4143
4144   if (retval)
4145     goto end;
4146
4147   n = clib_net_to_host_u32 (mp->count);
4148
4149   for (i = 0; i < n; i++)
4150     {
4151       a = &mp->adjacencies[i];
4152       print (vam->ofp, "%U %40U",
4153              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4154              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4155     }
4156
4157 end:
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_adjacencies_get_reply_t_handler_json
4164   (vl_api_one_adjacencies_get_reply_t * mp)
4165 {
4166   u8 *s = 0;
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t *e = 0, root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171   vl_api_one_adjacency_t *a;
4172
4173   if (retval)
4174     goto end;
4175
4176   n = clib_net_to_host_u32 (mp->count);
4177   vat_json_init_array (&root);
4178
4179   for (i = 0; i < n; i++)
4180     {
4181       e = vat_json_array_add (&root);
4182       a = &mp->adjacencies[i];
4183
4184       vat_json_init_object (e);
4185       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4186                   a->leid_prefix_len);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "leid", s);
4189       vec_free (s);
4190
4191       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4192                   a->reid_prefix_len);
4193       vec_add1 (s, 0);
4194       vat_json_object_add_string_copy (e, "reid", s);
4195       vec_free (s);
4196     }
4197
4198   vat_json_print (vam->ofp, &root);
4199   vat_json_free (&root);
4200
4201 end:
4202   vam->retval = retval;
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210
4211   print (vam->ofp, "%=20U",
4212          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4213          mp->ip_address);
4214 }
4215
4216 static void
4217   vl_api_one_map_server_details_t_handler_json
4218   (vl_api_one_map_server_details_t * mp)
4219 {
4220   vat_main_t *vam = &vat_main;
4221   vat_json_node_t *node = NULL;
4222   struct in6_addr ip6;
4223   struct in_addr ip4;
4224
4225   if (VAT_JSON_ARRAY != vam->json_tree.type)
4226     {
4227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4228       vat_json_init_array (&vam->json_tree);
4229     }
4230   node = vat_json_array_add (&vam->json_tree);
4231
4232   vat_json_init_object (node);
4233   if (mp->is_ipv6)
4234     {
4235       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4236       vat_json_object_add_ip6 (node, "map-server", ip6);
4237     }
4238   else
4239     {
4240       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4241       vat_json_object_add_ip4 (node, "map-server", ip4);
4242     }
4243 }
4244
4245 static void
4246 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4247                                            * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250
4251   print (vam->ofp, "%=20U",
4252          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4253          mp->ip_address);
4254 }
4255
4256 static void
4257   vl_api_one_map_resolver_details_t_handler_json
4258   (vl_api_one_map_resolver_details_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *node = NULL;
4262   struct in6_addr ip6;
4263   struct in_addr ip4;
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   if (mp->is_ipv6)
4274     {
4275       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4276       vat_json_object_add_ip6 (node, "map resolver", ip6);
4277     }
4278   else
4279     {
4280       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4281       vat_json_object_add_ip4 (node, "map resolver", ip4);
4282     }
4283 }
4284
4285 static void
4286 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "feature: %s\ngpe: %s",
4294              mp->feature_status ? "enabled" : "disabled",
4295              mp->gpe_status ? "enabled" : "disabled");
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_status_reply_t_handler_json
4304   (vl_api_show_one_status_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *gpe_status = NULL;
4309   u8 *feature_status = NULL;
4310
4311   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4312   feature_status = format (0, "%s",
4313                            mp->feature_status ? "enabled" : "disabled");
4314   vec_add1 (gpe_status, 0);
4315   vec_add1 (feature_status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4319   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4320
4321   vec_free (gpe_status);
4322   vec_free (feature_status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4333   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (retval >= 0)
4339     {
4340       print (vam->ofp, "%=20s", mp->locator_set_name);
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t *node = NULL;
4353
4354   if (VAT_JSON_ARRAY != vam->json_tree.type)
4355     {
4356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4357       vat_json_init_array (&vam->json_tree);
4358     }
4359   node = vat_json_array_add (&vam->json_tree);
4360
4361   vat_json_init_object (node);
4362   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4363
4364   vat_json_print (vam->ofp, node);
4365   vat_json_free (node);
4366
4367   vam->retval = ntohl (mp->retval);
4368   vam->result_ready = 1;
4369 }
4370
4371 static u8 *
4372 format_lisp_map_request_mode (u8 * s, va_list * args)
4373 {
4374   u32 mode = va_arg (*args, u32);
4375
4376   switch (mode)
4377     {
4378     case 0:
4379       return format (0, "dst-only");
4380     case 1:
4381       return format (0, "src-dst");
4382     }
4383   return 0;
4384 }
4385
4386 static void
4387   vl_api_show_one_map_request_mode_reply_t_handler
4388   (vl_api_show_one_map_request_mode_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392
4393   if (0 <= retval)
4394     {
4395       u32 mode = mp->mode;
4396       print (vam->ofp, "map_request_mode: %U",
4397              format_lisp_map_request_mode, mode);
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_show_one_map_request_mode_reply_t_handler_json
4406   (vl_api_show_one_map_request_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *s = 0;
4411   u32 mode;
4412
4413   mode = mp->mode;
4414   s = format (0, "%U", format_lisp_map_request_mode, mode);
4415   vec_add1 (s, 0);
4416
4417   vat_json_init_object (&node);
4418   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4419   vat_json_print (vam->ofp, &node);
4420   vat_json_free (&node);
4421
4422   vec_free (s);
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_xtr_mode_reply_t_handler
4429   (vl_api_one_show_xtr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4437     }
4438
4439   vam->retval = retval;
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_one_show_xtr_mode_reply_t_handler_json
4445   (vl_api_one_show_xtr_mode_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456
4457   vec_free (status);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_one_show_pitr_mode_reply_t_handler
4468   (vl_api_one_show_pitr_mode_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   i32 retval = ntohl (mp->retval);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_one_show_pitr_mode_reply_t_handler_json
4484   (vl_api_one_show_pitr_mode_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495
4496   vec_free (status);
4497
4498   vat_json_print (vam->ofp, &node);
4499   vat_json_free (&node);
4500
4501   vam->retval = ntohl (mp->retval);
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_one_show_petr_mode_reply_t_handler
4507   (vl_api_one_show_petr_mode_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   i32 retval = ntohl (mp->retval);
4511
4512   if (0 <= retval)
4513     {
4514       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_petr_mode_reply_t_handler_json
4523   (vl_api_one_show_petr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "status", status);
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static void
4545   vl_api_show_one_use_petr_reply_t_handler
4546   (vl_api_show_one_use_petr_reply_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   i32 retval = ntohl (mp->retval);
4550
4551   if (0 <= retval)
4552     {
4553       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4554       if (mp->status)
4555         {
4556           print (vam->ofp, "Proxy-ETR address; %U",
4557                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4558                  mp->address);
4559         }
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_use_petr_reply_t_handler_json
4568   (vl_api_show_one_use_petr_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572   u8 *status = 0;
4573   struct in_addr ip4;
4574   struct in6_addr ip6;
4575
4576   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581   if (mp->status)
4582     {
4583       if (mp->is_ip4)
4584         {
4585           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4586           vat_json_object_add_ip6 (&node, "address", ip6);
4587         }
4588       else
4589         {
4590           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4591           vat_json_object_add_ip4 (&node, "address", ip4);
4592         }
4593     }
4594
4595   vec_free (status);
4596
4597   vat_json_print (vam->ofp, &node);
4598   vat_json_free (&node);
4599
4600   vam->retval = ntohl (mp->retval);
4601   vam->result_ready = 1;
4602 }
4603
4604 static void
4605   vl_api_show_one_nsh_mapping_reply_t_handler
4606   (vl_api_show_one_nsh_mapping_reply_t * mp)
4607 {
4608   vat_main_t *vam = &vat_main;
4609   i32 retval = ntohl (mp->retval);
4610
4611   if (0 <= retval)
4612     {
4613       print (vam->ofp, "%-20s%-16s",
4614              mp->is_set ? "set" : "not-set",
4615              mp->is_set ? (char *) mp->locator_set_name : "");
4616     }
4617
4618   vam->retval = retval;
4619   vam->result_ready = 1;
4620 }
4621
4622 static void
4623   vl_api_show_one_nsh_mapping_reply_t_handler_json
4624   (vl_api_show_one_nsh_mapping_reply_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t node;
4628   u8 *status = 0;
4629
4630   status = format (0, "%s", mp->is_set ? "yes" : "no");
4631   vec_add1 (status, 0);
4632
4633   vat_json_init_object (&node);
4634   vat_json_object_add_string_copy (&node, "is_set", status);
4635   if (mp->is_set)
4636     {
4637       vat_json_object_add_string_copy (&node, "locator_set",
4638                                        mp->locator_set_name);
4639     }
4640
4641   vec_free (status);
4642
4643   vat_json_print (vam->ofp, &node);
4644   vat_json_free (&node);
4645
4646   vam->retval = ntohl (mp->retval);
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_show_one_map_register_ttl_reply_t_handler
4652   (vl_api_show_one_map_register_ttl_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   i32 retval = ntohl (mp->retval);
4656
4657   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "ttl: %u", mp->ttl);
4662     }
4663
4664   vam->retval = retval;
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_show_one_map_register_ttl_reply_t_handler_json
4670   (vl_api_show_one_map_register_ttl_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   vat_json_node_t node;
4674
4675   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4676   vat_json_init_object (&node);
4677   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4678
4679   vat_json_print (vam->ofp, &node);
4680   vat_json_free (&node);
4681
4682   vam->retval = ntohl (mp->retval);
4683   vam->result_ready = 1;
4684 }
4685
4686 static void
4687 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   i32 retval = ntohl (mp->retval);
4691
4692   if (0 <= retval)
4693     {
4694       print (vam->ofp, "%-20s%-16s",
4695              mp->status ? "enabled" : "disabled",
4696              mp->status ? (char *) mp->locator_set_name : "");
4697     }
4698
4699   vam->retval = retval;
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t node;
4708   u8 *status = 0;
4709
4710   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4711   vec_add1 (status, 0);
4712
4713   vat_json_init_object (&node);
4714   vat_json_object_add_string_copy (&node, "status", status);
4715   if (mp->status)
4716     {
4717       vat_json_object_add_string_copy (&node, "locator_set",
4718                                        mp->locator_set_name);
4719     }
4720
4721   vec_free (status);
4722
4723   vat_json_print (vam->ofp, &node);
4724   vat_json_free (&node);
4725
4726   vam->retval = ntohl (mp->retval);
4727   vam->result_ready = 1;
4728 }
4729
4730 static u8 *
4731 format_policer_type (u8 * s, va_list * va)
4732 {
4733   u32 i = va_arg (*va, u32);
4734
4735   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4736     s = format (s, "1r2c");
4737   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4738     s = format (s, "1r3c");
4739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4740     s = format (s, "2r3c-2698");
4741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4742     s = format (s, "2r3c-4115");
4743   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4744     s = format (s, "2r3c-mef5cf1");
4745   else
4746     s = format (s, "ILLEGAL");
4747   return s;
4748 }
4749
4750 static u8 *
4751 format_policer_rate_type (u8 * s, va_list * va)
4752 {
4753   u32 i = va_arg (*va, u32);
4754
4755   if (i == SSE2_QOS_RATE_KBPS)
4756     s = format (s, "kbps");
4757   else if (i == SSE2_QOS_RATE_PPS)
4758     s = format (s, "pps");
4759   else
4760     s = format (s, "ILLEGAL");
4761   return s;
4762 }
4763
4764 static u8 *
4765 format_policer_round_type (u8 * s, va_list * va)
4766 {
4767   u32 i = va_arg (*va, u32);
4768
4769   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4770     s = format (s, "closest");
4771   else if (i == SSE2_QOS_ROUND_TO_UP)
4772     s = format (s, "up");
4773   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4774     s = format (s, "down");
4775   else
4776     s = format (s, "ILLEGAL");
4777   return s;
4778 }
4779
4780 static u8 *
4781 format_policer_action_type (u8 * s, va_list * va)
4782 {
4783   u32 i = va_arg (*va, u32);
4784
4785   if (i == SSE2_QOS_ACTION_DROP)
4786     s = format (s, "drop");
4787   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4788     s = format (s, "transmit");
4789   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4790     s = format (s, "mark-and-transmit");
4791   else
4792     s = format (s, "ILLEGAL");
4793   return s;
4794 }
4795
4796 static u8 *
4797 format_dscp (u8 * s, va_list * va)
4798 {
4799   u32 i = va_arg (*va, u32);
4800   char *t = 0;
4801
4802   switch (i)
4803     {
4804 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4805       foreach_vnet_dscp
4806 #undef _
4807     default:
4808       return format (s, "ILLEGAL");
4809     }
4810   s = format (s, "%s", t);
4811   return s;
4812 }
4813
4814 static void
4815 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4816 {
4817   vat_main_t *vam = &vat_main;
4818   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4819
4820   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4821     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822   else
4823     conform_dscp_str = format (0, "");
4824
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4827   else
4828     exceed_dscp_str = format (0, "");
4829
4830   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4831     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4832   else
4833     violate_dscp_str = format (0, "");
4834
4835   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4836          "rate type %U, round type %U, %s rate, %s color-aware, "
4837          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4838          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4839          "conform action %U%s, exceed action %U%s, violate action %U%s",
4840          mp->name,
4841          format_policer_type, mp->type,
4842          ntohl (mp->cir),
4843          ntohl (mp->eir),
4844          clib_net_to_host_u64 (mp->cb),
4845          clib_net_to_host_u64 (mp->eb),
4846          format_policer_rate_type, mp->rate_type,
4847          format_policer_round_type, mp->round_type,
4848          mp->single_rate ? "single" : "dual",
4849          mp->color_aware ? "is" : "not",
4850          ntohl (mp->cir_tokens_per_period),
4851          ntohl (mp->pir_tokens_per_period),
4852          ntohl (mp->scale),
4853          ntohl (mp->current_limit),
4854          ntohl (mp->current_bucket),
4855          ntohl (mp->extended_limit),
4856          ntohl (mp->extended_bucket),
4857          clib_net_to_host_u64 (mp->last_update_time),
4858          format_policer_action_type, mp->conform_action_type,
4859          conform_dscp_str,
4860          format_policer_action_type, mp->exceed_action_type,
4861          exceed_dscp_str,
4862          format_policer_action_type, mp->violate_action_type,
4863          violate_dscp_str);
4864
4865   vec_free (conform_dscp_str);
4866   vec_free (exceed_dscp_str);
4867   vec_free (violate_dscp_str);
4868 }
4869
4870 static void vl_api_policer_details_t_handler_json
4871   (vl_api_policer_details_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t *node;
4875   u8 *rate_type_str, *round_type_str, *type_str;
4876   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4877
4878   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4879   round_type_str =
4880     format (0, "%U", format_policer_round_type, mp->round_type);
4881   type_str = format (0, "%U", format_policer_type, mp->type);
4882   conform_action_str = format (0, "%U", format_policer_action_type,
4883                                mp->conform_action_type);
4884   exceed_action_str = format (0, "%U", format_policer_action_type,
4885                               mp->exceed_action_type);
4886   violate_action_str = format (0, "%U", format_policer_action_type,
4887                                mp->violate_action_type);
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_string_copy (node, "name", mp->name);
4898   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4899   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4900   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4901   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4902   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4903   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4904   vat_json_object_add_string_copy (node, "type", type_str);
4905   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4906   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4907   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4908   vat_json_object_add_uint (node, "cir_tokens_per_period",
4909                             ntohl (mp->cir_tokens_per_period));
4910   vat_json_object_add_uint (node, "eir_tokens_per_period",
4911                             ntohl (mp->pir_tokens_per_period));
4912   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4913   vat_json_object_add_uint (node, "current_bucket",
4914                             ntohl (mp->current_bucket));
4915   vat_json_object_add_uint (node, "extended_limit",
4916                             ntohl (mp->extended_limit));
4917   vat_json_object_add_uint (node, "extended_bucket",
4918                             ntohl (mp->extended_bucket));
4919   vat_json_object_add_uint (node, "last_update_time",
4920                             ntohl (mp->last_update_time));
4921   vat_json_object_add_string_copy (node, "conform_action",
4922                                    conform_action_str);
4923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     {
4925       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4926       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4927       vec_free (dscp_str);
4928     }
4929   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4930   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4931     {
4932       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4933       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4934       vec_free (dscp_str);
4935     }
4936   vat_json_object_add_string_copy (node, "violate_action",
4937                                    violate_action_str);
4938   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4939     {
4940       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4942       vec_free (dscp_str);
4943     }
4944
4945   vec_free (rate_type_str);
4946   vec_free (round_type_str);
4947   vec_free (type_str);
4948   vec_free (conform_action_str);
4949   vec_free (exceed_action_str);
4950   vec_free (violate_action_str);
4951 }
4952
4953 static void
4954 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4955                                            mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   int i, count = ntohl (mp->count);
4959
4960   if (count > 0)
4961     print (vam->ofp, "classify table ids (%d) : ", count);
4962   for (i = 0; i < count; i++)
4963     {
4964       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4965       print (vam->ofp, (i < count - 1) ? "," : "");
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void
4972   vl_api_classify_table_ids_reply_t_handler_json
4973   (vl_api_classify_table_ids_reply_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976   int i, count = ntohl (mp->count);
4977
4978   if (count > 0)
4979     {
4980       vat_json_node_t node;
4981
4982       vat_json_init_object (&node);
4983       for (i = 0; i < count; i++)
4984         {
4985           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4986         }
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995   vl_api_classify_table_by_interface_reply_t_handler
4996   (vl_api_classify_table_by_interface_reply_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   u32 table_id;
5000
5001   table_id = ntohl (mp->l2_table_id);
5002   if (table_id != ~0)
5003     print (vam->ofp, "l2 table id : %d", table_id);
5004   else
5005     print (vam->ofp, "l2 table id : No input ACL tables configured");
5006   table_id = ntohl (mp->ip4_table_id);
5007   if (table_id != ~0)
5008     print (vam->ofp, "ip4 table id : %d", table_id);
5009   else
5010     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5011   table_id = ntohl (mp->ip6_table_id);
5012   if (table_id != ~0)
5013     print (vam->ofp, "ip6 table id : %d", table_id);
5014   else
5015     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_by_interface_reply_t_handler_json
5022   (vl_api_classify_table_by_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   vat_json_init_object (&node);
5028
5029   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5030   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5031   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5032
5033   vat_json_print (vam->ofp, &node);
5034   vat_json_free (&node);
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_add_del_reply_t_handler
5041   (vl_api_policer_add_del_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   i32 retval = ntohl (mp->retval);
5045   if (vam->async_mode)
5046     {
5047       vam->async_errors += (retval < 0);
5048     }
5049   else
5050     {
5051       vam->retval = retval;
5052       vam->result_ready = 1;
5053       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5054         /*
5055          * Note: this is just barely thread-safe, depends on
5056          * the main thread spinning waiting for an answer...
5057          */
5058         errmsg ("policer index %d", ntohl (mp->policer_index));
5059     }
5060 }
5061
5062 static void vl_api_policer_add_del_reply_t_handler_json
5063   (vl_api_policer_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t node;
5067
5068   vat_json_init_object (&node);
5069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5070   vat_json_object_add_uint (&node, "policer_index",
5071                             ntohl (mp->policer_index));
5072
5073   vat_json_print (vam->ofp, &node);
5074   vat_json_free (&node);
5075
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 /* Format hex dump. */
5081 u8 *
5082 format_hex_bytes (u8 * s, va_list * va)
5083 {
5084   u8 *bytes = va_arg (*va, u8 *);
5085   int n_bytes = va_arg (*va, int);
5086   uword i;
5087
5088   /* Print short or long form depending on byte count. */
5089   uword short_form = n_bytes <= 32;
5090   u32 indent = format_get_indent (s);
5091
5092   if (n_bytes == 0)
5093     return s;
5094
5095   for (i = 0; i < n_bytes; i++)
5096     {
5097       if (!short_form && (i % 32) == 0)
5098         s = format (s, "%08x: ", i);
5099       s = format (s, "%02x", bytes[i]);
5100       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5101         s = format (s, "\n%U", format_white_space, indent);
5102     }
5103
5104   return s;
5105 }
5106
5107 static void
5108 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5109                                             * mp)
5110 {
5111   vat_main_t *vam = &vat_main;
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       print (vam->ofp, "classify table info :");
5116       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5117              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5118              ntohl (mp->miss_next_index));
5119       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5120              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5121              ntohl (mp->match_n_vectors));
5122       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5123              ntohl (mp->mask_length));
5124     }
5125   vam->retval = retval;
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_info_reply_t_handler_json
5131   (vl_api_classify_table_info_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   i32 retval = ntohl (mp->retval);
5137   if (retval == 0)
5138     {
5139       vat_json_init_object (&node);
5140
5141       vat_json_object_add_int (&node, "sessions",
5142                                ntohl (mp->active_sessions));
5143       vat_json_object_add_int (&node, "nexttbl",
5144                                ntohl (mp->next_table_index));
5145       vat_json_object_add_int (&node, "nextnode",
5146                                ntohl (mp->miss_next_index));
5147       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5148       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5149       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5150       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5151                       ntohl (mp->mask_length), 0);
5152       vat_json_object_add_string_copy (&node, "mask", s);
5153
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5163                                            mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166
5167   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5168          ntohl (mp->hit_next_index), ntohl (mp->advance),
5169          ntohl (mp->opaque_index));
5170   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5171          ntohl (mp->match_length));
5172 }
5173
5174 static void
5175   vl_api_classify_session_details_t_handler_json
5176   (vl_api_classify_session_details_t * mp)
5177 {
5178   vat_main_t *vam = &vat_main;
5179   vat_json_node_t *node = NULL;
5180
5181   if (VAT_JSON_ARRAY != vam->json_tree.type)
5182     {
5183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5184       vat_json_init_array (&vam->json_tree);
5185     }
5186   node = vat_json_array_add (&vam->json_tree);
5187
5188   vat_json_init_object (node);
5189   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5190   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5191   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5192   u8 *s =
5193     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5194             0);
5195   vat_json_object_add_string_copy (node, "match", s);
5196 }
5197
5198 static void vl_api_pg_create_interface_reply_t_handler
5199   (vl_api_pg_create_interface_reply_t * mp)
5200 {
5201   vat_main_t *vam = &vat_main;
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_pg_create_interface_reply_t_handler_json
5208   (vl_api_pg_create_interface_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5219
5220       vat_json_print (vam->ofp, &node);
5221       vat_json_free (&node);
5222     }
5223   vam->retval = ntohl (mp->retval);
5224   vam->result_ready = 1;
5225 }
5226
5227 static void vl_api_policer_classify_details_t_handler
5228   (vl_api_policer_classify_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231
5232   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5233          ntohl (mp->table_index));
5234 }
5235
5236 static void vl_api_policer_classify_details_t_handler_json
5237   (vl_api_policer_classify_details_t * mp)
5238 {
5239   vat_main_t *vam = &vat_main;
5240   vat_json_node_t *node;
5241
5242   if (VAT_JSON_ARRAY != vam->json_tree.type)
5243     {
5244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5245       vat_json_init_array (&vam->json_tree);
5246     }
5247   node = vat_json_array_add (&vam->json_tree);
5248
5249   vat_json_init_object (node);
5250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5251   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5252 }
5253
5254 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5255   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   i32 retval = ntohl (mp->retval);
5259   if (vam->async_mode)
5260     {
5261       vam->async_errors += (retval < 0);
5262     }
5263   else
5264     {
5265       vam->retval = retval;
5266       vam->sw_if_index = ntohl (mp->sw_if_index);
5267       vam->result_ready = 1;
5268     }
5269   vam->regenerate_interface_table = 1;
5270 }
5271
5272 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5273   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5274 {
5275   vat_main_t *vam = &vat_main;
5276   vat_json_node_t node;
5277
5278   vat_json_init_object (&node);
5279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5281
5282   vat_json_print (vam->ofp, &node);
5283   vat_json_free (&node);
5284
5285   vam->retval = ntohl (mp->retval);
5286   vam->result_ready = 1;
5287 }
5288
5289 static void vl_api_flow_classify_details_t_handler
5290   (vl_api_flow_classify_details_t * mp)
5291 {
5292   vat_main_t *vam = &vat_main;
5293
5294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5295          ntohl (mp->table_index));
5296 }
5297
5298 static void vl_api_flow_classify_details_t_handler_json
5299   (vl_api_flow_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t *node;
5303
5304   if (VAT_JSON_ARRAY != vam->json_tree.type)
5305     {
5306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5307       vat_json_init_array (&vam->json_tree);
5308     }
5309   node = vat_json_array_add (&vam->json_tree);
5310
5311   vat_json_init_object (node);
5312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5314 }
5315
5316 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5317 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5318 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5320 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5322 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5324 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5326 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5328 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5330 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5333 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5334 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5336 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5338
5339 /*
5340  * Generate boilerplate reply handlers, which
5341  * dig the return value out of the xxx_reply_t API message,
5342  * stick it into vam->retval, and set vam->result_ready
5343  *
5344  * Could also do this by pointing N message decode slots at
5345  * a single function, but that could break in subtle ways.
5346  */
5347
5348 #define foreach_standard_reply_retval_handler           \
5349 _(sw_interface_set_flags_reply)                         \
5350 _(sw_interface_add_del_address_reply)                   \
5351 _(sw_interface_set_rx_mode_reply)                       \
5352 _(sw_interface_set_rx_placement_reply)                  \
5353 _(sw_interface_set_table_reply)                         \
5354 _(sw_interface_set_mpls_enable_reply)                   \
5355 _(sw_interface_set_vpath_reply)                         \
5356 _(sw_interface_set_vxlan_bypass_reply)                  \
5357 _(sw_interface_set_geneve_bypass_reply)                 \
5358 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5359 _(sw_interface_set_l2_bridge_reply)                     \
5360 _(bridge_domain_add_del_reply)                          \
5361 _(sw_interface_set_l2_xconnect_reply)                   \
5362 _(l2fib_add_del_reply)                                  \
5363 _(l2fib_flush_int_reply)                                \
5364 _(l2fib_flush_bd_reply)                                 \
5365 _(ip_add_del_route_reply)                               \
5366 _(ip_table_add_del_reply)                               \
5367 _(ip_mroute_add_del_reply)                              \
5368 _(mpls_route_add_del_reply)                             \
5369 _(mpls_table_add_del_reply)                             \
5370 _(mpls_ip_bind_unbind_reply)                            \
5371 _(bier_route_add_del_reply)                             \
5372 _(bier_table_add_del_reply)                             \
5373 _(proxy_arp_add_del_reply)                              \
5374 _(proxy_arp_intfc_enable_disable_reply)                 \
5375 _(sw_interface_set_unnumbered_reply)                    \
5376 _(ip_neighbor_add_del_reply)                            \
5377 _(oam_add_del_reply)                                    \
5378 _(reset_fib_reply)                                      \
5379 _(dhcp_proxy_config_reply)                              \
5380 _(dhcp_proxy_set_vss_reply)                             \
5381 _(dhcp_client_config_reply)                             \
5382 _(set_ip_flow_hash_reply)                               \
5383 _(sw_interface_ip6_enable_disable_reply)                \
5384 _(sw_interface_ip6_set_link_local_address_reply)        \
5385 _(ip6nd_proxy_add_del_reply)                            \
5386 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5387 _(sw_interface_ip6nd_ra_config_reply)                   \
5388 _(set_arp_neighbor_limit_reply)                         \
5389 _(l2_patch_add_del_reply)                               \
5390 _(sr_mpls_policy_add_reply)                             \
5391 _(sr_mpls_policy_mod_reply)                             \
5392 _(sr_mpls_policy_del_reply)                             \
5393 _(sr_policy_add_reply)                                  \
5394 _(sr_policy_mod_reply)                                  \
5395 _(sr_policy_del_reply)                                  \
5396 _(sr_localsid_add_del_reply)                            \
5397 _(sr_steering_add_del_reply)                            \
5398 _(classify_add_del_session_reply)                       \
5399 _(classify_set_interface_ip_table_reply)                \
5400 _(classify_set_interface_l2_tables_reply)               \
5401 _(l2tpv3_set_tunnel_cookies_reply)                      \
5402 _(l2tpv3_interface_enable_disable_reply)                \
5403 _(l2tpv3_set_lookup_key_reply)                          \
5404 _(l2_fib_clear_table_reply)                             \
5405 _(l2_interface_efp_filter_reply)                        \
5406 _(l2_interface_vlan_tag_rewrite_reply)                  \
5407 _(modify_vhost_user_if_reply)                           \
5408 _(delete_vhost_user_if_reply)                           \
5409 _(ip_probe_neighbor_reply)                              \
5410 _(ip_scan_neighbor_enable_disable_reply)                \
5411 _(want_ip4_arp_events_reply)                            \
5412 _(want_ip6_nd_events_reply)                             \
5413 _(want_l2_macs_events_reply)                            \
5414 _(input_acl_set_interface_reply)                        \
5415 _(ipsec_spd_add_del_reply)                              \
5416 _(ipsec_interface_add_del_spd_reply)                    \
5417 _(ipsec_spd_add_del_entry_reply)                        \
5418 _(ipsec_sad_add_del_entry_reply)                        \
5419 _(ipsec_sa_set_key_reply)                               \
5420 _(ipsec_tunnel_if_add_del_reply)                        \
5421 _(ipsec_tunnel_if_set_key_reply)                        \
5422 _(ipsec_tunnel_if_set_sa_reply)                         \
5423 _(ikev2_profile_add_del_reply)                          \
5424 _(ikev2_profile_set_auth_reply)                         \
5425 _(ikev2_profile_set_id_reply)                           \
5426 _(ikev2_profile_set_ts_reply)                           \
5427 _(ikev2_set_local_key_reply)                            \
5428 _(ikev2_set_responder_reply)                            \
5429 _(ikev2_set_ike_transforms_reply)                       \
5430 _(ikev2_set_esp_transforms_reply)                       \
5431 _(ikev2_set_sa_lifetime_reply)                          \
5432 _(ikev2_initiate_sa_init_reply)                         \
5433 _(ikev2_initiate_del_ike_sa_reply)                      \
5434 _(ikev2_initiate_del_child_sa_reply)                    \
5435 _(ikev2_initiate_rekey_child_sa_reply)                  \
5436 _(delete_loopback_reply)                                \
5437 _(bd_ip_mac_add_del_reply)                              \
5438 _(want_interface_events_reply)                          \
5439 _(want_stats_reply)                                     \
5440 _(cop_interface_enable_disable_reply)                   \
5441 _(cop_whitelist_enable_disable_reply)                   \
5442 _(sw_interface_clear_stats_reply)                       \
5443 _(ioam_enable_reply)                                    \
5444 _(ioam_disable_reply)                                   \
5445 _(one_add_del_locator_reply)                            \
5446 _(one_add_del_local_eid_reply)                          \
5447 _(one_add_del_remote_mapping_reply)                     \
5448 _(one_add_del_adjacency_reply)                          \
5449 _(one_add_del_map_resolver_reply)                       \
5450 _(one_add_del_map_server_reply)                         \
5451 _(one_enable_disable_reply)                             \
5452 _(one_rloc_probe_enable_disable_reply)                  \
5453 _(one_map_register_enable_disable_reply)                \
5454 _(one_map_register_set_ttl_reply)                       \
5455 _(one_set_transport_protocol_reply)                     \
5456 _(one_map_register_fallback_threshold_reply)            \
5457 _(one_pitr_set_locator_set_reply)                       \
5458 _(one_map_request_mode_reply)                           \
5459 _(one_add_del_map_request_itr_rlocs_reply)              \
5460 _(one_eid_table_add_del_map_reply)                      \
5461 _(one_use_petr_reply)                                   \
5462 _(one_stats_enable_disable_reply)                       \
5463 _(one_add_del_l2_arp_entry_reply)                       \
5464 _(one_add_del_ndp_entry_reply)                          \
5465 _(one_stats_flush_reply)                                \
5466 _(one_enable_disable_xtr_mode_reply)                    \
5467 _(one_enable_disable_pitr_mode_reply)                   \
5468 _(one_enable_disable_petr_mode_reply)                   \
5469 _(gpe_enable_disable_reply)                             \
5470 _(gpe_set_encap_mode_reply)                             \
5471 _(gpe_add_del_iface_reply)                              \
5472 _(gpe_add_del_native_fwd_rpath_reply)                   \
5473 _(af_packet_delete_reply)                               \
5474 _(policer_classify_set_interface_reply)                 \
5475 _(netmap_create_reply)                                  \
5476 _(netmap_delete_reply)                                  \
5477 _(set_ipfix_exporter_reply)                             \
5478 _(set_ipfix_classify_stream_reply)                      \
5479 _(ipfix_classify_table_add_del_reply)                   \
5480 _(flow_classify_set_interface_reply)                    \
5481 _(sw_interface_span_enable_disable_reply)               \
5482 _(pg_capture_reply)                                     \
5483 _(pg_enable_disable_reply)                              \
5484 _(ip_source_and_port_range_check_add_del_reply)         \
5485 _(ip_source_and_port_range_check_interface_add_del_reply)\
5486 _(delete_subif_reply)                                   \
5487 _(l2_interface_pbb_tag_rewrite_reply)                   \
5488 _(punt_reply)                                           \
5489 _(feature_enable_disable_reply)                         \
5490 _(sw_interface_tag_add_del_reply)                       \
5491 _(hw_interface_set_mtu_reply)                           \
5492 _(p2p_ethernet_add_reply)                               \
5493 _(p2p_ethernet_del_reply)                               \
5494 _(lldp_config_reply)                                    \
5495 _(sw_interface_set_lldp_reply)                          \
5496 _(tcp_configure_src_addresses_reply)                    \
5497 _(dns_enable_disable_reply)                             \
5498 _(dns_name_server_add_del_reply)                        \
5499 _(session_rule_add_del_reply)                           \
5500 _(ip_container_proxy_add_del_reply)                     \
5501 _(output_acl_set_interface_reply)                       \
5502 _(qos_record_enable_disable_reply)
5503
5504 #define _(n)                                    \
5505     static void vl_api_##n##_t_handler          \
5506     (vl_api_##n##_t * mp)                       \
5507     {                                           \
5508         vat_main_t * vam = &vat_main;           \
5509         i32 retval = ntohl(mp->retval);         \
5510         if (vam->async_mode) {                  \
5511             vam->async_errors += (retval < 0);  \
5512         } else {                                \
5513             vam->retval = retval;               \
5514             vam->result_ready = 1;              \
5515         }                                       \
5516     }
5517 foreach_standard_reply_retval_handler;
5518 #undef _
5519
5520 #define _(n)                                    \
5521     static void vl_api_##n##_t_handler_json     \
5522     (vl_api_##n##_t * mp)                       \
5523     {                                           \
5524         vat_main_t * vam = &vat_main;           \
5525         vat_json_node_t node;                   \
5526         vat_json_init_object(&node);            \
5527         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5528         vat_json_print(vam->ofp, &node);        \
5529         vam->retval = ntohl(mp->retval);        \
5530         vam->result_ready = 1;                  \
5531     }
5532 foreach_standard_reply_retval_handler;
5533 #undef _
5534
5535 /*
5536  * Table of message reply handlers, must include boilerplate handlers
5537  * we just generated
5538  */
5539
5540 #define foreach_vpe_api_reply_msg                                       \
5541 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5542 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5543 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5544 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5545 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5546 _(CLI_REPLY, cli_reply)                                                 \
5547 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5548 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5549   sw_interface_add_del_address_reply)                                   \
5550 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5551 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5552 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5553 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5554 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5555 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5556 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5557 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5558 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5559   sw_interface_set_l2_xconnect_reply)                                   \
5560 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5561   sw_interface_set_l2_bridge_reply)                                     \
5562 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5563 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5564 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5565 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5566 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5567 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5568 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5569 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5570 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5571 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5572 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5573 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5574 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5575 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5576 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5577 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5578 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5579 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5580 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5581 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5582 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5583 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5584 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5585 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5586 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5587 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5588 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5589 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5590 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5591 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5592 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5593   proxy_arp_intfc_enable_disable_reply)                                 \
5594 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5595 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5596   sw_interface_set_unnumbered_reply)                                    \
5597 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5598 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5599 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5600 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5601 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5602 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5603 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5604 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5605 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5606 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5607 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5608   sw_interface_ip6_enable_disable_reply)                                \
5609 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5610   sw_interface_ip6_set_link_local_address_reply)                        \
5611 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5612 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5613 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5614   sw_interface_ip6nd_ra_prefix_reply)                                   \
5615 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5616   sw_interface_ip6nd_ra_config_reply)                                   \
5617 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5618 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5619 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5620 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5621 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5622 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5623 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5624 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5625 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5626 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5627 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5628 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5629 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5630 classify_set_interface_ip_table_reply)                                  \
5631 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5632   classify_set_interface_l2_tables_reply)                               \
5633 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5634 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5635 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5636 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5637 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5638   l2tpv3_interface_enable_disable_reply)                                \
5639 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5640 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5641 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5642 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5643 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5644 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5645 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5646 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5647 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5648 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5649 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5650 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5651 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5652 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5653 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5654 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5655 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5656 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5657 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5658 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5659 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5660 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5661 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5662 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5663 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5664 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5665 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5666 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5667 _(L2_MACS_EVENT, l2_macs_event)                                         \
5668 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5669 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5670 _(IP_DETAILS, ip_details)                                               \
5671 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5672 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5673 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5674 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5675 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5676 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5677 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5678 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5679 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5680 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5681 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5682 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5683 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5684 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5685 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5686 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5687 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5688 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5689 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5690 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5691 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5692 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5693 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5694 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5695 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5696 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5697 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5698 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5699 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5700 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5701 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5702 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5703 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5704 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5705 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5706 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5707 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5708 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5709 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5710 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5711 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5712 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5713 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5714 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5715   one_map_register_enable_disable_reply)                                \
5716 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5717 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5718 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5719 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5720   one_map_register_fallback_threshold_reply)                            \
5721 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5722   one_rloc_probe_enable_disable_reply)                                  \
5723 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5724 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5725 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5726 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5727 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5728 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5729 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5730 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5731 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5732 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5733 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5734 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5735 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5736 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5737 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5738 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5739   show_one_stats_enable_disable_reply)                                  \
5740 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5741 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5742 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5743 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5744 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5745 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5746 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5747 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5748   one_enable_disable_pitr_mode_reply)                                   \
5749 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5750   one_enable_disable_petr_mode_reply)                                   \
5751 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5752 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5753 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5754 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5755 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5756 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5757 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5758 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5759 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5760 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5761 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5762 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5763   gpe_add_del_native_fwd_rpath_reply)                                   \
5764 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5765   gpe_fwd_entry_path_details)                                           \
5766 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5767 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5768   one_add_del_map_request_itr_rlocs_reply)                              \
5769 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5770   one_get_map_request_itr_rlocs_reply)                                  \
5771 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5772 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5773 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5774 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5775 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5776 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5777   show_one_map_register_state_reply)                                    \
5778 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5779 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5780   show_one_map_register_fallback_threshold_reply)                       \
5781 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5782 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5783 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5784 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5785 _(POLICER_DETAILS, policer_details)                                     \
5786 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5787 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5788 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5789 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5790 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5791 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5792 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5793 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5794 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5795 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5796 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5797 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5798 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5799 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5800 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5801 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5802 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5803 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5804 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5805 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5806 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5807 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5808 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5809 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5810 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5811  ip_source_and_port_range_check_add_del_reply)                          \
5812 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5813  ip_source_and_port_range_check_interface_add_del_reply)                \
5814 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5815 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5816 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5817 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5818 _(PUNT_REPLY, punt_reply)                                               \
5819 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5820 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5821 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5822 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5823 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5824 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5825 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5826 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5827 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5828 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5829 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5830 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5831 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5832 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5833 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5834 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5835 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5836 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5837 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5838 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5839 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5840 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5841 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5842
5843 #define foreach_standalone_reply_msg                                    \
5844 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5845 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5846 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5847 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5848 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5849 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5850 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5851
5852 typedef struct
5853 {
5854   u8 *name;
5855   u32 value;
5856 } name_sort_t;
5857
5858 #define STR_VTR_OP_CASE(op)     \
5859     case L2_VTR_ ## op:         \
5860         return "" # op;
5861
5862 static const char *
5863 str_vtr_op (u32 vtr_op)
5864 {
5865   switch (vtr_op)
5866     {
5867       STR_VTR_OP_CASE (DISABLED);
5868       STR_VTR_OP_CASE (PUSH_1);
5869       STR_VTR_OP_CASE (PUSH_2);
5870       STR_VTR_OP_CASE (POP_1);
5871       STR_VTR_OP_CASE (POP_2);
5872       STR_VTR_OP_CASE (TRANSLATE_1_1);
5873       STR_VTR_OP_CASE (TRANSLATE_1_2);
5874       STR_VTR_OP_CASE (TRANSLATE_2_1);
5875       STR_VTR_OP_CASE (TRANSLATE_2_2);
5876     }
5877
5878   return "UNKNOWN";
5879 }
5880
5881 static int
5882 dump_sub_interface_table (vat_main_t * vam)
5883 {
5884   const sw_interface_subif_t *sub = NULL;
5885
5886   if (vam->json_output)
5887     {
5888       clib_warning
5889         ("JSON output supported only for VPE API calls and dump_stats_table");
5890       return -99;
5891     }
5892
5893   print (vam->ofp,
5894          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5895          "Interface", "sw_if_index",
5896          "sub id", "dot1ad", "tags", "outer id",
5897          "inner id", "exact", "default", "outer any", "inner any");
5898
5899   vec_foreach (sub, vam->sw_if_subif_table)
5900   {
5901     print (vam->ofp,
5902            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5903            sub->interface_name,
5904            sub->sw_if_index,
5905            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5906            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5907            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5908            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5909     if (sub->vtr_op != L2_VTR_DISABLED)
5910       {
5911         print (vam->ofp,
5912                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5913                "tag1: %d tag2: %d ]",
5914                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5915                sub->vtr_tag1, sub->vtr_tag2);
5916       }
5917   }
5918
5919   return 0;
5920 }
5921
5922 static int
5923 name_sort_cmp (void *a1, void *a2)
5924 {
5925   name_sort_t *n1 = a1;
5926   name_sort_t *n2 = a2;
5927
5928   return strcmp ((char *) n1->name, (char *) n2->name);
5929 }
5930
5931 static int
5932 dump_interface_table (vat_main_t * vam)
5933 {
5934   hash_pair_t *p;
5935   name_sort_t *nses = 0, *ns;
5936
5937   if (vam->json_output)
5938     {
5939       clib_warning
5940         ("JSON output supported only for VPE API calls and dump_stats_table");
5941       return -99;
5942     }
5943
5944   /* *INDENT-OFF* */
5945   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5946   ({
5947     vec_add2 (nses, ns, 1);
5948     ns->name = (u8 *)(p->key);
5949     ns->value = (u32) p->value[0];
5950   }));
5951   /* *INDENT-ON* */
5952
5953   vec_sort_with_function (nses, name_sort_cmp);
5954
5955   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5956   vec_foreach (ns, nses)
5957   {
5958     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5959   }
5960   vec_free (nses);
5961   return 0;
5962 }
5963
5964 static int
5965 dump_ip_table (vat_main_t * vam, int is_ipv6)
5966 {
5967   const ip_details_t *det = NULL;
5968   const ip_address_details_t *address = NULL;
5969   u32 i = ~0;
5970
5971   print (vam->ofp, "%-12s", "sw_if_index");
5972
5973   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5974   {
5975     i++;
5976     if (!det->present)
5977       {
5978         continue;
5979       }
5980     print (vam->ofp, "%-12d", i);
5981     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5982     if (!det->addr)
5983       {
5984         continue;
5985       }
5986     vec_foreach (address, det->addr)
5987     {
5988       print (vam->ofp,
5989              "            %-30U%-13d",
5990              is_ipv6 ? format_ip6_address : format_ip4_address,
5991              address->ip, address->prefix_length);
5992     }
5993   }
5994
5995   return 0;
5996 }
5997
5998 static int
5999 dump_ipv4_table (vat_main_t * vam)
6000 {
6001   if (vam->json_output)
6002     {
6003       clib_warning
6004         ("JSON output supported only for VPE API calls and dump_stats_table");
6005       return -99;
6006     }
6007
6008   return dump_ip_table (vam, 0);
6009 }
6010
6011 static int
6012 dump_ipv6_table (vat_main_t * vam)
6013 {
6014   if (vam->json_output)
6015     {
6016       clib_warning
6017         ("JSON output supported only for VPE API calls and dump_stats_table");
6018       return -99;
6019     }
6020
6021   return dump_ip_table (vam, 1);
6022 }
6023
6024 static char *
6025 counter_type_to_str (u8 counter_type, u8 is_combined)
6026 {
6027   if (!is_combined)
6028     {
6029       switch (counter_type)
6030         {
6031         case VNET_INTERFACE_COUNTER_DROP:
6032           return "drop";
6033         case VNET_INTERFACE_COUNTER_PUNT:
6034           return "punt";
6035         case VNET_INTERFACE_COUNTER_IP4:
6036           return "ip4";
6037         case VNET_INTERFACE_COUNTER_IP6:
6038           return "ip6";
6039         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6040           return "rx-no-buf";
6041         case VNET_INTERFACE_COUNTER_RX_MISS:
6042           return "rx-miss";
6043         case VNET_INTERFACE_COUNTER_RX_ERROR:
6044           return "rx-error";
6045         case VNET_INTERFACE_COUNTER_TX_ERROR:
6046           return "tx-error";
6047         default:
6048           return "INVALID-COUNTER-TYPE";
6049         }
6050     }
6051   else
6052     {
6053       switch (counter_type)
6054         {
6055         case VNET_INTERFACE_COUNTER_RX:
6056           return "rx";
6057         case VNET_INTERFACE_COUNTER_TX:
6058           return "tx";
6059         default:
6060           return "INVALID-COUNTER-TYPE";
6061         }
6062     }
6063 }
6064
6065 static int
6066 dump_stats_table (vat_main_t * vam)
6067 {
6068   vat_json_node_t node;
6069   vat_json_node_t *msg_array;
6070   vat_json_node_t *msg;
6071   vat_json_node_t *counter_array;
6072   vat_json_node_t *counter;
6073   interface_counter_t c;
6074   u64 packets;
6075   ip4_fib_counter_t *c4;
6076   ip6_fib_counter_t *c6;
6077   ip4_nbr_counter_t *n4;
6078   ip6_nbr_counter_t *n6;
6079   int i, j;
6080
6081   if (!vam->json_output)
6082     {
6083       clib_warning ("dump_stats_table supported only in JSON format");
6084       return -99;
6085     }
6086
6087   vat_json_init_object (&node);
6088
6089   /* interface counters */
6090   msg_array = vat_json_object_add (&node, "interface_counters");
6091   vat_json_init_array (msg_array);
6092   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6093     {
6094       msg = vat_json_array_add (msg_array);
6095       vat_json_init_object (msg);
6096       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6097                                        (u8 *) counter_type_to_str (i, 0));
6098       vat_json_object_add_int (msg, "is_combined", 0);
6099       counter_array = vat_json_object_add (msg, "data");
6100       vat_json_init_array (counter_array);
6101       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6102         {
6103           packets = vam->simple_interface_counters[i][j];
6104           vat_json_array_add_uint (counter_array, packets);
6105         }
6106     }
6107   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6108     {
6109       msg = vat_json_array_add (msg_array);
6110       vat_json_init_object (msg);
6111       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6112                                        (u8 *) counter_type_to_str (i, 1));
6113       vat_json_object_add_int (msg, "is_combined", 1);
6114       counter_array = vat_json_object_add (msg, "data");
6115       vat_json_init_array (counter_array);
6116       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6117         {
6118           c = vam->combined_interface_counters[i][j];
6119           counter = vat_json_array_add (counter_array);
6120           vat_json_init_object (counter);
6121           vat_json_object_add_uint (counter, "packets", c.packets);
6122           vat_json_object_add_uint (counter, "bytes", c.bytes);
6123         }
6124     }
6125
6126   /* ip4 fib counters */
6127   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6128   vat_json_init_array (msg_array);
6129   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6130     {
6131       msg = vat_json_array_add (msg_array);
6132       vat_json_init_object (msg);
6133       vat_json_object_add_uint (msg, "vrf_id",
6134                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6135       counter_array = vat_json_object_add (msg, "c");
6136       vat_json_init_array (counter_array);
6137       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6138         {
6139           counter = vat_json_array_add (counter_array);
6140           vat_json_init_object (counter);
6141           c4 = &vam->ip4_fib_counters[i][j];
6142           vat_json_object_add_ip4 (counter, "address", c4->address);
6143           vat_json_object_add_uint (counter, "address_length",
6144                                     c4->address_length);
6145           vat_json_object_add_uint (counter, "packets", c4->packets);
6146           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6147         }
6148     }
6149
6150   /* ip6 fib counters */
6151   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6152   vat_json_init_array (msg_array);
6153   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6154     {
6155       msg = vat_json_array_add (msg_array);
6156       vat_json_init_object (msg);
6157       vat_json_object_add_uint (msg, "vrf_id",
6158                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6159       counter_array = vat_json_object_add (msg, "c");
6160       vat_json_init_array (counter_array);
6161       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6162         {
6163           counter = vat_json_array_add (counter_array);
6164           vat_json_init_object (counter);
6165           c6 = &vam->ip6_fib_counters[i][j];
6166           vat_json_object_add_ip6 (counter, "address", c6->address);
6167           vat_json_object_add_uint (counter, "address_length",
6168                                     c6->address_length);
6169           vat_json_object_add_uint (counter, "packets", c6->packets);
6170           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6171         }
6172     }
6173
6174   /* ip4 nbr counters */
6175   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6176   vat_json_init_array (msg_array);
6177   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6178     {
6179       msg = vat_json_array_add (msg_array);
6180       vat_json_init_object (msg);
6181       vat_json_object_add_uint (msg, "sw_if_index", i);
6182       counter_array = vat_json_object_add (msg, "c");
6183       vat_json_init_array (counter_array);
6184       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6185         {
6186           counter = vat_json_array_add (counter_array);
6187           vat_json_init_object (counter);
6188           n4 = &vam->ip4_nbr_counters[i][j];
6189           vat_json_object_add_ip4 (counter, "address", n4->address);
6190           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6191           vat_json_object_add_uint (counter, "packets", n4->packets);
6192           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6193         }
6194     }
6195
6196   /* ip6 nbr counters */
6197   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6198   vat_json_init_array (msg_array);
6199   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6200     {
6201       msg = vat_json_array_add (msg_array);
6202       vat_json_init_object (msg);
6203       vat_json_object_add_uint (msg, "sw_if_index", i);
6204       counter_array = vat_json_object_add (msg, "c");
6205       vat_json_init_array (counter_array);
6206       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6207         {
6208           counter = vat_json_array_add (counter_array);
6209           vat_json_init_object (counter);
6210           n6 = &vam->ip6_nbr_counters[i][j];
6211           vat_json_object_add_ip6 (counter, "address", n6->address);
6212           vat_json_object_add_uint (counter, "packets", n6->packets);
6213           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6214         }
6215     }
6216
6217   vat_json_print (vam->ofp, &node);
6218   vat_json_free (&node);
6219
6220   return 0;
6221 }
6222
6223 /*
6224  * Pass CLI buffers directly in the CLI_INBAND API message,
6225  * instead of an additional shared memory area.
6226  */
6227 static int
6228 exec_inband (vat_main_t * vam)
6229 {
6230   vl_api_cli_inband_t *mp;
6231   unformat_input_t *i = vam->input;
6232   int ret;
6233
6234   if (vec_len (i->buffer) == 0)
6235     return -1;
6236
6237   if (vam->exec_mode == 0 && unformat (i, "mode"))
6238     {
6239       vam->exec_mode = 1;
6240       return 0;
6241     }
6242   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6243     {
6244       vam->exec_mode = 0;
6245       return 0;
6246     }
6247
6248   /*
6249    * In order for the CLI command to work, it
6250    * must be a vector ending in \n, not a C-string ending
6251    * in \n\0.
6252    */
6253   u32 len = vec_len (vam->input->buffer);
6254   M2 (CLI_INBAND, mp, len);
6255   clib_memcpy (mp->cmd, vam->input->buffer, len);
6256   mp->length = htonl (len);
6257
6258   S (mp);
6259   W (ret);
6260   /* json responses may or may not include a useful reply... */
6261   if (vec_len (vam->cmd_reply))
6262     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6263   return ret;
6264 }
6265
6266 int
6267 exec (vat_main_t * vam)
6268 {
6269   return exec_inband (vam);
6270 }
6271
6272 static int
6273 api_create_loopback (vat_main_t * vam)
6274 {
6275   unformat_input_t *i = vam->input;
6276   vl_api_create_loopback_t *mp;
6277   vl_api_create_loopback_instance_t *mp_lbi;
6278   u8 mac_address[6];
6279   u8 mac_set = 0;
6280   u8 is_specified = 0;
6281   u32 user_instance = 0;
6282   int ret;
6283
6284   memset (mac_address, 0, sizeof (mac_address));
6285
6286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6287     {
6288       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6289         mac_set = 1;
6290       if (unformat (i, "instance %d", &user_instance))
6291         is_specified = 1;
6292       else
6293         break;
6294     }
6295
6296   if (is_specified)
6297     {
6298       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6299       mp_lbi->is_specified = is_specified;
6300       if (is_specified)
6301         mp_lbi->user_instance = htonl (user_instance);
6302       if (mac_set)
6303         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6304       S (mp_lbi);
6305     }
6306   else
6307     {
6308       /* Construct the API message */
6309       M (CREATE_LOOPBACK, mp);
6310       if (mac_set)
6311         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6312       S (mp);
6313     }
6314
6315   W (ret);
6316   return ret;
6317 }
6318
6319 static int
6320 api_delete_loopback (vat_main_t * vam)
6321 {
6322   unformat_input_t *i = vam->input;
6323   vl_api_delete_loopback_t *mp;
6324   u32 sw_if_index = ~0;
6325   int ret;
6326
6327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6328     {
6329       if (unformat (i, "sw_if_index %d", &sw_if_index))
6330         ;
6331       else
6332         break;
6333     }
6334
6335   if (sw_if_index == ~0)
6336     {
6337       errmsg ("missing sw_if_index");
6338       return -99;
6339     }
6340
6341   /* Construct the API message */
6342   M (DELETE_LOOPBACK, mp);
6343   mp->sw_if_index = ntohl (sw_if_index);
6344
6345   S (mp);
6346   W (ret);
6347   return ret;
6348 }
6349
6350 static int
6351 api_want_stats (vat_main_t * vam)
6352 {
6353   unformat_input_t *i = vam->input;
6354   vl_api_want_stats_t *mp;
6355   int enable = -1;
6356   int ret;
6357
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "enable"))
6361         enable = 1;
6362       else if (unformat (i, "disable"))
6363         enable = 0;
6364       else
6365         break;
6366     }
6367
6368   if (enable == -1)
6369     {
6370       errmsg ("missing enable|disable");
6371       return -99;
6372     }
6373
6374   M (WANT_STATS, mp);
6375   mp->enable_disable = enable;
6376
6377   S (mp);
6378   W (ret);
6379   return ret;
6380 }
6381
6382 static int
6383 api_want_interface_events (vat_main_t * vam)
6384 {
6385   unformat_input_t *i = vam->input;
6386   vl_api_want_interface_events_t *mp;
6387   int enable = -1;
6388   int ret;
6389
6390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6391     {
6392       if (unformat (i, "enable"))
6393         enable = 1;
6394       else if (unformat (i, "disable"))
6395         enable = 0;
6396       else
6397         break;
6398     }
6399
6400   if (enable == -1)
6401     {
6402       errmsg ("missing enable|disable");
6403       return -99;
6404     }
6405
6406   M (WANT_INTERFACE_EVENTS, mp);
6407   mp->enable_disable = enable;
6408
6409   vam->interface_event_display = enable;
6410
6411   S (mp);
6412   W (ret);
6413   return ret;
6414 }
6415
6416
6417 /* Note: non-static, called once to set up the initial intfc table */
6418 int
6419 api_sw_interface_dump (vat_main_t * vam)
6420 {
6421   vl_api_sw_interface_dump_t *mp;
6422   vl_api_control_ping_t *mp_ping;
6423   hash_pair_t *p;
6424   name_sort_t *nses = 0, *ns;
6425   sw_interface_subif_t *sub = NULL;
6426   int ret;
6427
6428   /* Toss the old name table */
6429   /* *INDENT-OFF* */
6430   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6431   ({
6432     vec_add2 (nses, ns, 1);
6433     ns->name = (u8 *)(p->key);
6434     ns->value = (u32) p->value[0];
6435   }));
6436   /* *INDENT-ON* */
6437
6438   hash_free (vam->sw_if_index_by_interface_name);
6439
6440   vec_foreach (ns, nses) vec_free (ns->name);
6441
6442   vec_free (nses);
6443
6444   vec_foreach (sub, vam->sw_if_subif_table)
6445   {
6446     vec_free (sub->interface_name);
6447   }
6448   vec_free (vam->sw_if_subif_table);
6449
6450   /* recreate the interface name hash table */
6451   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6452
6453   /*
6454    * Ask for all interface names. Otherwise, the epic catalog of
6455    * name filters becomes ridiculously long, and vat ends up needing
6456    * to be taught about new interface types.
6457    */
6458   M (SW_INTERFACE_DUMP, mp);
6459   S (mp);
6460
6461   /* Use a control ping for synchronization */
6462   MPING (CONTROL_PING, mp_ping);
6463   S (mp_ping);
6464
6465   W (ret);
6466   return ret;
6467 }
6468
6469 static int
6470 api_sw_interface_set_flags (vat_main_t * vam)
6471 {
6472   unformat_input_t *i = vam->input;
6473   vl_api_sw_interface_set_flags_t *mp;
6474   u32 sw_if_index;
6475   u8 sw_if_index_set = 0;
6476   u8 admin_up = 0;
6477   int ret;
6478
6479   /* Parse args required to build the message */
6480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6481     {
6482       if (unformat (i, "admin-up"))
6483         admin_up = 1;
6484       else if (unformat (i, "admin-down"))
6485         admin_up = 0;
6486       else
6487         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6490         sw_if_index_set = 1;
6491       else
6492         break;
6493     }
6494
6495   if (sw_if_index_set == 0)
6496     {
6497       errmsg ("missing interface name or sw_if_index");
6498       return -99;
6499     }
6500
6501   /* Construct the API message */
6502   M (SW_INTERFACE_SET_FLAGS, mp);
6503   mp->sw_if_index = ntohl (sw_if_index);
6504   mp->admin_up_down = admin_up;
6505
6506   /* send it... */
6507   S (mp);
6508
6509   /* Wait for a reply, return the good/bad news... */
6510   W (ret);
6511   return ret;
6512 }
6513
6514 static int
6515 api_sw_interface_set_rx_mode (vat_main_t * vam)
6516 {
6517   unformat_input_t *i = vam->input;
6518   vl_api_sw_interface_set_rx_mode_t *mp;
6519   u32 sw_if_index;
6520   u8 sw_if_index_set = 0;
6521   int ret;
6522   u8 queue_id_valid = 0;
6523   u32 queue_id;
6524   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6525
6526   /* Parse args required to build the message */
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "queue %d", &queue_id))
6530         queue_id_valid = 1;
6531       else if (unformat (i, "polling"))
6532         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6533       else if (unformat (i, "interrupt"))
6534         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6535       else if (unformat (i, "adaptive"))
6536         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6537       else
6538         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6541         sw_if_index_set = 1;
6542       else
6543         break;
6544     }
6545
6546   if (sw_if_index_set == 0)
6547     {
6548       errmsg ("missing interface name or sw_if_index");
6549       return -99;
6550     }
6551   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6552     {
6553       errmsg ("missing rx-mode");
6554       return -99;
6555     }
6556
6557   /* Construct the API message */
6558   M (SW_INTERFACE_SET_RX_MODE, mp);
6559   mp->sw_if_index = ntohl (sw_if_index);
6560   mp->mode = mode;
6561   mp->queue_id_valid = queue_id_valid;
6562   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6563
6564   /* send it... */
6565   S (mp);
6566
6567   /* Wait for a reply, return the good/bad news... */
6568   W (ret);
6569   return ret;
6570 }
6571
6572 static int
6573 api_sw_interface_set_rx_placement (vat_main_t * vam)
6574 {
6575   unformat_input_t *i = vam->input;
6576   vl_api_sw_interface_set_rx_placement_t *mp;
6577   u32 sw_if_index;
6578   u8 sw_if_index_set = 0;
6579   int ret;
6580   u8 is_main = 0;
6581   u32 queue_id, thread_index;
6582
6583   /* Parse args required to build the message */
6584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6585     {
6586       if (unformat (i, "queue %d", &queue_id))
6587         ;
6588       else if (unformat (i, "main"))
6589         is_main = 1;
6590       else if (unformat (i, "worker %d", &thread_index))
6591         ;
6592       else
6593         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         sw_if_index_set = 1;
6597       else
6598         break;
6599     }
6600
6601   if (sw_if_index_set == 0)
6602     {
6603       errmsg ("missing interface name or sw_if_index");
6604       return -99;
6605     }
6606
6607   if (is_main)
6608     thread_index = 0;
6609   /* Construct the API message */
6610   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6611   mp->sw_if_index = ntohl (sw_if_index);
6612   mp->worker_id = ntohl (thread_index);
6613   mp->queue_id = ntohl (queue_id);
6614   mp->is_main = is_main;
6615
6616   /* send it... */
6617   S (mp);
6618   /* Wait for a reply, return the good/bad news... */
6619   W (ret);
6620   return ret;
6621 }
6622
6623 static int
6624 api_sw_interface_clear_stats (vat_main_t * vam)
6625 {
6626   unformat_input_t *i = vam->input;
6627   vl_api_sw_interface_clear_stats_t *mp;
6628   u32 sw_if_index;
6629   u8 sw_if_index_set = 0;
6630   int ret;
6631
6632   /* Parse args required to build the message */
6633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6634     {
6635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6636         sw_if_index_set = 1;
6637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6638         sw_if_index_set = 1;
6639       else
6640         break;
6641     }
6642
6643   /* Construct the API message */
6644   M (SW_INTERFACE_CLEAR_STATS, mp);
6645
6646   if (sw_if_index_set == 1)
6647     mp->sw_if_index = ntohl (sw_if_index);
6648   else
6649     mp->sw_if_index = ~0;
6650
6651   /* send it... */
6652   S (mp);
6653
6654   /* Wait for a reply, return the good/bad news... */
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static int
6660 api_sw_interface_add_del_address (vat_main_t * vam)
6661 {
6662   unformat_input_t *i = vam->input;
6663   vl_api_sw_interface_add_del_address_t *mp;
6664   u32 sw_if_index;
6665   u8 sw_if_index_set = 0;
6666   u8 is_add = 1, del_all = 0;
6667   u32 address_length = 0;
6668   u8 v4_address_set = 0;
6669   u8 v6_address_set = 0;
6670   ip4_address_t v4address;
6671   ip6_address_t v6address;
6672   int ret;
6673
6674   /* Parse args required to build the message */
6675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6676     {
6677       if (unformat (i, "del-all"))
6678         del_all = 1;
6679       else if (unformat (i, "del"))
6680         is_add = 0;
6681       else
6682         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6683         sw_if_index_set = 1;
6684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6685         sw_if_index_set = 1;
6686       else if (unformat (i, "%U/%d",
6687                          unformat_ip4_address, &v4address, &address_length))
6688         v4_address_set = 1;
6689       else if (unformat (i, "%U/%d",
6690                          unformat_ip6_address, &v6address, &address_length))
6691         v6_address_set = 1;
6692       else
6693         break;
6694     }
6695
6696   if (sw_if_index_set == 0)
6697     {
6698       errmsg ("missing interface name or sw_if_index");
6699       return -99;
6700     }
6701   if (v4_address_set && v6_address_set)
6702     {
6703       errmsg ("both v4 and v6 addresses set");
6704       return -99;
6705     }
6706   if (!v4_address_set && !v6_address_set && !del_all)
6707     {
6708       errmsg ("no addresses set");
6709       return -99;
6710     }
6711
6712   /* Construct the API message */
6713   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6714
6715   mp->sw_if_index = ntohl (sw_if_index);
6716   mp->is_add = is_add;
6717   mp->del_all = del_all;
6718   if (v6_address_set)
6719     {
6720       mp->is_ipv6 = 1;
6721       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6722     }
6723   else
6724     {
6725       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6726     }
6727   mp->address_length = address_length;
6728
6729   /* send it... */
6730   S (mp);
6731
6732   /* Wait for a reply, return good/bad news  */
6733   W (ret);
6734   return ret;
6735 }
6736
6737 static int
6738 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6739 {
6740   unformat_input_t *i = vam->input;
6741   vl_api_sw_interface_set_mpls_enable_t *mp;
6742   u32 sw_if_index;
6743   u8 sw_if_index_set = 0;
6744   u8 enable = 1;
6745   int ret;
6746
6747   /* Parse args required to build the message */
6748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6749     {
6750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6751         sw_if_index_set = 1;
6752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6753         sw_if_index_set = 1;
6754       else if (unformat (i, "disable"))
6755         enable = 0;
6756       else if (unformat (i, "dis"))
6757         enable = 0;
6758       else
6759         break;
6760     }
6761
6762   if (sw_if_index_set == 0)
6763     {
6764       errmsg ("missing interface name or sw_if_index");
6765       return -99;
6766     }
6767
6768   /* Construct the API message */
6769   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6770
6771   mp->sw_if_index = ntohl (sw_if_index);
6772   mp->enable = enable;
6773
6774   /* send it... */
6775   S (mp);
6776
6777   /* Wait for a reply... */
6778   W (ret);
6779   return ret;
6780 }
6781
6782 static int
6783 api_sw_interface_set_table (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_sw_interface_set_table_t *mp;
6787   u32 sw_if_index, vrf_id = 0;
6788   u8 sw_if_index_set = 0;
6789   u8 is_ipv6 = 0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "vrf %d", &vrf_id))
6800         ;
6801       else if (unformat (i, "ipv6"))
6802         is_ipv6 = 1;
6803       else
6804         break;
6805     }
6806
6807   if (sw_if_index_set == 0)
6808     {
6809       errmsg ("missing interface name or sw_if_index");
6810       return -99;
6811     }
6812
6813   /* Construct the API message */
6814   M (SW_INTERFACE_SET_TABLE, mp);
6815
6816   mp->sw_if_index = ntohl (sw_if_index);
6817   mp->is_ipv6 = is_ipv6;
6818   mp->vrf_id = ntohl (vrf_id);
6819
6820   /* send it... */
6821   S (mp);
6822
6823   /* Wait for a reply... */
6824   W (ret);
6825   return ret;
6826 }
6827
6828 static void vl_api_sw_interface_get_table_reply_t_handler
6829   (vl_api_sw_interface_get_table_reply_t * mp)
6830 {
6831   vat_main_t *vam = &vat_main;
6832
6833   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6834
6835   vam->retval = ntohl (mp->retval);
6836   vam->result_ready = 1;
6837
6838 }
6839
6840 static void vl_api_sw_interface_get_table_reply_t_handler_json
6841   (vl_api_sw_interface_get_table_reply_t * mp)
6842 {
6843   vat_main_t *vam = &vat_main;
6844   vat_json_node_t node;
6845
6846   vat_json_init_object (&node);
6847   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6848   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6849
6850   vat_json_print (vam->ofp, &node);
6851   vat_json_free (&node);
6852
6853   vam->retval = ntohl (mp->retval);
6854   vam->result_ready = 1;
6855 }
6856
6857 static int
6858 api_sw_interface_get_table (vat_main_t * vam)
6859 {
6860   unformat_input_t *i = vam->input;
6861   vl_api_sw_interface_get_table_t *mp;
6862   u32 sw_if_index;
6863   u8 sw_if_index_set = 0;
6864   u8 is_ipv6 = 0;
6865   int ret;
6866
6867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6868     {
6869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6870         sw_if_index_set = 1;
6871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6872         sw_if_index_set = 1;
6873       else if (unformat (i, "ipv6"))
6874         is_ipv6 = 1;
6875       else
6876         break;
6877     }
6878
6879   if (sw_if_index_set == 0)
6880     {
6881       errmsg ("missing interface name or sw_if_index");
6882       return -99;
6883     }
6884
6885   M (SW_INTERFACE_GET_TABLE, mp);
6886   mp->sw_if_index = htonl (sw_if_index);
6887   mp->is_ipv6 = is_ipv6;
6888
6889   S (mp);
6890   W (ret);
6891   return ret;
6892 }
6893
6894 static int
6895 api_sw_interface_set_vpath (vat_main_t * vam)
6896 {
6897   unformat_input_t *i = vam->input;
6898   vl_api_sw_interface_set_vpath_t *mp;
6899   u32 sw_if_index = 0;
6900   u8 sw_if_index_set = 0;
6901   u8 is_enable = 0;
6902   int ret;
6903
6904   /* Parse args required to build the message */
6905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6906     {
6907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6908         sw_if_index_set = 1;
6909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6910         sw_if_index_set = 1;
6911       else if (unformat (i, "enable"))
6912         is_enable = 1;
6913       else if (unformat (i, "disable"))
6914         is_enable = 0;
6915       else
6916         break;
6917     }
6918
6919   if (sw_if_index_set == 0)
6920     {
6921       errmsg ("missing interface name or sw_if_index");
6922       return -99;
6923     }
6924
6925   /* Construct the API message */
6926   M (SW_INTERFACE_SET_VPATH, mp);
6927
6928   mp->sw_if_index = ntohl (sw_if_index);
6929   mp->enable = is_enable;
6930
6931   /* send it... */
6932   S (mp);
6933
6934   /* Wait for a reply... */
6935   W (ret);
6936   return ret;
6937 }
6938
6939 static int
6940 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6944   u32 sw_if_index = 0;
6945   u8 sw_if_index_set = 0;
6946   u8 is_enable = 1;
6947   u8 is_ipv6 = 0;
6948   int ret;
6949
6950   /* Parse args required to build the message */
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6954         sw_if_index_set = 1;
6955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6956         sw_if_index_set = 1;
6957       else if (unformat (i, "enable"))
6958         is_enable = 1;
6959       else if (unformat (i, "disable"))
6960         is_enable = 0;
6961       else if (unformat (i, "ip4"))
6962         is_ipv6 = 0;
6963       else if (unformat (i, "ip6"))
6964         is_ipv6 = 1;
6965       else
6966         break;
6967     }
6968
6969   if (sw_if_index_set == 0)
6970     {
6971       errmsg ("missing interface name or sw_if_index");
6972       return -99;
6973     }
6974
6975   /* Construct the API message */
6976   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6977
6978   mp->sw_if_index = ntohl (sw_if_index);
6979   mp->enable = is_enable;
6980   mp->is_ipv6 = is_ipv6;
6981
6982   /* send it... */
6983   S (mp);
6984
6985   /* Wait for a reply... */
6986   W (ret);
6987   return ret;
6988 }
6989
6990 static int
6991 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6992 {
6993   unformat_input_t *i = vam->input;
6994   vl_api_sw_interface_set_geneve_bypass_t *mp;
6995   u32 sw_if_index = 0;
6996   u8 sw_if_index_set = 0;
6997   u8 is_enable = 1;
6998   u8 is_ipv6 = 0;
6999   int ret;
7000
7001   /* Parse args required to build the message */
7002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003     {
7004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005         sw_if_index_set = 1;
7006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7007         sw_if_index_set = 1;
7008       else if (unformat (i, "enable"))
7009         is_enable = 1;
7010       else if (unformat (i, "disable"))
7011         is_enable = 0;
7012       else if (unformat (i, "ip4"))
7013         is_ipv6 = 0;
7014       else if (unformat (i, "ip6"))
7015         is_ipv6 = 1;
7016       else
7017         break;
7018     }
7019
7020   if (sw_if_index_set == 0)
7021     {
7022       errmsg ("missing interface name or sw_if_index");
7023       return -99;
7024     }
7025
7026   /* Construct the API message */
7027   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7028
7029   mp->sw_if_index = ntohl (sw_if_index);
7030   mp->enable = is_enable;
7031   mp->is_ipv6 = is_ipv6;
7032
7033   /* send it... */
7034   S (mp);
7035
7036   /* Wait for a reply... */
7037   W (ret);
7038   return ret;
7039 }
7040
7041 static int
7042 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7043 {
7044   unformat_input_t *i = vam->input;
7045   vl_api_sw_interface_set_l2_xconnect_t *mp;
7046   u32 rx_sw_if_index;
7047   u8 rx_sw_if_index_set = 0;
7048   u32 tx_sw_if_index;
7049   u8 tx_sw_if_index_set = 0;
7050   u8 enable = 1;
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, "rx_sw_if_index %d", &rx_sw_if_index))
7057         rx_sw_if_index_set = 1;
7058       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7059         tx_sw_if_index_set = 1;
7060       else if (unformat (i, "rx"))
7061         {
7062           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063             {
7064               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7065                             &rx_sw_if_index))
7066                 rx_sw_if_index_set = 1;
7067             }
7068           else
7069             break;
7070         }
7071       else if (unformat (i, "tx"))
7072         {
7073           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7074             {
7075               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7076                             &tx_sw_if_index))
7077                 tx_sw_if_index_set = 1;
7078             }
7079           else
7080             break;
7081         }
7082       else if (unformat (i, "enable"))
7083         enable = 1;
7084       else if (unformat (i, "disable"))
7085         enable = 0;
7086       else
7087         break;
7088     }
7089
7090   if (rx_sw_if_index_set == 0)
7091     {
7092       errmsg ("missing rx interface name or rx_sw_if_index");
7093       return -99;
7094     }
7095
7096   if (enable && (tx_sw_if_index_set == 0))
7097     {
7098       errmsg ("missing tx interface name or tx_sw_if_index");
7099       return -99;
7100     }
7101
7102   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7103
7104   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7105   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7106   mp->enable = enable;
7107
7108   S (mp);
7109   W (ret);
7110   return ret;
7111 }
7112
7113 static int
7114 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_sw_interface_set_l2_bridge_t *mp;
7118   u32 rx_sw_if_index;
7119   u8 rx_sw_if_index_set = 0;
7120   u32 bd_id;
7121   u8 bd_id_set = 0;
7122   u8 bvi = 0;
7123   u32 shg = 0;
7124   u8 enable = 1;
7125   int ret;
7126
7127   /* Parse args required to build the message */
7128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129     {
7130       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7131         rx_sw_if_index_set = 1;
7132       else if (unformat (i, "bd_id %d", &bd_id))
7133         bd_id_set = 1;
7134       else
7135         if (unformat
7136             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7137         rx_sw_if_index_set = 1;
7138       else if (unformat (i, "shg %d", &shg))
7139         ;
7140       else if (unformat (i, "bvi"))
7141         bvi = 1;
7142       else if (unformat (i, "enable"))
7143         enable = 1;
7144       else if (unformat (i, "disable"))
7145         enable = 0;
7146       else
7147         break;
7148     }
7149
7150   if (rx_sw_if_index_set == 0)
7151     {
7152       errmsg ("missing rx interface name or sw_if_index");
7153       return -99;
7154     }
7155
7156   if (enable && (bd_id_set == 0))
7157     {
7158       errmsg ("missing bridge domain");
7159       return -99;
7160     }
7161
7162   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7163
7164   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7165   mp->bd_id = ntohl (bd_id);
7166   mp->shg = (u8) shg;
7167   mp->bvi = bvi;
7168   mp->enable = enable;
7169
7170   S (mp);
7171   W (ret);
7172   return ret;
7173 }
7174
7175 static int
7176 api_bridge_domain_dump (vat_main_t * vam)
7177 {
7178   unformat_input_t *i = vam->input;
7179   vl_api_bridge_domain_dump_t *mp;
7180   vl_api_control_ping_t *mp_ping;
7181   u32 bd_id = ~0;
7182   int ret;
7183
7184   /* Parse args required to build the message */
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "bd_id %d", &bd_id))
7188         ;
7189       else
7190         break;
7191     }
7192
7193   M (BRIDGE_DOMAIN_DUMP, mp);
7194   mp->bd_id = ntohl (bd_id);
7195   S (mp);
7196
7197   /* Use a control ping for synchronization */
7198   MPING (CONTROL_PING, mp_ping);
7199   S (mp_ping);
7200
7201   W (ret);
7202   return ret;
7203 }
7204
7205 static int
7206 api_bridge_domain_add_del (vat_main_t * vam)
7207 {
7208   unformat_input_t *i = vam->input;
7209   vl_api_bridge_domain_add_del_t *mp;
7210   u32 bd_id = ~0;
7211   u8 is_add = 1;
7212   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7213   u8 *bd_tag = NULL;
7214   u32 mac_age = 0;
7215   int ret;
7216
7217   /* Parse args required to build the message */
7218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7219     {
7220       if (unformat (i, "bd_id %d", &bd_id))
7221         ;
7222       else if (unformat (i, "flood %d", &flood))
7223         ;
7224       else if (unformat (i, "uu-flood %d", &uu_flood))
7225         ;
7226       else if (unformat (i, "forward %d", &forward))
7227         ;
7228       else if (unformat (i, "learn %d", &learn))
7229         ;
7230       else if (unformat (i, "arp-term %d", &arp_term))
7231         ;
7232       else if (unformat (i, "mac-age %d", &mac_age))
7233         ;
7234       else if (unformat (i, "bd-tag %s", &bd_tag))
7235         ;
7236       else if (unformat (i, "del"))
7237         {
7238           is_add = 0;
7239           flood = uu_flood = forward = learn = 0;
7240         }
7241       else
7242         break;
7243     }
7244
7245   if (bd_id == ~0)
7246     {
7247       errmsg ("missing bridge domain");
7248       ret = -99;
7249       goto done;
7250     }
7251
7252   if (mac_age > 255)
7253     {
7254       errmsg ("mac age must be less than 256 ");
7255       ret = -99;
7256       goto done;
7257     }
7258
7259   if ((bd_tag) && (vec_len (bd_tag) > 63))
7260     {
7261       errmsg ("bd-tag cannot be longer than 63");
7262       ret = -99;
7263       goto done;
7264     }
7265
7266   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7267
7268   mp->bd_id = ntohl (bd_id);
7269   mp->flood = flood;
7270   mp->uu_flood = uu_flood;
7271   mp->forward = forward;
7272   mp->learn = learn;
7273   mp->arp_term = arp_term;
7274   mp->is_add = is_add;
7275   mp->mac_age = (u8) mac_age;
7276   if (bd_tag)
7277     {
7278       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7279       mp->bd_tag[vec_len (bd_tag)] = 0;
7280     }
7281   S (mp);
7282   W (ret);
7283
7284 done:
7285   vec_free (bd_tag);
7286   return ret;
7287 }
7288
7289 static int
7290 api_l2fib_flush_bd (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_l2fib_flush_bd_t *mp;
7294   u32 bd_id = ~0;
7295   int ret;
7296
7297   /* Parse args required to build the message */
7298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7299     {
7300       if (unformat (i, "bd_id %d", &bd_id));
7301       else
7302         break;
7303     }
7304
7305   if (bd_id == ~0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310
7311   M (L2FIB_FLUSH_BD, mp);
7312
7313   mp->bd_id = htonl (bd_id);
7314
7315   S (mp);
7316   W (ret);
7317   return ret;
7318 }
7319
7320 static int
7321 api_l2fib_flush_int (vat_main_t * vam)
7322 {
7323   unformat_input_t *i = vam->input;
7324   vl_api_l2fib_flush_int_t *mp;
7325   u32 sw_if_index = ~0;
7326   int ret;
7327
7328   /* Parse args required to build the message */
7329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7330     {
7331       if (unformat (i, "sw_if_index %d", &sw_if_index));
7332       else
7333         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7334       else
7335         break;
7336     }
7337
7338   if (sw_if_index == ~0)
7339     {
7340       errmsg ("missing interface name or sw_if_index");
7341       return -99;
7342     }
7343
7344   M (L2FIB_FLUSH_INT, mp);
7345
7346   mp->sw_if_index = ntohl (sw_if_index);
7347
7348   S (mp);
7349   W (ret);
7350   return ret;
7351 }
7352
7353 static int
7354 api_l2fib_add_del (vat_main_t * vam)
7355 {
7356   unformat_input_t *i = vam->input;
7357   vl_api_l2fib_add_del_t *mp;
7358   f64 timeout;
7359   u8 mac[6] = { 0 };
7360   u8 mac_set = 0;
7361   u32 bd_id;
7362   u8 bd_id_set = 0;
7363   u32 sw_if_index = 0;
7364   u8 sw_if_index_set = 0;
7365   u8 is_add = 1;
7366   u8 static_mac = 0;
7367   u8 filter_mac = 0;
7368   u8 bvi_mac = 0;
7369   int count = 1;
7370   f64 before = 0;
7371   int j;
7372
7373   /* Parse args required to build the message */
7374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7375     {
7376       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7377         mac_set = 1;
7378       else if (unformat (i, "bd_id %d", &bd_id))
7379         bd_id_set = 1;
7380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7381         sw_if_index_set = 1;
7382       else if (unformat (i, "sw_if"))
7383         {
7384           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7385             {
7386               if (unformat
7387                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7388                 sw_if_index_set = 1;
7389             }
7390           else
7391             break;
7392         }
7393       else if (unformat (i, "static"))
7394         static_mac = 1;
7395       else if (unformat (i, "filter"))
7396         {
7397           filter_mac = 1;
7398           static_mac = 1;
7399         }
7400       else if (unformat (i, "bvi"))
7401         {
7402           bvi_mac = 1;
7403           static_mac = 1;
7404         }
7405       else if (unformat (i, "del"))
7406         is_add = 0;
7407       else if (unformat (i, "count %d", &count))
7408         ;
7409       else
7410         break;
7411     }
7412
7413   if (mac_set == 0)
7414     {
7415       errmsg ("missing mac address");
7416       return -99;
7417     }
7418
7419   if (bd_id_set == 0)
7420     {
7421       errmsg ("missing bridge domain");
7422       return -99;
7423     }
7424
7425   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7426     {
7427       errmsg ("missing interface name or sw_if_index");
7428       return -99;
7429     }
7430
7431   if (count > 1)
7432     {
7433       /* Turn on async mode */
7434       vam->async_mode = 1;
7435       vam->async_errors = 0;
7436       before = vat_time_now (vam);
7437     }
7438
7439   for (j = 0; j < count; j++)
7440     {
7441       M (L2FIB_ADD_DEL, mp);
7442
7443       clib_memcpy (mp->mac, mac, 6);
7444       mp->bd_id = ntohl (bd_id);
7445       mp->is_add = is_add;
7446       mp->sw_if_index = ntohl (sw_if_index);
7447
7448       if (is_add)
7449         {
7450           mp->static_mac = static_mac;
7451           mp->filter_mac = filter_mac;
7452           mp->bvi_mac = bvi_mac;
7453         }
7454       increment_mac_address (mac);
7455       /* send it... */
7456       S (mp);
7457     }
7458
7459   if (count > 1)
7460     {
7461       vl_api_control_ping_t *mp_ping;
7462       f64 after;
7463
7464       /* Shut off async mode */
7465       vam->async_mode = 0;
7466
7467       MPING (CONTROL_PING, mp_ping);
7468       S (mp_ping);
7469
7470       timeout = vat_time_now (vam) + 1.0;
7471       while (vat_time_now (vam) < timeout)
7472         if (vam->result_ready == 1)
7473           goto out;
7474       vam->retval = -99;
7475
7476     out:
7477       if (vam->retval == -99)
7478         errmsg ("timeout");
7479
7480       if (vam->async_errors > 0)
7481         {
7482           errmsg ("%d asynchronous errors", vam->async_errors);
7483           vam->retval = -98;
7484         }
7485       vam->async_errors = 0;
7486       after = vat_time_now (vam);
7487
7488       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7489              count, after - before, count / (after - before));
7490     }
7491   else
7492     {
7493       int ret;
7494
7495       /* Wait for a reply... */
7496       W (ret);
7497       return ret;
7498     }
7499   /* Return the good/bad news */
7500   return (vam->retval);
7501 }
7502
7503 static int
7504 api_bridge_domain_set_mac_age (vat_main_t * vam)
7505 {
7506   unformat_input_t *i = vam->input;
7507   vl_api_bridge_domain_set_mac_age_t *mp;
7508   u32 bd_id = ~0;
7509   u32 mac_age = 0;
7510   int ret;
7511
7512   /* Parse args required to build the message */
7513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7514     {
7515       if (unformat (i, "bd_id %d", &bd_id));
7516       else if (unformat (i, "mac-age %d", &mac_age));
7517       else
7518         break;
7519     }
7520
7521   if (bd_id == ~0)
7522     {
7523       errmsg ("missing bridge domain");
7524       return -99;
7525     }
7526
7527   if (mac_age > 255)
7528     {
7529       errmsg ("mac age must be less than 256 ");
7530       return -99;
7531     }
7532
7533   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7534
7535   mp->bd_id = htonl (bd_id);
7536   mp->mac_age = (u8) mac_age;
7537
7538   S (mp);
7539   W (ret);
7540   return ret;
7541 }
7542
7543 static int
7544 api_l2_flags (vat_main_t * vam)
7545 {
7546   unformat_input_t *i = vam->input;
7547   vl_api_l2_flags_t *mp;
7548   u32 sw_if_index;
7549   u32 flags = 0;
7550   u8 sw_if_index_set = 0;
7551   u8 is_set = 0;
7552   int ret;
7553
7554   /* Parse args required to build the message */
7555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556     {
7557       if (unformat (i, "sw_if_index %d", &sw_if_index))
7558         sw_if_index_set = 1;
7559       else if (unformat (i, "sw_if"))
7560         {
7561           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7562             {
7563               if (unformat
7564                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7565                 sw_if_index_set = 1;
7566             }
7567           else
7568             break;
7569         }
7570       else if (unformat (i, "learn"))
7571         flags |= L2_LEARN;
7572       else if (unformat (i, "forward"))
7573         flags |= L2_FWD;
7574       else if (unformat (i, "flood"))
7575         flags |= L2_FLOOD;
7576       else if (unformat (i, "uu-flood"))
7577         flags |= L2_UU_FLOOD;
7578       else if (unformat (i, "arp-term"))
7579         flags |= L2_ARP_TERM;
7580       else if (unformat (i, "off"))
7581         is_set = 0;
7582       else if (unformat (i, "disable"))
7583         is_set = 0;
7584       else
7585         break;
7586     }
7587
7588   if (sw_if_index_set == 0)
7589     {
7590       errmsg ("missing interface name or sw_if_index");
7591       return -99;
7592     }
7593
7594   M (L2_FLAGS, mp);
7595
7596   mp->sw_if_index = ntohl (sw_if_index);
7597   mp->feature_bitmap = ntohl (flags);
7598   mp->is_set = is_set;
7599
7600   S (mp);
7601   W (ret);
7602   return ret;
7603 }
7604
7605 static int
7606 api_bridge_flags (vat_main_t * vam)
7607 {
7608   unformat_input_t *i = vam->input;
7609   vl_api_bridge_flags_t *mp;
7610   u32 bd_id;
7611   u8 bd_id_set = 0;
7612   u8 is_set = 1;
7613   u32 flags = 0;
7614   int ret;
7615
7616   /* Parse args required to build the message */
7617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7618     {
7619       if (unformat (i, "bd_id %d", &bd_id))
7620         bd_id_set = 1;
7621       else if (unformat (i, "learn"))
7622         flags |= L2_LEARN;
7623       else if (unformat (i, "forward"))
7624         flags |= L2_FWD;
7625       else if (unformat (i, "flood"))
7626         flags |= L2_FLOOD;
7627       else if (unformat (i, "uu-flood"))
7628         flags |= L2_UU_FLOOD;
7629       else if (unformat (i, "arp-term"))
7630         flags |= L2_ARP_TERM;
7631       else if (unformat (i, "off"))
7632         is_set = 0;
7633       else if (unformat (i, "disable"))
7634         is_set = 0;
7635       else
7636         break;
7637     }
7638
7639   if (bd_id_set == 0)
7640     {
7641       errmsg ("missing bridge domain");
7642       return -99;
7643     }
7644
7645   M (BRIDGE_FLAGS, mp);
7646
7647   mp->bd_id = ntohl (bd_id);
7648   mp->feature_bitmap = ntohl (flags);
7649   mp->is_set = is_set;
7650
7651   S (mp);
7652   W (ret);
7653   return ret;
7654 }
7655
7656 static int
7657 api_bd_ip_mac_add_del (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_bd_ip_mac_add_del_t *mp;
7661   u32 bd_id;
7662   u8 is_ipv6 = 0;
7663   u8 is_add = 1;
7664   u8 bd_id_set = 0;
7665   u8 ip_set = 0;
7666   u8 mac_set = 0;
7667   ip4_address_t v4addr;
7668   ip6_address_t v6addr;
7669   u8 macaddr[6];
7670   int ret;
7671
7672
7673   /* Parse args required to build the message */
7674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675     {
7676       if (unformat (i, "bd_id %d", &bd_id))
7677         {
7678           bd_id_set++;
7679         }
7680       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7681         {
7682           ip_set++;
7683         }
7684       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7685         {
7686           ip_set++;
7687           is_ipv6++;
7688         }
7689       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7690         {
7691           mac_set++;
7692         }
7693       else if (unformat (i, "del"))
7694         is_add = 0;
7695       else
7696         break;
7697     }
7698
7699   if (bd_id_set == 0)
7700     {
7701       errmsg ("missing bridge domain");
7702       return -99;
7703     }
7704   else if (ip_set == 0)
7705     {
7706       errmsg ("missing IP address");
7707       return -99;
7708     }
7709   else if (mac_set == 0)
7710     {
7711       errmsg ("missing MAC address");
7712       return -99;
7713     }
7714
7715   M (BD_IP_MAC_ADD_DEL, mp);
7716
7717   mp->bd_id = ntohl (bd_id);
7718   mp->is_ipv6 = is_ipv6;
7719   mp->is_add = is_add;
7720   if (is_ipv6)
7721     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7722   else
7723     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7724   clib_memcpy (mp->mac_address, macaddr, 6);
7725   S (mp);
7726   W (ret);
7727   return ret;
7728 }
7729
7730 static void vl_api_bd_ip_mac_details_t_handler
7731   (vl_api_bd_ip_mac_details_t * mp)
7732 {
7733   vat_main_t *vam = &vat_main;
7734   u8 *ip = 0;
7735
7736   if (!mp->is_ipv6)
7737     ip =
7738       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7739   else
7740     ip =
7741       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7742
7743   print (vam->ofp,
7744          "\n%-5d %-7s %-20U %-30s",
7745          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7746          format_ethernet_address, mp->mac_address, ip);
7747
7748   vec_free (ip);
7749 }
7750
7751 static void vl_api_bd_ip_mac_details_t_handler_json
7752   (vl_api_bd_ip_mac_details_t * mp)
7753 {
7754   vat_main_t *vam = &vat_main;
7755   vat_json_node_t *node = NULL;
7756
7757   if (VAT_JSON_ARRAY != vam->json_tree.type)
7758     {
7759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7760       vat_json_init_array (&vam->json_tree);
7761     }
7762   node = vat_json_array_add (&vam->json_tree);
7763
7764   vat_json_init_object (node);
7765   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7766   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7767   vat_json_object_add_string_copy (node, "mac_address",
7768                                    format (0, "%U", format_ethernet_address,
7769                                            &mp->mac_address));
7770   u8 *ip = 0;
7771
7772   if (!mp->is_ipv6)
7773     ip =
7774       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7775   else
7776     ip =
7777       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7778   vat_json_object_add_string_copy (node, "ip_address", ip);
7779   vec_free (ip);
7780 }
7781
7782 static int
7783 api_bd_ip_mac_dump (vat_main_t * vam)
7784 {
7785   unformat_input_t *i = vam->input;
7786   vl_api_bd_ip_mac_dump_t *mp;
7787   vl_api_control_ping_t *mp_ping;
7788   int ret;
7789   u32 bd_id;
7790   u8 bd_id_set = 0;
7791
7792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7793     {
7794       if (unformat (i, "bd_id %d", &bd_id))
7795         {
7796           bd_id_set++;
7797         }
7798       else
7799         break;
7800     }
7801
7802   print (vam->ofp,
7803          "\n%-5s %-7s %-20s %-30s",
7804          "bd_id", "is_ipv6", "mac_address", "ip_address");
7805
7806   /* Dump Bridge Domain Ip to Mac entries */
7807   M (BD_IP_MAC_DUMP, mp);
7808
7809   if (bd_id_set)
7810     mp->bd_id = htonl (bd_id);
7811   else
7812     mp->bd_id = ~0;
7813
7814   S (mp);
7815
7816   /* Use a control ping for synchronization */
7817   MPING (CONTROL_PING, mp_ping);
7818   S (mp_ping);
7819
7820   W (ret);
7821   return ret;
7822 }
7823
7824 static int
7825 api_tap_connect (vat_main_t * vam)
7826 {
7827   unformat_input_t *i = vam->input;
7828   vl_api_tap_connect_t *mp;
7829   u8 mac_address[6];
7830   u8 random_mac = 1;
7831   u8 name_set = 0;
7832   u8 *tap_name;
7833   u8 *tag = 0;
7834   ip4_address_t ip4_address;
7835   u32 ip4_mask_width;
7836   int ip4_address_set = 0;
7837   ip6_address_t ip6_address;
7838   u32 ip6_mask_width;
7839   int ip6_address_set = 0;
7840   int ret;
7841
7842   memset (mac_address, 0, sizeof (mac_address));
7843
7844   /* Parse args required to build the message */
7845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7846     {
7847       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7848         {
7849           random_mac = 0;
7850         }
7851       else if (unformat (i, "random-mac"))
7852         random_mac = 1;
7853       else if (unformat (i, "tapname %s", &tap_name))
7854         name_set = 1;
7855       else if (unformat (i, "tag %s", &tag))
7856         ;
7857       else if (unformat (i, "address %U/%d",
7858                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7859         ip4_address_set = 1;
7860       else if (unformat (i, "address %U/%d",
7861                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7862         ip6_address_set = 1;
7863       else
7864         break;
7865     }
7866
7867   if (name_set == 0)
7868     {
7869       errmsg ("missing tap name");
7870       return -99;
7871     }
7872   if (vec_len (tap_name) > 63)
7873     {
7874       errmsg ("tap name too long");
7875       return -99;
7876     }
7877   vec_add1 (tap_name, 0);
7878
7879   if (vec_len (tag) > 63)
7880     {
7881       errmsg ("tag too long");
7882       return -99;
7883     }
7884
7885   /* Construct the API message */
7886   M (TAP_CONNECT, mp);
7887
7888   mp->use_random_mac = random_mac;
7889   clib_memcpy (mp->mac_address, mac_address, 6);
7890   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7891   if (tag)
7892     clib_memcpy (mp->tag, tag, vec_len (tag));
7893
7894   if (ip4_address_set)
7895     {
7896       mp->ip4_address_set = 1;
7897       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7898       mp->ip4_mask_width = ip4_mask_width;
7899     }
7900   if (ip6_address_set)
7901     {
7902       mp->ip6_address_set = 1;
7903       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7904       mp->ip6_mask_width = ip6_mask_width;
7905     }
7906
7907   vec_free (tap_name);
7908   vec_free (tag);
7909
7910   /* send it... */
7911   S (mp);
7912
7913   /* Wait for a reply... */
7914   W (ret);
7915   return ret;
7916 }
7917
7918 static int
7919 api_tap_modify (vat_main_t * vam)
7920 {
7921   unformat_input_t *i = vam->input;
7922   vl_api_tap_modify_t *mp;
7923   u8 mac_address[6];
7924   u8 random_mac = 1;
7925   u8 name_set = 0;
7926   u8 *tap_name;
7927   u32 sw_if_index = ~0;
7928   u8 sw_if_index_set = 0;
7929   int ret;
7930
7931   memset (mac_address, 0, sizeof (mac_address));
7932
7933   /* Parse args required to build the message */
7934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7937         sw_if_index_set = 1;
7938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7939         sw_if_index_set = 1;
7940       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7941         {
7942           random_mac = 0;
7943         }
7944       else if (unformat (i, "random-mac"))
7945         random_mac = 1;
7946       else if (unformat (i, "tapname %s", &tap_name))
7947         name_set = 1;
7948       else
7949         break;
7950     }
7951
7952   if (sw_if_index_set == 0)
7953     {
7954       errmsg ("missing vpp interface name");
7955       return -99;
7956     }
7957   if (name_set == 0)
7958     {
7959       errmsg ("missing tap name");
7960       return -99;
7961     }
7962   if (vec_len (tap_name) > 63)
7963     {
7964       errmsg ("tap name too long");
7965     }
7966   vec_add1 (tap_name, 0);
7967
7968   /* Construct the API message */
7969   M (TAP_MODIFY, mp);
7970
7971   mp->use_random_mac = random_mac;
7972   mp->sw_if_index = ntohl (sw_if_index);
7973   clib_memcpy (mp->mac_address, mac_address, 6);
7974   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7975   vec_free (tap_name);
7976
7977   /* send it... */
7978   S (mp);
7979
7980   /* Wait for a reply... */
7981   W (ret);
7982   return ret;
7983 }
7984
7985 static int
7986 api_tap_delete (vat_main_t * vam)
7987 {
7988   unformat_input_t *i = vam->input;
7989   vl_api_tap_delete_t *mp;
7990   u32 sw_if_index = ~0;
7991   u8 sw_if_index_set = 0;
7992   int ret;
7993
7994   /* Parse args required to build the message */
7995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7996     {
7997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7998         sw_if_index_set = 1;
7999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8000         sw_if_index_set = 1;
8001       else
8002         break;
8003     }
8004
8005   if (sw_if_index_set == 0)
8006     {
8007       errmsg ("missing vpp interface name");
8008       return -99;
8009     }
8010
8011   /* Construct the API message */
8012   M (TAP_DELETE, mp);
8013
8014   mp->sw_if_index = ntohl (sw_if_index);
8015
8016   /* send it... */
8017   S (mp);
8018
8019   /* Wait for a reply... */
8020   W (ret);
8021   return ret;
8022 }
8023
8024 static int
8025 api_tap_create_v2 (vat_main_t * vam)
8026 {
8027   unformat_input_t *i = vam->input;
8028   vl_api_tap_create_v2_t *mp;
8029   u8 mac_address[6];
8030   u8 random_mac = 1;
8031   u32 id = ~0;
8032   u8 *host_if_name = 0;
8033   u8 *host_ns = 0;
8034   u8 host_mac_addr[6];
8035   u8 host_mac_addr_set = 0;
8036   u8 *host_bridge = 0;
8037   ip4_address_t host_ip4_addr;
8038   ip4_address_t host_ip4_gw;
8039   u8 host_ip4_gw_set = 0;
8040   u32 host_ip4_prefix_len = 0;
8041   ip6_address_t host_ip6_addr;
8042   ip6_address_t host_ip6_gw;
8043   u8 host_ip6_gw_set = 0;
8044   u32 host_ip6_prefix_len = 0;
8045   int ret;
8046   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8047
8048   memset (mac_address, 0, sizeof (mac_address));
8049
8050   /* Parse args required to build the message */
8051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8052     {
8053       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8054         {
8055           random_mac = 0;
8056         }
8057       else if (unformat (i, "id %u", &id))
8058         ;
8059       else if (unformat (i, "host-if-name %s", &host_if_name))
8060         ;
8061       else if (unformat (i, "host-ns %s", &host_ns))
8062         ;
8063       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8064                          host_mac_addr))
8065         host_mac_addr_set = 1;
8066       else if (unformat (i, "host-bridge %s", &host_bridge))
8067         ;
8068       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8069                          &host_ip4_addr, &host_ip4_prefix_len))
8070         ;
8071       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8072                          &host_ip6_addr, &host_ip6_prefix_len))
8073         ;
8074       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8075                          &host_ip4_gw))
8076         host_ip4_gw_set = 1;
8077       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8078                          &host_ip6_gw))
8079         host_ip6_gw_set = 1;
8080       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8081         ;
8082       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8083         ;
8084       else
8085         break;
8086     }
8087
8088   if (vec_len (host_if_name) > 63)
8089     {
8090       errmsg ("tap name too long. ");
8091       return -99;
8092     }
8093   if (vec_len (host_ns) > 63)
8094     {
8095       errmsg ("host name space too long. ");
8096       return -99;
8097     }
8098   if (vec_len (host_bridge) > 63)
8099     {
8100       errmsg ("host bridge name too long. ");
8101       return -99;
8102     }
8103   if (host_ip4_prefix_len > 32)
8104     {
8105       errmsg ("host ip4 prefix length not valid. ");
8106       return -99;
8107     }
8108   if (host_ip6_prefix_len > 128)
8109     {
8110       errmsg ("host ip6 prefix length not valid. ");
8111       return -99;
8112     }
8113   if (!is_pow2 (rx_ring_sz))
8114     {
8115       errmsg ("rx ring size must be power of 2. ");
8116       return -99;
8117     }
8118   if (rx_ring_sz > 32768)
8119     {
8120       errmsg ("rx ring size must be 32768 or lower. ");
8121       return -99;
8122     }
8123   if (!is_pow2 (tx_ring_sz))
8124     {
8125       errmsg ("tx ring size must be power of 2. ");
8126       return -99;
8127     }
8128   if (tx_ring_sz > 32768)
8129     {
8130       errmsg ("tx ring size must be 32768 or lower. ");
8131       return -99;
8132     }
8133
8134   /* Construct the API message */
8135   M (TAP_CREATE_V2, mp);
8136
8137   mp->use_random_mac = random_mac;
8138
8139   mp->id = ntohl (id);
8140   mp->host_namespace_set = host_ns != 0;
8141   mp->host_bridge_set = host_bridge != 0;
8142   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8143   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8144   mp->rx_ring_sz = ntohs (rx_ring_sz);
8145   mp->tx_ring_sz = ntohs (tx_ring_sz);
8146
8147   if (random_mac == 0)
8148     clib_memcpy (mp->mac_address, mac_address, 6);
8149   if (host_mac_addr_set)
8150     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8151   if (host_if_name)
8152     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8153   if (host_ns)
8154     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8155   if (host_bridge)
8156     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8157   if (host_ip4_prefix_len)
8158     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8159   if (host_ip4_prefix_len)
8160     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8161   if (host_ip4_gw_set)
8162     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8163   if (host_ip6_gw_set)
8164     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8165
8166   vec_free (host_ns);
8167   vec_free (host_if_name);
8168   vec_free (host_bridge);
8169
8170   /* send it... */
8171   S (mp);
8172
8173   /* Wait for a reply... */
8174   W (ret);
8175   return ret;
8176 }
8177
8178 static int
8179 api_tap_delete_v2 (vat_main_t * vam)
8180 {
8181   unformat_input_t *i = vam->input;
8182   vl_api_tap_delete_v2_t *mp;
8183   u32 sw_if_index = ~0;
8184   u8 sw_if_index_set = 0;
8185   int ret;
8186
8187   /* Parse args required to build the message */
8188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8189     {
8190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8191         sw_if_index_set = 1;
8192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8193         sw_if_index_set = 1;
8194       else
8195         break;
8196     }
8197
8198   if (sw_if_index_set == 0)
8199     {
8200       errmsg ("missing vpp interface name. ");
8201       return -99;
8202     }
8203
8204   /* Construct the API message */
8205   M (TAP_DELETE_V2, mp);
8206
8207   mp->sw_if_index = ntohl (sw_if_index);
8208
8209   /* send it... */
8210   S (mp);
8211
8212   /* Wait for a reply... */
8213   W (ret);
8214   return ret;
8215 }
8216
8217 static int
8218 api_bond_create (vat_main_t * vam)
8219 {
8220   unformat_input_t *i = vam->input;
8221   vl_api_bond_create_t *mp;
8222   u8 mac_address[6];
8223   u8 custom_mac = 0;
8224   int ret;
8225   u8 mode;
8226   u8 lb;
8227   u8 mode_is_set = 0;
8228
8229   memset (mac_address, 0, sizeof (mac_address));
8230   lb = BOND_LB_L2;
8231
8232   /* Parse args required to build the message */
8233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8234     {
8235       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8236         mode_is_set = 1;
8237       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8238                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8239         ;
8240       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8241                          mac_address))
8242         custom_mac = 1;
8243       else
8244         break;
8245     }
8246
8247   if (mode_is_set == 0)
8248     {
8249       errmsg ("Missing bond mode. ");
8250       return -99;
8251     }
8252
8253   /* Construct the API message */
8254   M (BOND_CREATE, mp);
8255
8256   mp->use_custom_mac = custom_mac;
8257
8258   mp->mode = mode;
8259   mp->lb = lb;
8260
8261   if (custom_mac)
8262     clib_memcpy (mp->mac_address, mac_address, 6);
8263
8264   /* send it... */
8265   S (mp);
8266
8267   /* Wait for a reply... */
8268   W (ret);
8269   return ret;
8270 }
8271
8272 static int
8273 api_bond_delete (vat_main_t * vam)
8274 {
8275   unformat_input_t *i = vam->input;
8276   vl_api_bond_delete_t *mp;
8277   u32 sw_if_index = ~0;
8278   u8 sw_if_index_set = 0;
8279   int ret;
8280
8281   /* Parse args required to build the message */
8282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8283     {
8284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8285         sw_if_index_set = 1;
8286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8287         sw_if_index_set = 1;
8288       else
8289         break;
8290     }
8291
8292   if (sw_if_index_set == 0)
8293     {
8294       errmsg ("missing vpp interface name. ");
8295       return -99;
8296     }
8297
8298   /* Construct the API message */
8299   M (BOND_DELETE, mp);
8300
8301   mp->sw_if_index = ntohl (sw_if_index);
8302
8303   /* send it... */
8304   S (mp);
8305
8306   /* Wait for a reply... */
8307   W (ret);
8308   return ret;
8309 }
8310
8311 static int
8312 api_bond_enslave (vat_main_t * vam)
8313 {
8314   unformat_input_t *i = vam->input;
8315   vl_api_bond_enslave_t *mp;
8316   u32 bond_sw_if_index;
8317   int ret;
8318   u8 is_passive;
8319   u8 is_long_timeout;
8320   u32 bond_sw_if_index_is_set = 0;
8321   u32 sw_if_index;
8322   u8 sw_if_index_is_set = 0;
8323
8324   /* Parse args required to build the message */
8325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8326     {
8327       if (unformat (i, "sw_if_index %d", &sw_if_index))
8328         sw_if_index_is_set = 1;
8329       else if (unformat (i, "bond %u", &bond_sw_if_index))
8330         bond_sw_if_index_is_set = 1;
8331       else if (unformat (i, "passive %d", &is_passive))
8332         ;
8333       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8334         ;
8335       else
8336         break;
8337     }
8338
8339   if (bond_sw_if_index_is_set == 0)
8340     {
8341       errmsg ("Missing bond sw_if_index. ");
8342       return -99;
8343     }
8344   if (sw_if_index_is_set == 0)
8345     {
8346       errmsg ("Missing slave sw_if_index. ");
8347       return -99;
8348     }
8349
8350   /* Construct the API message */
8351   M (BOND_ENSLAVE, mp);
8352
8353   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8354   mp->sw_if_index = ntohl (sw_if_index);
8355   mp->is_long_timeout = is_long_timeout;
8356   mp->is_passive = is_passive;
8357
8358   /* send it... */
8359   S (mp);
8360
8361   /* Wait for a reply... */
8362   W (ret);
8363   return ret;
8364 }
8365
8366 static int
8367 api_bond_detach_slave (vat_main_t * vam)
8368 {
8369   unformat_input_t *i = vam->input;
8370   vl_api_bond_detach_slave_t *mp;
8371   u32 sw_if_index = ~0;
8372   u8 sw_if_index_set = 0;
8373   int ret;
8374
8375   /* Parse args required to build the message */
8376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8377     {
8378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8379         sw_if_index_set = 1;
8380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8381         sw_if_index_set = 1;
8382       else
8383         break;
8384     }
8385
8386   if (sw_if_index_set == 0)
8387     {
8388       errmsg ("missing vpp interface name. ");
8389       return -99;
8390     }
8391
8392   /* Construct the API message */
8393   M (BOND_DETACH_SLAVE, mp);
8394
8395   mp->sw_if_index = ntohl (sw_if_index);
8396
8397   /* send it... */
8398   S (mp);
8399
8400   /* Wait for a reply... */
8401   W (ret);
8402   return ret;
8403 }
8404
8405 static int
8406 api_ip_table_add_del (vat_main_t * vam)
8407 {
8408   unformat_input_t *i = vam->input;
8409   vl_api_ip_table_add_del_t *mp;
8410   u32 table_id = ~0;
8411   u8 is_ipv6 = 0;
8412   u8 is_add = 1;
8413   int ret = 0;
8414
8415   /* Parse args required to build the message */
8416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8417     {
8418       if (unformat (i, "ipv6"))
8419         is_ipv6 = 1;
8420       else if (unformat (i, "del"))
8421         is_add = 0;
8422       else if (unformat (i, "add"))
8423         is_add = 1;
8424       else if (unformat (i, "table %d", &table_id))
8425         ;
8426       else
8427         {
8428           clib_warning ("parse error '%U'", format_unformat_error, i);
8429           return -99;
8430         }
8431     }
8432
8433   if (~0 == table_id)
8434     {
8435       errmsg ("missing table-ID");
8436       return -99;
8437     }
8438
8439   /* Construct the API message */
8440   M (IP_TABLE_ADD_DEL, mp);
8441
8442   mp->table_id = ntohl (table_id);
8443   mp->is_ipv6 = is_ipv6;
8444   mp->is_add = is_add;
8445
8446   /* send it... */
8447   S (mp);
8448
8449   /* Wait for a reply... */
8450   W (ret);
8451
8452   return ret;
8453 }
8454
8455 static int
8456 api_ip_add_del_route (vat_main_t * vam)
8457 {
8458   unformat_input_t *i = vam->input;
8459   vl_api_ip_add_del_route_t *mp;
8460   u32 sw_if_index = ~0, vrf_id = 0;
8461   u8 is_ipv6 = 0;
8462   u8 is_local = 0, is_drop = 0;
8463   u8 is_unreach = 0, is_prohibit = 0;
8464   u8 is_add = 1;
8465   u32 next_hop_weight = 1;
8466   u8 is_multipath = 0;
8467   u8 address_set = 0;
8468   u8 address_length_set = 0;
8469   u32 next_hop_table_id = 0;
8470   u32 resolve_attempts = 0;
8471   u32 dst_address_length = 0;
8472   u8 next_hop_set = 0;
8473   ip4_address_t v4_dst_address, v4_next_hop_address;
8474   ip6_address_t v6_dst_address, v6_next_hop_address;
8475   int count = 1;
8476   int j;
8477   f64 before = 0;
8478   u32 random_add_del = 0;
8479   u32 *random_vector = 0;
8480   uword *random_hash;
8481   u32 random_seed = 0xdeaddabe;
8482   u32 classify_table_index = ~0;
8483   u8 is_classify = 0;
8484   u8 resolve_host = 0, resolve_attached = 0;
8485   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8486   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8487   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8488
8489   /* Parse args required to build the message */
8490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8491     {
8492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8493         ;
8494       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8495         ;
8496       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8497         {
8498           address_set = 1;
8499           is_ipv6 = 0;
8500         }
8501       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8502         {
8503           address_set = 1;
8504           is_ipv6 = 1;
8505         }
8506       else if (unformat (i, "/%d", &dst_address_length))
8507         {
8508           address_length_set = 1;
8509         }
8510
8511       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8512                                          &v4_next_hop_address))
8513         {
8514           next_hop_set = 1;
8515         }
8516       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8517                                          &v6_next_hop_address))
8518         {
8519           next_hop_set = 1;
8520         }
8521       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8522         ;
8523       else if (unformat (i, "weight %d", &next_hop_weight))
8524         ;
8525       else if (unformat (i, "drop"))
8526         {
8527           is_drop = 1;
8528         }
8529       else if (unformat (i, "null-send-unreach"))
8530         {
8531           is_unreach = 1;
8532         }
8533       else if (unformat (i, "null-send-prohibit"))
8534         {
8535           is_prohibit = 1;
8536         }
8537       else if (unformat (i, "local"))
8538         {
8539           is_local = 1;
8540         }
8541       else if (unformat (i, "classify %d", &classify_table_index))
8542         {
8543           is_classify = 1;
8544         }
8545       else if (unformat (i, "del"))
8546         is_add = 0;
8547       else if (unformat (i, "add"))
8548         is_add = 1;
8549       else if (unformat (i, "resolve-via-host"))
8550         resolve_host = 1;
8551       else if (unformat (i, "resolve-via-attached"))
8552         resolve_attached = 1;
8553       else if (unformat (i, "multipath"))
8554         is_multipath = 1;
8555       else if (unformat (i, "vrf %d", &vrf_id))
8556         ;
8557       else if (unformat (i, "count %d", &count))
8558         ;
8559       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8560         ;
8561       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8562         ;
8563       else if (unformat (i, "out-label %d", &next_hop_out_label))
8564         {
8565           vl_api_fib_mpls_label_t fib_label = {
8566             .label = ntohl (next_hop_out_label),
8567             .ttl = 64,
8568             .exp = 0,
8569           };
8570           vec_add1 (next_hop_out_label_stack, fib_label);
8571         }
8572       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8573         ;
8574       else if (unformat (i, "random"))
8575         random_add_del = 1;
8576       else if (unformat (i, "seed %d", &random_seed))
8577         ;
8578       else
8579         {
8580           clib_warning ("parse error '%U'", format_unformat_error, i);
8581           return -99;
8582         }
8583     }
8584
8585   if (!next_hop_set && !is_drop && !is_local &&
8586       !is_classify && !is_unreach && !is_prohibit &&
8587       MPLS_LABEL_INVALID == next_hop_via_label)
8588     {
8589       errmsg
8590         ("next hop / local / drop / unreach / prohibit / classify not set");
8591       return -99;
8592     }
8593
8594   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8595     {
8596       errmsg ("next hop and next-hop via label set");
8597       return -99;
8598     }
8599   if (address_set == 0)
8600     {
8601       errmsg ("missing addresses");
8602       return -99;
8603     }
8604
8605   if (address_length_set == 0)
8606     {
8607       errmsg ("missing address length");
8608       return -99;
8609     }
8610
8611   /* Generate a pile of unique, random routes */
8612   if (random_add_del)
8613     {
8614       u32 this_random_address;
8615       random_hash = hash_create (count, sizeof (uword));
8616
8617       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8618       for (j = 0; j <= count; j++)
8619         {
8620           do
8621             {
8622               this_random_address = random_u32 (&random_seed);
8623               this_random_address =
8624                 clib_host_to_net_u32 (this_random_address);
8625             }
8626           while (hash_get (random_hash, this_random_address));
8627           vec_add1 (random_vector, this_random_address);
8628           hash_set (random_hash, this_random_address, 1);
8629         }
8630       hash_free (random_hash);
8631       v4_dst_address.as_u32 = random_vector[0];
8632     }
8633
8634   if (count > 1)
8635     {
8636       /* Turn on async mode */
8637       vam->async_mode = 1;
8638       vam->async_errors = 0;
8639       before = vat_time_now (vam);
8640     }
8641
8642   for (j = 0; j < count; j++)
8643     {
8644       /* Construct the API message */
8645       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8646           vec_len (next_hop_out_label_stack));
8647
8648       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8649       mp->table_id = ntohl (vrf_id);
8650
8651       mp->is_add = is_add;
8652       mp->is_drop = is_drop;
8653       mp->is_unreach = is_unreach;
8654       mp->is_prohibit = is_prohibit;
8655       mp->is_ipv6 = is_ipv6;
8656       mp->is_local = is_local;
8657       mp->is_classify = is_classify;
8658       mp->is_multipath = is_multipath;
8659       mp->is_resolve_host = resolve_host;
8660       mp->is_resolve_attached = resolve_attached;
8661       mp->next_hop_weight = next_hop_weight;
8662       mp->dst_address_length = dst_address_length;
8663       mp->next_hop_table_id = ntohl (next_hop_table_id);
8664       mp->classify_table_index = ntohl (classify_table_index);
8665       mp->next_hop_via_label = ntohl (next_hop_via_label);
8666       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8667       if (0 != mp->next_hop_n_out_labels)
8668         {
8669           memcpy (mp->next_hop_out_label_stack,
8670                   next_hop_out_label_stack,
8671                   (vec_len (next_hop_out_label_stack) *
8672                    sizeof (vl_api_fib_mpls_label_t)));
8673           vec_free (next_hop_out_label_stack);
8674         }
8675
8676       if (is_ipv6)
8677         {
8678           clib_memcpy (mp->dst_address, &v6_dst_address,
8679                        sizeof (v6_dst_address));
8680           if (next_hop_set)
8681             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8682                          sizeof (v6_next_hop_address));
8683           increment_v6_address (&v6_dst_address);
8684         }
8685       else
8686         {
8687           clib_memcpy (mp->dst_address, &v4_dst_address,
8688                        sizeof (v4_dst_address));
8689           if (next_hop_set)
8690             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8691                          sizeof (v4_next_hop_address));
8692           if (random_add_del)
8693             v4_dst_address.as_u32 = random_vector[j + 1];
8694           else
8695             increment_v4_address (&v4_dst_address);
8696         }
8697       /* send it... */
8698       S (mp);
8699       /* If we receive SIGTERM, stop now... */
8700       if (vam->do_exit)
8701         break;
8702     }
8703
8704   /* When testing multiple add/del ops, use a control-ping to sync */
8705   if (count > 1)
8706     {
8707       vl_api_control_ping_t *mp_ping;
8708       f64 after;
8709       f64 timeout;
8710
8711       /* Shut off async mode */
8712       vam->async_mode = 0;
8713
8714       MPING (CONTROL_PING, mp_ping);
8715       S (mp_ping);
8716
8717       timeout = vat_time_now (vam) + 1.0;
8718       while (vat_time_now (vam) < timeout)
8719         if (vam->result_ready == 1)
8720           goto out;
8721       vam->retval = -99;
8722
8723     out:
8724       if (vam->retval == -99)
8725         errmsg ("timeout");
8726
8727       if (vam->async_errors > 0)
8728         {
8729           errmsg ("%d asynchronous errors", vam->async_errors);
8730           vam->retval = -98;
8731         }
8732       vam->async_errors = 0;
8733       after = vat_time_now (vam);
8734
8735       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8736       if (j > 0)
8737         count = j;
8738
8739       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8740              count, after - before, count / (after - before));
8741     }
8742   else
8743     {
8744       int ret;
8745
8746       /* Wait for a reply... */
8747       W (ret);
8748       return ret;
8749     }
8750
8751   /* Return the good/bad news */
8752   return (vam->retval);
8753 }
8754
8755 static int
8756 api_ip_mroute_add_del (vat_main_t * vam)
8757 {
8758   unformat_input_t *i = vam->input;
8759   vl_api_ip_mroute_add_del_t *mp;
8760   u32 sw_if_index = ~0, vrf_id = 0;
8761   u8 is_ipv6 = 0;
8762   u8 is_local = 0;
8763   u8 is_add = 1;
8764   u8 address_set = 0;
8765   u32 grp_address_length = 0;
8766   ip4_address_t v4_grp_address, v4_src_address;
8767   ip6_address_t v6_grp_address, v6_src_address;
8768   mfib_itf_flags_t iflags = 0;
8769   mfib_entry_flags_t eflags = 0;
8770   int ret;
8771
8772   /* Parse args required to build the message */
8773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8774     {
8775       if (unformat (i, "sw_if_index %d", &sw_if_index))
8776         ;
8777       else if (unformat (i, "%U %U",
8778                          unformat_ip4_address, &v4_src_address,
8779                          unformat_ip4_address, &v4_grp_address))
8780         {
8781           grp_address_length = 64;
8782           address_set = 1;
8783           is_ipv6 = 0;
8784         }
8785       else if (unformat (i, "%U %U",
8786                          unformat_ip6_address, &v6_src_address,
8787                          unformat_ip6_address, &v6_grp_address))
8788         {
8789           grp_address_length = 256;
8790           address_set = 1;
8791           is_ipv6 = 1;
8792         }
8793       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8794         {
8795           memset (&v4_src_address, 0, sizeof (v4_src_address));
8796           grp_address_length = 32;
8797           address_set = 1;
8798           is_ipv6 = 0;
8799         }
8800       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8801         {
8802           memset (&v6_src_address, 0, sizeof (v6_src_address));
8803           grp_address_length = 128;
8804           address_set = 1;
8805           is_ipv6 = 1;
8806         }
8807       else if (unformat (i, "/%d", &grp_address_length))
8808         ;
8809       else if (unformat (i, "local"))
8810         {
8811           is_local = 1;
8812         }
8813       else if (unformat (i, "del"))
8814         is_add = 0;
8815       else if (unformat (i, "add"))
8816         is_add = 1;
8817       else if (unformat (i, "vrf %d", &vrf_id))
8818         ;
8819       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8820         ;
8821       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8822         ;
8823       else
8824         {
8825           clib_warning ("parse error '%U'", format_unformat_error, i);
8826           return -99;
8827         }
8828     }
8829
8830   if (address_set == 0)
8831     {
8832       errmsg ("missing addresses\n");
8833       return -99;
8834     }
8835
8836   /* Construct the API message */
8837   M (IP_MROUTE_ADD_DEL, mp);
8838
8839   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8840   mp->table_id = ntohl (vrf_id);
8841
8842   mp->is_add = is_add;
8843   mp->is_ipv6 = is_ipv6;
8844   mp->is_local = is_local;
8845   mp->itf_flags = ntohl (iflags);
8846   mp->entry_flags = ntohl (eflags);
8847   mp->grp_address_length = grp_address_length;
8848   mp->grp_address_length = ntohs (mp->grp_address_length);
8849
8850   if (is_ipv6)
8851     {
8852       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8853       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8854     }
8855   else
8856     {
8857       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8858       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8859
8860     }
8861
8862   /* send it... */
8863   S (mp);
8864   /* Wait for a reply... */
8865   W (ret);
8866   return ret;
8867 }
8868
8869 static int
8870 api_mpls_table_add_del (vat_main_t * vam)
8871 {
8872   unformat_input_t *i = vam->input;
8873   vl_api_mpls_table_add_del_t *mp;
8874   u32 table_id = ~0;
8875   u8 is_add = 1;
8876   int ret = 0;
8877
8878   /* Parse args required to build the message */
8879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8880     {
8881       if (unformat (i, "table %d", &table_id))
8882         ;
8883       else if (unformat (i, "del"))
8884         is_add = 0;
8885       else if (unformat (i, "add"))
8886         is_add = 1;
8887       else
8888         {
8889           clib_warning ("parse error '%U'", format_unformat_error, i);
8890           return -99;
8891         }
8892     }
8893
8894   if (~0 == table_id)
8895     {
8896       errmsg ("missing table-ID");
8897       return -99;
8898     }
8899
8900   /* Construct the API message */
8901   M (MPLS_TABLE_ADD_DEL, mp);
8902
8903   mp->mt_table_id = ntohl (table_id);
8904   mp->mt_is_add = is_add;
8905
8906   /* send it... */
8907   S (mp);
8908
8909   /* Wait for a reply... */
8910   W (ret);
8911
8912   return ret;
8913 }
8914
8915 static int
8916 api_mpls_route_add_del (vat_main_t * vam)
8917 {
8918   unformat_input_t *i = vam->input;
8919   vl_api_mpls_route_add_del_t *mp;
8920   u32 sw_if_index = ~0, table_id = 0;
8921   u8 is_add = 1;
8922   u32 next_hop_weight = 1;
8923   u8 is_multipath = 0;
8924   u32 next_hop_table_id = 0;
8925   u8 next_hop_set = 0;
8926   ip4_address_t v4_next_hop_address = {
8927     .as_u32 = 0,
8928   };
8929   ip6_address_t v6_next_hop_address = { {0} };
8930   int count = 1;
8931   int j;
8932   f64 before = 0;
8933   u32 classify_table_index = ~0;
8934   u8 is_classify = 0;
8935   u8 resolve_host = 0, resolve_attached = 0;
8936   u8 is_interface_rx = 0;
8937   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8938   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8939   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8940   mpls_label_t local_label = MPLS_LABEL_INVALID;
8941   u8 is_eos = 0;
8942   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8943
8944   /* Parse args required to build the message */
8945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8946     {
8947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8948         ;
8949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8950         ;
8951       else if (unformat (i, "%d", &local_label))
8952         ;
8953       else if (unformat (i, "eos"))
8954         is_eos = 1;
8955       else if (unformat (i, "non-eos"))
8956         is_eos = 0;
8957       else if (unformat (i, "via %U", unformat_ip4_address,
8958                          &v4_next_hop_address))
8959         {
8960           next_hop_set = 1;
8961           next_hop_proto = DPO_PROTO_IP4;
8962         }
8963       else if (unformat (i, "via %U", unformat_ip6_address,
8964                          &v6_next_hop_address))
8965         {
8966           next_hop_set = 1;
8967           next_hop_proto = DPO_PROTO_IP6;
8968         }
8969       else if (unformat (i, "weight %d", &next_hop_weight))
8970         ;
8971       else if (unformat (i, "classify %d", &classify_table_index))
8972         {
8973           is_classify = 1;
8974         }
8975       else if (unformat (i, "del"))
8976         is_add = 0;
8977       else if (unformat (i, "add"))
8978         is_add = 1;
8979       else if (unformat (i, "resolve-via-host"))
8980         resolve_host = 1;
8981       else if (unformat (i, "resolve-via-attached"))
8982         resolve_attached = 1;
8983       else if (unformat (i, "multipath"))
8984         is_multipath = 1;
8985       else if (unformat (i, "count %d", &count))
8986         ;
8987       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8988         {
8989           next_hop_set = 1;
8990           next_hop_proto = DPO_PROTO_IP4;
8991         }
8992       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8993         {
8994           next_hop_set = 1;
8995           next_hop_proto = DPO_PROTO_IP6;
8996         }
8997       else
8998         if (unformat
8999             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9000              &sw_if_index))
9001         {
9002           next_hop_set = 1;
9003           next_hop_proto = DPO_PROTO_ETHERNET;
9004           is_interface_rx = 1;
9005         }
9006       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9007         {
9008           next_hop_set = 1;
9009           next_hop_proto = DPO_PROTO_ETHERNET;
9010           is_interface_rx = 1;
9011         }
9012       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9013         next_hop_set = 1;
9014       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9015         next_hop_set = 1;
9016       else if (unformat (i, "out-label %d", &next_hop_out_label))
9017         {
9018           vl_api_fib_mpls_label_t fib_label = {
9019             .label = ntohl (next_hop_out_label),
9020             .ttl = 64,
9021             .exp = 0,
9022           };
9023           vec_add1 (next_hop_out_label_stack, fib_label);
9024         }
9025       else
9026         {
9027           clib_warning ("parse error '%U'", format_unformat_error, i);
9028           return -99;
9029         }
9030     }
9031
9032   if (!next_hop_set && !is_classify)
9033     {
9034       errmsg ("next hop / classify not set");
9035       return -99;
9036     }
9037
9038   if (MPLS_LABEL_INVALID == local_label)
9039     {
9040       errmsg ("missing label");
9041       return -99;
9042     }
9043
9044   if (count > 1)
9045     {
9046       /* Turn on async mode */
9047       vam->async_mode = 1;
9048       vam->async_errors = 0;
9049       before = vat_time_now (vam);
9050     }
9051
9052   for (j = 0; j < count; j++)
9053     {
9054       /* Construct the API message */
9055       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9056           vec_len (next_hop_out_label_stack));
9057
9058       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9059       mp->mr_table_id = ntohl (table_id);
9060
9061       mp->mr_is_add = is_add;
9062       mp->mr_next_hop_proto = next_hop_proto;
9063       mp->mr_is_classify = is_classify;
9064       mp->mr_is_multipath = is_multipath;
9065       mp->mr_is_resolve_host = resolve_host;
9066       mp->mr_is_resolve_attached = resolve_attached;
9067       mp->mr_is_interface_rx = is_interface_rx;
9068       mp->mr_next_hop_weight = next_hop_weight;
9069       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9070       mp->mr_classify_table_index = ntohl (classify_table_index);
9071       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9072       mp->mr_label = ntohl (local_label);
9073       mp->mr_eos = is_eos;
9074
9075       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9076       if (0 != mp->mr_next_hop_n_out_labels)
9077         {
9078           memcpy (mp->mr_next_hop_out_label_stack,
9079                   next_hop_out_label_stack,
9080                   vec_len (next_hop_out_label_stack) *
9081                   sizeof (vl_api_fib_mpls_label_t));
9082           vec_free (next_hop_out_label_stack);
9083         }
9084
9085       if (next_hop_set)
9086         {
9087           if (DPO_PROTO_IP4 == next_hop_proto)
9088             {
9089               clib_memcpy (mp->mr_next_hop,
9090                            &v4_next_hop_address,
9091                            sizeof (v4_next_hop_address));
9092             }
9093           else if (DPO_PROTO_IP6 == next_hop_proto)
9094
9095             {
9096               clib_memcpy (mp->mr_next_hop,
9097                            &v6_next_hop_address,
9098                            sizeof (v6_next_hop_address));
9099             }
9100         }
9101       local_label++;
9102
9103       /* send it... */
9104       S (mp);
9105       /* If we receive SIGTERM, stop now... */
9106       if (vam->do_exit)
9107         break;
9108     }
9109
9110   /* When testing multiple add/del ops, use a control-ping to sync */
9111   if (count > 1)
9112     {
9113       vl_api_control_ping_t *mp_ping;
9114       f64 after;
9115       f64 timeout;
9116
9117       /* Shut off async mode */
9118       vam->async_mode = 0;
9119
9120       MPING (CONTROL_PING, mp_ping);
9121       S (mp_ping);
9122
9123       timeout = vat_time_now (vam) + 1.0;
9124       while (vat_time_now (vam) < timeout)
9125         if (vam->result_ready == 1)
9126           goto out;
9127       vam->retval = -99;
9128
9129     out:
9130       if (vam->retval == -99)
9131         errmsg ("timeout");
9132
9133       if (vam->async_errors > 0)
9134         {
9135           errmsg ("%d asynchronous errors", vam->async_errors);
9136           vam->retval = -98;
9137         }
9138       vam->async_errors = 0;
9139       after = vat_time_now (vam);
9140
9141       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9142       if (j > 0)
9143         count = j;
9144
9145       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9146              count, after - before, count / (after - before));
9147     }
9148   else
9149     {
9150       int ret;
9151
9152       /* Wait for a reply... */
9153       W (ret);
9154       return ret;
9155     }
9156
9157   /* Return the good/bad news */
9158   return (vam->retval);
9159 }
9160
9161 static int
9162 api_mpls_ip_bind_unbind (vat_main_t * vam)
9163 {
9164   unformat_input_t *i = vam->input;
9165   vl_api_mpls_ip_bind_unbind_t *mp;
9166   u32 ip_table_id = 0;
9167   u8 is_bind = 1;
9168   u8 is_ip4 = 1;
9169   ip4_address_t v4_address;
9170   ip6_address_t v6_address;
9171   u32 address_length;
9172   u8 address_set = 0;
9173   mpls_label_t local_label = MPLS_LABEL_INVALID;
9174   int ret;
9175
9176   /* Parse args required to build the message */
9177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9178     {
9179       if (unformat (i, "%U/%d", unformat_ip4_address,
9180                     &v4_address, &address_length))
9181         {
9182           is_ip4 = 1;
9183           address_set = 1;
9184         }
9185       else if (unformat (i, "%U/%d", unformat_ip6_address,
9186                          &v6_address, &address_length))
9187         {
9188           is_ip4 = 0;
9189           address_set = 1;
9190         }
9191       else if (unformat (i, "%d", &local_label))
9192         ;
9193       else if (unformat (i, "table-id %d", &ip_table_id))
9194         ;
9195       else if (unformat (i, "unbind"))
9196         is_bind = 0;
9197       else if (unformat (i, "bind"))
9198         is_bind = 1;
9199       else
9200         {
9201           clib_warning ("parse error '%U'", format_unformat_error, i);
9202           return -99;
9203         }
9204     }
9205
9206   if (!address_set)
9207     {
9208       errmsg ("IP addres not set");
9209       return -99;
9210     }
9211
9212   if (MPLS_LABEL_INVALID == local_label)
9213     {
9214       errmsg ("missing label");
9215       return -99;
9216     }
9217
9218   /* Construct the API message */
9219   M (MPLS_IP_BIND_UNBIND, mp);
9220
9221   mp->mb_is_bind = is_bind;
9222   mp->mb_is_ip4 = is_ip4;
9223   mp->mb_ip_table_id = ntohl (ip_table_id);
9224   mp->mb_mpls_table_id = 0;
9225   mp->mb_label = ntohl (local_label);
9226   mp->mb_address_length = address_length;
9227
9228   if (is_ip4)
9229     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9230   else
9231     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9232
9233   /* send it... */
9234   S (mp);
9235
9236   /* Wait for a reply... */
9237   W (ret);
9238   return ret;
9239 }
9240
9241 static int
9242 api_sr_mpls_policy_add (vat_main_t * vam)
9243 {
9244   unformat_input_t *i = vam->input;
9245   vl_api_sr_mpls_policy_add_t *mp;
9246   u32 bsid = 0;
9247   u32 weight = 1;
9248   u8 type = 0;
9249   u8 n_segments = 0;
9250   u32 sid;
9251   u32 *segments = NULL;
9252   int ret;
9253
9254   /* Parse args required to build the message */
9255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9256     {
9257       if (unformat (i, "bsid %d", &bsid))
9258         ;
9259       else if (unformat (i, "weight %d", &weight))
9260         ;
9261       else if (unformat (i, "spray"))
9262         type = 1;
9263       else if (unformat (i, "next %d", &sid))
9264         {
9265           n_segments += 1;
9266           vec_add1 (segments, htonl (sid));
9267         }
9268       else
9269         {
9270           clib_warning ("parse error '%U'", format_unformat_error, i);
9271           return -99;
9272         }
9273     }
9274
9275   if (bsid == 0)
9276     {
9277       errmsg ("bsid not set");
9278       return -99;
9279     }
9280
9281   if (n_segments == 0)
9282     {
9283       errmsg ("no sid in segment stack");
9284       return -99;
9285     }
9286
9287   /* Construct the API message */
9288   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9289
9290   mp->bsid = htonl (bsid);
9291   mp->weight = htonl (weight);
9292   mp->type = type;
9293   mp->n_segments = n_segments;
9294   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9295   vec_free (segments);
9296
9297   /* send it... */
9298   S (mp);
9299
9300   /* Wait for a reply... */
9301   W (ret);
9302   return ret;
9303 }
9304
9305 static int
9306 api_sr_mpls_policy_del (vat_main_t * vam)
9307 {
9308   unformat_input_t *i = vam->input;
9309   vl_api_sr_mpls_policy_del_t *mp;
9310   u32 bsid = 0;
9311   int ret;
9312
9313   /* Parse args required to build the message */
9314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9315     {
9316       if (unformat (i, "bsid %d", &bsid))
9317         ;
9318       else
9319         {
9320           clib_warning ("parse error '%U'", format_unformat_error, i);
9321           return -99;
9322         }
9323     }
9324
9325   if (bsid == 0)
9326     {
9327       errmsg ("bsid not set");
9328       return -99;
9329     }
9330
9331   /* Construct the API message */
9332   M (SR_MPLS_POLICY_DEL, mp);
9333
9334   mp->bsid = htonl (bsid);
9335
9336   /* send it... */
9337   S (mp);
9338
9339   /* Wait for a reply... */
9340   W (ret);
9341   return ret;
9342 }
9343
9344 static int
9345 api_bier_table_add_del (vat_main_t * vam)
9346 {
9347   unformat_input_t *i = vam->input;
9348   vl_api_bier_table_add_del_t *mp;
9349   u8 is_add = 1;
9350   u32 set = 0, sub_domain = 0, hdr_len = 3;
9351   mpls_label_t local_label = MPLS_LABEL_INVALID;
9352   int ret;
9353
9354   /* Parse args required to build the message */
9355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9356     {
9357       if (unformat (i, "sub-domain %d", &sub_domain))
9358         ;
9359       else if (unformat (i, "set %d", &set))
9360         ;
9361       else if (unformat (i, "label %d", &local_label))
9362         ;
9363       else if (unformat (i, "hdr-len %d", &hdr_len))
9364         ;
9365       else if (unformat (i, "add"))
9366         is_add = 1;
9367       else if (unformat (i, "del"))
9368         is_add = 0;
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (MPLS_LABEL_INVALID == local_label)
9377     {
9378       errmsg ("missing label\n");
9379       return -99;
9380     }
9381
9382   /* Construct the API message */
9383   M (BIER_TABLE_ADD_DEL, mp);
9384
9385   mp->bt_is_add = is_add;
9386   mp->bt_label = ntohl (local_label);
9387   mp->bt_tbl_id.bt_set = set;
9388   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9389   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9390
9391   /* send it... */
9392   S (mp);
9393
9394   /* Wait for a reply... */
9395   W (ret);
9396
9397   return (ret);
9398 }
9399
9400 static int
9401 api_bier_route_add_del (vat_main_t * vam)
9402 {
9403   unformat_input_t *i = vam->input;
9404   vl_api_bier_route_add_del_t *mp;
9405   u8 is_add = 1;
9406   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9407   ip4_address_t v4_next_hop_address;
9408   ip6_address_t v6_next_hop_address;
9409   u8 next_hop_set = 0;
9410   u8 next_hop_proto_is_ip4 = 1;
9411   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9412   int ret;
9413
9414   /* Parse args required to build the message */
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9418         {
9419           next_hop_proto_is_ip4 = 1;
9420           next_hop_set = 1;
9421         }
9422       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9423         {
9424           next_hop_proto_is_ip4 = 0;
9425           next_hop_set = 1;
9426         }
9427       if (unformat (i, "sub-domain %d", &sub_domain))
9428         ;
9429       else if (unformat (i, "set %d", &set))
9430         ;
9431       else if (unformat (i, "hdr-len %d", &hdr_len))
9432         ;
9433       else if (unformat (i, "bp %d", &bp))
9434         ;
9435       else if (unformat (i, "add"))
9436         is_add = 1;
9437       else if (unformat (i, "del"))
9438         is_add = 0;
9439       else if (unformat (i, "out-label %d", &next_hop_out_label))
9440         ;
9441       else
9442         {
9443           clib_warning ("parse error '%U'", format_unformat_error, i);
9444           return -99;
9445         }
9446     }
9447
9448   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9449     {
9450       errmsg ("next hop / label set\n");
9451       return -99;
9452     }
9453   if (0 == bp)
9454     {
9455       errmsg ("bit=position not set\n");
9456       return -99;
9457     }
9458
9459   /* Construct the API message */
9460   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9461
9462   mp->br_is_add = is_add;
9463   mp->br_tbl_id.bt_set = set;
9464   mp->br_tbl_id.bt_sub_domain = sub_domain;
9465   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9466   mp->br_bp = ntohs (bp);
9467   mp->br_n_paths = 1;
9468   mp->br_paths[0].n_labels = 1;
9469   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9470   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9471
9472   if (next_hop_proto_is_ip4)
9473     {
9474       clib_memcpy (mp->br_paths[0].next_hop,
9475                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9476     }
9477   else
9478     {
9479       clib_memcpy (mp->br_paths[0].next_hop,
9480                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9481     }
9482
9483   /* send it... */
9484   S (mp);
9485
9486   /* Wait for a reply... */
9487   W (ret);
9488
9489   return (ret);
9490 }
9491
9492 static int
9493 api_proxy_arp_add_del (vat_main_t * vam)
9494 {
9495   unformat_input_t *i = vam->input;
9496   vl_api_proxy_arp_add_del_t *mp;
9497   u32 vrf_id = 0;
9498   u8 is_add = 1;
9499   ip4_address_t lo, hi;
9500   u8 range_set = 0;
9501   int ret;
9502
9503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9504     {
9505       if (unformat (i, "vrf %d", &vrf_id))
9506         ;
9507       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9508                          unformat_ip4_address, &hi))
9509         range_set = 1;
9510       else if (unformat (i, "del"))
9511         is_add = 0;
9512       else
9513         {
9514           clib_warning ("parse error '%U'", format_unformat_error, i);
9515           return -99;
9516         }
9517     }
9518
9519   if (range_set == 0)
9520     {
9521       errmsg ("address range not set");
9522       return -99;
9523     }
9524
9525   M (PROXY_ARP_ADD_DEL, mp);
9526
9527   mp->proxy.vrf_id = ntohl (vrf_id);
9528   mp->is_add = is_add;
9529   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9530   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9531
9532   S (mp);
9533   W (ret);
9534   return ret;
9535 }
9536
9537 static int
9538 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9539 {
9540   unformat_input_t *i = vam->input;
9541   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9542   u32 sw_if_index;
9543   u8 enable = 1;
9544   u8 sw_if_index_set = 0;
9545   int ret;
9546
9547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9548     {
9549       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9550         sw_if_index_set = 1;
9551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9552         sw_if_index_set = 1;
9553       else if (unformat (i, "enable"))
9554         enable = 1;
9555       else if (unformat (i, "disable"))
9556         enable = 0;
9557       else
9558         {
9559           clib_warning ("parse error '%U'", format_unformat_error, i);
9560           return -99;
9561         }
9562     }
9563
9564   if (sw_if_index_set == 0)
9565     {
9566       errmsg ("missing interface name or sw_if_index");
9567       return -99;
9568     }
9569
9570   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9571
9572   mp->sw_if_index = ntohl (sw_if_index);
9573   mp->enable_disable = enable;
9574
9575   S (mp);
9576   W (ret);
9577   return ret;
9578 }
9579
9580 static int
9581 api_mpls_tunnel_add_del (vat_main_t * vam)
9582 {
9583   unformat_input_t *i = vam->input;
9584   vl_api_mpls_tunnel_add_del_t *mp;
9585
9586   u8 is_add = 1;
9587   u8 l2_only = 0;
9588   u32 sw_if_index = ~0;
9589   u32 next_hop_sw_if_index = ~0;
9590   u32 next_hop_proto_is_ip4 = 1;
9591
9592   u32 next_hop_table_id = 0;
9593   ip4_address_t v4_next_hop_address = {
9594     .as_u32 = 0,
9595   };
9596   ip6_address_t v6_next_hop_address = { {0} };
9597   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9598   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9599   int ret;
9600
9601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9602     {
9603       if (unformat (i, "add"))
9604         is_add = 1;
9605       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9606         is_add = 0;
9607       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9608         ;
9609       else if (unformat (i, "via %U",
9610                          unformat_ip4_address, &v4_next_hop_address))
9611         {
9612           next_hop_proto_is_ip4 = 1;
9613         }
9614       else if (unformat (i, "via %U",
9615                          unformat_ip6_address, &v6_next_hop_address))
9616         {
9617           next_hop_proto_is_ip4 = 0;
9618         }
9619       else if (unformat (i, "via-label %d", &next_hop_via_label))
9620         ;
9621       else if (unformat (i, "l2-only"))
9622         l2_only = 1;
9623       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9624         ;
9625       else if (unformat (i, "out-label %d", &next_hop_out_label))
9626         vec_add1 (labels, ntohl (next_hop_out_label));
9627       else
9628         {
9629           clib_warning ("parse error '%U'", format_unformat_error, i);
9630           return -99;
9631         }
9632     }
9633
9634   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9635
9636   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9637   mp->mt_sw_if_index = ntohl (sw_if_index);
9638   mp->mt_is_add = is_add;
9639   mp->mt_l2_only = l2_only;
9640   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9641   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9642   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9643
9644   mp->mt_next_hop_n_out_labels = vec_len (labels);
9645
9646   if (0 != mp->mt_next_hop_n_out_labels)
9647     {
9648       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9649                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9650       vec_free (labels);
9651     }
9652
9653   if (next_hop_proto_is_ip4)
9654     {
9655       clib_memcpy (mp->mt_next_hop,
9656                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9657     }
9658   else
9659     {
9660       clib_memcpy (mp->mt_next_hop,
9661                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9662     }
9663
9664   S (mp);
9665   W (ret);
9666   return ret;
9667 }
9668
9669 static int
9670 api_sw_interface_set_unnumbered (vat_main_t * vam)
9671 {
9672   unformat_input_t *i = vam->input;
9673   vl_api_sw_interface_set_unnumbered_t *mp;
9674   u32 sw_if_index;
9675   u32 unnum_sw_index = ~0;
9676   u8 is_add = 1;
9677   u8 sw_if_index_set = 0;
9678   int ret;
9679
9680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9683         sw_if_index_set = 1;
9684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9685         sw_if_index_set = 1;
9686       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9687         ;
9688       else if (unformat (i, "del"))
9689         is_add = 0;
9690       else
9691         {
9692           clib_warning ("parse error '%U'", format_unformat_error, i);
9693           return -99;
9694         }
9695     }
9696
9697   if (sw_if_index_set == 0)
9698     {
9699       errmsg ("missing interface name or sw_if_index");
9700       return -99;
9701     }
9702
9703   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9704
9705   mp->sw_if_index = ntohl (sw_if_index);
9706   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9707   mp->is_add = is_add;
9708
9709   S (mp);
9710   W (ret);
9711   return ret;
9712 }
9713
9714 static int
9715 api_ip_neighbor_add_del (vat_main_t * vam)
9716 {
9717   unformat_input_t *i = vam->input;
9718   vl_api_ip_neighbor_add_del_t *mp;
9719   u32 sw_if_index;
9720   u8 sw_if_index_set = 0;
9721   u8 is_add = 1;
9722   u8 is_static = 0;
9723   u8 is_no_fib_entry = 0;
9724   u8 mac_address[6];
9725   u8 mac_set = 0;
9726   u8 v4_address_set = 0;
9727   u8 v6_address_set = 0;
9728   ip4_address_t v4address;
9729   ip6_address_t v6address;
9730   int ret;
9731
9732   memset (mac_address, 0, sizeof (mac_address));
9733
9734   /* Parse args required to build the message */
9735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9736     {
9737       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9738         {
9739           mac_set = 1;
9740         }
9741       else if (unformat (i, "del"))
9742         is_add = 0;
9743       else
9744         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9745         sw_if_index_set = 1;
9746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9747         sw_if_index_set = 1;
9748       else if (unformat (i, "is_static"))
9749         is_static = 1;
9750       else if (unformat (i, "no-fib-entry"))
9751         is_no_fib_entry = 1;
9752       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9753         v4_address_set = 1;
9754       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9755         v6_address_set = 1;
9756       else
9757         {
9758           clib_warning ("parse error '%U'", format_unformat_error, i);
9759           return -99;
9760         }
9761     }
9762
9763   if (sw_if_index_set == 0)
9764     {
9765       errmsg ("missing interface name or sw_if_index");
9766       return -99;
9767     }
9768   if (v4_address_set && v6_address_set)
9769     {
9770       errmsg ("both v4 and v6 addresses set");
9771       return -99;
9772     }
9773   if (!v4_address_set && !v6_address_set)
9774     {
9775       errmsg ("no address set");
9776       return -99;
9777     }
9778
9779   /* Construct the API message */
9780   M (IP_NEIGHBOR_ADD_DEL, mp);
9781
9782   mp->sw_if_index = ntohl (sw_if_index);
9783   mp->is_add = is_add;
9784   mp->is_static = is_static;
9785   mp->is_no_adj_fib = is_no_fib_entry;
9786   if (mac_set)
9787     clib_memcpy (mp->mac_address, mac_address, 6);
9788   if (v6_address_set)
9789     {
9790       mp->is_ipv6 = 1;
9791       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9792     }
9793   else
9794     {
9795       /* mp->is_ipv6 = 0; via memset in M macro above */
9796       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9797     }
9798
9799   /* send it... */
9800   S (mp);
9801
9802   /* Wait for a reply, return good/bad news  */
9803   W (ret);
9804   return ret;
9805 }
9806
9807 static int
9808 api_create_vlan_subif (vat_main_t * vam)
9809 {
9810   unformat_input_t *i = vam->input;
9811   vl_api_create_vlan_subif_t *mp;
9812   u32 sw_if_index;
9813   u8 sw_if_index_set = 0;
9814   u32 vlan_id;
9815   u8 vlan_id_set = 0;
9816   int ret;
9817
9818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9819     {
9820       if (unformat (i, "sw_if_index %d", &sw_if_index))
9821         sw_if_index_set = 1;
9822       else
9823         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9824         sw_if_index_set = 1;
9825       else if (unformat (i, "vlan %d", &vlan_id))
9826         vlan_id_set = 1;
9827       else
9828         {
9829           clib_warning ("parse error '%U'", format_unformat_error, i);
9830           return -99;
9831         }
9832     }
9833
9834   if (sw_if_index_set == 0)
9835     {
9836       errmsg ("missing interface name or sw_if_index");
9837       return -99;
9838     }
9839
9840   if (vlan_id_set == 0)
9841     {
9842       errmsg ("missing vlan_id");
9843       return -99;
9844     }
9845   M (CREATE_VLAN_SUBIF, mp);
9846
9847   mp->sw_if_index = ntohl (sw_if_index);
9848   mp->vlan_id = ntohl (vlan_id);
9849
9850   S (mp);
9851   W (ret);
9852   return ret;
9853 }
9854
9855 #define foreach_create_subif_bit                \
9856 _(no_tags)                                      \
9857 _(one_tag)                                      \
9858 _(two_tags)                                     \
9859 _(dot1ad)                                       \
9860 _(exact_match)                                  \
9861 _(default_sub)                                  \
9862 _(outer_vlan_id_any)                            \
9863 _(inner_vlan_id_any)
9864
9865 static int
9866 api_create_subif (vat_main_t * vam)
9867 {
9868   unformat_input_t *i = vam->input;
9869   vl_api_create_subif_t *mp;
9870   u32 sw_if_index;
9871   u8 sw_if_index_set = 0;
9872   u32 sub_id;
9873   u8 sub_id_set = 0;
9874   u32 no_tags = 0;
9875   u32 one_tag = 0;
9876   u32 two_tags = 0;
9877   u32 dot1ad = 0;
9878   u32 exact_match = 0;
9879   u32 default_sub = 0;
9880   u32 outer_vlan_id_any = 0;
9881   u32 inner_vlan_id_any = 0;
9882   u32 tmp;
9883   u16 outer_vlan_id = 0;
9884   u16 inner_vlan_id = 0;
9885   int ret;
9886
9887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9888     {
9889       if (unformat (i, "sw_if_index %d", &sw_if_index))
9890         sw_if_index_set = 1;
9891       else
9892         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9893         sw_if_index_set = 1;
9894       else if (unformat (i, "sub_id %d", &sub_id))
9895         sub_id_set = 1;
9896       else if (unformat (i, "outer_vlan_id %d", &tmp))
9897         outer_vlan_id = tmp;
9898       else if (unformat (i, "inner_vlan_id %d", &tmp))
9899         inner_vlan_id = tmp;
9900
9901 #define _(a) else if (unformat (i, #a)) a = 1 ;
9902       foreach_create_subif_bit
9903 #undef _
9904         else
9905         {
9906           clib_warning ("parse error '%U'", format_unformat_error, i);
9907           return -99;
9908         }
9909     }
9910
9911   if (sw_if_index_set == 0)
9912     {
9913       errmsg ("missing interface name or sw_if_index");
9914       return -99;
9915     }
9916
9917   if (sub_id_set == 0)
9918     {
9919       errmsg ("missing sub_id");
9920       return -99;
9921     }
9922   M (CREATE_SUBIF, mp);
9923
9924   mp->sw_if_index = ntohl (sw_if_index);
9925   mp->sub_id = ntohl (sub_id);
9926
9927 #define _(a) mp->a = a;
9928   foreach_create_subif_bit;
9929 #undef _
9930
9931   mp->outer_vlan_id = ntohs (outer_vlan_id);
9932   mp->inner_vlan_id = ntohs (inner_vlan_id);
9933
9934   S (mp);
9935   W (ret);
9936   return ret;
9937 }
9938
9939 static int
9940 api_oam_add_del (vat_main_t * vam)
9941 {
9942   unformat_input_t *i = vam->input;
9943   vl_api_oam_add_del_t *mp;
9944   u32 vrf_id = 0;
9945   u8 is_add = 1;
9946   ip4_address_t src, dst;
9947   u8 src_set = 0;
9948   u8 dst_set = 0;
9949   int ret;
9950
9951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9952     {
9953       if (unformat (i, "vrf %d", &vrf_id))
9954         ;
9955       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9956         src_set = 1;
9957       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9958         dst_set = 1;
9959       else if (unformat (i, "del"))
9960         is_add = 0;
9961       else
9962         {
9963           clib_warning ("parse error '%U'", format_unformat_error, i);
9964           return -99;
9965         }
9966     }
9967
9968   if (src_set == 0)
9969     {
9970       errmsg ("missing src addr");
9971       return -99;
9972     }
9973
9974   if (dst_set == 0)
9975     {
9976       errmsg ("missing dst addr");
9977       return -99;
9978     }
9979
9980   M (OAM_ADD_DEL, mp);
9981
9982   mp->vrf_id = ntohl (vrf_id);
9983   mp->is_add = is_add;
9984   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9985   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9986
9987   S (mp);
9988   W (ret);
9989   return ret;
9990 }
9991
9992 static int
9993 api_reset_fib (vat_main_t * vam)
9994 {
9995   unformat_input_t *i = vam->input;
9996   vl_api_reset_fib_t *mp;
9997   u32 vrf_id = 0;
9998   u8 is_ipv6 = 0;
9999   u8 vrf_id_set = 0;
10000
10001   int ret;
10002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10003     {
10004       if (unformat (i, "vrf %d", &vrf_id))
10005         vrf_id_set = 1;
10006       else if (unformat (i, "ipv6"))
10007         is_ipv6 = 1;
10008       else
10009         {
10010           clib_warning ("parse error '%U'", format_unformat_error, i);
10011           return -99;
10012         }
10013     }
10014
10015   if (vrf_id_set == 0)
10016     {
10017       errmsg ("missing vrf id");
10018       return -99;
10019     }
10020
10021   M (RESET_FIB, mp);
10022
10023   mp->vrf_id = ntohl (vrf_id);
10024   mp->is_ipv6 = is_ipv6;
10025
10026   S (mp);
10027   W (ret);
10028   return ret;
10029 }
10030
10031 static int
10032 api_dhcp_proxy_config (vat_main_t * vam)
10033 {
10034   unformat_input_t *i = vam->input;
10035   vl_api_dhcp_proxy_config_t *mp;
10036   u32 rx_vrf_id = 0;
10037   u32 server_vrf_id = 0;
10038   u8 is_add = 1;
10039   u8 v4_address_set = 0;
10040   u8 v6_address_set = 0;
10041   ip4_address_t v4address;
10042   ip6_address_t v6address;
10043   u8 v4_src_address_set = 0;
10044   u8 v6_src_address_set = 0;
10045   ip4_address_t v4srcaddress;
10046   ip6_address_t v6srcaddress;
10047   int ret;
10048
10049   /* Parse args required to build the message */
10050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10051     {
10052       if (unformat (i, "del"))
10053         is_add = 0;
10054       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10055         ;
10056       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10057         ;
10058       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10059         v4_address_set = 1;
10060       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10061         v6_address_set = 1;
10062       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10063         v4_src_address_set = 1;
10064       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10065         v6_src_address_set = 1;
10066       else
10067         break;
10068     }
10069
10070   if (v4_address_set && v6_address_set)
10071     {
10072       errmsg ("both v4 and v6 server addresses set");
10073       return -99;
10074     }
10075   if (!v4_address_set && !v6_address_set)
10076     {
10077       errmsg ("no server addresses set");
10078       return -99;
10079     }
10080
10081   if (v4_src_address_set && v6_src_address_set)
10082     {
10083       errmsg ("both v4 and v6  src addresses set");
10084       return -99;
10085     }
10086   if (!v4_src_address_set && !v6_src_address_set)
10087     {
10088       errmsg ("no src addresses set");
10089       return -99;
10090     }
10091
10092   if (!(v4_src_address_set && v4_address_set) &&
10093       !(v6_src_address_set && v6_address_set))
10094     {
10095       errmsg ("no matching server and src addresses set");
10096       return -99;
10097     }
10098
10099   /* Construct the API message */
10100   M (DHCP_PROXY_CONFIG, mp);
10101
10102   mp->is_add = is_add;
10103   mp->rx_vrf_id = ntohl (rx_vrf_id);
10104   mp->server_vrf_id = ntohl (server_vrf_id);
10105   if (v6_address_set)
10106     {
10107       mp->is_ipv6 = 1;
10108       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10109       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10110     }
10111   else
10112     {
10113       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10114       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10115     }
10116
10117   /* send it... */
10118   S (mp);
10119
10120   /* Wait for a reply, return good/bad news  */
10121   W (ret);
10122   return ret;
10123 }
10124
10125 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10126 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10127
10128 static void
10129 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10130 {
10131   vat_main_t *vam = &vat_main;
10132   u32 i, count = mp->count;
10133   vl_api_dhcp_server_t *s;
10134
10135   if (mp->is_ipv6)
10136     print (vam->ofp,
10137            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10138            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10139            ntohl (mp->rx_vrf_id),
10140            format_ip6_address, mp->dhcp_src_address,
10141            mp->vss_type, mp->vss_vpn_ascii_id,
10142            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10143   else
10144     print (vam->ofp,
10145            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10146            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10147            ntohl (mp->rx_vrf_id),
10148            format_ip4_address, mp->dhcp_src_address,
10149            mp->vss_type, mp->vss_vpn_ascii_id,
10150            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10151
10152   for (i = 0; i < count; i++)
10153     {
10154       s = &mp->servers[i];
10155
10156       if (mp->is_ipv6)
10157         print (vam->ofp,
10158                " Server Table-ID %d, Server Address %U",
10159                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10160       else
10161         print (vam->ofp,
10162                " Server Table-ID %d, Server Address %U",
10163                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10164     }
10165 }
10166
10167 static void vl_api_dhcp_proxy_details_t_handler_json
10168   (vl_api_dhcp_proxy_details_t * mp)
10169 {
10170   vat_main_t *vam = &vat_main;
10171   vat_json_node_t *node = NULL;
10172   u32 i, count = mp->count;
10173   struct in_addr ip4;
10174   struct in6_addr ip6;
10175   vl_api_dhcp_server_t *s;
10176
10177   if (VAT_JSON_ARRAY != vam->json_tree.type)
10178     {
10179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10180       vat_json_init_array (&vam->json_tree);
10181     }
10182   node = vat_json_array_add (&vam->json_tree);
10183
10184   vat_json_init_object (node);
10185   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10186   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10187                              sizeof (mp->vss_type));
10188   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10189                                    mp->vss_vpn_ascii_id);
10190   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10191   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10192
10193   if (mp->is_ipv6)
10194     {
10195       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10196       vat_json_object_add_ip6 (node, "src_address", ip6);
10197     }
10198   else
10199     {
10200       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10201       vat_json_object_add_ip4 (node, "src_address", ip4);
10202     }
10203
10204   for (i = 0; i < count; i++)
10205     {
10206       s = &mp->servers[i];
10207
10208       vat_json_object_add_uint (node, "server-table-id",
10209                                 ntohl (s->server_vrf_id));
10210
10211       if (mp->is_ipv6)
10212         {
10213           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10214           vat_json_object_add_ip4 (node, "src_address", ip4);
10215         }
10216       else
10217         {
10218           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10219           vat_json_object_add_ip6 (node, "server_address", ip6);
10220         }
10221     }
10222 }
10223
10224 static int
10225 api_dhcp_proxy_dump (vat_main_t * vam)
10226 {
10227   unformat_input_t *i = vam->input;
10228   vl_api_control_ping_t *mp_ping;
10229   vl_api_dhcp_proxy_dump_t *mp;
10230   u8 is_ipv6 = 0;
10231   int ret;
10232
10233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10234     {
10235       if (unformat (i, "ipv6"))
10236         is_ipv6 = 1;
10237       else
10238         {
10239           clib_warning ("parse error '%U'", format_unformat_error, i);
10240           return -99;
10241         }
10242     }
10243
10244   M (DHCP_PROXY_DUMP, mp);
10245
10246   mp->is_ip6 = is_ipv6;
10247   S (mp);
10248
10249   /* Use a control ping for synchronization */
10250   MPING (CONTROL_PING, mp_ping);
10251   S (mp_ping);
10252
10253   W (ret);
10254   return ret;
10255 }
10256
10257 static int
10258 api_dhcp_proxy_set_vss (vat_main_t * vam)
10259 {
10260   unformat_input_t *i = vam->input;
10261   vl_api_dhcp_proxy_set_vss_t *mp;
10262   u8 is_ipv6 = 0;
10263   u8 is_add = 1;
10264   u32 tbl_id = ~0;
10265   u8 vss_type = VSS_TYPE_DEFAULT;
10266   u8 *vpn_ascii_id = 0;
10267   u32 oui = 0;
10268   u32 fib_id = 0;
10269   int ret;
10270
10271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10272     {
10273       if (unformat (i, "tbl_id %d", &tbl_id))
10274         ;
10275       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10276         vss_type = VSS_TYPE_ASCII;
10277       else if (unformat (i, "fib_id %d", &fib_id))
10278         vss_type = VSS_TYPE_VPN_ID;
10279       else if (unformat (i, "oui %d", &oui))
10280         vss_type = VSS_TYPE_VPN_ID;
10281       else if (unformat (i, "ipv6"))
10282         is_ipv6 = 1;
10283       else if (unformat (i, "del"))
10284         is_add = 0;
10285       else
10286         break;
10287     }
10288
10289   if (tbl_id == ~0)
10290     {
10291       errmsg ("missing tbl_id ");
10292       vec_free (vpn_ascii_id);
10293       return -99;
10294     }
10295
10296   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10297     {
10298       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10299       vec_free (vpn_ascii_id);
10300       return -99;
10301     }
10302
10303   M (DHCP_PROXY_SET_VSS, mp);
10304   mp->tbl_id = ntohl (tbl_id);
10305   mp->vss_type = vss_type;
10306   if (vpn_ascii_id)
10307     {
10308       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10309       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10310     }
10311   mp->vpn_index = ntohl (fib_id);
10312   mp->oui = ntohl (oui);
10313   mp->is_ipv6 = is_ipv6;
10314   mp->is_add = is_add;
10315
10316   S (mp);
10317   W (ret);
10318
10319   vec_free (vpn_ascii_id);
10320   return ret;
10321 }
10322
10323 static int
10324 api_dhcp_client_config (vat_main_t * vam)
10325 {
10326   unformat_input_t *i = vam->input;
10327   vl_api_dhcp_client_config_t *mp;
10328   u32 sw_if_index;
10329   u8 sw_if_index_set = 0;
10330   u8 is_add = 1;
10331   u8 *hostname = 0;
10332   u8 disable_event = 0;
10333   int ret;
10334
10335   /* Parse args required to build the message */
10336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10337     {
10338       if (unformat (i, "del"))
10339         is_add = 0;
10340       else
10341         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10342         sw_if_index_set = 1;
10343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10344         sw_if_index_set = 1;
10345       else if (unformat (i, "hostname %s", &hostname))
10346         ;
10347       else if (unformat (i, "disable_event"))
10348         disable_event = 1;
10349       else
10350         break;
10351     }
10352
10353   if (sw_if_index_set == 0)
10354     {
10355       errmsg ("missing interface name or sw_if_index");
10356       return -99;
10357     }
10358
10359   if (vec_len (hostname) > 63)
10360     {
10361       errmsg ("hostname too long");
10362     }
10363   vec_add1 (hostname, 0);
10364
10365   /* Construct the API message */
10366   M (DHCP_CLIENT_CONFIG, mp);
10367
10368   mp->is_add = is_add;
10369   mp->client.sw_if_index = htonl (sw_if_index);
10370   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10371   vec_free (hostname);
10372   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10373   mp->client.pid = htonl (getpid ());
10374
10375   /* send it... */
10376   S (mp);
10377
10378   /* Wait for a reply, return good/bad news  */
10379   W (ret);
10380   return ret;
10381 }
10382
10383 static int
10384 api_set_ip_flow_hash (vat_main_t * vam)
10385 {
10386   unformat_input_t *i = vam->input;
10387   vl_api_set_ip_flow_hash_t *mp;
10388   u32 vrf_id = 0;
10389   u8 is_ipv6 = 0;
10390   u8 vrf_id_set = 0;
10391   u8 src = 0;
10392   u8 dst = 0;
10393   u8 sport = 0;
10394   u8 dport = 0;
10395   u8 proto = 0;
10396   u8 reverse = 0;
10397   int ret;
10398
10399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (i, "vrf %d", &vrf_id))
10402         vrf_id_set = 1;
10403       else if (unformat (i, "ipv6"))
10404         is_ipv6 = 1;
10405       else if (unformat (i, "src"))
10406         src = 1;
10407       else if (unformat (i, "dst"))
10408         dst = 1;
10409       else if (unformat (i, "sport"))
10410         sport = 1;
10411       else if (unformat (i, "dport"))
10412         dport = 1;
10413       else if (unformat (i, "proto"))
10414         proto = 1;
10415       else if (unformat (i, "reverse"))
10416         reverse = 1;
10417
10418       else
10419         {
10420           clib_warning ("parse error '%U'", format_unformat_error, i);
10421           return -99;
10422         }
10423     }
10424
10425   if (vrf_id_set == 0)
10426     {
10427       errmsg ("missing vrf id");
10428       return -99;
10429     }
10430
10431   M (SET_IP_FLOW_HASH, mp);
10432   mp->src = src;
10433   mp->dst = dst;
10434   mp->sport = sport;
10435   mp->dport = dport;
10436   mp->proto = proto;
10437   mp->reverse = reverse;
10438   mp->vrf_id = ntohl (vrf_id);
10439   mp->is_ipv6 = is_ipv6;
10440
10441   S (mp);
10442   W (ret);
10443   return ret;
10444 }
10445
10446 static int
10447 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10448 {
10449   unformat_input_t *i = vam->input;
10450   vl_api_sw_interface_ip6_enable_disable_t *mp;
10451   u32 sw_if_index;
10452   u8 sw_if_index_set = 0;
10453   u8 enable = 0;
10454   int ret;
10455
10456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10457     {
10458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10459         sw_if_index_set = 1;
10460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10461         sw_if_index_set = 1;
10462       else if (unformat (i, "enable"))
10463         enable = 1;
10464       else if (unformat (i, "disable"))
10465         enable = 0;
10466       else
10467         {
10468           clib_warning ("parse error '%U'", format_unformat_error, i);
10469           return -99;
10470         }
10471     }
10472
10473   if (sw_if_index_set == 0)
10474     {
10475       errmsg ("missing interface name or sw_if_index");
10476       return -99;
10477     }
10478
10479   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10480
10481   mp->sw_if_index = ntohl (sw_if_index);
10482   mp->enable = enable;
10483
10484   S (mp);
10485   W (ret);
10486   return ret;
10487 }
10488
10489 static int
10490 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10491 {
10492   unformat_input_t *i = vam->input;
10493   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10494   u32 sw_if_index;
10495   u8 sw_if_index_set = 0;
10496   u8 v6_address_set = 0;
10497   ip6_address_t v6address;
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, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10504         sw_if_index_set = 1;
10505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10506         sw_if_index_set = 1;
10507       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10508         v6_address_set = 1;
10509       else
10510         break;
10511     }
10512
10513   if (sw_if_index_set == 0)
10514     {
10515       errmsg ("missing interface name or sw_if_index");
10516       return -99;
10517     }
10518   if (!v6_address_set)
10519     {
10520       errmsg ("no address set");
10521       return -99;
10522     }
10523
10524   /* Construct the API message */
10525   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10526
10527   mp->sw_if_index = ntohl (sw_if_index);
10528   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10529
10530   /* send it... */
10531   S (mp);
10532
10533   /* Wait for a reply, return good/bad news  */
10534   W (ret);
10535   return ret;
10536 }
10537
10538 static int
10539 api_ip6nd_proxy_add_del (vat_main_t * vam)
10540 {
10541   unformat_input_t *i = vam->input;
10542   vl_api_ip6nd_proxy_add_del_t *mp;
10543   u32 sw_if_index = ~0;
10544   u8 v6_address_set = 0;
10545   ip6_address_t v6address;
10546   u8 is_del = 0;
10547   int ret;
10548
10549   /* Parse args required to build the message */
10550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10553         ;
10554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10555         ;
10556       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10557         v6_address_set = 1;
10558       if (unformat (i, "del"))
10559         is_del = 1;
10560       else
10561         {
10562           clib_warning ("parse error '%U'", format_unformat_error, i);
10563           return -99;
10564         }
10565     }
10566
10567   if (sw_if_index == ~0)
10568     {
10569       errmsg ("missing interface name or sw_if_index");
10570       return -99;
10571     }
10572   if (!v6_address_set)
10573     {
10574       errmsg ("no address set");
10575       return -99;
10576     }
10577
10578   /* Construct the API message */
10579   M (IP6ND_PROXY_ADD_DEL, mp);
10580
10581   mp->is_del = is_del;
10582   mp->sw_if_index = ntohl (sw_if_index);
10583   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10584
10585   /* send it... */
10586   S (mp);
10587
10588   /* Wait for a reply, return good/bad news  */
10589   W (ret);
10590   return ret;
10591 }
10592
10593 static int
10594 api_ip6nd_proxy_dump (vat_main_t * vam)
10595 {
10596   vl_api_ip6nd_proxy_dump_t *mp;
10597   vl_api_control_ping_t *mp_ping;
10598   int ret;
10599
10600   M (IP6ND_PROXY_DUMP, mp);
10601
10602   S (mp);
10603
10604   /* Use a control ping for synchronization */
10605   MPING (CONTROL_PING, mp_ping);
10606   S (mp_ping);
10607
10608   W (ret);
10609   return ret;
10610 }
10611
10612 static void vl_api_ip6nd_proxy_details_t_handler
10613   (vl_api_ip6nd_proxy_details_t * mp)
10614 {
10615   vat_main_t *vam = &vat_main;
10616
10617   print (vam->ofp, "host %U sw_if_index %d",
10618          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10619 }
10620
10621 static void vl_api_ip6nd_proxy_details_t_handler_json
10622   (vl_api_ip6nd_proxy_details_t * mp)
10623 {
10624   vat_main_t *vam = &vat_main;
10625   struct in6_addr ip6;
10626   vat_json_node_t *node = NULL;
10627
10628   if (VAT_JSON_ARRAY != vam->json_tree.type)
10629     {
10630       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10631       vat_json_init_array (&vam->json_tree);
10632     }
10633   node = vat_json_array_add (&vam->json_tree);
10634
10635   vat_json_init_object (node);
10636   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10637
10638   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10639   vat_json_object_add_ip6 (node, "host", ip6);
10640 }
10641
10642 static int
10643 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10644 {
10645   unformat_input_t *i = vam->input;
10646   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10647   u32 sw_if_index;
10648   u8 sw_if_index_set = 0;
10649   u32 address_length = 0;
10650   u8 v6_address_set = 0;
10651   ip6_address_t v6address;
10652   u8 use_default = 0;
10653   u8 no_advertise = 0;
10654   u8 off_link = 0;
10655   u8 no_autoconfig = 0;
10656   u8 no_onlink = 0;
10657   u8 is_no = 0;
10658   u32 val_lifetime = 0;
10659   u32 pref_lifetime = 0;
10660   int ret;
10661
10662   /* Parse args required to build the message */
10663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10664     {
10665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10666         sw_if_index_set = 1;
10667       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10668         sw_if_index_set = 1;
10669       else if (unformat (i, "%U/%d",
10670                          unformat_ip6_address, &v6address, &address_length))
10671         v6_address_set = 1;
10672       else if (unformat (i, "val_life %d", &val_lifetime))
10673         ;
10674       else if (unformat (i, "pref_life %d", &pref_lifetime))
10675         ;
10676       else if (unformat (i, "def"))
10677         use_default = 1;
10678       else if (unformat (i, "noadv"))
10679         no_advertise = 1;
10680       else if (unformat (i, "offl"))
10681         off_link = 1;
10682       else if (unformat (i, "noauto"))
10683         no_autoconfig = 1;
10684       else if (unformat (i, "nolink"))
10685         no_onlink = 1;
10686       else if (unformat (i, "isno"))
10687         is_no = 1;
10688       else
10689         {
10690           clib_warning ("parse error '%U'", format_unformat_error, i);
10691           return -99;
10692         }
10693     }
10694
10695   if (sw_if_index_set == 0)
10696     {
10697       errmsg ("missing interface name or sw_if_index");
10698       return -99;
10699     }
10700   if (!v6_address_set)
10701     {
10702       errmsg ("no address set");
10703       return -99;
10704     }
10705
10706   /* Construct the API message */
10707   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10708
10709   mp->sw_if_index = ntohl (sw_if_index);
10710   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10711   mp->address_length = address_length;
10712   mp->use_default = use_default;
10713   mp->no_advertise = no_advertise;
10714   mp->off_link = off_link;
10715   mp->no_autoconfig = no_autoconfig;
10716   mp->no_onlink = no_onlink;
10717   mp->is_no = is_no;
10718   mp->val_lifetime = ntohl (val_lifetime);
10719   mp->pref_lifetime = ntohl (pref_lifetime);
10720
10721   /* send it... */
10722   S (mp);
10723
10724   /* Wait for a reply, return good/bad news  */
10725   W (ret);
10726   return ret;
10727 }
10728
10729 static int
10730 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10731 {
10732   unformat_input_t *i = vam->input;
10733   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10734   u32 sw_if_index;
10735   u8 sw_if_index_set = 0;
10736   u8 suppress = 0;
10737   u8 managed = 0;
10738   u8 other = 0;
10739   u8 ll_option = 0;
10740   u8 send_unicast = 0;
10741   u8 cease = 0;
10742   u8 is_no = 0;
10743   u8 default_router = 0;
10744   u32 max_interval = 0;
10745   u32 min_interval = 0;
10746   u32 lifetime = 0;
10747   u32 initial_count = 0;
10748   u32 initial_interval = 0;
10749   int ret;
10750
10751
10752   /* Parse args required to build the message */
10753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10754     {
10755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10756         sw_if_index_set = 1;
10757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10758         sw_if_index_set = 1;
10759       else if (unformat (i, "maxint %d", &max_interval))
10760         ;
10761       else if (unformat (i, "minint %d", &min_interval))
10762         ;
10763       else if (unformat (i, "life %d", &lifetime))
10764         ;
10765       else if (unformat (i, "count %d", &initial_count))
10766         ;
10767       else if (unformat (i, "interval %d", &initial_interval))
10768         ;
10769       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10770         suppress = 1;
10771       else if (unformat (i, "managed"))
10772         managed = 1;
10773       else if (unformat (i, "other"))
10774         other = 1;
10775       else if (unformat (i, "ll"))
10776         ll_option = 1;
10777       else if (unformat (i, "send"))
10778         send_unicast = 1;
10779       else if (unformat (i, "cease"))
10780         cease = 1;
10781       else if (unformat (i, "isno"))
10782         is_no = 1;
10783       else if (unformat (i, "def"))
10784         default_router = 1;
10785       else
10786         {
10787           clib_warning ("parse error '%U'", format_unformat_error, i);
10788           return -99;
10789         }
10790     }
10791
10792   if (sw_if_index_set == 0)
10793     {
10794       errmsg ("missing interface name or sw_if_index");
10795       return -99;
10796     }
10797
10798   /* Construct the API message */
10799   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10800
10801   mp->sw_if_index = ntohl (sw_if_index);
10802   mp->max_interval = ntohl (max_interval);
10803   mp->min_interval = ntohl (min_interval);
10804   mp->lifetime = ntohl (lifetime);
10805   mp->initial_count = ntohl (initial_count);
10806   mp->initial_interval = ntohl (initial_interval);
10807   mp->suppress = suppress;
10808   mp->managed = managed;
10809   mp->other = other;
10810   mp->ll_option = ll_option;
10811   mp->send_unicast = send_unicast;
10812   mp->cease = cease;
10813   mp->is_no = is_no;
10814   mp->default_router = default_router;
10815
10816   /* send it... */
10817   S (mp);
10818
10819   /* Wait for a reply, return good/bad news  */
10820   W (ret);
10821   return ret;
10822 }
10823
10824 static int
10825 api_set_arp_neighbor_limit (vat_main_t * vam)
10826 {
10827   unformat_input_t *i = vam->input;
10828   vl_api_set_arp_neighbor_limit_t *mp;
10829   u32 arp_nbr_limit;
10830   u8 limit_set = 0;
10831   u8 is_ipv6 = 0;
10832   int ret;
10833
10834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10835     {
10836       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10837         limit_set = 1;
10838       else if (unformat (i, "ipv6"))
10839         is_ipv6 = 1;
10840       else
10841         {
10842           clib_warning ("parse error '%U'", format_unformat_error, i);
10843           return -99;
10844         }
10845     }
10846
10847   if (limit_set == 0)
10848     {
10849       errmsg ("missing limit value");
10850       return -99;
10851     }
10852
10853   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10854
10855   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10856   mp->is_ipv6 = is_ipv6;
10857
10858   S (mp);
10859   W (ret);
10860   return ret;
10861 }
10862
10863 static int
10864 api_l2_patch_add_del (vat_main_t * vam)
10865 {
10866   unformat_input_t *i = vam->input;
10867   vl_api_l2_patch_add_del_t *mp;
10868   u32 rx_sw_if_index;
10869   u8 rx_sw_if_index_set = 0;
10870   u32 tx_sw_if_index;
10871   u8 tx_sw_if_index_set = 0;
10872   u8 is_add = 1;
10873   int ret;
10874
10875   /* Parse args required to build the message */
10876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10879         rx_sw_if_index_set = 1;
10880       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10881         tx_sw_if_index_set = 1;
10882       else if (unformat (i, "rx"))
10883         {
10884           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10885             {
10886               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10887                             &rx_sw_if_index))
10888                 rx_sw_if_index_set = 1;
10889             }
10890           else
10891             break;
10892         }
10893       else if (unformat (i, "tx"))
10894         {
10895           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10896             {
10897               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10898                             &tx_sw_if_index))
10899                 tx_sw_if_index_set = 1;
10900             }
10901           else
10902             break;
10903         }
10904       else if (unformat (i, "del"))
10905         is_add = 0;
10906       else
10907         break;
10908     }
10909
10910   if (rx_sw_if_index_set == 0)
10911     {
10912       errmsg ("missing rx interface name or rx_sw_if_index");
10913       return -99;
10914     }
10915
10916   if (tx_sw_if_index_set == 0)
10917     {
10918       errmsg ("missing tx interface name or tx_sw_if_index");
10919       return -99;
10920     }
10921
10922   M (L2_PATCH_ADD_DEL, mp);
10923
10924   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10925   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10926   mp->is_add = is_add;
10927
10928   S (mp);
10929   W (ret);
10930   return ret;
10931 }
10932
10933 u8 is_del;
10934 u8 localsid_addr[16];
10935 u8 end_psp;
10936 u8 behavior;
10937 u32 sw_if_index;
10938 u32 vlan_index;
10939 u32 fib_table;
10940 u8 nh_addr[16];
10941
10942 static int
10943 api_sr_localsid_add_del (vat_main_t * vam)
10944 {
10945   unformat_input_t *i = vam->input;
10946   vl_api_sr_localsid_add_del_t *mp;
10947
10948   u8 is_del;
10949   ip6_address_t localsid;
10950   u8 end_psp = 0;
10951   u8 behavior = ~0;
10952   u32 sw_if_index;
10953   u32 fib_table = ~(u32) 0;
10954   ip6_address_t nh_addr6;
10955   ip4_address_t nh_addr4;
10956   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10957   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10958
10959   bool nexthop_set = 0;
10960
10961   int ret;
10962
10963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10964     {
10965       if (unformat (i, "del"))
10966         is_del = 1;
10967       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10968       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10969         nexthop_set = 1;
10970       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10971         nexthop_set = 1;
10972       else if (unformat (i, "behavior %u", &behavior));
10973       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10974       else if (unformat (i, "fib-table %u", &fib_table));
10975       else if (unformat (i, "end.psp %u", &behavior));
10976       else
10977         break;
10978     }
10979
10980   M (SR_LOCALSID_ADD_DEL, mp);
10981
10982   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10983   if (nexthop_set)
10984     {
10985       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10986       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10987     }
10988   mp->behavior = behavior;
10989   mp->sw_if_index = ntohl (sw_if_index);
10990   mp->fib_table = ntohl (fib_table);
10991   mp->end_psp = end_psp;
10992   mp->is_del = is_del;
10993
10994   S (mp);
10995   W (ret);
10996   return ret;
10997 }
10998
10999 static int
11000 api_ioam_enable (vat_main_t * vam)
11001 {
11002   unformat_input_t *input = vam->input;
11003   vl_api_ioam_enable_t *mp;
11004   u32 id = 0;
11005   int has_trace_option = 0;
11006   int has_pot_option = 0;
11007   int has_seqno_option = 0;
11008   int has_analyse_option = 0;
11009   int ret;
11010
11011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11012     {
11013       if (unformat (input, "trace"))
11014         has_trace_option = 1;
11015       else if (unformat (input, "pot"))
11016         has_pot_option = 1;
11017       else if (unformat (input, "seqno"))
11018         has_seqno_option = 1;
11019       else if (unformat (input, "analyse"))
11020         has_analyse_option = 1;
11021       else
11022         break;
11023     }
11024   M (IOAM_ENABLE, mp);
11025   mp->id = htons (id);
11026   mp->seqno = has_seqno_option;
11027   mp->analyse = has_analyse_option;
11028   mp->pot_enable = has_pot_option;
11029   mp->trace_enable = has_trace_option;
11030
11031   S (mp);
11032   W (ret);
11033   return ret;
11034 }
11035
11036
11037 static int
11038 api_ioam_disable (vat_main_t * vam)
11039 {
11040   vl_api_ioam_disable_t *mp;
11041   int ret;
11042
11043   M (IOAM_DISABLE, mp);
11044   S (mp);
11045   W (ret);
11046   return ret;
11047 }
11048
11049 #define foreach_tcp_proto_field                 \
11050 _(src_port)                                     \
11051 _(dst_port)
11052
11053 #define foreach_udp_proto_field                 \
11054 _(src_port)                                     \
11055 _(dst_port)
11056
11057 #define foreach_ip4_proto_field                 \
11058 _(src_address)                                  \
11059 _(dst_address)                                  \
11060 _(tos)                                          \
11061 _(length)                                       \
11062 _(fragment_id)                                  \
11063 _(ttl)                                          \
11064 _(protocol)                                     \
11065 _(checksum)
11066
11067 typedef struct
11068 {
11069   u16 src_port, dst_port;
11070 } tcpudp_header_t;
11071
11072 #if VPP_API_TEST_BUILTIN == 0
11073 uword
11074 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11075 {
11076   u8 **maskp = va_arg (*args, u8 **);
11077   u8 *mask = 0;
11078   u8 found_something = 0;
11079   tcp_header_t *tcp;
11080
11081 #define _(a) u8 a=0;
11082   foreach_tcp_proto_field;
11083 #undef _
11084
11085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11086     {
11087       if (0);
11088 #define _(a) else if (unformat (input, #a)) a=1;
11089       foreach_tcp_proto_field
11090 #undef _
11091         else
11092         break;
11093     }
11094
11095 #define _(a) found_something += a;
11096   foreach_tcp_proto_field;
11097 #undef _
11098
11099   if (found_something == 0)
11100     return 0;
11101
11102   vec_validate (mask, sizeof (*tcp) - 1);
11103
11104   tcp = (tcp_header_t *) mask;
11105
11106 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11107   foreach_tcp_proto_field;
11108 #undef _
11109
11110   *maskp = mask;
11111   return 1;
11112 }
11113
11114 uword
11115 unformat_udp_mask (unformat_input_t * input, va_list * args)
11116 {
11117   u8 **maskp = va_arg (*args, u8 **);
11118   u8 *mask = 0;
11119   u8 found_something = 0;
11120   udp_header_t *udp;
11121
11122 #define _(a) u8 a=0;
11123   foreach_udp_proto_field;
11124 #undef _
11125
11126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11127     {
11128       if (0);
11129 #define _(a) else if (unformat (input, #a)) a=1;
11130       foreach_udp_proto_field
11131 #undef _
11132         else
11133         break;
11134     }
11135
11136 #define _(a) found_something += a;
11137   foreach_udp_proto_field;
11138 #undef _
11139
11140   if (found_something == 0)
11141     return 0;
11142
11143   vec_validate (mask, sizeof (*udp) - 1);
11144
11145   udp = (udp_header_t *) mask;
11146
11147 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11148   foreach_udp_proto_field;
11149 #undef _
11150
11151   *maskp = mask;
11152   return 1;
11153 }
11154
11155 uword
11156 unformat_l4_mask (unformat_input_t * input, va_list * args)
11157 {
11158   u8 **maskp = va_arg (*args, u8 **);
11159   u16 src_port = 0, dst_port = 0;
11160   tcpudp_header_t *tcpudp;
11161
11162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11163     {
11164       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11165         return 1;
11166       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11167         return 1;
11168       else if (unformat (input, "src_port"))
11169         src_port = 0xFFFF;
11170       else if (unformat (input, "dst_port"))
11171         dst_port = 0xFFFF;
11172       else
11173         return 0;
11174     }
11175
11176   if (!src_port && !dst_port)
11177     return 0;
11178
11179   u8 *mask = 0;
11180   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11181
11182   tcpudp = (tcpudp_header_t *) mask;
11183   tcpudp->src_port = src_port;
11184   tcpudp->dst_port = dst_port;
11185
11186   *maskp = mask;
11187
11188   return 1;
11189 }
11190
11191 uword
11192 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11193 {
11194   u8 **maskp = va_arg (*args, u8 **);
11195   u8 *mask = 0;
11196   u8 found_something = 0;
11197   ip4_header_t *ip;
11198
11199 #define _(a) u8 a=0;
11200   foreach_ip4_proto_field;
11201 #undef _
11202   u8 version = 0;
11203   u8 hdr_length = 0;
11204
11205
11206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11207     {
11208       if (unformat (input, "version"))
11209         version = 1;
11210       else if (unformat (input, "hdr_length"))
11211         hdr_length = 1;
11212       else if (unformat (input, "src"))
11213         src_address = 1;
11214       else if (unformat (input, "dst"))
11215         dst_address = 1;
11216       else if (unformat (input, "proto"))
11217         protocol = 1;
11218
11219 #define _(a) else if (unformat (input, #a)) a=1;
11220       foreach_ip4_proto_field
11221 #undef _
11222         else
11223         break;
11224     }
11225
11226 #define _(a) found_something += a;
11227   foreach_ip4_proto_field;
11228 #undef _
11229
11230   if (found_something == 0)
11231     return 0;
11232
11233   vec_validate (mask, sizeof (*ip) - 1);
11234
11235   ip = (ip4_header_t *) mask;
11236
11237 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11238   foreach_ip4_proto_field;
11239 #undef _
11240
11241   ip->ip_version_and_header_length = 0;
11242
11243   if (version)
11244     ip->ip_version_and_header_length |= 0xF0;
11245
11246   if (hdr_length)
11247     ip->ip_version_and_header_length |= 0x0F;
11248
11249   *maskp = mask;
11250   return 1;
11251 }
11252
11253 #define foreach_ip6_proto_field                 \
11254 _(src_address)                                  \
11255 _(dst_address)                                  \
11256 _(payload_length)                               \
11257 _(hop_limit)                                    \
11258 _(protocol)
11259
11260 uword
11261 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11262 {
11263   u8 **maskp = va_arg (*args, u8 **);
11264   u8 *mask = 0;
11265   u8 found_something = 0;
11266   ip6_header_t *ip;
11267   u32 ip_version_traffic_class_and_flow_label;
11268
11269 #define _(a) u8 a=0;
11270   foreach_ip6_proto_field;
11271 #undef _
11272   u8 version = 0;
11273   u8 traffic_class = 0;
11274   u8 flow_label = 0;
11275
11276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11277     {
11278       if (unformat (input, "version"))
11279         version = 1;
11280       else if (unformat (input, "traffic-class"))
11281         traffic_class = 1;
11282       else if (unformat (input, "flow-label"))
11283         flow_label = 1;
11284       else if (unformat (input, "src"))
11285         src_address = 1;
11286       else if (unformat (input, "dst"))
11287         dst_address = 1;
11288       else if (unformat (input, "proto"))
11289         protocol = 1;
11290
11291 #define _(a) else if (unformat (input, #a)) a=1;
11292       foreach_ip6_proto_field
11293 #undef _
11294         else
11295         break;
11296     }
11297
11298 #define _(a) found_something += a;
11299   foreach_ip6_proto_field;
11300 #undef _
11301
11302   if (found_something == 0)
11303     return 0;
11304
11305   vec_validate (mask, sizeof (*ip) - 1);
11306
11307   ip = (ip6_header_t *) mask;
11308
11309 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11310   foreach_ip6_proto_field;
11311 #undef _
11312
11313   ip_version_traffic_class_and_flow_label = 0;
11314
11315   if (version)
11316     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11317
11318   if (traffic_class)
11319     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11320
11321   if (flow_label)
11322     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11323
11324   ip->ip_version_traffic_class_and_flow_label =
11325     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11326
11327   *maskp = mask;
11328   return 1;
11329 }
11330
11331 uword
11332 unformat_l3_mask (unformat_input_t * input, va_list * args)
11333 {
11334   u8 **maskp = va_arg (*args, u8 **);
11335
11336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11337     {
11338       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11339         return 1;
11340       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11341         return 1;
11342       else
11343         break;
11344     }
11345   return 0;
11346 }
11347
11348 uword
11349 unformat_l2_mask (unformat_input_t * input, va_list * args)
11350 {
11351   u8 **maskp = va_arg (*args, u8 **);
11352   u8 *mask = 0;
11353   u8 src = 0;
11354   u8 dst = 0;
11355   u8 proto = 0;
11356   u8 tag1 = 0;
11357   u8 tag2 = 0;
11358   u8 ignore_tag1 = 0;
11359   u8 ignore_tag2 = 0;
11360   u8 cos1 = 0;
11361   u8 cos2 = 0;
11362   u8 dot1q = 0;
11363   u8 dot1ad = 0;
11364   int len = 14;
11365
11366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11367     {
11368       if (unformat (input, "src"))
11369         src = 1;
11370       else if (unformat (input, "dst"))
11371         dst = 1;
11372       else if (unformat (input, "proto"))
11373         proto = 1;
11374       else if (unformat (input, "tag1"))
11375         tag1 = 1;
11376       else if (unformat (input, "tag2"))
11377         tag2 = 1;
11378       else if (unformat (input, "ignore-tag1"))
11379         ignore_tag1 = 1;
11380       else if (unformat (input, "ignore-tag2"))
11381         ignore_tag2 = 1;
11382       else if (unformat (input, "cos1"))
11383         cos1 = 1;
11384       else if (unformat (input, "cos2"))
11385         cos2 = 1;
11386       else if (unformat (input, "dot1q"))
11387         dot1q = 1;
11388       else if (unformat (input, "dot1ad"))
11389         dot1ad = 1;
11390       else
11391         break;
11392     }
11393   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11394        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11395     return 0;
11396
11397   if (tag1 || ignore_tag1 || cos1 || dot1q)
11398     len = 18;
11399   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11400     len = 22;
11401
11402   vec_validate (mask, len - 1);
11403
11404   if (dst)
11405     memset (mask, 0xff, 6);
11406
11407   if (src)
11408     memset (mask + 6, 0xff, 6);
11409
11410   if (tag2 || dot1ad)
11411     {
11412       /* inner vlan tag */
11413       if (tag2)
11414         {
11415           mask[19] = 0xff;
11416           mask[18] = 0x0f;
11417         }
11418       if (cos2)
11419         mask[18] |= 0xe0;
11420       if (proto)
11421         mask[21] = mask[20] = 0xff;
11422       if (tag1)
11423         {
11424           mask[15] = 0xff;
11425           mask[14] = 0x0f;
11426         }
11427       if (cos1)
11428         mask[14] |= 0xe0;
11429       *maskp = mask;
11430       return 1;
11431     }
11432   if (tag1 | dot1q)
11433     {
11434       if (tag1)
11435         {
11436           mask[15] = 0xff;
11437           mask[14] = 0x0f;
11438         }
11439       if (cos1)
11440         mask[14] |= 0xe0;
11441       if (proto)
11442         mask[16] = mask[17] = 0xff;
11443
11444       *maskp = mask;
11445       return 1;
11446     }
11447   if (cos2)
11448     mask[18] |= 0xe0;
11449   if (cos1)
11450     mask[14] |= 0xe0;
11451   if (proto)
11452     mask[12] = mask[13] = 0xff;
11453
11454   *maskp = mask;
11455   return 1;
11456 }
11457
11458 uword
11459 unformat_classify_mask (unformat_input_t * input, va_list * args)
11460 {
11461   u8 **maskp = va_arg (*args, u8 **);
11462   u32 *skipp = va_arg (*args, u32 *);
11463   u32 *matchp = va_arg (*args, u32 *);
11464   u32 match;
11465   u8 *mask = 0;
11466   u8 *l2 = 0;
11467   u8 *l3 = 0;
11468   u8 *l4 = 0;
11469   int i;
11470
11471   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11472     {
11473       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11474         ;
11475       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11476         ;
11477       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11478         ;
11479       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11480         ;
11481       else
11482         break;
11483     }
11484
11485   if (l4 && !l3)
11486     {
11487       vec_free (mask);
11488       vec_free (l2);
11489       vec_free (l4);
11490       return 0;
11491     }
11492
11493   if (mask || l2 || l3 || l4)
11494     {
11495       if (l2 || l3 || l4)
11496         {
11497           /* "With a free Ethernet header in every package" */
11498           if (l2 == 0)
11499             vec_validate (l2, 13);
11500           mask = l2;
11501           if (vec_len (l3))
11502             {
11503               vec_append (mask, l3);
11504               vec_free (l3);
11505             }
11506           if (vec_len (l4))
11507             {
11508               vec_append (mask, l4);
11509               vec_free (l4);
11510             }
11511         }
11512
11513       /* Scan forward looking for the first significant mask octet */
11514       for (i = 0; i < vec_len (mask); i++)
11515         if (mask[i])
11516           break;
11517
11518       /* compute (skip, match) params */
11519       *skipp = i / sizeof (u32x4);
11520       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11521
11522       /* Pad mask to an even multiple of the vector size */
11523       while (vec_len (mask) % sizeof (u32x4))
11524         vec_add1 (mask, 0);
11525
11526       match = vec_len (mask) / sizeof (u32x4);
11527
11528       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11529         {
11530           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11531           if (*tmp || *(tmp + 1))
11532             break;
11533           match--;
11534         }
11535       if (match == 0)
11536         clib_warning ("BUG: match 0");
11537
11538       _vec_len (mask) = match * sizeof (u32x4);
11539
11540       *matchp = match;
11541       *maskp = mask;
11542
11543       return 1;
11544     }
11545
11546   return 0;
11547 }
11548 #endif /* VPP_API_TEST_BUILTIN */
11549
11550 #define foreach_l2_next                         \
11551 _(drop, DROP)                                   \
11552 _(ethernet, ETHERNET_INPUT)                     \
11553 _(ip4, IP4_INPUT)                               \
11554 _(ip6, IP6_INPUT)
11555
11556 uword
11557 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11558 {
11559   u32 *miss_next_indexp = va_arg (*args, u32 *);
11560   u32 next_index = 0;
11561   u32 tmp;
11562
11563 #define _(n,N) \
11564   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11565   foreach_l2_next;
11566 #undef _
11567
11568   if (unformat (input, "%d", &tmp))
11569     {
11570       next_index = tmp;
11571       goto out;
11572     }
11573
11574   return 0;
11575
11576 out:
11577   *miss_next_indexp = next_index;
11578   return 1;
11579 }
11580
11581 #define foreach_ip_next                         \
11582 _(drop, DROP)                                   \
11583 _(local, LOCAL)                                 \
11584 _(rewrite, REWRITE)
11585
11586 uword
11587 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11588 {
11589   u32 *miss_next_indexp = va_arg (*args, u32 *);
11590   u32 next_index = 0;
11591   u32 tmp;
11592
11593 #define _(n,N) \
11594   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11595   foreach_ip_next;
11596 #undef _
11597
11598   if (unformat (input, "%d", &tmp))
11599     {
11600       next_index = tmp;
11601       goto out;
11602     }
11603
11604   return 0;
11605
11606 out:
11607   *miss_next_indexp = next_index;
11608   return 1;
11609 }
11610
11611 #define foreach_acl_next                        \
11612 _(deny, DENY)
11613
11614 uword
11615 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11616 {
11617   u32 *miss_next_indexp = va_arg (*args, u32 *);
11618   u32 next_index = 0;
11619   u32 tmp;
11620
11621 #define _(n,N) \
11622   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11623   foreach_acl_next;
11624 #undef _
11625
11626   if (unformat (input, "permit"))
11627     {
11628       next_index = ~0;
11629       goto out;
11630     }
11631   else if (unformat (input, "%d", &tmp))
11632     {
11633       next_index = tmp;
11634       goto out;
11635     }
11636
11637   return 0;
11638
11639 out:
11640   *miss_next_indexp = next_index;
11641   return 1;
11642 }
11643
11644 uword
11645 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11646 {
11647   u32 *r = va_arg (*args, u32 *);
11648
11649   if (unformat (input, "conform-color"))
11650     *r = POLICE_CONFORM;
11651   else if (unformat (input, "exceed-color"))
11652     *r = POLICE_EXCEED;
11653   else
11654     return 0;
11655
11656   return 1;
11657 }
11658
11659 static int
11660 api_classify_add_del_table (vat_main_t * vam)
11661 {
11662   unformat_input_t *i = vam->input;
11663   vl_api_classify_add_del_table_t *mp;
11664
11665   u32 nbuckets = 2;
11666   u32 skip = ~0;
11667   u32 match = ~0;
11668   int is_add = 1;
11669   int del_chain = 0;
11670   u32 table_index = ~0;
11671   u32 next_table_index = ~0;
11672   u32 miss_next_index = ~0;
11673   u32 memory_size = 32 << 20;
11674   u8 *mask = 0;
11675   u32 current_data_flag = 0;
11676   int current_data_offset = 0;
11677   int ret;
11678
11679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11680     {
11681       if (unformat (i, "del"))
11682         is_add = 0;
11683       else if (unformat (i, "del-chain"))
11684         {
11685           is_add = 0;
11686           del_chain = 1;
11687         }
11688       else if (unformat (i, "buckets %d", &nbuckets))
11689         ;
11690       else if (unformat (i, "memory_size %d", &memory_size))
11691         ;
11692       else if (unformat (i, "skip %d", &skip))
11693         ;
11694       else if (unformat (i, "match %d", &match))
11695         ;
11696       else if (unformat (i, "table %d", &table_index))
11697         ;
11698       else if (unformat (i, "mask %U", unformat_classify_mask,
11699                          &mask, &skip, &match))
11700         ;
11701       else if (unformat (i, "next-table %d", &next_table_index))
11702         ;
11703       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11704                          &miss_next_index))
11705         ;
11706       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11707                          &miss_next_index))
11708         ;
11709       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11710                          &miss_next_index))
11711         ;
11712       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11713         ;
11714       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11715         ;
11716       else
11717         break;
11718     }
11719
11720   if (is_add && mask == 0)
11721     {
11722       errmsg ("Mask required");
11723       return -99;
11724     }
11725
11726   if (is_add && skip == ~0)
11727     {
11728       errmsg ("skip count required");
11729       return -99;
11730     }
11731
11732   if (is_add && match == ~0)
11733     {
11734       errmsg ("match count required");
11735       return -99;
11736     }
11737
11738   if (!is_add && table_index == ~0)
11739     {
11740       errmsg ("table index required for delete");
11741       return -99;
11742     }
11743
11744   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11745
11746   mp->is_add = is_add;
11747   mp->del_chain = del_chain;
11748   mp->table_index = ntohl (table_index);
11749   mp->nbuckets = ntohl (nbuckets);
11750   mp->memory_size = ntohl (memory_size);
11751   mp->skip_n_vectors = ntohl (skip);
11752   mp->match_n_vectors = ntohl (match);
11753   mp->next_table_index = ntohl (next_table_index);
11754   mp->miss_next_index = ntohl (miss_next_index);
11755   mp->current_data_flag = ntohl (current_data_flag);
11756   mp->current_data_offset = ntohl (current_data_offset);
11757   mp->mask_len = ntohl (vec_len (mask));
11758   clib_memcpy (mp->mask, mask, vec_len (mask));
11759
11760   vec_free (mask);
11761
11762   S (mp);
11763   W (ret);
11764   return ret;
11765 }
11766
11767 #if VPP_API_TEST_BUILTIN == 0
11768 uword
11769 unformat_l4_match (unformat_input_t * input, va_list * args)
11770 {
11771   u8 **matchp = va_arg (*args, u8 **);
11772
11773   u8 *proto_header = 0;
11774   int src_port = 0;
11775   int dst_port = 0;
11776
11777   tcpudp_header_t h;
11778
11779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11780     {
11781       if (unformat (input, "src_port %d", &src_port))
11782         ;
11783       else if (unformat (input, "dst_port %d", &dst_port))
11784         ;
11785       else
11786         return 0;
11787     }
11788
11789   h.src_port = clib_host_to_net_u16 (src_port);
11790   h.dst_port = clib_host_to_net_u16 (dst_port);
11791   vec_validate (proto_header, sizeof (h) - 1);
11792   memcpy (proto_header, &h, sizeof (h));
11793
11794   *matchp = proto_header;
11795
11796   return 1;
11797 }
11798
11799 uword
11800 unformat_ip4_match (unformat_input_t * input, va_list * args)
11801 {
11802   u8 **matchp = va_arg (*args, u8 **);
11803   u8 *match = 0;
11804   ip4_header_t *ip;
11805   int version = 0;
11806   u32 version_val;
11807   int hdr_length = 0;
11808   u32 hdr_length_val;
11809   int src = 0, dst = 0;
11810   ip4_address_t src_val, dst_val;
11811   int proto = 0;
11812   u32 proto_val;
11813   int tos = 0;
11814   u32 tos_val;
11815   int length = 0;
11816   u32 length_val;
11817   int fragment_id = 0;
11818   u32 fragment_id_val;
11819   int ttl = 0;
11820   int ttl_val;
11821   int checksum = 0;
11822   u32 checksum_val;
11823
11824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11825     {
11826       if (unformat (input, "version %d", &version_val))
11827         version = 1;
11828       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11829         hdr_length = 1;
11830       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11831         src = 1;
11832       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11833         dst = 1;
11834       else if (unformat (input, "proto %d", &proto_val))
11835         proto = 1;
11836       else if (unformat (input, "tos %d", &tos_val))
11837         tos = 1;
11838       else if (unformat (input, "length %d", &length_val))
11839         length = 1;
11840       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11841         fragment_id = 1;
11842       else if (unformat (input, "ttl %d", &ttl_val))
11843         ttl = 1;
11844       else if (unformat (input, "checksum %d", &checksum_val))
11845         checksum = 1;
11846       else
11847         break;
11848     }
11849
11850   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11851       + ttl + checksum == 0)
11852     return 0;
11853
11854   /*
11855    * Aligned because we use the real comparison functions
11856    */
11857   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11858
11859   ip = (ip4_header_t *) match;
11860
11861   /* These are realistically matched in practice */
11862   if (src)
11863     ip->src_address.as_u32 = src_val.as_u32;
11864
11865   if (dst)
11866     ip->dst_address.as_u32 = dst_val.as_u32;
11867
11868   if (proto)
11869     ip->protocol = proto_val;
11870
11871
11872   /* These are not, but they're included for completeness */
11873   if (version)
11874     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11875
11876   if (hdr_length)
11877     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11878
11879   if (tos)
11880     ip->tos = tos_val;
11881
11882   if (length)
11883     ip->length = clib_host_to_net_u16 (length_val);
11884
11885   if (ttl)
11886     ip->ttl = ttl_val;
11887
11888   if (checksum)
11889     ip->checksum = clib_host_to_net_u16 (checksum_val);
11890
11891   *matchp = match;
11892   return 1;
11893 }
11894
11895 uword
11896 unformat_ip6_match (unformat_input_t * input, va_list * args)
11897 {
11898   u8 **matchp = va_arg (*args, u8 **);
11899   u8 *match = 0;
11900   ip6_header_t *ip;
11901   int version = 0;
11902   u32 version_val;
11903   u8 traffic_class = 0;
11904   u32 traffic_class_val = 0;
11905   u8 flow_label = 0;
11906   u8 flow_label_val;
11907   int src = 0, dst = 0;
11908   ip6_address_t src_val, dst_val;
11909   int proto = 0;
11910   u32 proto_val;
11911   int payload_length = 0;
11912   u32 payload_length_val;
11913   int hop_limit = 0;
11914   int hop_limit_val;
11915   u32 ip_version_traffic_class_and_flow_label;
11916
11917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (input, "version %d", &version_val))
11920         version = 1;
11921       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11922         traffic_class = 1;
11923       else if (unformat (input, "flow_label %d", &flow_label_val))
11924         flow_label = 1;
11925       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11926         src = 1;
11927       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11928         dst = 1;
11929       else if (unformat (input, "proto %d", &proto_val))
11930         proto = 1;
11931       else if (unformat (input, "payload_length %d", &payload_length_val))
11932         payload_length = 1;
11933       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11934         hop_limit = 1;
11935       else
11936         break;
11937     }
11938
11939   if (version + traffic_class + flow_label + src + dst + proto +
11940       payload_length + hop_limit == 0)
11941     return 0;
11942
11943   /*
11944    * Aligned because we use the real comparison functions
11945    */
11946   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11947
11948   ip = (ip6_header_t *) match;
11949
11950   if (src)
11951     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11952
11953   if (dst)
11954     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11955
11956   if (proto)
11957     ip->protocol = proto_val;
11958
11959   ip_version_traffic_class_and_flow_label = 0;
11960
11961   if (version)
11962     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11963
11964   if (traffic_class)
11965     ip_version_traffic_class_and_flow_label |=
11966       (traffic_class_val & 0xFF) << 20;
11967
11968   if (flow_label)
11969     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11970
11971   ip->ip_version_traffic_class_and_flow_label =
11972     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11973
11974   if (payload_length)
11975     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11976
11977   if (hop_limit)
11978     ip->hop_limit = hop_limit_val;
11979
11980   *matchp = match;
11981   return 1;
11982 }
11983
11984 uword
11985 unformat_l3_match (unformat_input_t * input, va_list * args)
11986 {
11987   u8 **matchp = va_arg (*args, u8 **);
11988
11989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11990     {
11991       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11992         return 1;
11993       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11994         return 1;
11995       else
11996         break;
11997     }
11998   return 0;
11999 }
12000
12001 uword
12002 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12003 {
12004   u8 *tagp = va_arg (*args, u8 *);
12005   u32 tag;
12006
12007   if (unformat (input, "%d", &tag))
12008     {
12009       tagp[0] = (tag >> 8) & 0x0F;
12010       tagp[1] = tag & 0xFF;
12011       return 1;
12012     }
12013
12014   return 0;
12015 }
12016
12017 uword
12018 unformat_l2_match (unformat_input_t * input, va_list * args)
12019 {
12020   u8 **matchp = va_arg (*args, u8 **);
12021   u8 *match = 0;
12022   u8 src = 0;
12023   u8 src_val[6];
12024   u8 dst = 0;
12025   u8 dst_val[6];
12026   u8 proto = 0;
12027   u16 proto_val;
12028   u8 tag1 = 0;
12029   u8 tag1_val[2];
12030   u8 tag2 = 0;
12031   u8 tag2_val[2];
12032   int len = 14;
12033   u8 ignore_tag1 = 0;
12034   u8 ignore_tag2 = 0;
12035   u8 cos1 = 0;
12036   u8 cos2 = 0;
12037   u32 cos1_val = 0;
12038   u32 cos2_val = 0;
12039
12040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12041     {
12042       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12043         src = 1;
12044       else
12045         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12046         dst = 1;
12047       else if (unformat (input, "proto %U",
12048                          unformat_ethernet_type_host_byte_order, &proto_val))
12049         proto = 1;
12050       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12051         tag1 = 1;
12052       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12053         tag2 = 1;
12054       else if (unformat (input, "ignore-tag1"))
12055         ignore_tag1 = 1;
12056       else if (unformat (input, "ignore-tag2"))
12057         ignore_tag2 = 1;
12058       else if (unformat (input, "cos1 %d", &cos1_val))
12059         cos1 = 1;
12060       else if (unformat (input, "cos2 %d", &cos2_val))
12061         cos2 = 1;
12062       else
12063         break;
12064     }
12065   if ((src + dst + proto + tag1 + tag2 +
12066        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12067     return 0;
12068
12069   if (tag1 || ignore_tag1 || cos1)
12070     len = 18;
12071   if (tag2 || ignore_tag2 || cos2)
12072     len = 22;
12073
12074   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12075
12076   if (dst)
12077     clib_memcpy (match, dst_val, 6);
12078
12079   if (src)
12080     clib_memcpy (match + 6, src_val, 6);
12081
12082   if (tag2)
12083     {
12084       /* inner vlan tag */
12085       match[19] = tag2_val[1];
12086       match[18] = tag2_val[0];
12087       if (cos2)
12088         match[18] |= (cos2_val & 0x7) << 5;
12089       if (proto)
12090         {
12091           match[21] = proto_val & 0xff;
12092           match[20] = proto_val >> 8;
12093         }
12094       if (tag1)
12095         {
12096           match[15] = tag1_val[1];
12097           match[14] = tag1_val[0];
12098         }
12099       if (cos1)
12100         match[14] |= (cos1_val & 0x7) << 5;
12101       *matchp = match;
12102       return 1;
12103     }
12104   if (tag1)
12105     {
12106       match[15] = tag1_val[1];
12107       match[14] = tag1_val[0];
12108       if (proto)
12109         {
12110           match[17] = proto_val & 0xff;
12111           match[16] = proto_val >> 8;
12112         }
12113       if (cos1)
12114         match[14] |= (cos1_val & 0x7) << 5;
12115
12116       *matchp = match;
12117       return 1;
12118     }
12119   if (cos2)
12120     match[18] |= (cos2_val & 0x7) << 5;
12121   if (cos1)
12122     match[14] |= (cos1_val & 0x7) << 5;
12123   if (proto)
12124     {
12125       match[13] = proto_val & 0xff;
12126       match[12] = proto_val >> 8;
12127     }
12128
12129   *matchp = match;
12130   return 1;
12131 }
12132
12133 uword
12134 unformat_qos_source (unformat_input_t * input, va_list * args)
12135 {
12136   int *qs = va_arg (*args, int *);
12137
12138   if (unformat (input, "ip"))
12139     *qs = QOS_SOURCE_IP;
12140   else if (unformat (input, "mpls"))
12141     *qs = QOS_SOURCE_MPLS;
12142   else if (unformat (input, "ext"))
12143     *qs = QOS_SOURCE_EXT;
12144   else if (unformat (input, "vlan"))
12145     *qs = QOS_SOURCE_VLAN;
12146   else
12147     return 0;
12148
12149   return 1;
12150 }
12151 #endif
12152
12153 uword
12154 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12155 {
12156   u8 **matchp = va_arg (*args, u8 **);
12157   u32 skip_n_vectors = va_arg (*args, u32);
12158   u32 match_n_vectors = va_arg (*args, u32);
12159
12160   u8 *match = 0;
12161   u8 *l2 = 0;
12162   u8 *l3 = 0;
12163   u8 *l4 = 0;
12164
12165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12166     {
12167       if (unformat (input, "hex %U", unformat_hex_string, &match))
12168         ;
12169       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12170         ;
12171       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12172         ;
12173       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12174         ;
12175       else
12176         break;
12177     }
12178
12179   if (l4 && !l3)
12180     {
12181       vec_free (match);
12182       vec_free (l2);
12183       vec_free (l4);
12184       return 0;
12185     }
12186
12187   if (match || l2 || l3 || l4)
12188     {
12189       if (l2 || l3 || l4)
12190         {
12191           /* "Win a free Ethernet header in every packet" */
12192           if (l2 == 0)
12193             vec_validate_aligned (l2, 13, sizeof (u32x4));
12194           match = l2;
12195           if (vec_len (l3))
12196             {
12197               vec_append_aligned (match, l3, sizeof (u32x4));
12198               vec_free (l3);
12199             }
12200           if (vec_len (l4))
12201             {
12202               vec_append_aligned (match, l4, sizeof (u32x4));
12203               vec_free (l4);
12204             }
12205         }
12206
12207       /* Make sure the vector is big enough even if key is all 0's */
12208       vec_validate_aligned
12209         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12210          sizeof (u32x4));
12211
12212       /* Set size, include skipped vectors */
12213       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12214
12215       *matchp = match;
12216
12217       return 1;
12218     }
12219
12220   return 0;
12221 }
12222
12223 static int
12224 api_classify_add_del_session (vat_main_t * vam)
12225 {
12226   unformat_input_t *i = vam->input;
12227   vl_api_classify_add_del_session_t *mp;
12228   int is_add = 1;
12229   u32 table_index = ~0;
12230   u32 hit_next_index = ~0;
12231   u32 opaque_index = ~0;
12232   u8 *match = 0;
12233   i32 advance = 0;
12234   u32 skip_n_vectors = 0;
12235   u32 match_n_vectors = 0;
12236   u32 action = 0;
12237   u32 metadata = 0;
12238   int ret;
12239
12240   /*
12241    * Warning: you have to supply skip_n and match_n
12242    * because the API client cant simply look at the classify
12243    * table object.
12244    */
12245
12246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (i, "del"))
12249         is_add = 0;
12250       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12251                          &hit_next_index))
12252         ;
12253       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12254                          &hit_next_index))
12255         ;
12256       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12257                          &hit_next_index))
12258         ;
12259       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12260         ;
12261       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12262         ;
12263       else if (unformat (i, "opaque-index %d", &opaque_index))
12264         ;
12265       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12266         ;
12267       else if (unformat (i, "match_n %d", &match_n_vectors))
12268         ;
12269       else if (unformat (i, "match %U", api_unformat_classify_match,
12270                          &match, skip_n_vectors, match_n_vectors))
12271         ;
12272       else if (unformat (i, "advance %d", &advance))
12273         ;
12274       else if (unformat (i, "table-index %d", &table_index))
12275         ;
12276       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12277         action = 1;
12278       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12279         action = 2;
12280       else if (unformat (i, "action %d", &action))
12281         ;
12282       else if (unformat (i, "metadata %d", &metadata))
12283         ;
12284       else
12285         break;
12286     }
12287
12288   if (table_index == ~0)
12289     {
12290       errmsg ("Table index required");
12291       return -99;
12292     }
12293
12294   if (is_add && match == 0)
12295     {
12296       errmsg ("Match value required");
12297       return -99;
12298     }
12299
12300   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12301
12302   mp->is_add = is_add;
12303   mp->table_index = ntohl (table_index);
12304   mp->hit_next_index = ntohl (hit_next_index);
12305   mp->opaque_index = ntohl (opaque_index);
12306   mp->advance = ntohl (advance);
12307   mp->action = action;
12308   mp->metadata = ntohl (metadata);
12309   mp->match_len = ntohl (vec_len (match));
12310   clib_memcpy (mp->match, match, vec_len (match));
12311   vec_free (match);
12312
12313   S (mp);
12314   W (ret);
12315   return ret;
12316 }
12317
12318 static int
12319 api_classify_set_interface_ip_table (vat_main_t * vam)
12320 {
12321   unformat_input_t *i = vam->input;
12322   vl_api_classify_set_interface_ip_table_t *mp;
12323   u32 sw_if_index;
12324   int sw_if_index_set;
12325   u32 table_index = ~0;
12326   u8 is_ipv6 = 0;
12327   int ret;
12328
12329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12332         sw_if_index_set = 1;
12333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12334         sw_if_index_set = 1;
12335       else if (unformat (i, "table %d", &table_index))
12336         ;
12337       else
12338         {
12339           clib_warning ("parse error '%U'", format_unformat_error, i);
12340           return -99;
12341         }
12342     }
12343
12344   if (sw_if_index_set == 0)
12345     {
12346       errmsg ("missing interface name or sw_if_index");
12347       return -99;
12348     }
12349
12350
12351   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12352
12353   mp->sw_if_index = ntohl (sw_if_index);
12354   mp->table_index = ntohl (table_index);
12355   mp->is_ipv6 = is_ipv6;
12356
12357   S (mp);
12358   W (ret);
12359   return ret;
12360 }
12361
12362 static int
12363 api_classify_set_interface_l2_tables (vat_main_t * vam)
12364 {
12365   unformat_input_t *i = vam->input;
12366   vl_api_classify_set_interface_l2_tables_t *mp;
12367   u32 sw_if_index;
12368   int sw_if_index_set;
12369   u32 ip4_table_index = ~0;
12370   u32 ip6_table_index = ~0;
12371   u32 other_table_index = ~0;
12372   u32 is_input = 1;
12373   int ret;
12374
12375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12376     {
12377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12378         sw_if_index_set = 1;
12379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12380         sw_if_index_set = 1;
12381       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12382         ;
12383       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12384         ;
12385       else if (unformat (i, "other-table %d", &other_table_index))
12386         ;
12387       else if (unformat (i, "is-input %d", &is_input))
12388         ;
12389       else
12390         {
12391           clib_warning ("parse error '%U'", format_unformat_error, i);
12392           return -99;
12393         }
12394     }
12395
12396   if (sw_if_index_set == 0)
12397     {
12398       errmsg ("missing interface name or sw_if_index");
12399       return -99;
12400     }
12401
12402
12403   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12404
12405   mp->sw_if_index = ntohl (sw_if_index);
12406   mp->ip4_table_index = ntohl (ip4_table_index);
12407   mp->ip6_table_index = ntohl (ip6_table_index);
12408   mp->other_table_index = ntohl (other_table_index);
12409   mp->is_input = (u8) is_input;
12410
12411   S (mp);
12412   W (ret);
12413   return ret;
12414 }
12415
12416 static int
12417 api_set_ipfix_exporter (vat_main_t * vam)
12418 {
12419   unformat_input_t *i = vam->input;
12420   vl_api_set_ipfix_exporter_t *mp;
12421   ip4_address_t collector_address;
12422   u8 collector_address_set = 0;
12423   u32 collector_port = ~0;
12424   ip4_address_t src_address;
12425   u8 src_address_set = 0;
12426   u32 vrf_id = ~0;
12427   u32 path_mtu = ~0;
12428   u32 template_interval = ~0;
12429   u8 udp_checksum = 0;
12430   int ret;
12431
12432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12433     {
12434       if (unformat (i, "collector_address %U", unformat_ip4_address,
12435                     &collector_address))
12436         collector_address_set = 1;
12437       else if (unformat (i, "collector_port %d", &collector_port))
12438         ;
12439       else if (unformat (i, "src_address %U", unformat_ip4_address,
12440                          &src_address))
12441         src_address_set = 1;
12442       else if (unformat (i, "vrf_id %d", &vrf_id))
12443         ;
12444       else if (unformat (i, "path_mtu %d", &path_mtu))
12445         ;
12446       else if (unformat (i, "template_interval %d", &template_interval))
12447         ;
12448       else if (unformat (i, "udp_checksum"))
12449         udp_checksum = 1;
12450       else
12451         break;
12452     }
12453
12454   if (collector_address_set == 0)
12455     {
12456       errmsg ("collector_address required");
12457       return -99;
12458     }
12459
12460   if (src_address_set == 0)
12461     {
12462       errmsg ("src_address required");
12463       return -99;
12464     }
12465
12466   M (SET_IPFIX_EXPORTER, mp);
12467
12468   memcpy (mp->collector_address, collector_address.data,
12469           sizeof (collector_address.data));
12470   mp->collector_port = htons ((u16) collector_port);
12471   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12472   mp->vrf_id = htonl (vrf_id);
12473   mp->path_mtu = htonl (path_mtu);
12474   mp->template_interval = htonl (template_interval);
12475   mp->udp_checksum = udp_checksum;
12476
12477   S (mp);
12478   W (ret);
12479   return ret;
12480 }
12481
12482 static int
12483 api_set_ipfix_classify_stream (vat_main_t * vam)
12484 {
12485   unformat_input_t *i = vam->input;
12486   vl_api_set_ipfix_classify_stream_t *mp;
12487   u32 domain_id = 0;
12488   u32 src_port = UDP_DST_PORT_ipfix;
12489   int ret;
12490
12491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12492     {
12493       if (unformat (i, "domain %d", &domain_id))
12494         ;
12495       else if (unformat (i, "src_port %d", &src_port))
12496         ;
12497       else
12498         {
12499           errmsg ("unknown input `%U'", format_unformat_error, i);
12500           return -99;
12501         }
12502     }
12503
12504   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12505
12506   mp->domain_id = htonl (domain_id);
12507   mp->src_port = htons ((u16) src_port);
12508
12509   S (mp);
12510   W (ret);
12511   return ret;
12512 }
12513
12514 static int
12515 api_ipfix_classify_table_add_del (vat_main_t * vam)
12516 {
12517   unformat_input_t *i = vam->input;
12518   vl_api_ipfix_classify_table_add_del_t *mp;
12519   int is_add = -1;
12520   u32 classify_table_index = ~0;
12521   u8 ip_version = 0;
12522   u8 transport_protocol = 255;
12523   int ret;
12524
12525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12526     {
12527       if (unformat (i, "add"))
12528         is_add = 1;
12529       else if (unformat (i, "del"))
12530         is_add = 0;
12531       else if (unformat (i, "table %d", &classify_table_index))
12532         ;
12533       else if (unformat (i, "ip4"))
12534         ip_version = 4;
12535       else if (unformat (i, "ip6"))
12536         ip_version = 6;
12537       else if (unformat (i, "tcp"))
12538         transport_protocol = 6;
12539       else if (unformat (i, "udp"))
12540         transport_protocol = 17;
12541       else
12542         {
12543           errmsg ("unknown input `%U'", format_unformat_error, i);
12544           return -99;
12545         }
12546     }
12547
12548   if (is_add == -1)
12549     {
12550       errmsg ("expecting: add|del");
12551       return -99;
12552     }
12553   if (classify_table_index == ~0)
12554     {
12555       errmsg ("classifier table not specified");
12556       return -99;
12557     }
12558   if (ip_version == 0)
12559     {
12560       errmsg ("IP version not specified");
12561       return -99;
12562     }
12563
12564   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12565
12566   mp->is_add = is_add;
12567   mp->table_id = htonl (classify_table_index);
12568   mp->ip_version = ip_version;
12569   mp->transport_protocol = transport_protocol;
12570
12571   S (mp);
12572   W (ret);
12573   return ret;
12574 }
12575
12576 static int
12577 api_get_node_index (vat_main_t * vam)
12578 {
12579   unformat_input_t *i = vam->input;
12580   vl_api_get_node_index_t *mp;
12581   u8 *name = 0;
12582   int ret;
12583
12584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12585     {
12586       if (unformat (i, "node %s", &name))
12587         ;
12588       else
12589         break;
12590     }
12591   if (name == 0)
12592     {
12593       errmsg ("node name required");
12594       return -99;
12595     }
12596   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12597     {
12598       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12599       return -99;
12600     }
12601
12602   M (GET_NODE_INDEX, mp);
12603   clib_memcpy (mp->node_name, name, vec_len (name));
12604   vec_free (name);
12605
12606   S (mp);
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_get_next_index (vat_main_t * vam)
12613 {
12614   unformat_input_t *i = vam->input;
12615   vl_api_get_next_index_t *mp;
12616   u8 *node_name = 0, *next_node_name = 0;
12617   int ret;
12618
12619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12620     {
12621       if (unformat (i, "node-name %s", &node_name))
12622         ;
12623       else if (unformat (i, "next-node-name %s", &next_node_name))
12624         break;
12625     }
12626
12627   if (node_name == 0)
12628     {
12629       errmsg ("node name required");
12630       return -99;
12631     }
12632   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12633     {
12634       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12635       return -99;
12636     }
12637
12638   if (next_node_name == 0)
12639     {
12640       errmsg ("next node name required");
12641       return -99;
12642     }
12643   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12644     {
12645       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12646       return -99;
12647     }
12648
12649   M (GET_NEXT_INDEX, mp);
12650   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12651   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12652   vec_free (node_name);
12653   vec_free (next_node_name);
12654
12655   S (mp);
12656   W (ret);
12657   return ret;
12658 }
12659
12660 static int
12661 api_add_node_next (vat_main_t * vam)
12662 {
12663   unformat_input_t *i = vam->input;
12664   vl_api_add_node_next_t *mp;
12665   u8 *name = 0;
12666   u8 *next = 0;
12667   int ret;
12668
12669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12670     {
12671       if (unformat (i, "node %s", &name))
12672         ;
12673       else if (unformat (i, "next %s", &next))
12674         ;
12675       else
12676         break;
12677     }
12678   if (name == 0)
12679     {
12680       errmsg ("node name required");
12681       return -99;
12682     }
12683   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12684     {
12685       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12686       return -99;
12687     }
12688   if (next == 0)
12689     {
12690       errmsg ("next node required");
12691       return -99;
12692     }
12693   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12694     {
12695       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12696       return -99;
12697     }
12698
12699   M (ADD_NODE_NEXT, mp);
12700   clib_memcpy (mp->node_name, name, vec_len (name));
12701   clib_memcpy (mp->next_name, next, vec_len (next));
12702   vec_free (name);
12703   vec_free (next);
12704
12705   S (mp);
12706   W (ret);
12707   return ret;
12708 }
12709
12710 static int
12711 api_l2tpv3_create_tunnel (vat_main_t * vam)
12712 {
12713   unformat_input_t *i = vam->input;
12714   ip6_address_t client_address, our_address;
12715   int client_address_set = 0;
12716   int our_address_set = 0;
12717   u32 local_session_id = 0;
12718   u32 remote_session_id = 0;
12719   u64 local_cookie = 0;
12720   u64 remote_cookie = 0;
12721   u8 l2_sublayer_present = 0;
12722   vl_api_l2tpv3_create_tunnel_t *mp;
12723   int ret;
12724
12725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12726     {
12727       if (unformat (i, "client_address %U", unformat_ip6_address,
12728                     &client_address))
12729         client_address_set = 1;
12730       else if (unformat (i, "our_address %U", unformat_ip6_address,
12731                          &our_address))
12732         our_address_set = 1;
12733       else if (unformat (i, "local_session_id %d", &local_session_id))
12734         ;
12735       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12736         ;
12737       else if (unformat (i, "local_cookie %lld", &local_cookie))
12738         ;
12739       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12740         ;
12741       else if (unformat (i, "l2-sublayer-present"))
12742         l2_sublayer_present = 1;
12743       else
12744         break;
12745     }
12746
12747   if (client_address_set == 0)
12748     {
12749       errmsg ("client_address required");
12750       return -99;
12751     }
12752
12753   if (our_address_set == 0)
12754     {
12755       errmsg ("our_address required");
12756       return -99;
12757     }
12758
12759   M (L2TPV3_CREATE_TUNNEL, mp);
12760
12761   clib_memcpy (mp->client_address, client_address.as_u8,
12762                sizeof (mp->client_address));
12763
12764   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12765
12766   mp->local_session_id = ntohl (local_session_id);
12767   mp->remote_session_id = ntohl (remote_session_id);
12768   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12769   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12770   mp->l2_sublayer_present = l2_sublayer_present;
12771   mp->is_ipv6 = 1;
12772
12773   S (mp);
12774   W (ret);
12775   return ret;
12776 }
12777
12778 static int
12779 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12780 {
12781   unformat_input_t *i = vam->input;
12782   u32 sw_if_index;
12783   u8 sw_if_index_set = 0;
12784   u64 new_local_cookie = 0;
12785   u64 new_remote_cookie = 0;
12786   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12787   int ret;
12788
12789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12790     {
12791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12792         sw_if_index_set = 1;
12793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12794         sw_if_index_set = 1;
12795       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12796         ;
12797       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12798         ;
12799       else
12800         break;
12801     }
12802
12803   if (sw_if_index_set == 0)
12804     {
12805       errmsg ("missing interface name or sw_if_index");
12806       return -99;
12807     }
12808
12809   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12810
12811   mp->sw_if_index = ntohl (sw_if_index);
12812   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12813   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12814
12815   S (mp);
12816   W (ret);
12817   return ret;
12818 }
12819
12820 static int
12821 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12822 {
12823   unformat_input_t *i = vam->input;
12824   vl_api_l2tpv3_interface_enable_disable_t *mp;
12825   u32 sw_if_index;
12826   u8 sw_if_index_set = 0;
12827   u8 enable_disable = 1;
12828   int ret;
12829
12830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12831     {
12832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12833         sw_if_index_set = 1;
12834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12835         sw_if_index_set = 1;
12836       else if (unformat (i, "enable"))
12837         enable_disable = 1;
12838       else if (unformat (i, "disable"))
12839         enable_disable = 0;
12840       else
12841         break;
12842     }
12843
12844   if (sw_if_index_set == 0)
12845     {
12846       errmsg ("missing interface name or sw_if_index");
12847       return -99;
12848     }
12849
12850   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12851
12852   mp->sw_if_index = ntohl (sw_if_index);
12853   mp->enable_disable = enable_disable;
12854
12855   S (mp);
12856   W (ret);
12857   return ret;
12858 }
12859
12860 static int
12861 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12862 {
12863   unformat_input_t *i = vam->input;
12864   vl_api_l2tpv3_set_lookup_key_t *mp;
12865   u8 key = ~0;
12866   int ret;
12867
12868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12869     {
12870       if (unformat (i, "lookup_v6_src"))
12871         key = L2T_LOOKUP_SRC_ADDRESS;
12872       else if (unformat (i, "lookup_v6_dst"))
12873         key = L2T_LOOKUP_DST_ADDRESS;
12874       else if (unformat (i, "lookup_session_id"))
12875         key = L2T_LOOKUP_SESSION_ID;
12876       else
12877         break;
12878     }
12879
12880   if (key == (u8) ~ 0)
12881     {
12882       errmsg ("l2tp session lookup key unset");
12883       return -99;
12884     }
12885
12886   M (L2TPV3_SET_LOOKUP_KEY, mp);
12887
12888   mp->key = key;
12889
12890   S (mp);
12891   W (ret);
12892   return ret;
12893 }
12894
12895 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12896   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12897 {
12898   vat_main_t *vam = &vat_main;
12899
12900   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12901          format_ip6_address, mp->our_address,
12902          format_ip6_address, mp->client_address,
12903          clib_net_to_host_u32 (mp->sw_if_index));
12904
12905   print (vam->ofp,
12906          "   local cookies %016llx %016llx remote cookie %016llx",
12907          clib_net_to_host_u64 (mp->local_cookie[0]),
12908          clib_net_to_host_u64 (mp->local_cookie[1]),
12909          clib_net_to_host_u64 (mp->remote_cookie));
12910
12911   print (vam->ofp, "   local session-id %d remote session-id %d",
12912          clib_net_to_host_u32 (mp->local_session_id),
12913          clib_net_to_host_u32 (mp->remote_session_id));
12914
12915   print (vam->ofp, "   l2 specific sublayer %s\n",
12916          mp->l2_sublayer_present ? "preset" : "absent");
12917
12918 }
12919
12920 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12921   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12922 {
12923   vat_main_t *vam = &vat_main;
12924   vat_json_node_t *node = NULL;
12925   struct in6_addr addr;
12926
12927   if (VAT_JSON_ARRAY != vam->json_tree.type)
12928     {
12929       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12930       vat_json_init_array (&vam->json_tree);
12931     }
12932   node = vat_json_array_add (&vam->json_tree);
12933
12934   vat_json_init_object (node);
12935
12936   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12937   vat_json_object_add_ip6 (node, "our_address", addr);
12938   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12939   vat_json_object_add_ip6 (node, "client_address", addr);
12940
12941   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12942   vat_json_init_array (lc);
12943   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12944   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12945   vat_json_object_add_uint (node, "remote_cookie",
12946                             clib_net_to_host_u64 (mp->remote_cookie));
12947
12948   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12949   vat_json_object_add_uint (node, "local_session_id",
12950                             clib_net_to_host_u32 (mp->local_session_id));
12951   vat_json_object_add_uint (node, "remote_session_id",
12952                             clib_net_to_host_u32 (mp->remote_session_id));
12953   vat_json_object_add_string_copy (node, "l2_sublayer",
12954                                    mp->l2_sublayer_present ? (u8 *) "present"
12955                                    : (u8 *) "absent");
12956 }
12957
12958 static int
12959 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12960 {
12961   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12962   vl_api_control_ping_t *mp_ping;
12963   int ret;
12964
12965   /* Get list of l2tpv3-tunnel interfaces */
12966   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12967   S (mp);
12968
12969   /* Use a control ping for synchronization */
12970   MPING (CONTROL_PING, mp_ping);
12971   S (mp_ping);
12972
12973   W (ret);
12974   return ret;
12975 }
12976
12977
12978 static void vl_api_sw_interface_tap_details_t_handler
12979   (vl_api_sw_interface_tap_details_t * mp)
12980 {
12981   vat_main_t *vam = &vat_main;
12982
12983   print (vam->ofp, "%-16s %d",
12984          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12985 }
12986
12987 static void vl_api_sw_interface_tap_details_t_handler_json
12988   (vl_api_sw_interface_tap_details_t * mp)
12989 {
12990   vat_main_t *vam = &vat_main;
12991   vat_json_node_t *node = NULL;
12992
12993   if (VAT_JSON_ARRAY != vam->json_tree.type)
12994     {
12995       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12996       vat_json_init_array (&vam->json_tree);
12997     }
12998   node = vat_json_array_add (&vam->json_tree);
12999
13000   vat_json_init_object (node);
13001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13002   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13003 }
13004
13005 static int
13006 api_sw_interface_tap_dump (vat_main_t * vam)
13007 {
13008   vl_api_sw_interface_tap_dump_t *mp;
13009   vl_api_control_ping_t *mp_ping;
13010   int ret;
13011
13012   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13013   /* Get list of tap interfaces */
13014   M (SW_INTERFACE_TAP_DUMP, mp);
13015   S (mp);
13016
13017   /* Use a control ping for synchronization */
13018   MPING (CONTROL_PING, mp_ping);
13019   S (mp_ping);
13020
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static void vl_api_sw_interface_tap_v2_details_t_handler
13026   (vl_api_sw_interface_tap_v2_details_t * mp)
13027 {
13028   vat_main_t *vam = &vat_main;
13029
13030   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13031                     mp->host_ip4_prefix_len);
13032   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13033                     mp->host_ip6_prefix_len);
13034
13035   print (vam->ofp,
13036          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13037          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13038          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13039          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13040          mp->host_bridge, ip4, ip6);
13041
13042   vec_free (ip4);
13043   vec_free (ip6);
13044 }
13045
13046 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13047   (vl_api_sw_interface_tap_v2_details_t * mp)
13048 {
13049   vat_main_t *vam = &vat_main;
13050   vat_json_node_t *node = NULL;
13051
13052   if (VAT_JSON_ARRAY != vam->json_tree.type)
13053     {
13054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13055       vat_json_init_array (&vam->json_tree);
13056     }
13057   node = vat_json_array_add (&vam->json_tree);
13058
13059   vat_json_init_object (node);
13060   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13061   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13062   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13063   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13064   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13065   vat_json_object_add_string_copy (node, "host_mac_addr",
13066                                    format (0, "%U", format_ethernet_address,
13067                                            &mp->host_mac_addr));
13068   vat_json_object_add_string_copy (node, "host_namespace",
13069                                    mp->host_namespace);
13070   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13071   vat_json_object_add_string_copy (node, "host_ip4_addr",
13072                                    format (0, "%U/%d", format_ip4_address,
13073                                            mp->host_ip4_addr,
13074                                            mp->host_ip4_prefix_len));
13075   vat_json_object_add_string_copy (node, "host_ip6_addr",
13076                                    format (0, "%U/%d", format_ip6_address,
13077                                            mp->host_ip6_addr,
13078                                            mp->host_ip6_prefix_len));
13079
13080 }
13081
13082 static int
13083 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13084 {
13085   vl_api_sw_interface_tap_v2_dump_t *mp;
13086   vl_api_control_ping_t *mp_ping;
13087   int ret;
13088
13089   print (vam->ofp,
13090          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13091          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13092          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13093          "host_ip6_addr");
13094
13095   /* Get list of tap interfaces */
13096   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13097   S (mp);
13098
13099   /* Use a control ping for synchronization */
13100   MPING (CONTROL_PING, mp_ping);
13101   S (mp_ping);
13102
13103   W (ret);
13104   return ret;
13105 }
13106
13107 static int
13108 api_vxlan_offload_rx (vat_main_t * vam)
13109 {
13110   unformat_input_t *line_input = vam->input;
13111   vl_api_vxlan_offload_rx_t *mp;
13112   u32 hw_if_index = ~0, rx_if_index = ~0;
13113   u8 is_add = 1;
13114   int ret;
13115
13116   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13117     {
13118       if (unformat (line_input, "del"))
13119         is_add = 0;
13120       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13121                          &hw_if_index))
13122         ;
13123       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13124         ;
13125       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13126                          &rx_if_index))
13127         ;
13128       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13129         ;
13130       else
13131         {
13132           errmsg ("parse error '%U'", format_unformat_error, line_input);
13133           return -99;
13134         }
13135     }
13136
13137   if (hw_if_index == ~0)
13138     {
13139       errmsg ("no hw interface");
13140       return -99;
13141     }
13142
13143   if (rx_if_index == ~0)
13144     {
13145       errmsg ("no rx tunnel");
13146       return -99;
13147     }
13148
13149   M (VXLAN_OFFLOAD_RX, mp);
13150
13151   mp->hw_if_index = ntohl (hw_if_index);
13152   mp->sw_if_index = ntohl (rx_if_index);
13153   mp->enable = is_add;
13154
13155   S (mp);
13156   W (ret);
13157   return ret;
13158 }
13159
13160 static uword unformat_vxlan_decap_next
13161   (unformat_input_t * input, va_list * args)
13162 {
13163   u32 *result = va_arg (*args, u32 *);
13164   u32 tmp;
13165
13166   if (unformat (input, "l2"))
13167     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13168   else if (unformat (input, "%d", &tmp))
13169     *result = tmp;
13170   else
13171     return 0;
13172   return 1;
13173 }
13174
13175 static int
13176 api_vxlan_add_del_tunnel (vat_main_t * vam)
13177 {
13178   unformat_input_t *line_input = vam->input;
13179   vl_api_vxlan_add_del_tunnel_t *mp;
13180   ip46_address_t src, dst;
13181   u8 is_add = 1;
13182   u8 ipv4_set = 0, ipv6_set = 0;
13183   u8 src_set = 0;
13184   u8 dst_set = 0;
13185   u8 grp_set = 0;
13186   u32 instance = ~0;
13187   u32 mcast_sw_if_index = ~0;
13188   u32 encap_vrf_id = 0;
13189   u32 decap_next_index = ~0;
13190   u32 vni = 0;
13191   int ret;
13192
13193   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13194   memset (&src, 0, sizeof src);
13195   memset (&dst, 0, sizeof dst);
13196
13197   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13198     {
13199       if (unformat (line_input, "del"))
13200         is_add = 0;
13201       else if (unformat (line_input, "instance %d", &instance))
13202         ;
13203       else
13204         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13205         {
13206           ipv4_set = 1;
13207           src_set = 1;
13208         }
13209       else
13210         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13211         {
13212           ipv4_set = 1;
13213           dst_set = 1;
13214         }
13215       else
13216         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13217         {
13218           ipv6_set = 1;
13219           src_set = 1;
13220         }
13221       else
13222         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13223         {
13224           ipv6_set = 1;
13225           dst_set = 1;
13226         }
13227       else if (unformat (line_input, "group %U %U",
13228                          unformat_ip4_address, &dst.ip4,
13229                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13230         {
13231           grp_set = dst_set = 1;
13232           ipv4_set = 1;
13233         }
13234       else if (unformat (line_input, "group %U",
13235                          unformat_ip4_address, &dst.ip4))
13236         {
13237           grp_set = dst_set = 1;
13238           ipv4_set = 1;
13239         }
13240       else if (unformat (line_input, "group %U %U",
13241                          unformat_ip6_address, &dst.ip6,
13242                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13243         {
13244           grp_set = dst_set = 1;
13245           ipv6_set = 1;
13246         }
13247       else if (unformat (line_input, "group %U",
13248                          unformat_ip6_address, &dst.ip6))
13249         {
13250           grp_set = dst_set = 1;
13251           ipv6_set = 1;
13252         }
13253       else
13254         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13255         ;
13256       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13257         ;
13258       else if (unformat (line_input, "decap-next %U",
13259                          unformat_vxlan_decap_next, &decap_next_index))
13260         ;
13261       else if (unformat (line_input, "vni %d", &vni))
13262         ;
13263       else
13264         {
13265           errmsg ("parse error '%U'", format_unformat_error, line_input);
13266           return -99;
13267         }
13268     }
13269
13270   if (src_set == 0)
13271     {
13272       errmsg ("tunnel src address not specified");
13273       return -99;
13274     }
13275   if (dst_set == 0)
13276     {
13277       errmsg ("tunnel dst address not specified");
13278       return -99;
13279     }
13280
13281   if (grp_set && !ip46_address_is_multicast (&dst))
13282     {
13283       errmsg ("tunnel group address not multicast");
13284       return -99;
13285     }
13286   if (grp_set && mcast_sw_if_index == ~0)
13287     {
13288       errmsg ("tunnel nonexistent multicast device");
13289       return -99;
13290     }
13291   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13292     {
13293       errmsg ("tunnel dst address must be unicast");
13294       return -99;
13295     }
13296
13297
13298   if (ipv4_set && ipv6_set)
13299     {
13300       errmsg ("both IPv4 and IPv6 addresses specified");
13301       return -99;
13302     }
13303
13304   if ((vni == 0) || (vni >> 24))
13305     {
13306       errmsg ("vni not specified or out of range");
13307       return -99;
13308     }
13309
13310   M (VXLAN_ADD_DEL_TUNNEL, mp);
13311
13312   if (ipv6_set)
13313     {
13314       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13315       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13316     }
13317   else
13318     {
13319       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13320       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13321     }
13322
13323   mp->instance = htonl (instance);
13324   mp->encap_vrf_id = ntohl (encap_vrf_id);
13325   mp->decap_next_index = ntohl (decap_next_index);
13326   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13327   mp->vni = ntohl (vni);
13328   mp->is_add = is_add;
13329   mp->is_ipv6 = ipv6_set;
13330
13331   S (mp);
13332   W (ret);
13333   return ret;
13334 }
13335
13336 static void vl_api_vxlan_tunnel_details_t_handler
13337   (vl_api_vxlan_tunnel_details_t * mp)
13338 {
13339   vat_main_t *vam = &vat_main;
13340   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13341   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13342
13343   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13344          ntohl (mp->sw_if_index),
13345          ntohl (mp->instance),
13346          format_ip46_address, &src, IP46_TYPE_ANY,
13347          format_ip46_address, &dst, IP46_TYPE_ANY,
13348          ntohl (mp->encap_vrf_id),
13349          ntohl (mp->decap_next_index), ntohl (mp->vni),
13350          ntohl (mp->mcast_sw_if_index));
13351 }
13352
13353 static void vl_api_vxlan_tunnel_details_t_handler_json
13354   (vl_api_vxlan_tunnel_details_t * mp)
13355 {
13356   vat_main_t *vam = &vat_main;
13357   vat_json_node_t *node = NULL;
13358
13359   if (VAT_JSON_ARRAY != vam->json_tree.type)
13360     {
13361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13362       vat_json_init_array (&vam->json_tree);
13363     }
13364   node = vat_json_array_add (&vam->json_tree);
13365
13366   vat_json_init_object (node);
13367   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13368
13369   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13370
13371   if (mp->is_ipv6)
13372     {
13373       struct in6_addr ip6;
13374
13375       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13376       vat_json_object_add_ip6 (node, "src_address", ip6);
13377       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13378       vat_json_object_add_ip6 (node, "dst_address", ip6);
13379     }
13380   else
13381     {
13382       struct in_addr ip4;
13383
13384       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13385       vat_json_object_add_ip4 (node, "src_address", ip4);
13386       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13387       vat_json_object_add_ip4 (node, "dst_address", ip4);
13388     }
13389   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13390   vat_json_object_add_uint (node, "decap_next_index",
13391                             ntohl (mp->decap_next_index));
13392   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13393   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13394   vat_json_object_add_uint (node, "mcast_sw_if_index",
13395                             ntohl (mp->mcast_sw_if_index));
13396 }
13397
13398 static int
13399 api_vxlan_tunnel_dump (vat_main_t * vam)
13400 {
13401   unformat_input_t *i = vam->input;
13402   vl_api_vxlan_tunnel_dump_t *mp;
13403   vl_api_control_ping_t *mp_ping;
13404   u32 sw_if_index;
13405   u8 sw_if_index_set = 0;
13406   int ret;
13407
13408   /* Parse args required to build the message */
13409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13410     {
13411       if (unformat (i, "sw_if_index %d", &sw_if_index))
13412         sw_if_index_set = 1;
13413       else
13414         break;
13415     }
13416
13417   if (sw_if_index_set == 0)
13418     {
13419       sw_if_index = ~0;
13420     }
13421
13422   if (!vam->json_output)
13423     {
13424       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13425              "sw_if_index", "instance", "src_address", "dst_address",
13426              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13427     }
13428
13429   /* Get list of vxlan-tunnel interfaces */
13430   M (VXLAN_TUNNEL_DUMP, mp);
13431
13432   mp->sw_if_index = htonl (sw_if_index);
13433
13434   S (mp);
13435
13436   /* Use a control ping for synchronization */
13437   MPING (CONTROL_PING, mp_ping);
13438   S (mp_ping);
13439
13440   W (ret);
13441   return ret;
13442 }
13443
13444 static uword unformat_geneve_decap_next
13445   (unformat_input_t * input, va_list * args)
13446 {
13447   u32 *result = va_arg (*args, u32 *);
13448   u32 tmp;
13449
13450   if (unformat (input, "l2"))
13451     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13452   else if (unformat (input, "%d", &tmp))
13453     *result = tmp;
13454   else
13455     return 0;
13456   return 1;
13457 }
13458
13459 static int
13460 api_geneve_add_del_tunnel (vat_main_t * vam)
13461 {
13462   unformat_input_t *line_input = vam->input;
13463   vl_api_geneve_add_del_tunnel_t *mp;
13464   ip46_address_t src, dst;
13465   u8 is_add = 1;
13466   u8 ipv4_set = 0, ipv6_set = 0;
13467   u8 src_set = 0;
13468   u8 dst_set = 0;
13469   u8 grp_set = 0;
13470   u32 mcast_sw_if_index = ~0;
13471   u32 encap_vrf_id = 0;
13472   u32 decap_next_index = ~0;
13473   u32 vni = 0;
13474   int ret;
13475
13476   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13477   memset (&src, 0, sizeof src);
13478   memset (&dst, 0, sizeof dst);
13479
13480   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13481     {
13482       if (unformat (line_input, "del"))
13483         is_add = 0;
13484       else
13485         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13486         {
13487           ipv4_set = 1;
13488           src_set = 1;
13489         }
13490       else
13491         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13492         {
13493           ipv4_set = 1;
13494           dst_set = 1;
13495         }
13496       else
13497         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13498         {
13499           ipv6_set = 1;
13500           src_set = 1;
13501         }
13502       else
13503         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13504         {
13505           ipv6_set = 1;
13506           dst_set = 1;
13507         }
13508       else if (unformat (line_input, "group %U %U",
13509                          unformat_ip4_address, &dst.ip4,
13510                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13511         {
13512           grp_set = dst_set = 1;
13513           ipv4_set = 1;
13514         }
13515       else if (unformat (line_input, "group %U",
13516                          unformat_ip4_address, &dst.ip4))
13517         {
13518           grp_set = dst_set = 1;
13519           ipv4_set = 1;
13520         }
13521       else if (unformat (line_input, "group %U %U",
13522                          unformat_ip6_address, &dst.ip6,
13523                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13524         {
13525           grp_set = dst_set = 1;
13526           ipv6_set = 1;
13527         }
13528       else if (unformat (line_input, "group %U",
13529                          unformat_ip6_address, &dst.ip6))
13530         {
13531           grp_set = dst_set = 1;
13532           ipv6_set = 1;
13533         }
13534       else
13535         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13536         ;
13537       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13538         ;
13539       else if (unformat (line_input, "decap-next %U",
13540                          unformat_geneve_decap_next, &decap_next_index))
13541         ;
13542       else if (unformat (line_input, "vni %d", &vni))
13543         ;
13544       else
13545         {
13546           errmsg ("parse error '%U'", format_unformat_error, line_input);
13547           return -99;
13548         }
13549     }
13550
13551   if (src_set == 0)
13552     {
13553       errmsg ("tunnel src address not specified");
13554       return -99;
13555     }
13556   if (dst_set == 0)
13557     {
13558       errmsg ("tunnel dst address not specified");
13559       return -99;
13560     }
13561
13562   if (grp_set && !ip46_address_is_multicast (&dst))
13563     {
13564       errmsg ("tunnel group address not multicast");
13565       return -99;
13566     }
13567   if (grp_set && mcast_sw_if_index == ~0)
13568     {
13569       errmsg ("tunnel nonexistent multicast device");
13570       return -99;
13571     }
13572   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13573     {
13574       errmsg ("tunnel dst address must be unicast");
13575       return -99;
13576     }
13577
13578
13579   if (ipv4_set && ipv6_set)
13580     {
13581       errmsg ("both IPv4 and IPv6 addresses specified");
13582       return -99;
13583     }
13584
13585   if ((vni == 0) || (vni >> 24))
13586     {
13587       errmsg ("vni not specified or out of range");
13588       return -99;
13589     }
13590
13591   M (GENEVE_ADD_DEL_TUNNEL, mp);
13592
13593   if (ipv6_set)
13594     {
13595       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13596       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13597     }
13598   else
13599     {
13600       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13601       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13602     }
13603   mp->encap_vrf_id = ntohl (encap_vrf_id);
13604   mp->decap_next_index = ntohl (decap_next_index);
13605   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13606   mp->vni = ntohl (vni);
13607   mp->is_add = is_add;
13608   mp->is_ipv6 = ipv6_set;
13609
13610   S (mp);
13611   W (ret);
13612   return ret;
13613 }
13614
13615 static void vl_api_geneve_tunnel_details_t_handler
13616   (vl_api_geneve_tunnel_details_t * mp)
13617 {
13618   vat_main_t *vam = &vat_main;
13619   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13620   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13621
13622   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13623          ntohl (mp->sw_if_index),
13624          format_ip46_address, &src, IP46_TYPE_ANY,
13625          format_ip46_address, &dst, IP46_TYPE_ANY,
13626          ntohl (mp->encap_vrf_id),
13627          ntohl (mp->decap_next_index), ntohl (mp->vni),
13628          ntohl (mp->mcast_sw_if_index));
13629 }
13630
13631 static void vl_api_geneve_tunnel_details_t_handler_json
13632   (vl_api_geneve_tunnel_details_t * mp)
13633 {
13634   vat_main_t *vam = &vat_main;
13635   vat_json_node_t *node = NULL;
13636
13637   if (VAT_JSON_ARRAY != vam->json_tree.type)
13638     {
13639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13640       vat_json_init_array (&vam->json_tree);
13641     }
13642   node = vat_json_array_add (&vam->json_tree);
13643
13644   vat_json_init_object (node);
13645   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13646   if (mp->is_ipv6)
13647     {
13648       struct in6_addr ip6;
13649
13650       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13651       vat_json_object_add_ip6 (node, "src_address", ip6);
13652       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13653       vat_json_object_add_ip6 (node, "dst_address", ip6);
13654     }
13655   else
13656     {
13657       struct in_addr ip4;
13658
13659       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13660       vat_json_object_add_ip4 (node, "src_address", ip4);
13661       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13662       vat_json_object_add_ip4 (node, "dst_address", ip4);
13663     }
13664   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13665   vat_json_object_add_uint (node, "decap_next_index",
13666                             ntohl (mp->decap_next_index));
13667   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13668   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13669   vat_json_object_add_uint (node, "mcast_sw_if_index",
13670                             ntohl (mp->mcast_sw_if_index));
13671 }
13672
13673 static int
13674 api_geneve_tunnel_dump (vat_main_t * vam)
13675 {
13676   unformat_input_t *i = vam->input;
13677   vl_api_geneve_tunnel_dump_t *mp;
13678   vl_api_control_ping_t *mp_ping;
13679   u32 sw_if_index;
13680   u8 sw_if_index_set = 0;
13681   int ret;
13682
13683   /* Parse args required to build the message */
13684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (i, "sw_if_index %d", &sw_if_index))
13687         sw_if_index_set = 1;
13688       else
13689         break;
13690     }
13691
13692   if (sw_if_index_set == 0)
13693     {
13694       sw_if_index = ~0;
13695     }
13696
13697   if (!vam->json_output)
13698     {
13699       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13700              "sw_if_index", "local_address", "remote_address",
13701              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13702     }
13703
13704   /* Get list of geneve-tunnel interfaces */
13705   M (GENEVE_TUNNEL_DUMP, mp);
13706
13707   mp->sw_if_index = htonl (sw_if_index);
13708
13709   S (mp);
13710
13711   /* Use a control ping for synchronization */
13712   M (CONTROL_PING, mp_ping);
13713   S (mp_ping);
13714
13715   W (ret);
13716   return ret;
13717 }
13718
13719 static int
13720 api_gre_add_del_tunnel (vat_main_t * vam)
13721 {
13722   unformat_input_t *line_input = vam->input;
13723   vl_api_gre_add_del_tunnel_t *mp;
13724   ip4_address_t src4, dst4;
13725   ip6_address_t src6, dst6;
13726   u8 is_add = 1;
13727   u8 ipv4_set = 0;
13728   u8 ipv6_set = 0;
13729   u8 t_type = GRE_TUNNEL_TYPE_L3;
13730   u8 src_set = 0;
13731   u8 dst_set = 0;
13732   u32 outer_fib_id = 0;
13733   u32 session_id = 0;
13734   u32 instance = ~0;
13735   int ret;
13736
13737   memset (&src4, 0, sizeof src4);
13738   memset (&dst4, 0, sizeof dst4);
13739   memset (&src6, 0, sizeof src6);
13740   memset (&dst6, 0, sizeof dst6);
13741
13742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13743     {
13744       if (unformat (line_input, "del"))
13745         is_add = 0;
13746       else if (unformat (line_input, "instance %d", &instance))
13747         ;
13748       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13749         {
13750           src_set = 1;
13751           ipv4_set = 1;
13752         }
13753       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13754         {
13755           dst_set = 1;
13756           ipv4_set = 1;
13757         }
13758       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13759         {
13760           src_set = 1;
13761           ipv6_set = 1;
13762         }
13763       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13764         {
13765           dst_set = 1;
13766           ipv6_set = 1;
13767         }
13768       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13769         ;
13770       else if (unformat (line_input, "teb"))
13771         t_type = GRE_TUNNEL_TYPE_TEB;
13772       else if (unformat (line_input, "erspan %d", &session_id))
13773         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13774       else
13775         {
13776           errmsg ("parse error '%U'", format_unformat_error, line_input);
13777           return -99;
13778         }
13779     }
13780
13781   if (src_set == 0)
13782     {
13783       errmsg ("tunnel src address not specified");
13784       return -99;
13785     }
13786   if (dst_set == 0)
13787     {
13788       errmsg ("tunnel dst address not specified");
13789       return -99;
13790     }
13791   if (ipv4_set && ipv6_set)
13792     {
13793       errmsg ("both IPv4 and IPv6 addresses specified");
13794       return -99;
13795     }
13796
13797
13798   M (GRE_ADD_DEL_TUNNEL, mp);
13799
13800   if (ipv4_set)
13801     {
13802       clib_memcpy (&mp->src_address, &src4, 4);
13803       clib_memcpy (&mp->dst_address, &dst4, 4);
13804     }
13805   else
13806     {
13807       clib_memcpy (&mp->src_address, &src6, 16);
13808       clib_memcpy (&mp->dst_address, &dst6, 16);
13809     }
13810   mp->instance = htonl (instance);
13811   mp->outer_fib_id = htonl (outer_fib_id);
13812   mp->is_add = is_add;
13813   mp->session_id = htons ((u16) session_id);
13814   mp->tunnel_type = t_type;
13815   mp->is_ipv6 = ipv6_set;
13816
13817   S (mp);
13818   W (ret);
13819   return ret;
13820 }
13821
13822 static void vl_api_gre_tunnel_details_t_handler
13823   (vl_api_gre_tunnel_details_t * mp)
13824 {
13825   vat_main_t *vam = &vat_main;
13826   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13827   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13828
13829   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13830          ntohl (mp->sw_if_index),
13831          ntohl (mp->instance),
13832          format_ip46_address, &src, IP46_TYPE_ANY,
13833          format_ip46_address, &dst, IP46_TYPE_ANY,
13834          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13835 }
13836
13837 static void vl_api_gre_tunnel_details_t_handler_json
13838   (vl_api_gre_tunnel_details_t * mp)
13839 {
13840   vat_main_t *vam = &vat_main;
13841   vat_json_node_t *node = NULL;
13842   struct in_addr ip4;
13843   struct in6_addr ip6;
13844
13845   if (VAT_JSON_ARRAY != vam->json_tree.type)
13846     {
13847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13848       vat_json_init_array (&vam->json_tree);
13849     }
13850   node = vat_json_array_add (&vam->json_tree);
13851
13852   vat_json_init_object (node);
13853   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13854   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13855   if (!mp->is_ipv6)
13856     {
13857       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13858       vat_json_object_add_ip4 (node, "src_address", ip4);
13859       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13860       vat_json_object_add_ip4 (node, "dst_address", ip4);
13861     }
13862   else
13863     {
13864       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13865       vat_json_object_add_ip6 (node, "src_address", ip6);
13866       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13867       vat_json_object_add_ip6 (node, "dst_address", ip6);
13868     }
13869   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13870   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13871   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13872   vat_json_object_add_uint (node, "session_id", mp->session_id);
13873 }
13874
13875 static int
13876 api_gre_tunnel_dump (vat_main_t * vam)
13877 {
13878   unformat_input_t *i = vam->input;
13879   vl_api_gre_tunnel_dump_t *mp;
13880   vl_api_control_ping_t *mp_ping;
13881   u32 sw_if_index;
13882   u8 sw_if_index_set = 0;
13883   int ret;
13884
13885   /* Parse args required to build the message */
13886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (i, "sw_if_index %d", &sw_if_index))
13889         sw_if_index_set = 1;
13890       else
13891         break;
13892     }
13893
13894   if (sw_if_index_set == 0)
13895     {
13896       sw_if_index = ~0;
13897     }
13898
13899   if (!vam->json_output)
13900     {
13901       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13902              "sw_if_index", "instance", "src_address", "dst_address",
13903              "tunnel_type", "outer_fib_id", "session_id");
13904     }
13905
13906   /* Get list of gre-tunnel interfaces */
13907   M (GRE_TUNNEL_DUMP, mp);
13908
13909   mp->sw_if_index = htonl (sw_if_index);
13910
13911   S (mp);
13912
13913   /* Use a control ping for synchronization */
13914   MPING (CONTROL_PING, mp_ping);
13915   S (mp_ping);
13916
13917   W (ret);
13918   return ret;
13919 }
13920
13921 static int
13922 api_l2_fib_clear_table (vat_main_t * vam)
13923 {
13924 //  unformat_input_t * i = vam->input;
13925   vl_api_l2_fib_clear_table_t *mp;
13926   int ret;
13927
13928   M (L2_FIB_CLEAR_TABLE, mp);
13929
13930   S (mp);
13931   W (ret);
13932   return ret;
13933 }
13934
13935 static int
13936 api_l2_interface_efp_filter (vat_main_t * vam)
13937 {
13938   unformat_input_t *i = vam->input;
13939   vl_api_l2_interface_efp_filter_t *mp;
13940   u32 sw_if_index;
13941   u8 enable = 1;
13942   u8 sw_if_index_set = 0;
13943   int ret;
13944
13945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13946     {
13947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13948         sw_if_index_set = 1;
13949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13950         sw_if_index_set = 1;
13951       else if (unformat (i, "enable"))
13952         enable = 1;
13953       else if (unformat (i, "disable"))
13954         enable = 0;
13955       else
13956         {
13957           clib_warning ("parse error '%U'", format_unformat_error, i);
13958           return -99;
13959         }
13960     }
13961
13962   if (sw_if_index_set == 0)
13963     {
13964       errmsg ("missing sw_if_index");
13965       return -99;
13966     }
13967
13968   M (L2_INTERFACE_EFP_FILTER, mp);
13969
13970   mp->sw_if_index = ntohl (sw_if_index);
13971   mp->enable_disable = enable;
13972
13973   S (mp);
13974   W (ret);
13975   return ret;
13976 }
13977
13978 #define foreach_vtr_op                          \
13979 _("disable",  L2_VTR_DISABLED)                  \
13980 _("push-1",  L2_VTR_PUSH_1)                     \
13981 _("push-2",  L2_VTR_PUSH_2)                     \
13982 _("pop-1",  L2_VTR_POP_1)                       \
13983 _("pop-2",  L2_VTR_POP_2)                       \
13984 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13985 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13986 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13987 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13988
13989 static int
13990 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13991 {
13992   unformat_input_t *i = vam->input;
13993   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13994   u32 sw_if_index;
13995   u8 sw_if_index_set = 0;
13996   u8 vtr_op_set = 0;
13997   u32 vtr_op = 0;
13998   u32 push_dot1q = 1;
13999   u32 tag1 = ~0;
14000   u32 tag2 = ~0;
14001   int ret;
14002
14003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14004     {
14005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14006         sw_if_index_set = 1;
14007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14008         sw_if_index_set = 1;
14009       else if (unformat (i, "vtr_op %d", &vtr_op))
14010         vtr_op_set = 1;
14011 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14012       foreach_vtr_op
14013 #undef _
14014         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14015         ;
14016       else if (unformat (i, "tag1 %d", &tag1))
14017         ;
14018       else if (unformat (i, "tag2 %d", &tag2))
14019         ;
14020       else
14021         {
14022           clib_warning ("parse error '%U'", format_unformat_error, i);
14023           return -99;
14024         }
14025     }
14026
14027   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14028     {
14029       errmsg ("missing vtr operation or sw_if_index");
14030       return -99;
14031     }
14032
14033   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14034   mp->sw_if_index = ntohl (sw_if_index);
14035   mp->vtr_op = ntohl (vtr_op);
14036   mp->push_dot1q = ntohl (push_dot1q);
14037   mp->tag1 = ntohl (tag1);
14038   mp->tag2 = ntohl (tag2);
14039
14040   S (mp);
14041   W (ret);
14042   return ret;
14043 }
14044
14045 static int
14046 api_create_vhost_user_if (vat_main_t * vam)
14047 {
14048   unformat_input_t *i = vam->input;
14049   vl_api_create_vhost_user_if_t *mp;
14050   u8 *file_name;
14051   u8 is_server = 0;
14052   u8 file_name_set = 0;
14053   u32 custom_dev_instance = ~0;
14054   u8 hwaddr[6];
14055   u8 use_custom_mac = 0;
14056   u8 disable_mrg_rxbuf = 0;
14057   u8 disable_indirect_desc = 0;
14058   u8 *tag = 0;
14059   int ret;
14060
14061   /* Shut up coverity */
14062   memset (hwaddr, 0, sizeof (hwaddr));
14063
14064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14065     {
14066       if (unformat (i, "socket %s", &file_name))
14067         {
14068           file_name_set = 1;
14069         }
14070       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14071         ;
14072       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14073         use_custom_mac = 1;
14074       else if (unformat (i, "server"))
14075         is_server = 1;
14076       else if (unformat (i, "disable_mrg_rxbuf"))
14077         disable_mrg_rxbuf = 1;
14078       else if (unformat (i, "disable_indirect_desc"))
14079         disable_indirect_desc = 1;
14080       else if (unformat (i, "tag %s", &tag))
14081         ;
14082       else
14083         break;
14084     }
14085
14086   if (file_name_set == 0)
14087     {
14088       errmsg ("missing socket file name");
14089       return -99;
14090     }
14091
14092   if (vec_len (file_name) > 255)
14093     {
14094       errmsg ("socket file name too long");
14095       return -99;
14096     }
14097   vec_add1 (file_name, 0);
14098
14099   M (CREATE_VHOST_USER_IF, mp);
14100
14101   mp->is_server = is_server;
14102   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14103   mp->disable_indirect_desc = disable_indirect_desc;
14104   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14105   vec_free (file_name);
14106   if (custom_dev_instance != ~0)
14107     {
14108       mp->renumber = 1;
14109       mp->custom_dev_instance = ntohl (custom_dev_instance);
14110     }
14111
14112   mp->use_custom_mac = use_custom_mac;
14113   clib_memcpy (mp->mac_address, hwaddr, 6);
14114   if (tag)
14115     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14116   vec_free (tag);
14117
14118   S (mp);
14119   W (ret);
14120   return ret;
14121 }
14122
14123 static int
14124 api_modify_vhost_user_if (vat_main_t * vam)
14125 {
14126   unformat_input_t *i = vam->input;
14127   vl_api_modify_vhost_user_if_t *mp;
14128   u8 *file_name;
14129   u8 is_server = 0;
14130   u8 file_name_set = 0;
14131   u32 custom_dev_instance = ~0;
14132   u8 sw_if_index_set = 0;
14133   u32 sw_if_index = (u32) ~ 0;
14134   int ret;
14135
14136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14137     {
14138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14139         sw_if_index_set = 1;
14140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14141         sw_if_index_set = 1;
14142       else if (unformat (i, "socket %s", &file_name))
14143         {
14144           file_name_set = 1;
14145         }
14146       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14147         ;
14148       else if (unformat (i, "server"))
14149         is_server = 1;
14150       else
14151         break;
14152     }
14153
14154   if (sw_if_index_set == 0)
14155     {
14156       errmsg ("missing sw_if_index or interface name");
14157       return -99;
14158     }
14159
14160   if (file_name_set == 0)
14161     {
14162       errmsg ("missing socket file name");
14163       return -99;
14164     }
14165
14166   if (vec_len (file_name) > 255)
14167     {
14168       errmsg ("socket file name too long");
14169       return -99;
14170     }
14171   vec_add1 (file_name, 0);
14172
14173   M (MODIFY_VHOST_USER_IF, mp);
14174
14175   mp->sw_if_index = ntohl (sw_if_index);
14176   mp->is_server = is_server;
14177   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14178   vec_free (file_name);
14179   if (custom_dev_instance != ~0)
14180     {
14181       mp->renumber = 1;
14182       mp->custom_dev_instance = ntohl (custom_dev_instance);
14183     }
14184
14185   S (mp);
14186   W (ret);
14187   return ret;
14188 }
14189
14190 static int
14191 api_delete_vhost_user_if (vat_main_t * vam)
14192 {
14193   unformat_input_t *i = vam->input;
14194   vl_api_delete_vhost_user_if_t *mp;
14195   u32 sw_if_index = ~0;
14196   u8 sw_if_index_set = 0;
14197   int ret;
14198
14199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14200     {
14201       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14202         sw_if_index_set = 1;
14203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14204         sw_if_index_set = 1;
14205       else
14206         break;
14207     }
14208
14209   if (sw_if_index_set == 0)
14210     {
14211       errmsg ("missing sw_if_index or interface name");
14212       return -99;
14213     }
14214
14215
14216   M (DELETE_VHOST_USER_IF, mp);
14217
14218   mp->sw_if_index = ntohl (sw_if_index);
14219
14220   S (mp);
14221   W (ret);
14222   return ret;
14223 }
14224
14225 static void vl_api_sw_interface_vhost_user_details_t_handler
14226   (vl_api_sw_interface_vhost_user_details_t * mp)
14227 {
14228   vat_main_t *vam = &vat_main;
14229
14230   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14231          (char *) mp->interface_name,
14232          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14233          clib_net_to_host_u64 (mp->features), mp->is_server,
14234          ntohl (mp->num_regions), (char *) mp->sock_filename);
14235   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14236 }
14237
14238 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14239   (vl_api_sw_interface_vhost_user_details_t * mp)
14240 {
14241   vat_main_t *vam = &vat_main;
14242   vat_json_node_t *node = NULL;
14243
14244   if (VAT_JSON_ARRAY != vam->json_tree.type)
14245     {
14246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14247       vat_json_init_array (&vam->json_tree);
14248     }
14249   node = vat_json_array_add (&vam->json_tree);
14250
14251   vat_json_init_object (node);
14252   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14253   vat_json_object_add_string_copy (node, "interface_name",
14254                                    mp->interface_name);
14255   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14256                             ntohl (mp->virtio_net_hdr_sz));
14257   vat_json_object_add_uint (node, "features",
14258                             clib_net_to_host_u64 (mp->features));
14259   vat_json_object_add_uint (node, "is_server", mp->is_server);
14260   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14261   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14262   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14263 }
14264
14265 static int
14266 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14267 {
14268   vl_api_sw_interface_vhost_user_dump_t *mp;
14269   vl_api_control_ping_t *mp_ping;
14270   int ret;
14271   print (vam->ofp,
14272          "Interface name            idx hdr_sz features server regions filename");
14273
14274   /* Get list of vhost-user interfaces */
14275   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14276   S (mp);
14277
14278   /* Use a control ping for synchronization */
14279   MPING (CONTROL_PING, mp_ping);
14280   S (mp_ping);
14281
14282   W (ret);
14283   return ret;
14284 }
14285
14286 static int
14287 api_show_version (vat_main_t * vam)
14288 {
14289   vl_api_show_version_t *mp;
14290   int ret;
14291
14292   M (SHOW_VERSION, mp);
14293
14294   S (mp);
14295   W (ret);
14296   return ret;
14297 }
14298
14299
14300 static int
14301 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14302 {
14303   unformat_input_t *line_input = vam->input;
14304   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14305   ip4_address_t local4, remote4;
14306   ip6_address_t local6, remote6;
14307   u8 is_add = 1;
14308   u8 ipv4_set = 0, ipv6_set = 0;
14309   u8 local_set = 0;
14310   u8 remote_set = 0;
14311   u8 grp_set = 0;
14312   u32 mcast_sw_if_index = ~0;
14313   u32 encap_vrf_id = 0;
14314   u32 decap_vrf_id = 0;
14315   u8 protocol = ~0;
14316   u32 vni;
14317   u8 vni_set = 0;
14318   int ret;
14319
14320   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14321   memset (&local4, 0, sizeof local4);
14322   memset (&remote4, 0, sizeof remote4);
14323   memset (&local6, 0, sizeof local6);
14324   memset (&remote6, 0, sizeof remote6);
14325
14326   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14327     {
14328       if (unformat (line_input, "del"))
14329         is_add = 0;
14330       else if (unformat (line_input, "local %U",
14331                          unformat_ip4_address, &local4))
14332         {
14333           local_set = 1;
14334           ipv4_set = 1;
14335         }
14336       else if (unformat (line_input, "remote %U",
14337                          unformat_ip4_address, &remote4))
14338         {
14339           remote_set = 1;
14340           ipv4_set = 1;
14341         }
14342       else if (unformat (line_input, "local %U",
14343                          unformat_ip6_address, &local6))
14344         {
14345           local_set = 1;
14346           ipv6_set = 1;
14347         }
14348       else if (unformat (line_input, "remote %U",
14349                          unformat_ip6_address, &remote6))
14350         {
14351           remote_set = 1;
14352           ipv6_set = 1;
14353         }
14354       else if (unformat (line_input, "group %U %U",
14355                          unformat_ip4_address, &remote4,
14356                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14357         {
14358           grp_set = remote_set = 1;
14359           ipv4_set = 1;
14360         }
14361       else if (unformat (line_input, "group %U",
14362                          unformat_ip4_address, &remote4))
14363         {
14364           grp_set = remote_set = 1;
14365           ipv4_set = 1;
14366         }
14367       else if (unformat (line_input, "group %U %U",
14368                          unformat_ip6_address, &remote6,
14369                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14370         {
14371           grp_set = remote_set = 1;
14372           ipv6_set = 1;
14373         }
14374       else if (unformat (line_input, "group %U",
14375                          unformat_ip6_address, &remote6))
14376         {
14377           grp_set = remote_set = 1;
14378           ipv6_set = 1;
14379         }
14380       else
14381         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14382         ;
14383       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14384         ;
14385       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14386         ;
14387       else if (unformat (line_input, "vni %d", &vni))
14388         vni_set = 1;
14389       else if (unformat (line_input, "next-ip4"))
14390         protocol = 1;
14391       else if (unformat (line_input, "next-ip6"))
14392         protocol = 2;
14393       else if (unformat (line_input, "next-ethernet"))
14394         protocol = 3;
14395       else if (unformat (line_input, "next-nsh"))
14396         protocol = 4;
14397       else
14398         {
14399           errmsg ("parse error '%U'", format_unformat_error, line_input);
14400           return -99;
14401         }
14402     }
14403
14404   if (local_set == 0)
14405     {
14406       errmsg ("tunnel local address not specified");
14407       return -99;
14408     }
14409   if (remote_set == 0)
14410     {
14411       errmsg ("tunnel remote address not specified");
14412       return -99;
14413     }
14414   if (grp_set && mcast_sw_if_index == ~0)
14415     {
14416       errmsg ("tunnel nonexistent multicast device");
14417       return -99;
14418     }
14419   if (ipv4_set && ipv6_set)
14420     {
14421       errmsg ("both IPv4 and IPv6 addresses specified");
14422       return -99;
14423     }
14424
14425   if (vni_set == 0)
14426     {
14427       errmsg ("vni not specified");
14428       return -99;
14429     }
14430
14431   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14432
14433
14434   if (ipv6_set)
14435     {
14436       clib_memcpy (&mp->local, &local6, sizeof (local6));
14437       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14438     }
14439   else
14440     {
14441       clib_memcpy (&mp->local, &local4, sizeof (local4));
14442       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14443     }
14444
14445   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14446   mp->encap_vrf_id = ntohl (encap_vrf_id);
14447   mp->decap_vrf_id = ntohl (decap_vrf_id);
14448   mp->protocol = protocol;
14449   mp->vni = ntohl (vni);
14450   mp->is_add = is_add;
14451   mp->is_ipv6 = ipv6_set;
14452
14453   S (mp);
14454   W (ret);
14455   return ret;
14456 }
14457
14458 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14459   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14460 {
14461   vat_main_t *vam = &vat_main;
14462   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14463   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14464
14465   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14466          ntohl (mp->sw_if_index),
14467          format_ip46_address, &local, IP46_TYPE_ANY,
14468          format_ip46_address, &remote, IP46_TYPE_ANY,
14469          ntohl (mp->vni), mp->protocol,
14470          ntohl (mp->mcast_sw_if_index),
14471          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14472 }
14473
14474
14475 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14476   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14477 {
14478   vat_main_t *vam = &vat_main;
14479   vat_json_node_t *node = NULL;
14480   struct in_addr ip4;
14481   struct in6_addr ip6;
14482
14483   if (VAT_JSON_ARRAY != vam->json_tree.type)
14484     {
14485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14486       vat_json_init_array (&vam->json_tree);
14487     }
14488   node = vat_json_array_add (&vam->json_tree);
14489
14490   vat_json_init_object (node);
14491   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14492   if (mp->is_ipv6)
14493     {
14494       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14495       vat_json_object_add_ip6 (node, "local", ip6);
14496       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14497       vat_json_object_add_ip6 (node, "remote", ip6);
14498     }
14499   else
14500     {
14501       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14502       vat_json_object_add_ip4 (node, "local", ip4);
14503       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14504       vat_json_object_add_ip4 (node, "remote", ip4);
14505     }
14506   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14507   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14508   vat_json_object_add_uint (node, "mcast_sw_if_index",
14509                             ntohl (mp->mcast_sw_if_index));
14510   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14511   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14512   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14513 }
14514
14515 static int
14516 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14517 {
14518   unformat_input_t *i = vam->input;
14519   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14520   vl_api_control_ping_t *mp_ping;
14521   u32 sw_if_index;
14522   u8 sw_if_index_set = 0;
14523   int ret;
14524
14525   /* Parse args required to build the message */
14526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14527     {
14528       if (unformat (i, "sw_if_index %d", &sw_if_index))
14529         sw_if_index_set = 1;
14530       else
14531         break;
14532     }
14533
14534   if (sw_if_index_set == 0)
14535     {
14536       sw_if_index = ~0;
14537     }
14538
14539   if (!vam->json_output)
14540     {
14541       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14542              "sw_if_index", "local", "remote", "vni",
14543              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14544     }
14545
14546   /* Get list of vxlan-tunnel interfaces */
14547   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14548
14549   mp->sw_if_index = htonl (sw_if_index);
14550
14551   S (mp);
14552
14553   /* Use a control ping for synchronization */
14554   MPING (CONTROL_PING, mp_ping);
14555   S (mp_ping);
14556
14557   W (ret);
14558   return ret;
14559 }
14560
14561 static void vl_api_l2_fib_table_details_t_handler
14562   (vl_api_l2_fib_table_details_t * mp)
14563 {
14564   vat_main_t *vam = &vat_main;
14565
14566   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14567          "       %d       %d     %d",
14568          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14569          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14570          mp->bvi_mac);
14571 }
14572
14573 static void vl_api_l2_fib_table_details_t_handler_json
14574   (vl_api_l2_fib_table_details_t * mp)
14575 {
14576   vat_main_t *vam = &vat_main;
14577   vat_json_node_t *node = NULL;
14578
14579   if (VAT_JSON_ARRAY != vam->json_tree.type)
14580     {
14581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14582       vat_json_init_array (&vam->json_tree);
14583     }
14584   node = vat_json_array_add (&vam->json_tree);
14585
14586   vat_json_init_object (node);
14587   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14588   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14589   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14590   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14591   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14592   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14593 }
14594
14595 static int
14596 api_l2_fib_table_dump (vat_main_t * vam)
14597 {
14598   unformat_input_t *i = vam->input;
14599   vl_api_l2_fib_table_dump_t *mp;
14600   vl_api_control_ping_t *mp_ping;
14601   u32 bd_id;
14602   u8 bd_id_set = 0;
14603   int ret;
14604
14605   /* Parse args required to build the message */
14606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14607     {
14608       if (unformat (i, "bd_id %d", &bd_id))
14609         bd_id_set = 1;
14610       else
14611         break;
14612     }
14613
14614   if (bd_id_set == 0)
14615     {
14616       errmsg ("missing bridge domain");
14617       return -99;
14618     }
14619
14620   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14621
14622   /* Get list of l2 fib entries */
14623   M (L2_FIB_TABLE_DUMP, mp);
14624
14625   mp->bd_id = ntohl (bd_id);
14626   S (mp);
14627
14628   /* Use a control ping for synchronization */
14629   MPING (CONTROL_PING, mp_ping);
14630   S (mp_ping);
14631
14632   W (ret);
14633   return ret;
14634 }
14635
14636
14637 static int
14638 api_interface_name_renumber (vat_main_t * vam)
14639 {
14640   unformat_input_t *line_input = vam->input;
14641   vl_api_interface_name_renumber_t *mp;
14642   u32 sw_if_index = ~0;
14643   u32 new_show_dev_instance = ~0;
14644   int ret;
14645
14646   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14647     {
14648       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14649                     &sw_if_index))
14650         ;
14651       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14652         ;
14653       else if (unformat (line_input, "new_show_dev_instance %d",
14654                          &new_show_dev_instance))
14655         ;
14656       else
14657         break;
14658     }
14659
14660   if (sw_if_index == ~0)
14661     {
14662       errmsg ("missing interface name or sw_if_index");
14663       return -99;
14664     }
14665
14666   if (new_show_dev_instance == ~0)
14667     {
14668       errmsg ("missing new_show_dev_instance");
14669       return -99;
14670     }
14671
14672   M (INTERFACE_NAME_RENUMBER, mp);
14673
14674   mp->sw_if_index = ntohl (sw_if_index);
14675   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14676
14677   S (mp);
14678   W (ret);
14679   return ret;
14680 }
14681
14682 static int
14683 api_ip_probe_neighbor (vat_main_t * vam)
14684 {
14685   unformat_input_t *i = vam->input;
14686   vl_api_ip_probe_neighbor_t *mp;
14687   u8 int_set = 0;
14688   u8 adr_set = 0;
14689   u8 is_ipv6 = 0;
14690   u8 dst_adr[16];
14691   u32 sw_if_index;
14692   int ret;
14693
14694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14695     {
14696       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14697         int_set = 1;
14698       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14699         int_set = 1;
14700       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14701         adr_set = 1;
14702       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14703         {
14704           adr_set = 1;
14705           is_ipv6 = 1;
14706         }
14707       else
14708         break;
14709     }
14710
14711   if (int_set == 0)
14712     {
14713       errmsg ("missing interface");
14714       return -99;
14715     }
14716
14717   if (adr_set == 0)
14718     {
14719       errmsg ("missing addresses");
14720       return -99;
14721     }
14722
14723   M (IP_PROBE_NEIGHBOR, mp);
14724
14725   mp->sw_if_index = ntohl (sw_if_index);
14726   mp->is_ipv6 = is_ipv6;
14727   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14728
14729   S (mp);
14730   W (ret);
14731   return ret;
14732 }
14733
14734 static int
14735 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14736 {
14737   unformat_input_t *i = vam->input;
14738   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14739   u8 mode = IP_SCAN_V46_NEIGHBORS;
14740   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14741   int ret;
14742
14743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14744     {
14745       if (unformat (i, "ip4"))
14746         mode = IP_SCAN_V4_NEIGHBORS;
14747       else if (unformat (i, "ip6"))
14748         mode = IP_SCAN_V6_NEIGHBORS;
14749       if (unformat (i, "both"))
14750         mode = IP_SCAN_V46_NEIGHBORS;
14751       else if (unformat (i, "disable"))
14752         mode = IP_SCAN_DISABLED;
14753       else if (unformat (i, "interval %d", &interval))
14754         ;
14755       else if (unformat (i, "max-time %d", &time))
14756         ;
14757       else if (unformat (i, "max-update %d", &update))
14758         ;
14759       else if (unformat (i, "delay %d", &delay))
14760         ;
14761       else if (unformat (i, "stale %d", &stale))
14762         ;
14763       else
14764         break;
14765     }
14766
14767   if (interval > 255)
14768     {
14769       errmsg ("interval cannot exceed 255 minutes.");
14770       return -99;
14771     }
14772   if (time > 255)
14773     {
14774       errmsg ("max-time cannot exceed 255 usec.");
14775       return -99;
14776     }
14777   if (update > 255)
14778     {
14779       errmsg ("max-update cannot exceed 255.");
14780       return -99;
14781     }
14782   if (delay > 255)
14783     {
14784       errmsg ("delay cannot exceed 255 msec.");
14785       return -99;
14786     }
14787   if (stale > 255)
14788     {
14789       errmsg ("stale cannot exceed 255 minutes.");
14790       return -99;
14791     }
14792
14793   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14794   mp->mode = mode;
14795   mp->scan_interval = interval;
14796   mp->max_proc_time = time;
14797   mp->max_update = update;
14798   mp->scan_int_delay = delay;
14799   mp->stale_threshold = stale;
14800
14801   S (mp);
14802   W (ret);
14803   return ret;
14804 }
14805
14806 static int
14807 api_want_ip4_arp_events (vat_main_t * vam)
14808 {
14809   unformat_input_t *line_input = vam->input;
14810   vl_api_want_ip4_arp_events_t *mp;
14811   ip4_address_t address;
14812   int address_set = 0;
14813   u32 enable_disable = 1;
14814   int ret;
14815
14816   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14817     {
14818       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14819         address_set = 1;
14820       else if (unformat (line_input, "del"))
14821         enable_disable = 0;
14822       else
14823         break;
14824     }
14825
14826   if (address_set == 0)
14827     {
14828       errmsg ("missing addresses");
14829       return -99;
14830     }
14831
14832   M (WANT_IP4_ARP_EVENTS, mp);
14833   mp->enable_disable = enable_disable;
14834   mp->pid = htonl (getpid ());
14835   mp->address = address.as_u32;
14836
14837   S (mp);
14838   W (ret);
14839   return ret;
14840 }
14841
14842 static int
14843 api_want_ip6_nd_events (vat_main_t * vam)
14844 {
14845   unformat_input_t *line_input = vam->input;
14846   vl_api_want_ip6_nd_events_t *mp;
14847   ip6_address_t address;
14848   int address_set = 0;
14849   u32 enable_disable = 1;
14850   int ret;
14851
14852   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14853     {
14854       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14855         address_set = 1;
14856       else if (unformat (line_input, "del"))
14857         enable_disable = 0;
14858       else
14859         break;
14860     }
14861
14862   if (address_set == 0)
14863     {
14864       errmsg ("missing addresses");
14865       return -99;
14866     }
14867
14868   M (WANT_IP6_ND_EVENTS, mp);
14869   mp->enable_disable = enable_disable;
14870   mp->pid = htonl (getpid ());
14871   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14872
14873   S (mp);
14874   W (ret);
14875   return ret;
14876 }
14877
14878 static int
14879 api_want_l2_macs_events (vat_main_t * vam)
14880 {
14881   unformat_input_t *line_input = vam->input;
14882   vl_api_want_l2_macs_events_t *mp;
14883   u8 enable_disable = 1;
14884   u32 scan_delay = 0;
14885   u32 max_macs_in_event = 0;
14886   u32 learn_limit = 0;
14887   int ret;
14888
14889   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14890     {
14891       if (unformat (line_input, "learn-limit %d", &learn_limit))
14892         ;
14893       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14894         ;
14895       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14896         ;
14897       else if (unformat (line_input, "disable"))
14898         enable_disable = 0;
14899       else
14900         break;
14901     }
14902
14903   M (WANT_L2_MACS_EVENTS, mp);
14904   mp->enable_disable = enable_disable;
14905   mp->pid = htonl (getpid ());
14906   mp->learn_limit = htonl (learn_limit);
14907   mp->scan_delay = (u8) scan_delay;
14908   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14909   S (mp);
14910   W (ret);
14911   return ret;
14912 }
14913
14914 static int
14915 api_input_acl_set_interface (vat_main_t * vam)
14916 {
14917   unformat_input_t *i = vam->input;
14918   vl_api_input_acl_set_interface_t *mp;
14919   u32 sw_if_index;
14920   int sw_if_index_set;
14921   u32 ip4_table_index = ~0;
14922   u32 ip6_table_index = ~0;
14923   u32 l2_table_index = ~0;
14924   u8 is_add = 1;
14925   int ret;
14926
14927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14928     {
14929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14930         sw_if_index_set = 1;
14931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14932         sw_if_index_set = 1;
14933       else if (unformat (i, "del"))
14934         is_add = 0;
14935       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14936         ;
14937       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14938         ;
14939       else if (unformat (i, "l2-table %d", &l2_table_index))
14940         ;
14941       else
14942         {
14943           clib_warning ("parse error '%U'", format_unformat_error, i);
14944           return -99;
14945         }
14946     }
14947
14948   if (sw_if_index_set == 0)
14949     {
14950       errmsg ("missing interface name or sw_if_index");
14951       return -99;
14952     }
14953
14954   M (INPUT_ACL_SET_INTERFACE, mp);
14955
14956   mp->sw_if_index = ntohl (sw_if_index);
14957   mp->ip4_table_index = ntohl (ip4_table_index);
14958   mp->ip6_table_index = ntohl (ip6_table_index);
14959   mp->l2_table_index = ntohl (l2_table_index);
14960   mp->is_add = is_add;
14961
14962   S (mp);
14963   W (ret);
14964   return ret;
14965 }
14966
14967 static int
14968 api_output_acl_set_interface (vat_main_t * vam)
14969 {
14970   unformat_input_t *i = vam->input;
14971   vl_api_output_acl_set_interface_t *mp;
14972   u32 sw_if_index;
14973   int sw_if_index_set;
14974   u32 ip4_table_index = ~0;
14975   u32 ip6_table_index = ~0;
14976   u32 l2_table_index = ~0;
14977   u8 is_add = 1;
14978   int ret;
14979
14980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14981     {
14982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14983         sw_if_index_set = 1;
14984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14985         sw_if_index_set = 1;
14986       else if (unformat (i, "del"))
14987         is_add = 0;
14988       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14989         ;
14990       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14991         ;
14992       else if (unformat (i, "l2-table %d", &l2_table_index))
14993         ;
14994       else
14995         {
14996           clib_warning ("parse error '%U'", format_unformat_error, i);
14997           return -99;
14998         }
14999     }
15000
15001   if (sw_if_index_set == 0)
15002     {
15003       errmsg ("missing interface name or sw_if_index");
15004       return -99;
15005     }
15006
15007   M (OUTPUT_ACL_SET_INTERFACE, mp);
15008
15009   mp->sw_if_index = ntohl (sw_if_index);
15010   mp->ip4_table_index = ntohl (ip4_table_index);
15011   mp->ip6_table_index = ntohl (ip6_table_index);
15012   mp->l2_table_index = ntohl (l2_table_index);
15013   mp->is_add = is_add;
15014
15015   S (mp);
15016   W (ret);
15017   return ret;
15018 }
15019
15020 static int
15021 api_ip_address_dump (vat_main_t * vam)
15022 {
15023   unformat_input_t *i = vam->input;
15024   vl_api_ip_address_dump_t *mp;
15025   vl_api_control_ping_t *mp_ping;
15026   u32 sw_if_index = ~0;
15027   u8 sw_if_index_set = 0;
15028   u8 ipv4_set = 0;
15029   u8 ipv6_set = 0;
15030   int ret;
15031
15032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15033     {
15034       if (unformat (i, "sw_if_index %d", &sw_if_index))
15035         sw_if_index_set = 1;
15036       else
15037         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15038         sw_if_index_set = 1;
15039       else if (unformat (i, "ipv4"))
15040         ipv4_set = 1;
15041       else if (unformat (i, "ipv6"))
15042         ipv6_set = 1;
15043       else
15044         break;
15045     }
15046
15047   if (ipv4_set && ipv6_set)
15048     {
15049       errmsg ("ipv4 and ipv6 flags cannot be both set");
15050       return -99;
15051     }
15052
15053   if ((!ipv4_set) && (!ipv6_set))
15054     {
15055       errmsg ("no ipv4 nor ipv6 flag set");
15056       return -99;
15057     }
15058
15059   if (sw_if_index_set == 0)
15060     {
15061       errmsg ("missing interface name or sw_if_index");
15062       return -99;
15063     }
15064
15065   vam->current_sw_if_index = sw_if_index;
15066   vam->is_ipv6 = ipv6_set;
15067
15068   M (IP_ADDRESS_DUMP, mp);
15069   mp->sw_if_index = ntohl (sw_if_index);
15070   mp->is_ipv6 = ipv6_set;
15071   S (mp);
15072
15073   /* Use a control ping for synchronization */
15074   MPING (CONTROL_PING, mp_ping);
15075   S (mp_ping);
15076
15077   W (ret);
15078   return ret;
15079 }
15080
15081 static int
15082 api_ip_dump (vat_main_t * vam)
15083 {
15084   vl_api_ip_dump_t *mp;
15085   vl_api_control_ping_t *mp_ping;
15086   unformat_input_t *in = vam->input;
15087   int ipv4_set = 0;
15088   int ipv6_set = 0;
15089   int is_ipv6;
15090   int i;
15091   int ret;
15092
15093   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15094     {
15095       if (unformat (in, "ipv4"))
15096         ipv4_set = 1;
15097       else if (unformat (in, "ipv6"))
15098         ipv6_set = 1;
15099       else
15100         break;
15101     }
15102
15103   if (ipv4_set && ipv6_set)
15104     {
15105       errmsg ("ipv4 and ipv6 flags cannot be both set");
15106       return -99;
15107     }
15108
15109   if ((!ipv4_set) && (!ipv6_set))
15110     {
15111       errmsg ("no ipv4 nor ipv6 flag set");
15112       return -99;
15113     }
15114
15115   is_ipv6 = ipv6_set;
15116   vam->is_ipv6 = is_ipv6;
15117
15118   /* free old data */
15119   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15120     {
15121       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15122     }
15123   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15124
15125   M (IP_DUMP, mp);
15126   mp->is_ipv6 = ipv6_set;
15127   S (mp);
15128
15129   /* Use a control ping for synchronization */
15130   MPING (CONTROL_PING, mp_ping);
15131   S (mp_ping);
15132
15133   W (ret);
15134   return ret;
15135 }
15136
15137 static int
15138 api_ipsec_spd_add_del (vat_main_t * vam)
15139 {
15140   unformat_input_t *i = vam->input;
15141   vl_api_ipsec_spd_add_del_t *mp;
15142   u32 spd_id = ~0;
15143   u8 is_add = 1;
15144   int ret;
15145
15146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15147     {
15148       if (unformat (i, "spd_id %d", &spd_id))
15149         ;
15150       else if (unformat (i, "del"))
15151         is_add = 0;
15152       else
15153         {
15154           clib_warning ("parse error '%U'", format_unformat_error, i);
15155           return -99;
15156         }
15157     }
15158   if (spd_id == ~0)
15159     {
15160       errmsg ("spd_id must be set");
15161       return -99;
15162     }
15163
15164   M (IPSEC_SPD_ADD_DEL, mp);
15165
15166   mp->spd_id = ntohl (spd_id);
15167   mp->is_add = is_add;
15168
15169   S (mp);
15170   W (ret);
15171   return ret;
15172 }
15173
15174 static int
15175 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15176 {
15177   unformat_input_t *i = vam->input;
15178   vl_api_ipsec_interface_add_del_spd_t *mp;
15179   u32 sw_if_index;
15180   u8 sw_if_index_set = 0;
15181   u32 spd_id = (u32) ~ 0;
15182   u8 is_add = 1;
15183   int ret;
15184
15185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (i, "del"))
15188         is_add = 0;
15189       else if (unformat (i, "spd_id %d", &spd_id))
15190         ;
15191       else
15192         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15193         sw_if_index_set = 1;
15194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15195         sw_if_index_set = 1;
15196       else
15197         {
15198           clib_warning ("parse error '%U'", format_unformat_error, i);
15199           return -99;
15200         }
15201
15202     }
15203
15204   if (spd_id == (u32) ~ 0)
15205     {
15206       errmsg ("spd_id must be set");
15207       return -99;
15208     }
15209
15210   if (sw_if_index_set == 0)
15211     {
15212       errmsg ("missing interface name or sw_if_index");
15213       return -99;
15214     }
15215
15216   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15217
15218   mp->spd_id = ntohl (spd_id);
15219   mp->sw_if_index = ntohl (sw_if_index);
15220   mp->is_add = is_add;
15221
15222   S (mp);
15223   W (ret);
15224   return ret;
15225 }
15226
15227 static int
15228 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15229 {
15230   unformat_input_t *i = vam->input;
15231   vl_api_ipsec_spd_add_del_entry_t *mp;
15232   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15233   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15234   i32 priority = 0;
15235   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15236   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15237   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15238   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15239   int ret;
15240
15241   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15242   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15243   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15244   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15245   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15246   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15247
15248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15249     {
15250       if (unformat (i, "del"))
15251         is_add = 0;
15252       if (unformat (i, "outbound"))
15253         is_outbound = 1;
15254       if (unformat (i, "inbound"))
15255         is_outbound = 0;
15256       else if (unformat (i, "spd_id %d", &spd_id))
15257         ;
15258       else if (unformat (i, "sa_id %d", &sa_id))
15259         ;
15260       else if (unformat (i, "priority %d", &priority))
15261         ;
15262       else if (unformat (i, "protocol %d", &protocol))
15263         ;
15264       else if (unformat (i, "lport_start %d", &lport_start))
15265         ;
15266       else if (unformat (i, "lport_stop %d", &lport_stop))
15267         ;
15268       else if (unformat (i, "rport_start %d", &rport_start))
15269         ;
15270       else if (unformat (i, "rport_stop %d", &rport_stop))
15271         ;
15272       else
15273         if (unformat
15274             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15275         {
15276           is_ipv6 = 0;
15277           is_ip_any = 0;
15278         }
15279       else
15280         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15281         {
15282           is_ipv6 = 0;
15283           is_ip_any = 0;
15284         }
15285       else
15286         if (unformat
15287             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15288         {
15289           is_ipv6 = 0;
15290           is_ip_any = 0;
15291         }
15292       else
15293         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15294         {
15295           is_ipv6 = 0;
15296           is_ip_any = 0;
15297         }
15298       else
15299         if (unformat
15300             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15301         {
15302           is_ipv6 = 1;
15303           is_ip_any = 0;
15304         }
15305       else
15306         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15307         {
15308           is_ipv6 = 1;
15309           is_ip_any = 0;
15310         }
15311       else
15312         if (unformat
15313             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15314         {
15315           is_ipv6 = 1;
15316           is_ip_any = 0;
15317         }
15318       else
15319         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15320         {
15321           is_ipv6 = 1;
15322           is_ip_any = 0;
15323         }
15324       else
15325         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15326         {
15327           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15328             {
15329               clib_warning ("unsupported action: 'resolve'");
15330               return -99;
15331             }
15332         }
15333       else
15334         {
15335           clib_warning ("parse error '%U'", format_unformat_error, i);
15336           return -99;
15337         }
15338
15339     }
15340
15341   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15342
15343   mp->spd_id = ntohl (spd_id);
15344   mp->priority = ntohl (priority);
15345   mp->is_outbound = is_outbound;
15346
15347   mp->is_ipv6 = is_ipv6;
15348   if (is_ipv6 || is_ip_any)
15349     {
15350       clib_memcpy (mp->remote_address_start, &raddr6_start,
15351                    sizeof (ip6_address_t));
15352       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15353                    sizeof (ip6_address_t));
15354       clib_memcpy (mp->local_address_start, &laddr6_start,
15355                    sizeof (ip6_address_t));
15356       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15357                    sizeof (ip6_address_t));
15358     }
15359   else
15360     {
15361       clib_memcpy (mp->remote_address_start, &raddr4_start,
15362                    sizeof (ip4_address_t));
15363       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15364                    sizeof (ip4_address_t));
15365       clib_memcpy (mp->local_address_start, &laddr4_start,
15366                    sizeof (ip4_address_t));
15367       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15368                    sizeof (ip4_address_t));
15369     }
15370   mp->protocol = (u8) protocol;
15371   mp->local_port_start = ntohs ((u16) lport_start);
15372   mp->local_port_stop = ntohs ((u16) lport_stop);
15373   mp->remote_port_start = ntohs ((u16) rport_start);
15374   mp->remote_port_stop = ntohs ((u16) rport_stop);
15375   mp->policy = (u8) policy;
15376   mp->sa_id = ntohl (sa_id);
15377   mp->is_add = is_add;
15378   mp->is_ip_any = is_ip_any;
15379   S (mp);
15380   W (ret);
15381   return ret;
15382 }
15383
15384 static int
15385 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15386 {
15387   unformat_input_t *i = vam->input;
15388   vl_api_ipsec_sad_add_del_entry_t *mp;
15389   u32 sad_id = 0, spi = 0;
15390   u8 *ck = 0, *ik = 0;
15391   u8 is_add = 1;
15392
15393   u8 protocol = IPSEC_PROTOCOL_AH;
15394   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15395   u32 crypto_alg = 0, integ_alg = 0;
15396   ip4_address_t tun_src4;
15397   ip4_address_t tun_dst4;
15398   ip6_address_t tun_src6;
15399   ip6_address_t tun_dst6;
15400   int ret;
15401
15402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15403     {
15404       if (unformat (i, "del"))
15405         is_add = 0;
15406       else if (unformat (i, "sad_id %d", &sad_id))
15407         ;
15408       else if (unformat (i, "spi %d", &spi))
15409         ;
15410       else if (unformat (i, "esp"))
15411         protocol = IPSEC_PROTOCOL_ESP;
15412       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15413         {
15414           is_tunnel = 1;
15415           is_tunnel_ipv6 = 0;
15416         }
15417       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15418         {
15419           is_tunnel = 1;
15420           is_tunnel_ipv6 = 0;
15421         }
15422       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15423         {
15424           is_tunnel = 1;
15425           is_tunnel_ipv6 = 1;
15426         }
15427       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15428         {
15429           is_tunnel = 1;
15430           is_tunnel_ipv6 = 1;
15431         }
15432       else
15433         if (unformat
15434             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15435         {
15436           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15437             {
15438               clib_warning ("unsupported crypto-alg: '%U'",
15439                             format_ipsec_crypto_alg, crypto_alg);
15440               return -99;
15441             }
15442         }
15443       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15444         ;
15445       else
15446         if (unformat
15447             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15448         {
15449           if (integ_alg >= IPSEC_INTEG_N_ALG)
15450             {
15451               clib_warning ("unsupported integ-alg: '%U'",
15452                             format_ipsec_integ_alg, integ_alg);
15453               return -99;
15454             }
15455         }
15456       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15457         ;
15458       else
15459         {
15460           clib_warning ("parse error '%U'", format_unformat_error, i);
15461           return -99;
15462         }
15463
15464     }
15465
15466   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15467
15468   mp->sad_id = ntohl (sad_id);
15469   mp->is_add = is_add;
15470   mp->protocol = protocol;
15471   mp->spi = ntohl (spi);
15472   mp->is_tunnel = is_tunnel;
15473   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15474   mp->crypto_algorithm = crypto_alg;
15475   mp->integrity_algorithm = integ_alg;
15476   mp->crypto_key_length = vec_len (ck);
15477   mp->integrity_key_length = vec_len (ik);
15478
15479   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15480     mp->crypto_key_length = sizeof (mp->crypto_key);
15481
15482   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15483     mp->integrity_key_length = sizeof (mp->integrity_key);
15484
15485   if (ck)
15486     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15487   if (ik)
15488     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15489
15490   if (is_tunnel)
15491     {
15492       if (is_tunnel_ipv6)
15493         {
15494           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15495                        sizeof (ip6_address_t));
15496           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15497                        sizeof (ip6_address_t));
15498         }
15499       else
15500         {
15501           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15502                        sizeof (ip4_address_t));
15503           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15504                        sizeof (ip4_address_t));
15505         }
15506     }
15507
15508   S (mp);
15509   W (ret);
15510   return ret;
15511 }
15512
15513 static int
15514 api_ipsec_sa_set_key (vat_main_t * vam)
15515 {
15516   unformat_input_t *i = vam->input;
15517   vl_api_ipsec_sa_set_key_t *mp;
15518   u32 sa_id;
15519   u8 *ck = 0, *ik = 0;
15520   int ret;
15521
15522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15523     {
15524       if (unformat (i, "sa_id %d", &sa_id))
15525         ;
15526       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15527         ;
15528       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15529         ;
15530       else
15531         {
15532           clib_warning ("parse error '%U'", format_unformat_error, i);
15533           return -99;
15534         }
15535     }
15536
15537   M (IPSEC_SA_SET_KEY, mp);
15538
15539   mp->sa_id = ntohl (sa_id);
15540   mp->crypto_key_length = vec_len (ck);
15541   mp->integrity_key_length = vec_len (ik);
15542
15543   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15544     mp->crypto_key_length = sizeof (mp->crypto_key);
15545
15546   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15547     mp->integrity_key_length = sizeof (mp->integrity_key);
15548
15549   if (ck)
15550     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15551   if (ik)
15552     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15553
15554   S (mp);
15555   W (ret);
15556   return ret;
15557 }
15558
15559 static int
15560 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15561 {
15562   unformat_input_t *i = vam->input;
15563   vl_api_ipsec_tunnel_if_add_del_t *mp;
15564   u32 local_spi = 0, remote_spi = 0;
15565   u32 crypto_alg = 0, integ_alg = 0;
15566   u8 *lck = NULL, *rck = NULL;
15567   u8 *lik = NULL, *rik = NULL;
15568   ip4_address_t local_ip = { {0} };
15569   ip4_address_t remote_ip = { {0} };
15570   u8 is_add = 1;
15571   u8 esn = 0;
15572   u8 anti_replay = 0;
15573   u8 renumber = 0;
15574   u32 instance = ~0;
15575   int ret;
15576
15577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (i, "del"))
15580         is_add = 0;
15581       else if (unformat (i, "esn"))
15582         esn = 1;
15583       else if (unformat (i, "anti_replay"))
15584         anti_replay = 1;
15585       else if (unformat (i, "local_spi %d", &local_spi))
15586         ;
15587       else if (unformat (i, "remote_spi %d", &remote_spi))
15588         ;
15589       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15590         ;
15591       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15592         ;
15593       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15594         ;
15595       else
15596         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15597         ;
15598       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15599         ;
15600       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15601         ;
15602       else
15603         if (unformat
15604             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15605         {
15606           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15607             {
15608               errmsg ("unsupported crypto-alg: '%U'\n",
15609                       format_ipsec_crypto_alg, crypto_alg);
15610               return -99;
15611             }
15612         }
15613       else
15614         if (unformat
15615             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15616         {
15617           if (integ_alg >= IPSEC_INTEG_N_ALG)
15618             {
15619               errmsg ("unsupported integ-alg: '%U'\n",
15620                       format_ipsec_integ_alg, integ_alg);
15621               return -99;
15622             }
15623         }
15624       else if (unformat (i, "instance %u", &instance))
15625         renumber = 1;
15626       else
15627         {
15628           errmsg ("parse error '%U'\n", format_unformat_error, i);
15629           return -99;
15630         }
15631     }
15632
15633   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15634
15635   mp->is_add = is_add;
15636   mp->esn = esn;
15637   mp->anti_replay = anti_replay;
15638
15639   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15640   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15641
15642   mp->local_spi = htonl (local_spi);
15643   mp->remote_spi = htonl (remote_spi);
15644   mp->crypto_alg = (u8) crypto_alg;
15645
15646   mp->local_crypto_key_len = 0;
15647   if (lck)
15648     {
15649       mp->local_crypto_key_len = vec_len (lck);
15650       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15651         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15652       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15653     }
15654
15655   mp->remote_crypto_key_len = 0;
15656   if (rck)
15657     {
15658       mp->remote_crypto_key_len = vec_len (rck);
15659       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15660         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15661       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15662     }
15663
15664   mp->integ_alg = (u8) integ_alg;
15665
15666   mp->local_integ_key_len = 0;
15667   if (lik)
15668     {
15669       mp->local_integ_key_len = vec_len (lik);
15670       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15671         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15672       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15673     }
15674
15675   mp->remote_integ_key_len = 0;
15676   if (rik)
15677     {
15678       mp->remote_integ_key_len = vec_len (rik);
15679       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15680         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15681       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15682     }
15683
15684   if (renumber)
15685     {
15686       mp->renumber = renumber;
15687       mp->show_instance = ntohl (instance);
15688     }
15689
15690   S (mp);
15691   W (ret);
15692   return ret;
15693 }
15694
15695 static void
15696 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15697 {
15698   vat_main_t *vam = &vat_main;
15699
15700   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15701          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15702          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15703          "tunnel_src_addr %U tunnel_dst_addr %U "
15704          "salt %u seq_outbound %lu last_seq_inbound %lu "
15705          "replay_window %lu total_data_size %lu\n",
15706          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15707          mp->protocol,
15708          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15709          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15710          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15711          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15712          mp->tunnel_src_addr,
15713          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15714          mp->tunnel_dst_addr,
15715          ntohl (mp->salt),
15716          clib_net_to_host_u64 (mp->seq_outbound),
15717          clib_net_to_host_u64 (mp->last_seq_inbound),
15718          clib_net_to_host_u64 (mp->replay_window),
15719          clib_net_to_host_u64 (mp->total_data_size));
15720 }
15721
15722 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15723 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15724
15725 static void vl_api_ipsec_sa_details_t_handler_json
15726   (vl_api_ipsec_sa_details_t * mp)
15727 {
15728   vat_main_t *vam = &vat_main;
15729   vat_json_node_t *node = NULL;
15730   struct in_addr src_ip4, dst_ip4;
15731   struct in6_addr src_ip6, dst_ip6;
15732
15733   if (VAT_JSON_ARRAY != vam->json_tree.type)
15734     {
15735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15736       vat_json_init_array (&vam->json_tree);
15737     }
15738   node = vat_json_array_add (&vam->json_tree);
15739
15740   vat_json_init_object (node);
15741   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15742   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15743   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15744   vat_json_object_add_uint (node, "proto", mp->protocol);
15745   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15746   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15747   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15748   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15749   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15750   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15751   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15752                              mp->crypto_key_len);
15753   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15754                              mp->integ_key_len);
15755   if (mp->is_tunnel_ip6)
15756     {
15757       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15758       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15759       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15760       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15761     }
15762   else
15763     {
15764       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15765       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15766       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15767       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15768     }
15769   vat_json_object_add_uint (node, "replay_window",
15770                             clib_net_to_host_u64 (mp->replay_window));
15771   vat_json_object_add_uint (node, "total_data_size",
15772                             clib_net_to_host_u64 (mp->total_data_size));
15773
15774 }
15775
15776 static int
15777 api_ipsec_sa_dump (vat_main_t * vam)
15778 {
15779   unformat_input_t *i = vam->input;
15780   vl_api_ipsec_sa_dump_t *mp;
15781   vl_api_control_ping_t *mp_ping;
15782   u32 sa_id = ~0;
15783   int ret;
15784
15785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15786     {
15787       if (unformat (i, "sa_id %d", &sa_id))
15788         ;
15789       else
15790         {
15791           clib_warning ("parse error '%U'", format_unformat_error, i);
15792           return -99;
15793         }
15794     }
15795
15796   M (IPSEC_SA_DUMP, mp);
15797
15798   mp->sa_id = ntohl (sa_id);
15799
15800   S (mp);
15801
15802   /* Use a control ping for synchronization */
15803   M (CONTROL_PING, mp_ping);
15804   S (mp_ping);
15805
15806   W (ret);
15807   return ret;
15808 }
15809
15810 static int
15811 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15812 {
15813   unformat_input_t *i = vam->input;
15814   vl_api_ipsec_tunnel_if_set_key_t *mp;
15815   u32 sw_if_index = ~0;
15816   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15817   u8 *key = 0;
15818   u32 alg = ~0;
15819   int ret;
15820
15821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15822     {
15823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15824         ;
15825       else
15826         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15827         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15828       else
15829         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15830         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15831       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15832         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15833       else
15834         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15835         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15836       else if (unformat (i, "%U", unformat_hex_string, &key))
15837         ;
15838       else
15839         {
15840           clib_warning ("parse error '%U'", format_unformat_error, i);
15841           return -99;
15842         }
15843     }
15844
15845   if (sw_if_index == ~0)
15846     {
15847       errmsg ("interface must be specified");
15848       return -99;
15849     }
15850
15851   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15852     {
15853       errmsg ("key type must be specified");
15854       return -99;
15855     }
15856
15857   if (alg == ~0)
15858     {
15859       errmsg ("algorithm must be specified");
15860       return -99;
15861     }
15862
15863   if (vec_len (key) == 0)
15864     {
15865       errmsg ("key must be specified");
15866       return -99;
15867     }
15868
15869   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15870
15871   mp->sw_if_index = htonl (sw_if_index);
15872   mp->alg = alg;
15873   mp->key_type = key_type;
15874   mp->key_len = vec_len (key);
15875   clib_memcpy (mp->key, key, vec_len (key));
15876
15877   S (mp);
15878   W (ret);
15879
15880   return ret;
15881 }
15882
15883 static int
15884 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15885 {
15886   unformat_input_t *i = vam->input;
15887   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15888   u32 sw_if_index = ~0;
15889   u32 sa_id = ~0;
15890   u8 is_outbound = (u8) ~ 0;
15891   int ret;
15892
15893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15894     {
15895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15896         ;
15897       else if (unformat (i, "sa_id %d", &sa_id))
15898         ;
15899       else if (unformat (i, "outbound"))
15900         is_outbound = 1;
15901       else if (unformat (i, "inbound"))
15902         is_outbound = 0;
15903       else
15904         {
15905           clib_warning ("parse error '%U'", format_unformat_error, i);
15906           return -99;
15907         }
15908     }
15909
15910   if (sw_if_index == ~0)
15911     {
15912       errmsg ("interface must be specified");
15913       return -99;
15914     }
15915
15916   if (sa_id == ~0)
15917     {
15918       errmsg ("SA ID must be specified");
15919       return -99;
15920     }
15921
15922   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15923
15924   mp->sw_if_index = htonl (sw_if_index);
15925   mp->sa_id = htonl (sa_id);
15926   mp->is_outbound = is_outbound;
15927
15928   S (mp);
15929   W (ret);
15930
15931   return ret;
15932 }
15933
15934 static int
15935 api_ikev2_profile_add_del (vat_main_t * vam)
15936 {
15937   unformat_input_t *i = vam->input;
15938   vl_api_ikev2_profile_add_del_t *mp;
15939   u8 is_add = 1;
15940   u8 *name = 0;
15941   int ret;
15942
15943   const char *valid_chars = "a-zA-Z0-9_";
15944
15945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15946     {
15947       if (unformat (i, "del"))
15948         is_add = 0;
15949       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15950         vec_add1 (name, 0);
15951       else
15952         {
15953           errmsg ("parse error '%U'", format_unformat_error, i);
15954           return -99;
15955         }
15956     }
15957
15958   if (!vec_len (name))
15959     {
15960       errmsg ("profile name must be specified");
15961       return -99;
15962     }
15963
15964   if (vec_len (name) > 64)
15965     {
15966       errmsg ("profile name too long");
15967       return -99;
15968     }
15969
15970   M (IKEV2_PROFILE_ADD_DEL, mp);
15971
15972   clib_memcpy (mp->name, name, vec_len (name));
15973   mp->is_add = is_add;
15974   vec_free (name);
15975
15976   S (mp);
15977   W (ret);
15978   return ret;
15979 }
15980
15981 static int
15982 api_ikev2_profile_set_auth (vat_main_t * vam)
15983 {
15984   unformat_input_t *i = vam->input;
15985   vl_api_ikev2_profile_set_auth_t *mp;
15986   u8 *name = 0;
15987   u8 *data = 0;
15988   u32 auth_method = 0;
15989   u8 is_hex = 0;
15990   int ret;
15991
15992   const char *valid_chars = "a-zA-Z0-9_";
15993
15994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15995     {
15996       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15997         vec_add1 (name, 0);
15998       else if (unformat (i, "auth_method %U",
15999                          unformat_ikev2_auth_method, &auth_method))
16000         ;
16001       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16002         is_hex = 1;
16003       else if (unformat (i, "auth_data %v", &data))
16004         ;
16005       else
16006         {
16007           errmsg ("parse error '%U'", format_unformat_error, i);
16008           return -99;
16009         }
16010     }
16011
16012   if (!vec_len (name))
16013     {
16014       errmsg ("profile name must be specified");
16015       return -99;
16016     }
16017
16018   if (vec_len (name) > 64)
16019     {
16020       errmsg ("profile name too long");
16021       return -99;
16022     }
16023
16024   if (!vec_len (data))
16025     {
16026       errmsg ("auth_data must be specified");
16027       return -99;
16028     }
16029
16030   if (!auth_method)
16031     {
16032       errmsg ("auth_method must be specified");
16033       return -99;
16034     }
16035
16036   M (IKEV2_PROFILE_SET_AUTH, mp);
16037
16038   mp->is_hex = is_hex;
16039   mp->auth_method = (u8) auth_method;
16040   mp->data_len = vec_len (data);
16041   clib_memcpy (mp->name, name, vec_len (name));
16042   clib_memcpy (mp->data, data, vec_len (data));
16043   vec_free (name);
16044   vec_free (data);
16045
16046   S (mp);
16047   W (ret);
16048   return ret;
16049 }
16050
16051 static int
16052 api_ikev2_profile_set_id (vat_main_t * vam)
16053 {
16054   unformat_input_t *i = vam->input;
16055   vl_api_ikev2_profile_set_id_t *mp;
16056   u8 *name = 0;
16057   u8 *data = 0;
16058   u8 is_local = 0;
16059   u32 id_type = 0;
16060   ip4_address_t ip4;
16061   int ret;
16062
16063   const char *valid_chars = "a-zA-Z0-9_";
16064
16065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16066     {
16067       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16068         vec_add1 (name, 0);
16069       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16070         ;
16071       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16072         {
16073           data = vec_new (u8, 4);
16074           clib_memcpy (data, ip4.as_u8, 4);
16075         }
16076       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16077         ;
16078       else if (unformat (i, "id_data %v", &data))
16079         ;
16080       else if (unformat (i, "local"))
16081         is_local = 1;
16082       else if (unformat (i, "remote"))
16083         is_local = 0;
16084       else
16085         {
16086           errmsg ("parse error '%U'", format_unformat_error, i);
16087           return -99;
16088         }
16089     }
16090
16091   if (!vec_len (name))
16092     {
16093       errmsg ("profile name must be specified");
16094       return -99;
16095     }
16096
16097   if (vec_len (name) > 64)
16098     {
16099       errmsg ("profile name too long");
16100       return -99;
16101     }
16102
16103   if (!vec_len (data))
16104     {
16105       errmsg ("id_data must be specified");
16106       return -99;
16107     }
16108
16109   if (!id_type)
16110     {
16111       errmsg ("id_type must be specified");
16112       return -99;
16113     }
16114
16115   M (IKEV2_PROFILE_SET_ID, mp);
16116
16117   mp->is_local = is_local;
16118   mp->id_type = (u8) id_type;
16119   mp->data_len = vec_len (data);
16120   clib_memcpy (mp->name, name, vec_len (name));
16121   clib_memcpy (mp->data, data, vec_len (data));
16122   vec_free (name);
16123   vec_free (data);
16124
16125   S (mp);
16126   W (ret);
16127   return ret;
16128 }
16129
16130 static int
16131 api_ikev2_profile_set_ts (vat_main_t * vam)
16132 {
16133   unformat_input_t *i = vam->input;
16134   vl_api_ikev2_profile_set_ts_t *mp;
16135   u8 *name = 0;
16136   u8 is_local = 0;
16137   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16138   ip4_address_t start_addr, end_addr;
16139
16140   const char *valid_chars = "a-zA-Z0-9_";
16141   int ret;
16142
16143   start_addr.as_u32 = 0;
16144   end_addr.as_u32 = (u32) ~ 0;
16145
16146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16147     {
16148       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16149         vec_add1 (name, 0);
16150       else if (unformat (i, "protocol %d", &proto))
16151         ;
16152       else if (unformat (i, "start_port %d", &start_port))
16153         ;
16154       else if (unformat (i, "end_port %d", &end_port))
16155         ;
16156       else
16157         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16158         ;
16159       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16160         ;
16161       else if (unformat (i, "local"))
16162         is_local = 1;
16163       else if (unformat (i, "remote"))
16164         is_local = 0;
16165       else
16166         {
16167           errmsg ("parse error '%U'", format_unformat_error, i);
16168           return -99;
16169         }
16170     }
16171
16172   if (!vec_len (name))
16173     {
16174       errmsg ("profile name must be specified");
16175       return -99;
16176     }
16177
16178   if (vec_len (name) > 64)
16179     {
16180       errmsg ("profile name too long");
16181       return -99;
16182     }
16183
16184   M (IKEV2_PROFILE_SET_TS, mp);
16185
16186   mp->is_local = is_local;
16187   mp->proto = (u8) proto;
16188   mp->start_port = (u16) start_port;
16189   mp->end_port = (u16) end_port;
16190   mp->start_addr = start_addr.as_u32;
16191   mp->end_addr = end_addr.as_u32;
16192   clib_memcpy (mp->name, name, vec_len (name));
16193   vec_free (name);
16194
16195   S (mp);
16196   W (ret);
16197   return ret;
16198 }
16199
16200 static int
16201 api_ikev2_set_local_key (vat_main_t * vam)
16202 {
16203   unformat_input_t *i = vam->input;
16204   vl_api_ikev2_set_local_key_t *mp;
16205   u8 *file = 0;
16206   int ret;
16207
16208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16209     {
16210       if (unformat (i, "file %v", &file))
16211         vec_add1 (file, 0);
16212       else
16213         {
16214           errmsg ("parse error '%U'", format_unformat_error, i);
16215           return -99;
16216         }
16217     }
16218
16219   if (!vec_len (file))
16220     {
16221       errmsg ("RSA key file must be specified");
16222       return -99;
16223     }
16224
16225   if (vec_len (file) > 256)
16226     {
16227       errmsg ("file name too long");
16228       return -99;
16229     }
16230
16231   M (IKEV2_SET_LOCAL_KEY, mp);
16232
16233   clib_memcpy (mp->key_file, file, vec_len (file));
16234   vec_free (file);
16235
16236   S (mp);
16237   W (ret);
16238   return ret;
16239 }
16240
16241 static int
16242 api_ikev2_set_responder (vat_main_t * vam)
16243 {
16244   unformat_input_t *i = vam->input;
16245   vl_api_ikev2_set_responder_t *mp;
16246   int ret;
16247   u8 *name = 0;
16248   u32 sw_if_index = ~0;
16249   ip4_address_t address;
16250
16251   const char *valid_chars = "a-zA-Z0-9_";
16252
16253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16254     {
16255       if (unformat
16256           (i, "%U interface %d address %U", unformat_token, valid_chars,
16257            &name, &sw_if_index, unformat_ip4_address, &address))
16258         vec_add1 (name, 0);
16259       else
16260         {
16261           errmsg ("parse error '%U'", format_unformat_error, i);
16262           return -99;
16263         }
16264     }
16265
16266   if (!vec_len (name))
16267     {
16268       errmsg ("profile name must be specified");
16269       return -99;
16270     }
16271
16272   if (vec_len (name) > 64)
16273     {
16274       errmsg ("profile name too long");
16275       return -99;
16276     }
16277
16278   M (IKEV2_SET_RESPONDER, mp);
16279
16280   clib_memcpy (mp->name, name, vec_len (name));
16281   vec_free (name);
16282
16283   mp->sw_if_index = sw_if_index;
16284   clib_memcpy (mp->address, &address, sizeof (address));
16285
16286   S (mp);
16287   W (ret);
16288   return ret;
16289 }
16290
16291 static int
16292 api_ikev2_set_ike_transforms (vat_main_t * vam)
16293 {
16294   unformat_input_t *i = vam->input;
16295   vl_api_ikev2_set_ike_transforms_t *mp;
16296   int ret;
16297   u8 *name = 0;
16298   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16299
16300   const char *valid_chars = "a-zA-Z0-9_";
16301
16302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16303     {
16304       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16305                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16306         vec_add1 (name, 0);
16307       else
16308         {
16309           errmsg ("parse error '%U'", format_unformat_error, i);
16310           return -99;
16311         }
16312     }
16313
16314   if (!vec_len (name))
16315     {
16316       errmsg ("profile name must be specified");
16317       return -99;
16318     }
16319
16320   if (vec_len (name) > 64)
16321     {
16322       errmsg ("profile name too long");
16323       return -99;
16324     }
16325
16326   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16327
16328   clib_memcpy (mp->name, name, vec_len (name));
16329   vec_free (name);
16330   mp->crypto_alg = crypto_alg;
16331   mp->crypto_key_size = crypto_key_size;
16332   mp->integ_alg = integ_alg;
16333   mp->dh_group = dh_group;
16334
16335   S (mp);
16336   W (ret);
16337   return ret;
16338 }
16339
16340
16341 static int
16342 api_ikev2_set_esp_transforms (vat_main_t * vam)
16343 {
16344   unformat_input_t *i = vam->input;
16345   vl_api_ikev2_set_esp_transforms_t *mp;
16346   int ret;
16347   u8 *name = 0;
16348   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16349
16350   const char *valid_chars = "a-zA-Z0-9_";
16351
16352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16353     {
16354       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16355                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16356         vec_add1 (name, 0);
16357       else
16358         {
16359           errmsg ("parse error '%U'", format_unformat_error, i);
16360           return -99;
16361         }
16362     }
16363
16364   if (!vec_len (name))
16365     {
16366       errmsg ("profile name must be specified");
16367       return -99;
16368     }
16369
16370   if (vec_len (name) > 64)
16371     {
16372       errmsg ("profile name too long");
16373       return -99;
16374     }
16375
16376   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16377
16378   clib_memcpy (mp->name, name, vec_len (name));
16379   vec_free (name);
16380   mp->crypto_alg = crypto_alg;
16381   mp->crypto_key_size = crypto_key_size;
16382   mp->integ_alg = integ_alg;
16383   mp->dh_group = dh_group;
16384
16385   S (mp);
16386   W (ret);
16387   return ret;
16388 }
16389
16390 static int
16391 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16392 {
16393   unformat_input_t *i = vam->input;
16394   vl_api_ikev2_set_sa_lifetime_t *mp;
16395   int ret;
16396   u8 *name = 0;
16397   u64 lifetime, lifetime_maxdata;
16398   u32 lifetime_jitter, handover;
16399
16400   const char *valid_chars = "a-zA-Z0-9_";
16401
16402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16403     {
16404       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16405                     &lifetime, &lifetime_jitter, &handover,
16406                     &lifetime_maxdata))
16407         vec_add1 (name, 0);
16408       else
16409         {
16410           errmsg ("parse error '%U'", format_unformat_error, i);
16411           return -99;
16412         }
16413     }
16414
16415   if (!vec_len (name))
16416     {
16417       errmsg ("profile name must be specified");
16418       return -99;
16419     }
16420
16421   if (vec_len (name) > 64)
16422     {
16423       errmsg ("profile name too long");
16424       return -99;
16425     }
16426
16427   M (IKEV2_SET_SA_LIFETIME, mp);
16428
16429   clib_memcpy (mp->name, name, vec_len (name));
16430   vec_free (name);
16431   mp->lifetime = lifetime;
16432   mp->lifetime_jitter = lifetime_jitter;
16433   mp->handover = handover;
16434   mp->lifetime_maxdata = lifetime_maxdata;
16435
16436   S (mp);
16437   W (ret);
16438   return ret;
16439 }
16440
16441 static int
16442 api_ikev2_initiate_sa_init (vat_main_t * vam)
16443 {
16444   unformat_input_t *i = vam->input;
16445   vl_api_ikev2_initiate_sa_init_t *mp;
16446   int ret;
16447   u8 *name = 0;
16448
16449   const char *valid_chars = "a-zA-Z0-9_";
16450
16451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16452     {
16453       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16454         vec_add1 (name, 0);
16455       else
16456         {
16457           errmsg ("parse error '%U'", format_unformat_error, i);
16458           return -99;
16459         }
16460     }
16461
16462   if (!vec_len (name))
16463     {
16464       errmsg ("profile name must be specified");
16465       return -99;
16466     }
16467
16468   if (vec_len (name) > 64)
16469     {
16470       errmsg ("profile name too long");
16471       return -99;
16472     }
16473
16474   M (IKEV2_INITIATE_SA_INIT, mp);
16475
16476   clib_memcpy (mp->name, name, vec_len (name));
16477   vec_free (name);
16478
16479   S (mp);
16480   W (ret);
16481   return ret;
16482 }
16483
16484 static int
16485 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16486 {
16487   unformat_input_t *i = vam->input;
16488   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16489   int ret;
16490   u64 ispi;
16491
16492
16493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16494     {
16495       if (unformat (i, "%lx", &ispi))
16496         ;
16497       else
16498         {
16499           errmsg ("parse error '%U'", format_unformat_error, i);
16500           return -99;
16501         }
16502     }
16503
16504   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16505
16506   mp->ispi = ispi;
16507
16508   S (mp);
16509   W (ret);
16510   return ret;
16511 }
16512
16513 static int
16514 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16515 {
16516   unformat_input_t *i = vam->input;
16517   vl_api_ikev2_initiate_del_child_sa_t *mp;
16518   int ret;
16519   u32 ispi;
16520
16521
16522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16523     {
16524       if (unformat (i, "%x", &ispi))
16525         ;
16526       else
16527         {
16528           errmsg ("parse error '%U'", format_unformat_error, i);
16529           return -99;
16530         }
16531     }
16532
16533   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16534
16535   mp->ispi = ispi;
16536
16537   S (mp);
16538   W (ret);
16539   return ret;
16540 }
16541
16542 static int
16543 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16544 {
16545   unformat_input_t *i = vam->input;
16546   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16547   int ret;
16548   u32 ispi;
16549
16550
16551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16552     {
16553       if (unformat (i, "%x", &ispi))
16554         ;
16555       else
16556         {
16557           errmsg ("parse error '%U'", format_unformat_error, i);
16558           return -99;
16559         }
16560     }
16561
16562   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16563
16564   mp->ispi = ispi;
16565
16566   S (mp);
16567   W (ret);
16568   return ret;
16569 }
16570
16571 static int
16572 api_get_first_msg_id (vat_main_t * vam)
16573 {
16574   vl_api_get_first_msg_id_t *mp;
16575   unformat_input_t *i = vam->input;
16576   u8 *name;
16577   u8 name_set = 0;
16578   int ret;
16579
16580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16581     {
16582       if (unformat (i, "client %s", &name))
16583         name_set = 1;
16584       else
16585         break;
16586     }
16587
16588   if (name_set == 0)
16589     {
16590       errmsg ("missing client name");
16591       return -99;
16592     }
16593   vec_add1 (name, 0);
16594
16595   if (vec_len (name) > 63)
16596     {
16597       errmsg ("client name too long");
16598       return -99;
16599     }
16600
16601   M (GET_FIRST_MSG_ID, mp);
16602   clib_memcpy (mp->name, name, vec_len (name));
16603   S (mp);
16604   W (ret);
16605   return ret;
16606 }
16607
16608 static int
16609 api_cop_interface_enable_disable (vat_main_t * vam)
16610 {
16611   unformat_input_t *line_input = vam->input;
16612   vl_api_cop_interface_enable_disable_t *mp;
16613   u32 sw_if_index = ~0;
16614   u8 enable_disable = 1;
16615   int ret;
16616
16617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16618     {
16619       if (unformat (line_input, "disable"))
16620         enable_disable = 0;
16621       if (unformat (line_input, "enable"))
16622         enable_disable = 1;
16623       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16624                          vam, &sw_if_index))
16625         ;
16626       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16627         ;
16628       else
16629         break;
16630     }
16631
16632   if (sw_if_index == ~0)
16633     {
16634       errmsg ("missing interface name or sw_if_index");
16635       return -99;
16636     }
16637
16638   /* Construct the API message */
16639   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16640   mp->sw_if_index = ntohl (sw_if_index);
16641   mp->enable_disable = enable_disable;
16642
16643   /* send it... */
16644   S (mp);
16645   /* Wait for the reply */
16646   W (ret);
16647   return ret;
16648 }
16649
16650 static int
16651 api_cop_whitelist_enable_disable (vat_main_t * vam)
16652 {
16653   unformat_input_t *line_input = vam->input;
16654   vl_api_cop_whitelist_enable_disable_t *mp;
16655   u32 sw_if_index = ~0;
16656   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16657   u32 fib_id = 0;
16658   int ret;
16659
16660   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (line_input, "ip4"))
16663         ip4 = 1;
16664       else if (unformat (line_input, "ip6"))
16665         ip6 = 1;
16666       else if (unformat (line_input, "default"))
16667         default_cop = 1;
16668       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16669                          vam, &sw_if_index))
16670         ;
16671       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16672         ;
16673       else if (unformat (line_input, "fib-id %d", &fib_id))
16674         ;
16675       else
16676         break;
16677     }
16678
16679   if (sw_if_index == ~0)
16680     {
16681       errmsg ("missing interface name or sw_if_index");
16682       return -99;
16683     }
16684
16685   /* Construct the API message */
16686   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16687   mp->sw_if_index = ntohl (sw_if_index);
16688   mp->fib_id = ntohl (fib_id);
16689   mp->ip4 = ip4;
16690   mp->ip6 = ip6;
16691   mp->default_cop = default_cop;
16692
16693   /* send it... */
16694   S (mp);
16695   /* Wait for the reply */
16696   W (ret);
16697   return ret;
16698 }
16699
16700 static int
16701 api_get_node_graph (vat_main_t * vam)
16702 {
16703   vl_api_get_node_graph_t *mp;
16704   int ret;
16705
16706   M (GET_NODE_GRAPH, mp);
16707
16708   /* send it... */
16709   S (mp);
16710   /* Wait for the reply */
16711   W (ret);
16712   return ret;
16713 }
16714
16715 /* *INDENT-OFF* */
16716 /** Used for parsing LISP eids */
16717 typedef CLIB_PACKED(struct{
16718   u8 addr[16];   /**< eid address */
16719   u32 len;       /**< prefix length if IP */
16720   u8 type;      /**< type of eid */
16721 }) lisp_eid_vat_t;
16722 /* *INDENT-ON* */
16723
16724 static uword
16725 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16726 {
16727   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16728
16729   memset (a, 0, sizeof (a[0]));
16730
16731   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16732     {
16733       a->type = 0;              /* ipv4 type */
16734     }
16735   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16736     {
16737       a->type = 1;              /* ipv6 type */
16738     }
16739   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16740     {
16741       a->type = 2;              /* mac type */
16742     }
16743   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16744     {
16745       a->type = 3;              /* NSH type */
16746       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16747       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16748     }
16749   else
16750     {
16751       return 0;
16752     }
16753
16754   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16755     {
16756       return 0;
16757     }
16758
16759   return 1;
16760 }
16761
16762 static int
16763 lisp_eid_size_vat (u8 type)
16764 {
16765   switch (type)
16766     {
16767     case 0:
16768       return 4;
16769     case 1:
16770       return 16;
16771     case 2:
16772       return 6;
16773     case 3:
16774       return 5;
16775     }
16776   return 0;
16777 }
16778
16779 static void
16780 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16781 {
16782   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16783 }
16784
16785 static int
16786 api_one_add_del_locator_set (vat_main_t * vam)
16787 {
16788   unformat_input_t *input = vam->input;
16789   vl_api_one_add_del_locator_set_t *mp;
16790   u8 is_add = 1;
16791   u8 *locator_set_name = NULL;
16792   u8 locator_set_name_set = 0;
16793   vl_api_local_locator_t locator, *locators = 0;
16794   u32 sw_if_index, priority, weight;
16795   u32 data_len = 0;
16796
16797   int ret;
16798   /* Parse args required to build the message */
16799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16800     {
16801       if (unformat (input, "del"))
16802         {
16803           is_add = 0;
16804         }
16805       else if (unformat (input, "locator-set %s", &locator_set_name))
16806         {
16807           locator_set_name_set = 1;
16808         }
16809       else if (unformat (input, "sw_if_index %u p %u w %u",
16810                          &sw_if_index, &priority, &weight))
16811         {
16812           locator.sw_if_index = htonl (sw_if_index);
16813           locator.priority = priority;
16814           locator.weight = weight;
16815           vec_add1 (locators, locator);
16816         }
16817       else
16818         if (unformat
16819             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16820              &sw_if_index, &priority, &weight))
16821         {
16822           locator.sw_if_index = htonl (sw_if_index);
16823           locator.priority = priority;
16824           locator.weight = weight;
16825           vec_add1 (locators, locator);
16826         }
16827       else
16828         break;
16829     }
16830
16831   if (locator_set_name_set == 0)
16832     {
16833       errmsg ("missing locator-set name");
16834       vec_free (locators);
16835       return -99;
16836     }
16837
16838   if (vec_len (locator_set_name) > 64)
16839     {
16840       errmsg ("locator-set name too long");
16841       vec_free (locator_set_name);
16842       vec_free (locators);
16843       return -99;
16844     }
16845   vec_add1 (locator_set_name, 0);
16846
16847   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16848
16849   /* Construct the API message */
16850   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16851
16852   mp->is_add = is_add;
16853   clib_memcpy (mp->locator_set_name, locator_set_name,
16854                vec_len (locator_set_name));
16855   vec_free (locator_set_name);
16856
16857   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16858   if (locators)
16859     clib_memcpy (mp->locators, locators, data_len);
16860   vec_free (locators);
16861
16862   /* send it... */
16863   S (mp);
16864
16865   /* Wait for a reply... */
16866   W (ret);
16867   return ret;
16868 }
16869
16870 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16871
16872 static int
16873 api_one_add_del_locator (vat_main_t * vam)
16874 {
16875   unformat_input_t *input = vam->input;
16876   vl_api_one_add_del_locator_t *mp;
16877   u32 tmp_if_index = ~0;
16878   u32 sw_if_index = ~0;
16879   u8 sw_if_index_set = 0;
16880   u8 sw_if_index_if_name_set = 0;
16881   u32 priority = ~0;
16882   u8 priority_set = 0;
16883   u32 weight = ~0;
16884   u8 weight_set = 0;
16885   u8 is_add = 1;
16886   u8 *locator_set_name = NULL;
16887   u8 locator_set_name_set = 0;
16888   int ret;
16889
16890   /* Parse args required to build the message */
16891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16892     {
16893       if (unformat (input, "del"))
16894         {
16895           is_add = 0;
16896         }
16897       else if (unformat (input, "locator-set %s", &locator_set_name))
16898         {
16899           locator_set_name_set = 1;
16900         }
16901       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16902                          &tmp_if_index))
16903         {
16904           sw_if_index_if_name_set = 1;
16905           sw_if_index = tmp_if_index;
16906         }
16907       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16908         {
16909           sw_if_index_set = 1;
16910           sw_if_index = tmp_if_index;
16911         }
16912       else if (unformat (input, "p %d", &priority))
16913         {
16914           priority_set = 1;
16915         }
16916       else if (unformat (input, "w %d", &weight))
16917         {
16918           weight_set = 1;
16919         }
16920       else
16921         break;
16922     }
16923
16924   if (locator_set_name_set == 0)
16925     {
16926       errmsg ("missing locator-set name");
16927       return -99;
16928     }
16929
16930   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16931     {
16932       errmsg ("missing sw_if_index");
16933       vec_free (locator_set_name);
16934       return -99;
16935     }
16936
16937   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16938     {
16939       errmsg ("cannot use both params interface name and sw_if_index");
16940       vec_free (locator_set_name);
16941       return -99;
16942     }
16943
16944   if (priority_set == 0)
16945     {
16946       errmsg ("missing locator-set priority");
16947       vec_free (locator_set_name);
16948       return -99;
16949     }
16950
16951   if (weight_set == 0)
16952     {
16953       errmsg ("missing locator-set weight");
16954       vec_free (locator_set_name);
16955       return -99;
16956     }
16957
16958   if (vec_len (locator_set_name) > 64)
16959     {
16960       errmsg ("locator-set name too long");
16961       vec_free (locator_set_name);
16962       return -99;
16963     }
16964   vec_add1 (locator_set_name, 0);
16965
16966   /* Construct the API message */
16967   M (ONE_ADD_DEL_LOCATOR, mp);
16968
16969   mp->is_add = is_add;
16970   mp->sw_if_index = ntohl (sw_if_index);
16971   mp->priority = priority;
16972   mp->weight = weight;
16973   clib_memcpy (mp->locator_set_name, locator_set_name,
16974                vec_len (locator_set_name));
16975   vec_free (locator_set_name);
16976
16977   /* send it... */
16978   S (mp);
16979
16980   /* Wait for a reply... */
16981   W (ret);
16982   return ret;
16983 }
16984
16985 #define api_lisp_add_del_locator api_one_add_del_locator
16986
16987 uword
16988 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16989 {
16990   u32 *key_id = va_arg (*args, u32 *);
16991   u8 *s = 0;
16992
16993   if (unformat (input, "%s", &s))
16994     {
16995       if (!strcmp ((char *) s, "sha1"))
16996         key_id[0] = HMAC_SHA_1_96;
16997       else if (!strcmp ((char *) s, "sha256"))
16998         key_id[0] = HMAC_SHA_256_128;
16999       else
17000         {
17001           clib_warning ("invalid key_id: '%s'", s);
17002           key_id[0] = HMAC_NO_KEY;
17003         }
17004     }
17005   else
17006     return 0;
17007
17008   vec_free (s);
17009   return 1;
17010 }
17011
17012 static int
17013 api_one_add_del_local_eid (vat_main_t * vam)
17014 {
17015   unformat_input_t *input = vam->input;
17016   vl_api_one_add_del_local_eid_t *mp;
17017   u8 is_add = 1;
17018   u8 eid_set = 0;
17019   lisp_eid_vat_t _eid, *eid = &_eid;
17020   u8 *locator_set_name = 0;
17021   u8 locator_set_name_set = 0;
17022   u32 vni = 0;
17023   u16 key_id = 0;
17024   u8 *key = 0;
17025   int ret;
17026
17027   /* Parse args required to build the message */
17028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17029     {
17030       if (unformat (input, "del"))
17031         {
17032           is_add = 0;
17033         }
17034       else if (unformat (input, "vni %d", &vni))
17035         {
17036           ;
17037         }
17038       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17039         {
17040           eid_set = 1;
17041         }
17042       else if (unformat (input, "locator-set %s", &locator_set_name))
17043         {
17044           locator_set_name_set = 1;
17045         }
17046       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17047         ;
17048       else if (unformat (input, "secret-key %_%v%_", &key))
17049         ;
17050       else
17051         break;
17052     }
17053
17054   if (locator_set_name_set == 0)
17055     {
17056       errmsg ("missing locator-set name");
17057       return -99;
17058     }
17059
17060   if (0 == eid_set)
17061     {
17062       errmsg ("EID address not set!");
17063       vec_free (locator_set_name);
17064       return -99;
17065     }
17066
17067   if (key && (0 == key_id))
17068     {
17069       errmsg ("invalid key_id!");
17070       return -99;
17071     }
17072
17073   if (vec_len (key) > 64)
17074     {
17075       errmsg ("key too long");
17076       vec_free (key);
17077       return -99;
17078     }
17079
17080   if (vec_len (locator_set_name) > 64)
17081     {
17082       errmsg ("locator-set name too long");
17083       vec_free (locator_set_name);
17084       return -99;
17085     }
17086   vec_add1 (locator_set_name, 0);
17087
17088   /* Construct the API message */
17089   M (ONE_ADD_DEL_LOCAL_EID, mp);
17090
17091   mp->is_add = is_add;
17092   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17093   mp->eid_type = eid->type;
17094   mp->prefix_len = eid->len;
17095   mp->vni = clib_host_to_net_u32 (vni);
17096   mp->key_id = clib_host_to_net_u16 (key_id);
17097   clib_memcpy (mp->locator_set_name, locator_set_name,
17098                vec_len (locator_set_name));
17099   clib_memcpy (mp->key, key, vec_len (key));
17100
17101   vec_free (locator_set_name);
17102   vec_free (key);
17103
17104   /* send it... */
17105   S (mp);
17106
17107   /* Wait for a reply... */
17108   W (ret);
17109   return ret;
17110 }
17111
17112 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17113
17114 static int
17115 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17116 {
17117   u32 dp_table = 0, vni = 0;;
17118   unformat_input_t *input = vam->input;
17119   vl_api_gpe_add_del_fwd_entry_t *mp;
17120   u8 is_add = 1;
17121   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17122   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17123   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17124   u32 action = ~0, w;
17125   ip4_address_t rmt_rloc4, lcl_rloc4;
17126   ip6_address_t rmt_rloc6, lcl_rloc6;
17127   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17128   int ret;
17129
17130   memset (&rloc, 0, sizeof (rloc));
17131
17132   /* Parse args required to build the message */
17133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17134     {
17135       if (unformat (input, "del"))
17136         is_add = 0;
17137       else if (unformat (input, "add"))
17138         is_add = 1;
17139       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17140         {
17141           rmt_eid_set = 1;
17142         }
17143       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17144         {
17145           lcl_eid_set = 1;
17146         }
17147       else if (unformat (input, "vrf %d", &dp_table))
17148         ;
17149       else if (unformat (input, "bd %d", &dp_table))
17150         ;
17151       else if (unformat (input, "vni %d", &vni))
17152         ;
17153       else if (unformat (input, "w %d", &w))
17154         {
17155           if (!curr_rloc)
17156             {
17157               errmsg ("No RLOC configured for setting priority/weight!");
17158               return -99;
17159             }
17160           curr_rloc->weight = w;
17161         }
17162       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17163                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17164         {
17165           rloc.is_ip4 = 1;
17166
17167           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17168           rloc.weight = 0;
17169           vec_add1 (lcl_locs, rloc);
17170
17171           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17172           vec_add1 (rmt_locs, rloc);
17173           /* weight saved in rmt loc */
17174           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17175         }
17176       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17177                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17178         {
17179           rloc.is_ip4 = 0;
17180           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17181           rloc.weight = 0;
17182           vec_add1 (lcl_locs, rloc);
17183
17184           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17185           vec_add1 (rmt_locs, rloc);
17186           /* weight saved in rmt loc */
17187           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17188         }
17189       else if (unformat (input, "action %d", &action))
17190         {
17191           ;
17192         }
17193       else
17194         {
17195           clib_warning ("parse error '%U'", format_unformat_error, input);
17196           return -99;
17197         }
17198     }
17199
17200   if (!rmt_eid_set)
17201     {
17202       errmsg ("remote eid addresses not set");
17203       return -99;
17204     }
17205
17206   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17207     {
17208       errmsg ("eid types don't match");
17209       return -99;
17210     }
17211
17212   if (0 == rmt_locs && (u32) ~ 0 == action)
17213     {
17214       errmsg ("action not set for negative mapping");
17215       return -99;
17216     }
17217
17218   /* Construct the API message */
17219   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17220       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17221
17222   mp->is_add = is_add;
17223   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17224   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17225   mp->eid_type = rmt_eid->type;
17226   mp->dp_table = clib_host_to_net_u32 (dp_table);
17227   mp->vni = clib_host_to_net_u32 (vni);
17228   mp->rmt_len = rmt_eid->len;
17229   mp->lcl_len = lcl_eid->len;
17230   mp->action = action;
17231
17232   if (0 != rmt_locs && 0 != lcl_locs)
17233     {
17234       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17235       clib_memcpy (mp->locs, lcl_locs,
17236                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17237
17238       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17239       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17240                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17241     }
17242   vec_free (lcl_locs);
17243   vec_free (rmt_locs);
17244
17245   /* send it... */
17246   S (mp);
17247
17248   /* Wait for a reply... */
17249   W (ret);
17250   return ret;
17251 }
17252
17253 static int
17254 api_one_add_del_map_server (vat_main_t * vam)
17255 {
17256   unformat_input_t *input = vam->input;
17257   vl_api_one_add_del_map_server_t *mp;
17258   u8 is_add = 1;
17259   u8 ipv4_set = 0;
17260   u8 ipv6_set = 0;
17261   ip4_address_t ipv4;
17262   ip6_address_t ipv6;
17263   int ret;
17264
17265   /* Parse args required to build the message */
17266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17267     {
17268       if (unformat (input, "del"))
17269         {
17270           is_add = 0;
17271         }
17272       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17273         {
17274           ipv4_set = 1;
17275         }
17276       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17277         {
17278           ipv6_set = 1;
17279         }
17280       else
17281         break;
17282     }
17283
17284   if (ipv4_set && ipv6_set)
17285     {
17286       errmsg ("both eid v4 and v6 addresses set");
17287       return -99;
17288     }
17289
17290   if (!ipv4_set && !ipv6_set)
17291     {
17292       errmsg ("eid addresses not set");
17293       return -99;
17294     }
17295
17296   /* Construct the API message */
17297   M (ONE_ADD_DEL_MAP_SERVER, mp);
17298
17299   mp->is_add = is_add;
17300   if (ipv6_set)
17301     {
17302       mp->is_ipv6 = 1;
17303       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17304     }
17305   else
17306     {
17307       mp->is_ipv6 = 0;
17308       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17309     }
17310
17311   /* send it... */
17312   S (mp);
17313
17314   /* Wait for a reply... */
17315   W (ret);
17316   return ret;
17317 }
17318
17319 #define api_lisp_add_del_map_server api_one_add_del_map_server
17320
17321 static int
17322 api_one_add_del_map_resolver (vat_main_t * vam)
17323 {
17324   unformat_input_t *input = vam->input;
17325   vl_api_one_add_del_map_resolver_t *mp;
17326   u8 is_add = 1;
17327   u8 ipv4_set = 0;
17328   u8 ipv6_set = 0;
17329   ip4_address_t ipv4;
17330   ip6_address_t ipv6;
17331   int ret;
17332
17333   /* Parse args required to build the message */
17334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17335     {
17336       if (unformat (input, "del"))
17337         {
17338           is_add = 0;
17339         }
17340       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17341         {
17342           ipv4_set = 1;
17343         }
17344       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17345         {
17346           ipv6_set = 1;
17347         }
17348       else
17349         break;
17350     }
17351
17352   if (ipv4_set && ipv6_set)
17353     {
17354       errmsg ("both eid v4 and v6 addresses set");
17355       return -99;
17356     }
17357
17358   if (!ipv4_set && !ipv6_set)
17359     {
17360       errmsg ("eid addresses not set");
17361       return -99;
17362     }
17363
17364   /* Construct the API message */
17365   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17366
17367   mp->is_add = is_add;
17368   if (ipv6_set)
17369     {
17370       mp->is_ipv6 = 1;
17371       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17372     }
17373   else
17374     {
17375       mp->is_ipv6 = 0;
17376       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17377     }
17378
17379   /* send it... */
17380   S (mp);
17381
17382   /* Wait for a reply... */
17383   W (ret);
17384   return ret;
17385 }
17386
17387 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17388
17389 static int
17390 api_lisp_gpe_enable_disable (vat_main_t * vam)
17391 {
17392   unformat_input_t *input = vam->input;
17393   vl_api_gpe_enable_disable_t *mp;
17394   u8 is_set = 0;
17395   u8 is_en = 1;
17396   int ret;
17397
17398   /* Parse args required to build the message */
17399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17400     {
17401       if (unformat (input, "enable"))
17402         {
17403           is_set = 1;
17404           is_en = 1;
17405         }
17406       else if (unformat (input, "disable"))
17407         {
17408           is_set = 1;
17409           is_en = 0;
17410         }
17411       else
17412         break;
17413     }
17414
17415   if (is_set == 0)
17416     {
17417       errmsg ("Value not set");
17418       return -99;
17419     }
17420
17421   /* Construct the API message */
17422   M (GPE_ENABLE_DISABLE, mp);
17423
17424   mp->is_en = is_en;
17425
17426   /* send it... */
17427   S (mp);
17428
17429   /* Wait for a reply... */
17430   W (ret);
17431   return ret;
17432 }
17433
17434 static int
17435 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17436 {
17437   unformat_input_t *input = vam->input;
17438   vl_api_one_rloc_probe_enable_disable_t *mp;
17439   u8 is_set = 0;
17440   u8 is_en = 0;
17441   int ret;
17442
17443   /* Parse args required to build the message */
17444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17445     {
17446       if (unformat (input, "enable"))
17447         {
17448           is_set = 1;
17449           is_en = 1;
17450         }
17451       else if (unformat (input, "disable"))
17452         is_set = 1;
17453       else
17454         break;
17455     }
17456
17457   if (!is_set)
17458     {
17459       errmsg ("Value not set");
17460       return -99;
17461     }
17462
17463   /* Construct the API message */
17464   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17465
17466   mp->is_enabled = is_en;
17467
17468   /* send it... */
17469   S (mp);
17470
17471   /* Wait for a reply... */
17472   W (ret);
17473   return ret;
17474 }
17475
17476 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17477
17478 static int
17479 api_one_map_register_enable_disable (vat_main_t * vam)
17480 {
17481   unformat_input_t *input = vam->input;
17482   vl_api_one_map_register_enable_disable_t *mp;
17483   u8 is_set = 0;
17484   u8 is_en = 0;
17485   int ret;
17486
17487   /* Parse args required to build the message */
17488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (input, "enable"))
17491         {
17492           is_set = 1;
17493           is_en = 1;
17494         }
17495       else if (unformat (input, "disable"))
17496         is_set = 1;
17497       else
17498         break;
17499     }
17500
17501   if (!is_set)
17502     {
17503       errmsg ("Value not set");
17504       return -99;
17505     }
17506
17507   /* Construct the API message */
17508   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17509
17510   mp->is_enabled = is_en;
17511
17512   /* send it... */
17513   S (mp);
17514
17515   /* Wait for a reply... */
17516   W (ret);
17517   return ret;
17518 }
17519
17520 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17521
17522 static int
17523 api_one_enable_disable (vat_main_t * vam)
17524 {
17525   unformat_input_t *input = vam->input;
17526   vl_api_one_enable_disable_t *mp;
17527   u8 is_set = 0;
17528   u8 is_en = 0;
17529   int ret;
17530
17531   /* Parse args required to build the message */
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "enable"))
17535         {
17536           is_set = 1;
17537           is_en = 1;
17538         }
17539       else if (unformat (input, "disable"))
17540         {
17541           is_set = 1;
17542         }
17543       else
17544         break;
17545     }
17546
17547   if (!is_set)
17548     {
17549       errmsg ("Value not set");
17550       return -99;
17551     }
17552
17553   /* Construct the API message */
17554   M (ONE_ENABLE_DISABLE, mp);
17555
17556   mp->is_en = is_en;
17557
17558   /* send it... */
17559   S (mp);
17560
17561   /* Wait for a reply... */
17562   W (ret);
17563   return ret;
17564 }
17565
17566 #define api_lisp_enable_disable api_one_enable_disable
17567
17568 static int
17569 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17570 {
17571   unformat_input_t *input = vam->input;
17572   vl_api_one_enable_disable_xtr_mode_t *mp;
17573   u8 is_set = 0;
17574   u8 is_en = 0;
17575   int ret;
17576
17577   /* Parse args required to build the message */
17578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17579     {
17580       if (unformat (input, "enable"))
17581         {
17582           is_set = 1;
17583           is_en = 1;
17584         }
17585       else if (unformat (input, "disable"))
17586         {
17587           is_set = 1;
17588         }
17589       else
17590         break;
17591     }
17592
17593   if (!is_set)
17594     {
17595       errmsg ("Value not set");
17596       return -99;
17597     }
17598
17599   /* Construct the API message */
17600   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17601
17602   mp->is_en = is_en;
17603
17604   /* send it... */
17605   S (mp);
17606
17607   /* Wait for a reply... */
17608   W (ret);
17609   return ret;
17610 }
17611
17612 static int
17613 api_one_show_xtr_mode (vat_main_t * vam)
17614 {
17615   vl_api_one_show_xtr_mode_t *mp;
17616   int ret;
17617
17618   /* Construct the API message */
17619   M (ONE_SHOW_XTR_MODE, mp);
17620
17621   /* send it... */
17622   S (mp);
17623
17624   /* Wait for a reply... */
17625   W (ret);
17626   return ret;
17627 }
17628
17629 static int
17630 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17631 {
17632   unformat_input_t *input = vam->input;
17633   vl_api_one_enable_disable_pitr_mode_t *mp;
17634   u8 is_set = 0;
17635   u8 is_en = 0;
17636   int ret;
17637
17638   /* Parse args required to build the message */
17639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17640     {
17641       if (unformat (input, "enable"))
17642         {
17643           is_set = 1;
17644           is_en = 1;
17645         }
17646       else if (unformat (input, "disable"))
17647         {
17648           is_set = 1;
17649         }
17650       else
17651         break;
17652     }
17653
17654   if (!is_set)
17655     {
17656       errmsg ("Value not set");
17657       return -99;
17658     }
17659
17660   /* Construct the API message */
17661   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17662
17663   mp->is_en = is_en;
17664
17665   /* send it... */
17666   S (mp);
17667
17668   /* Wait for a reply... */
17669   W (ret);
17670   return ret;
17671 }
17672
17673 static int
17674 api_one_show_pitr_mode (vat_main_t * vam)
17675 {
17676   vl_api_one_show_pitr_mode_t *mp;
17677   int ret;
17678
17679   /* Construct the API message */
17680   M (ONE_SHOW_PITR_MODE, mp);
17681
17682   /* send it... */
17683   S (mp);
17684
17685   /* Wait for a reply... */
17686   W (ret);
17687   return ret;
17688 }
17689
17690 static int
17691 api_one_enable_disable_petr_mode (vat_main_t * vam)
17692 {
17693   unformat_input_t *input = vam->input;
17694   vl_api_one_enable_disable_petr_mode_t *mp;
17695   u8 is_set = 0;
17696   u8 is_en = 0;
17697   int ret;
17698
17699   /* Parse args required to build the message */
17700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17701     {
17702       if (unformat (input, "enable"))
17703         {
17704           is_set = 1;
17705           is_en = 1;
17706         }
17707       else if (unformat (input, "disable"))
17708         {
17709           is_set = 1;
17710         }
17711       else
17712         break;
17713     }
17714
17715   if (!is_set)
17716     {
17717       errmsg ("Value not set");
17718       return -99;
17719     }
17720
17721   /* Construct the API message */
17722   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17723
17724   mp->is_en = is_en;
17725
17726   /* send it... */
17727   S (mp);
17728
17729   /* Wait for a reply... */
17730   W (ret);
17731   return ret;
17732 }
17733
17734 static int
17735 api_one_show_petr_mode (vat_main_t * vam)
17736 {
17737   vl_api_one_show_petr_mode_t *mp;
17738   int ret;
17739
17740   /* Construct the API message */
17741   M (ONE_SHOW_PETR_MODE, mp);
17742
17743   /* send it... */
17744   S (mp);
17745
17746   /* Wait for a reply... */
17747   W (ret);
17748   return ret;
17749 }
17750
17751 static int
17752 api_show_one_map_register_state (vat_main_t * vam)
17753 {
17754   vl_api_show_one_map_register_state_t *mp;
17755   int ret;
17756
17757   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17758
17759   /* send */
17760   S (mp);
17761
17762   /* wait for reply */
17763   W (ret);
17764   return ret;
17765 }
17766
17767 #define api_show_lisp_map_register_state api_show_one_map_register_state
17768
17769 static int
17770 api_show_one_rloc_probe_state (vat_main_t * vam)
17771 {
17772   vl_api_show_one_rloc_probe_state_t *mp;
17773   int ret;
17774
17775   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17776
17777   /* send */
17778   S (mp);
17779
17780   /* wait for reply */
17781   W (ret);
17782   return ret;
17783 }
17784
17785 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17786
17787 static int
17788 api_one_add_del_ndp_entry (vat_main_t * vam)
17789 {
17790   vl_api_one_add_del_ndp_entry_t *mp;
17791   unformat_input_t *input = vam->input;
17792   u8 is_add = 1;
17793   u8 mac_set = 0;
17794   u8 bd_set = 0;
17795   u8 ip_set = 0;
17796   u8 mac[6] = { 0, };
17797   u8 ip6[16] = { 0, };
17798   u32 bd = ~0;
17799   int ret;
17800
17801   /* Parse args required to build the message */
17802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17803     {
17804       if (unformat (input, "del"))
17805         is_add = 0;
17806       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17807         mac_set = 1;
17808       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17809         ip_set = 1;
17810       else if (unformat (input, "bd %d", &bd))
17811         bd_set = 1;
17812       else
17813         {
17814           errmsg ("parse error '%U'", format_unformat_error, input);
17815           return -99;
17816         }
17817     }
17818
17819   if (!bd_set || !ip_set || (!mac_set && is_add))
17820     {
17821       errmsg ("Missing BD, IP or MAC!");
17822       return -99;
17823     }
17824
17825   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17826   mp->is_add = is_add;
17827   clib_memcpy (mp->mac, mac, 6);
17828   mp->bd = clib_host_to_net_u32 (bd);
17829   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17830
17831   /* send */
17832   S (mp);
17833
17834   /* wait for reply */
17835   W (ret);
17836   return ret;
17837 }
17838
17839 static int
17840 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17841 {
17842   vl_api_one_add_del_l2_arp_entry_t *mp;
17843   unformat_input_t *input = vam->input;
17844   u8 is_add = 1;
17845   u8 mac_set = 0;
17846   u8 bd_set = 0;
17847   u8 ip_set = 0;
17848   u8 mac[6] = { 0, };
17849   u32 ip4 = 0, bd = ~0;
17850   int ret;
17851
17852   /* Parse args required to build the message */
17853   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17854     {
17855       if (unformat (input, "del"))
17856         is_add = 0;
17857       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17858         mac_set = 1;
17859       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17860         ip_set = 1;
17861       else if (unformat (input, "bd %d", &bd))
17862         bd_set = 1;
17863       else
17864         {
17865           errmsg ("parse error '%U'", format_unformat_error, input);
17866           return -99;
17867         }
17868     }
17869
17870   if (!bd_set || !ip_set || (!mac_set && is_add))
17871     {
17872       errmsg ("Missing BD, IP or MAC!");
17873       return -99;
17874     }
17875
17876   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17877   mp->is_add = is_add;
17878   clib_memcpy (mp->mac, mac, 6);
17879   mp->bd = clib_host_to_net_u32 (bd);
17880   mp->ip4 = ip4;
17881
17882   /* send */
17883   S (mp);
17884
17885   /* wait for reply */
17886   W (ret);
17887   return ret;
17888 }
17889
17890 static int
17891 api_one_ndp_bd_get (vat_main_t * vam)
17892 {
17893   vl_api_one_ndp_bd_get_t *mp;
17894   int ret;
17895
17896   M (ONE_NDP_BD_GET, mp);
17897
17898   /* send */
17899   S (mp);
17900
17901   /* wait for reply */
17902   W (ret);
17903   return ret;
17904 }
17905
17906 static int
17907 api_one_ndp_entries_get (vat_main_t * vam)
17908 {
17909   vl_api_one_ndp_entries_get_t *mp;
17910   unformat_input_t *input = vam->input;
17911   u8 bd_set = 0;
17912   u32 bd = ~0;
17913   int ret;
17914
17915   /* Parse args required to build the message */
17916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17917     {
17918       if (unformat (input, "bd %d", &bd))
17919         bd_set = 1;
17920       else
17921         {
17922           errmsg ("parse error '%U'", format_unformat_error, input);
17923           return -99;
17924         }
17925     }
17926
17927   if (!bd_set)
17928     {
17929       errmsg ("Expected bridge domain!");
17930       return -99;
17931     }
17932
17933   M (ONE_NDP_ENTRIES_GET, mp);
17934   mp->bd = clib_host_to_net_u32 (bd);
17935
17936   /* send */
17937   S (mp);
17938
17939   /* wait for reply */
17940   W (ret);
17941   return ret;
17942 }
17943
17944 static int
17945 api_one_l2_arp_bd_get (vat_main_t * vam)
17946 {
17947   vl_api_one_l2_arp_bd_get_t *mp;
17948   int ret;
17949
17950   M (ONE_L2_ARP_BD_GET, mp);
17951
17952   /* send */
17953   S (mp);
17954
17955   /* wait for reply */
17956   W (ret);
17957   return ret;
17958 }
17959
17960 static int
17961 api_one_l2_arp_entries_get (vat_main_t * vam)
17962 {
17963   vl_api_one_l2_arp_entries_get_t *mp;
17964   unformat_input_t *input = vam->input;
17965   u8 bd_set = 0;
17966   u32 bd = ~0;
17967   int ret;
17968
17969   /* Parse args required to build the message */
17970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17971     {
17972       if (unformat (input, "bd %d", &bd))
17973         bd_set = 1;
17974       else
17975         {
17976           errmsg ("parse error '%U'", format_unformat_error, input);
17977           return -99;
17978         }
17979     }
17980
17981   if (!bd_set)
17982     {
17983       errmsg ("Expected bridge domain!");
17984       return -99;
17985     }
17986
17987   M (ONE_L2_ARP_ENTRIES_GET, mp);
17988   mp->bd = clib_host_to_net_u32 (bd);
17989
17990   /* send */
17991   S (mp);
17992
17993   /* wait for reply */
17994   W (ret);
17995   return ret;
17996 }
17997
17998 static int
17999 api_one_stats_enable_disable (vat_main_t * vam)
18000 {
18001   vl_api_one_stats_enable_disable_t *mp;
18002   unformat_input_t *input = vam->input;
18003   u8 is_set = 0;
18004   u8 is_en = 0;
18005   int ret;
18006
18007   /* Parse args required to build the message */
18008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18009     {
18010       if (unformat (input, "enable"))
18011         {
18012           is_set = 1;
18013           is_en = 1;
18014         }
18015       else if (unformat (input, "disable"))
18016         {
18017           is_set = 1;
18018         }
18019       else
18020         break;
18021     }
18022
18023   if (!is_set)
18024     {
18025       errmsg ("Value not set");
18026       return -99;
18027     }
18028
18029   M (ONE_STATS_ENABLE_DISABLE, mp);
18030   mp->is_en = is_en;
18031
18032   /* send */
18033   S (mp);
18034
18035   /* wait for reply */
18036   W (ret);
18037   return ret;
18038 }
18039
18040 static int
18041 api_show_one_stats_enable_disable (vat_main_t * vam)
18042 {
18043   vl_api_show_one_stats_enable_disable_t *mp;
18044   int ret;
18045
18046   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18047
18048   /* send */
18049   S (mp);
18050
18051   /* wait for reply */
18052   W (ret);
18053   return ret;
18054 }
18055
18056 static int
18057 api_show_one_map_request_mode (vat_main_t * vam)
18058 {
18059   vl_api_show_one_map_request_mode_t *mp;
18060   int ret;
18061
18062   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18063
18064   /* send */
18065   S (mp);
18066
18067   /* wait for reply */
18068   W (ret);
18069   return ret;
18070 }
18071
18072 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18073
18074 static int
18075 api_one_map_request_mode (vat_main_t * vam)
18076 {
18077   unformat_input_t *input = vam->input;
18078   vl_api_one_map_request_mode_t *mp;
18079   u8 mode = 0;
18080   int ret;
18081
18082   /* Parse args required to build the message */
18083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18084     {
18085       if (unformat (input, "dst-only"))
18086         mode = 0;
18087       else if (unformat (input, "src-dst"))
18088         mode = 1;
18089       else
18090         {
18091           errmsg ("parse error '%U'", format_unformat_error, input);
18092           return -99;
18093         }
18094     }
18095
18096   M (ONE_MAP_REQUEST_MODE, mp);
18097
18098   mp->mode = mode;
18099
18100   /* send */
18101   S (mp);
18102
18103   /* wait for reply */
18104   W (ret);
18105   return ret;
18106 }
18107
18108 #define api_lisp_map_request_mode api_one_map_request_mode
18109
18110 /**
18111  * Enable/disable ONE proxy ITR.
18112  *
18113  * @param vam vpp API test context
18114  * @return return code
18115  */
18116 static int
18117 api_one_pitr_set_locator_set (vat_main_t * vam)
18118 {
18119   u8 ls_name_set = 0;
18120   unformat_input_t *input = vam->input;
18121   vl_api_one_pitr_set_locator_set_t *mp;
18122   u8 is_add = 1;
18123   u8 *ls_name = 0;
18124   int ret;
18125
18126   /* Parse args required to build the message */
18127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18128     {
18129       if (unformat (input, "del"))
18130         is_add = 0;
18131       else if (unformat (input, "locator-set %s", &ls_name))
18132         ls_name_set = 1;
18133       else
18134         {
18135           errmsg ("parse error '%U'", format_unformat_error, input);
18136           return -99;
18137         }
18138     }
18139
18140   if (!ls_name_set)
18141     {
18142       errmsg ("locator-set name not set!");
18143       return -99;
18144     }
18145
18146   M (ONE_PITR_SET_LOCATOR_SET, mp);
18147
18148   mp->is_add = is_add;
18149   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18150   vec_free (ls_name);
18151
18152   /* send */
18153   S (mp);
18154
18155   /* wait for reply */
18156   W (ret);
18157   return ret;
18158 }
18159
18160 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18161
18162 static int
18163 api_one_nsh_set_locator_set (vat_main_t * vam)
18164 {
18165   u8 ls_name_set = 0;
18166   unformat_input_t *input = vam->input;
18167   vl_api_one_nsh_set_locator_set_t *mp;
18168   u8 is_add = 1;
18169   u8 *ls_name = 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, "del"))
18176         is_add = 0;
18177       else if (unformat (input, "ls %s", &ls_name))
18178         ls_name_set = 1;
18179       else
18180         {
18181           errmsg ("parse error '%U'", format_unformat_error, input);
18182           return -99;
18183         }
18184     }
18185
18186   if (!ls_name_set && is_add)
18187     {
18188       errmsg ("locator-set name not set!");
18189       return -99;
18190     }
18191
18192   M (ONE_NSH_SET_LOCATOR_SET, mp);
18193
18194   mp->is_add = is_add;
18195   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18196   vec_free (ls_name);
18197
18198   /* send */
18199   S (mp);
18200
18201   /* wait for reply */
18202   W (ret);
18203   return ret;
18204 }
18205
18206 static int
18207 api_show_one_pitr (vat_main_t * vam)
18208 {
18209   vl_api_show_one_pitr_t *mp;
18210   int ret;
18211
18212   if (!vam->json_output)
18213     {
18214       print (vam->ofp, "%=20s", "lisp status:");
18215     }
18216
18217   M (SHOW_ONE_PITR, mp);
18218   /* send it... */
18219   S (mp);
18220
18221   /* Wait for a reply... */
18222   W (ret);
18223   return ret;
18224 }
18225
18226 #define api_show_lisp_pitr api_show_one_pitr
18227
18228 static int
18229 api_one_use_petr (vat_main_t * vam)
18230 {
18231   unformat_input_t *input = vam->input;
18232   vl_api_one_use_petr_t *mp;
18233   u8 is_add = 0;
18234   ip_address_t ip;
18235   int ret;
18236
18237   memset (&ip, 0, sizeof (ip));
18238
18239   /* Parse args required to build the message */
18240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18241     {
18242       if (unformat (input, "disable"))
18243         is_add = 0;
18244       else
18245         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18246         {
18247           is_add = 1;
18248           ip_addr_version (&ip) = IP4;
18249         }
18250       else
18251         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18252         {
18253           is_add = 1;
18254           ip_addr_version (&ip) = IP6;
18255         }
18256       else
18257         {
18258           errmsg ("parse error '%U'", format_unformat_error, input);
18259           return -99;
18260         }
18261     }
18262
18263   M (ONE_USE_PETR, mp);
18264
18265   mp->is_add = is_add;
18266   if (is_add)
18267     {
18268       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18269       if (mp->is_ip4)
18270         clib_memcpy (mp->address, &ip, 4);
18271       else
18272         clib_memcpy (mp->address, &ip, 16);
18273     }
18274
18275   /* send */
18276   S (mp);
18277
18278   /* wait for reply */
18279   W (ret);
18280   return ret;
18281 }
18282
18283 #define api_lisp_use_petr api_one_use_petr
18284
18285 static int
18286 api_show_one_nsh_mapping (vat_main_t * vam)
18287 {
18288   vl_api_show_one_use_petr_t *mp;
18289   int ret;
18290
18291   if (!vam->json_output)
18292     {
18293       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18294     }
18295
18296   M (SHOW_ONE_NSH_MAPPING, mp);
18297   /* send it... */
18298   S (mp);
18299
18300   /* Wait for a reply... */
18301   W (ret);
18302   return ret;
18303 }
18304
18305 static int
18306 api_show_one_use_petr (vat_main_t * vam)
18307 {
18308   vl_api_show_one_use_petr_t *mp;
18309   int ret;
18310
18311   if (!vam->json_output)
18312     {
18313       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18314     }
18315
18316   M (SHOW_ONE_USE_PETR, mp);
18317   /* send it... */
18318   S (mp);
18319
18320   /* Wait for a reply... */
18321   W (ret);
18322   return ret;
18323 }
18324
18325 #define api_show_lisp_use_petr api_show_one_use_petr
18326
18327 /**
18328  * Add/delete mapping between vni and vrf
18329  */
18330 static int
18331 api_one_eid_table_add_del_map (vat_main_t * vam)
18332 {
18333   unformat_input_t *input = vam->input;
18334   vl_api_one_eid_table_add_del_map_t *mp;
18335   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18336   u32 vni, vrf, bd_index;
18337   int ret;
18338
18339   /* Parse args required to build the message */
18340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18341     {
18342       if (unformat (input, "del"))
18343         is_add = 0;
18344       else if (unformat (input, "vrf %d", &vrf))
18345         vrf_set = 1;
18346       else if (unformat (input, "bd_index %d", &bd_index))
18347         bd_index_set = 1;
18348       else if (unformat (input, "vni %d", &vni))
18349         vni_set = 1;
18350       else
18351         break;
18352     }
18353
18354   if (!vni_set || (!vrf_set && !bd_index_set))
18355     {
18356       errmsg ("missing arguments!");
18357       return -99;
18358     }
18359
18360   if (vrf_set && bd_index_set)
18361     {
18362       errmsg ("error: both vrf and bd entered!");
18363       return -99;
18364     }
18365
18366   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18367
18368   mp->is_add = is_add;
18369   mp->vni = htonl (vni);
18370   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18371   mp->is_l2 = bd_index_set;
18372
18373   /* send */
18374   S (mp);
18375
18376   /* wait for reply */
18377   W (ret);
18378   return ret;
18379 }
18380
18381 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18382
18383 uword
18384 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18385 {
18386   u32 *action = va_arg (*args, u32 *);
18387   u8 *s = 0;
18388
18389   if (unformat (input, "%s", &s))
18390     {
18391       if (!strcmp ((char *) s, "no-action"))
18392         action[0] = 0;
18393       else if (!strcmp ((char *) s, "natively-forward"))
18394         action[0] = 1;
18395       else if (!strcmp ((char *) s, "send-map-request"))
18396         action[0] = 2;
18397       else if (!strcmp ((char *) s, "drop"))
18398         action[0] = 3;
18399       else
18400         {
18401           clib_warning ("invalid action: '%s'", s);
18402           action[0] = 3;
18403         }
18404     }
18405   else
18406     return 0;
18407
18408   vec_free (s);
18409   return 1;
18410 }
18411
18412 /**
18413  * Add/del remote mapping to/from ONE control plane
18414  *
18415  * @param vam vpp API test context
18416  * @return return code
18417  */
18418 static int
18419 api_one_add_del_remote_mapping (vat_main_t * vam)
18420 {
18421   unformat_input_t *input = vam->input;
18422   vl_api_one_add_del_remote_mapping_t *mp;
18423   u32 vni = 0;
18424   lisp_eid_vat_t _eid, *eid = &_eid;
18425   lisp_eid_vat_t _seid, *seid = &_seid;
18426   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18427   u32 action = ~0, p, w, data_len;
18428   ip4_address_t rloc4;
18429   ip6_address_t rloc6;
18430   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18431   int ret;
18432
18433   memset (&rloc, 0, sizeof (rloc));
18434
18435   /* Parse args required to build the message */
18436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18437     {
18438       if (unformat (input, "del-all"))
18439         {
18440           del_all = 1;
18441         }
18442       else if (unformat (input, "del"))
18443         {
18444           is_add = 0;
18445         }
18446       else if (unformat (input, "add"))
18447         {
18448           is_add = 1;
18449         }
18450       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18451         {
18452           eid_set = 1;
18453         }
18454       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18455         {
18456           seid_set = 1;
18457         }
18458       else if (unformat (input, "vni %d", &vni))
18459         {
18460           ;
18461         }
18462       else if (unformat (input, "p %d w %d", &p, &w))
18463         {
18464           if (!curr_rloc)
18465             {
18466               errmsg ("No RLOC configured for setting priority/weight!");
18467               return -99;
18468             }
18469           curr_rloc->priority = p;
18470           curr_rloc->weight = w;
18471         }
18472       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18473         {
18474           rloc.is_ip4 = 1;
18475           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18476           vec_add1 (rlocs, rloc);
18477           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18478         }
18479       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18480         {
18481           rloc.is_ip4 = 0;
18482           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18483           vec_add1 (rlocs, rloc);
18484           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18485         }
18486       else if (unformat (input, "action %U",
18487                          unformat_negative_mapping_action, &action))
18488         {
18489           ;
18490         }
18491       else
18492         {
18493           clib_warning ("parse error '%U'", format_unformat_error, input);
18494           return -99;
18495         }
18496     }
18497
18498   if (0 == eid_set)
18499     {
18500       errmsg ("missing params!");
18501       return -99;
18502     }
18503
18504   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18505     {
18506       errmsg ("no action set for negative map-reply!");
18507       return -99;
18508     }
18509
18510   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18511
18512   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18513   mp->is_add = is_add;
18514   mp->vni = htonl (vni);
18515   mp->action = (u8) action;
18516   mp->is_src_dst = seid_set;
18517   mp->eid_len = eid->len;
18518   mp->seid_len = seid->len;
18519   mp->del_all = del_all;
18520   mp->eid_type = eid->type;
18521   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18522   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18523
18524   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18525   clib_memcpy (mp->rlocs, rlocs, data_len);
18526   vec_free (rlocs);
18527
18528   /* send it... */
18529   S (mp);
18530
18531   /* Wait for a reply... */
18532   W (ret);
18533   return ret;
18534 }
18535
18536 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18537
18538 /**
18539  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18540  * forwarding entries in data-plane accordingly.
18541  *
18542  * @param vam vpp API test context
18543  * @return return code
18544  */
18545 static int
18546 api_one_add_del_adjacency (vat_main_t * vam)
18547 {
18548   unformat_input_t *input = vam->input;
18549   vl_api_one_add_del_adjacency_t *mp;
18550   u32 vni = 0;
18551   ip4_address_t leid4, reid4;
18552   ip6_address_t leid6, reid6;
18553   u8 reid_mac[6] = { 0 };
18554   u8 leid_mac[6] = { 0 };
18555   u8 reid_type, leid_type;
18556   u32 leid_len = 0, reid_len = 0, len;
18557   u8 is_add = 1;
18558   int ret;
18559
18560   leid_type = reid_type = (u8) ~ 0;
18561
18562   /* Parse args required to build the message */
18563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18564     {
18565       if (unformat (input, "del"))
18566         {
18567           is_add = 0;
18568         }
18569       else if (unformat (input, "add"))
18570         {
18571           is_add = 1;
18572         }
18573       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18574                          &reid4, &len))
18575         {
18576           reid_type = 0;        /* ipv4 */
18577           reid_len = len;
18578         }
18579       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18580                          &reid6, &len))
18581         {
18582           reid_type = 1;        /* ipv6 */
18583           reid_len = len;
18584         }
18585       else if (unformat (input, "reid %U", unformat_ethernet_address,
18586                          reid_mac))
18587         {
18588           reid_type = 2;        /* mac */
18589         }
18590       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18591                          &leid4, &len))
18592         {
18593           leid_type = 0;        /* ipv4 */
18594           leid_len = len;
18595         }
18596       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18597                          &leid6, &len))
18598         {
18599           leid_type = 1;        /* ipv6 */
18600           leid_len = len;
18601         }
18602       else if (unformat (input, "leid %U", unformat_ethernet_address,
18603                          leid_mac))
18604         {
18605           leid_type = 2;        /* mac */
18606         }
18607       else if (unformat (input, "vni %d", &vni))
18608         {
18609           ;
18610         }
18611       else
18612         {
18613           errmsg ("parse error '%U'", format_unformat_error, input);
18614           return -99;
18615         }
18616     }
18617
18618   if ((u8) ~ 0 == reid_type)
18619     {
18620       errmsg ("missing params!");
18621       return -99;
18622     }
18623
18624   if (leid_type != reid_type)
18625     {
18626       errmsg ("remote and local EIDs are of different types!");
18627       return -99;
18628     }
18629
18630   M (ONE_ADD_DEL_ADJACENCY, mp);
18631   mp->is_add = is_add;
18632   mp->vni = htonl (vni);
18633   mp->leid_len = leid_len;
18634   mp->reid_len = reid_len;
18635   mp->eid_type = reid_type;
18636
18637   switch (mp->eid_type)
18638     {
18639     case 0:
18640       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18641       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18642       break;
18643     case 1:
18644       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18645       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18646       break;
18647     case 2:
18648       clib_memcpy (mp->leid, leid_mac, 6);
18649       clib_memcpy (mp->reid, reid_mac, 6);
18650       break;
18651     default:
18652       errmsg ("unknown EID type %d!", mp->eid_type);
18653       return 0;
18654     }
18655
18656   /* send it... */
18657   S (mp);
18658
18659   /* Wait for a reply... */
18660   W (ret);
18661   return ret;
18662 }
18663
18664 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18665
18666 uword
18667 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18668 {
18669   u32 *mode = va_arg (*args, u32 *);
18670
18671   if (unformat (input, "lisp"))
18672     *mode = 0;
18673   else if (unformat (input, "vxlan"))
18674     *mode = 1;
18675   else
18676     return 0;
18677
18678   return 1;
18679 }
18680
18681 static int
18682 api_gpe_get_encap_mode (vat_main_t * vam)
18683 {
18684   vl_api_gpe_get_encap_mode_t *mp;
18685   int ret;
18686
18687   /* Construct the API message */
18688   M (GPE_GET_ENCAP_MODE, mp);
18689
18690   /* send it... */
18691   S (mp);
18692
18693   /* Wait for a reply... */
18694   W (ret);
18695   return ret;
18696 }
18697
18698 static int
18699 api_gpe_set_encap_mode (vat_main_t * vam)
18700 {
18701   unformat_input_t *input = vam->input;
18702   vl_api_gpe_set_encap_mode_t *mp;
18703   int ret;
18704   u32 mode = 0;
18705
18706   /* Parse args required to build the message */
18707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18708     {
18709       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18710         ;
18711       else
18712         break;
18713     }
18714
18715   /* Construct the API message */
18716   M (GPE_SET_ENCAP_MODE, mp);
18717
18718   mp->mode = mode;
18719
18720   /* send it... */
18721   S (mp);
18722
18723   /* Wait for a reply... */
18724   W (ret);
18725   return ret;
18726 }
18727
18728 static int
18729 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18730 {
18731   unformat_input_t *input = vam->input;
18732   vl_api_gpe_add_del_iface_t *mp;
18733   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18734   u32 dp_table = 0, vni = 0;
18735   int ret;
18736
18737   /* Parse args required to build the message */
18738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18739     {
18740       if (unformat (input, "up"))
18741         {
18742           action_set = 1;
18743           is_add = 1;
18744         }
18745       else if (unformat (input, "down"))
18746         {
18747           action_set = 1;
18748           is_add = 0;
18749         }
18750       else if (unformat (input, "table_id %d", &dp_table))
18751         {
18752           dp_table_set = 1;
18753         }
18754       else if (unformat (input, "bd_id %d", &dp_table))
18755         {
18756           dp_table_set = 1;
18757           is_l2 = 1;
18758         }
18759       else if (unformat (input, "vni %d", &vni))
18760         {
18761           vni_set = 1;
18762         }
18763       else
18764         break;
18765     }
18766
18767   if (action_set == 0)
18768     {
18769       errmsg ("Action not set");
18770       return -99;
18771     }
18772   if (dp_table_set == 0 || vni_set == 0)
18773     {
18774       errmsg ("vni and dp_table must be set");
18775       return -99;
18776     }
18777
18778   /* Construct the API message */
18779   M (GPE_ADD_DEL_IFACE, mp);
18780
18781   mp->is_add = is_add;
18782   mp->dp_table = clib_host_to_net_u32 (dp_table);
18783   mp->is_l2 = is_l2;
18784   mp->vni = clib_host_to_net_u32 (vni);
18785
18786   /* send it... */
18787   S (mp);
18788
18789   /* Wait for a reply... */
18790   W (ret);
18791   return ret;
18792 }
18793
18794 static int
18795 api_one_map_register_fallback_threshold (vat_main_t * vam)
18796 {
18797   unformat_input_t *input = vam->input;
18798   vl_api_one_map_register_fallback_threshold_t *mp;
18799   u32 value = 0;
18800   u8 is_set = 0;
18801   int ret;
18802
18803   /* Parse args required to build the message */
18804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18805     {
18806       if (unformat (input, "%u", &value))
18807         is_set = 1;
18808       else
18809         {
18810           clib_warning ("parse error '%U'", format_unformat_error, input);
18811           return -99;
18812         }
18813     }
18814
18815   if (!is_set)
18816     {
18817       errmsg ("fallback threshold value is missing!");
18818       return -99;
18819     }
18820
18821   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18822   mp->value = clib_host_to_net_u32 (value);
18823
18824   /* send it... */
18825   S (mp);
18826
18827   /* Wait for a reply... */
18828   W (ret);
18829   return ret;
18830 }
18831
18832 static int
18833 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18834 {
18835   vl_api_show_one_map_register_fallback_threshold_t *mp;
18836   int ret;
18837
18838   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18839
18840   /* send it... */
18841   S (mp);
18842
18843   /* Wait for a reply... */
18844   W (ret);
18845   return ret;
18846 }
18847
18848 uword
18849 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18850 {
18851   u32 *proto = va_arg (*args, u32 *);
18852
18853   if (unformat (input, "udp"))
18854     *proto = 1;
18855   else if (unformat (input, "api"))
18856     *proto = 2;
18857   else
18858     return 0;
18859
18860   return 1;
18861 }
18862
18863 static int
18864 api_one_set_transport_protocol (vat_main_t * vam)
18865 {
18866   unformat_input_t *input = vam->input;
18867   vl_api_one_set_transport_protocol_t *mp;
18868   u8 is_set = 0;
18869   u32 protocol = 0;
18870   int ret;
18871
18872   /* Parse args required to build the message */
18873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18874     {
18875       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18876         is_set = 1;
18877       else
18878         {
18879           clib_warning ("parse error '%U'", format_unformat_error, input);
18880           return -99;
18881         }
18882     }
18883
18884   if (!is_set)
18885     {
18886       errmsg ("Transport protocol missing!");
18887       return -99;
18888     }
18889
18890   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18891   mp->protocol = (u8) protocol;
18892
18893   /* send it... */
18894   S (mp);
18895
18896   /* Wait for a reply... */
18897   W (ret);
18898   return ret;
18899 }
18900
18901 static int
18902 api_one_get_transport_protocol (vat_main_t * vam)
18903 {
18904   vl_api_one_get_transport_protocol_t *mp;
18905   int ret;
18906
18907   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18908
18909   /* send it... */
18910   S (mp);
18911
18912   /* Wait for a reply... */
18913   W (ret);
18914   return ret;
18915 }
18916
18917 static int
18918 api_one_map_register_set_ttl (vat_main_t * vam)
18919 {
18920   unformat_input_t *input = vam->input;
18921   vl_api_one_map_register_set_ttl_t *mp;
18922   u32 ttl = 0;
18923   u8 is_set = 0;
18924   int ret;
18925
18926   /* Parse args required to build the message */
18927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18928     {
18929       if (unformat (input, "%u", &ttl))
18930         is_set = 1;
18931       else
18932         {
18933           clib_warning ("parse error '%U'", format_unformat_error, input);
18934           return -99;
18935         }
18936     }
18937
18938   if (!is_set)
18939     {
18940       errmsg ("TTL value missing!");
18941       return -99;
18942     }
18943
18944   M (ONE_MAP_REGISTER_SET_TTL, mp);
18945   mp->ttl = clib_host_to_net_u32 (ttl);
18946
18947   /* send it... */
18948   S (mp);
18949
18950   /* Wait for a reply... */
18951   W (ret);
18952   return ret;
18953 }
18954
18955 static int
18956 api_show_one_map_register_ttl (vat_main_t * vam)
18957 {
18958   vl_api_show_one_map_register_ttl_t *mp;
18959   int ret;
18960
18961   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18962
18963   /* send it... */
18964   S (mp);
18965
18966   /* Wait for a reply... */
18967   W (ret);
18968   return ret;
18969 }
18970
18971 /**
18972  * Add/del map request itr rlocs from ONE control plane and updates
18973  *
18974  * @param vam vpp API test context
18975  * @return return code
18976  */
18977 static int
18978 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18979 {
18980   unformat_input_t *input = vam->input;
18981   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18982   u8 *locator_set_name = 0;
18983   u8 locator_set_name_set = 0;
18984   u8 is_add = 1;
18985   int ret;
18986
18987   /* Parse args required to build the message */
18988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18989     {
18990       if (unformat (input, "del"))
18991         {
18992           is_add = 0;
18993         }
18994       else if (unformat (input, "%_%v%_", &locator_set_name))
18995         {
18996           locator_set_name_set = 1;
18997         }
18998       else
18999         {
19000           clib_warning ("parse error '%U'", format_unformat_error, input);
19001           return -99;
19002         }
19003     }
19004
19005   if (is_add && !locator_set_name_set)
19006     {
19007       errmsg ("itr-rloc is not set!");
19008       return -99;
19009     }
19010
19011   if (is_add && vec_len (locator_set_name) > 64)
19012     {
19013       errmsg ("itr-rloc locator-set name too long");
19014       vec_free (locator_set_name);
19015       return -99;
19016     }
19017
19018   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19019   mp->is_add = is_add;
19020   if (is_add)
19021     {
19022       clib_memcpy (mp->locator_set_name, locator_set_name,
19023                    vec_len (locator_set_name));
19024     }
19025   else
19026     {
19027       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19028     }
19029   vec_free (locator_set_name);
19030
19031   /* send it... */
19032   S (mp);
19033
19034   /* Wait for a reply... */
19035   W (ret);
19036   return ret;
19037 }
19038
19039 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19040
19041 static int
19042 api_one_locator_dump (vat_main_t * vam)
19043 {
19044   unformat_input_t *input = vam->input;
19045   vl_api_one_locator_dump_t *mp;
19046   vl_api_control_ping_t *mp_ping;
19047   u8 is_index_set = 0, is_name_set = 0;
19048   u8 *ls_name = 0;
19049   u32 ls_index = ~0;
19050   int ret;
19051
19052   /* Parse args required to build the message */
19053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19054     {
19055       if (unformat (input, "ls_name %_%v%_", &ls_name))
19056         {
19057           is_name_set = 1;
19058         }
19059       else if (unformat (input, "ls_index %d", &ls_index))
19060         {
19061           is_index_set = 1;
19062         }
19063       else
19064         {
19065           errmsg ("parse error '%U'", format_unformat_error, input);
19066           return -99;
19067         }
19068     }
19069
19070   if (!is_index_set && !is_name_set)
19071     {
19072       errmsg ("error: expected one of index or name!");
19073       return -99;
19074     }
19075
19076   if (is_index_set && is_name_set)
19077     {
19078       errmsg ("error: only one param expected!");
19079       return -99;
19080     }
19081
19082   if (vec_len (ls_name) > 62)
19083     {
19084       errmsg ("error: locator set name too long!");
19085       return -99;
19086     }
19087
19088   if (!vam->json_output)
19089     {
19090       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19091     }
19092
19093   M (ONE_LOCATOR_DUMP, mp);
19094   mp->is_index_set = is_index_set;
19095
19096   if (is_index_set)
19097     mp->ls_index = clib_host_to_net_u32 (ls_index);
19098   else
19099     {
19100       vec_add1 (ls_name, 0);
19101       strncpy ((char *) mp->ls_name, (char *) ls_name,
19102                sizeof (mp->ls_name) - 1);
19103     }
19104
19105   /* send it... */
19106   S (mp);
19107
19108   /* Use a control ping for synchronization */
19109   MPING (CONTROL_PING, mp_ping);
19110   S (mp_ping);
19111
19112   /* Wait for a reply... */
19113   W (ret);
19114   return ret;
19115 }
19116
19117 #define api_lisp_locator_dump api_one_locator_dump
19118
19119 static int
19120 api_one_locator_set_dump (vat_main_t * vam)
19121 {
19122   vl_api_one_locator_set_dump_t *mp;
19123   vl_api_control_ping_t *mp_ping;
19124   unformat_input_t *input = vam->input;
19125   u8 filter = 0;
19126   int ret;
19127
19128   /* Parse args required to build the message */
19129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19130     {
19131       if (unformat (input, "local"))
19132         {
19133           filter = 1;
19134         }
19135       else if (unformat (input, "remote"))
19136         {
19137           filter = 2;
19138         }
19139       else
19140         {
19141           errmsg ("parse error '%U'", format_unformat_error, input);
19142           return -99;
19143         }
19144     }
19145
19146   if (!vam->json_output)
19147     {
19148       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19149     }
19150
19151   M (ONE_LOCATOR_SET_DUMP, mp);
19152
19153   mp->filter = filter;
19154
19155   /* send it... */
19156   S (mp);
19157
19158   /* Use a control ping for synchronization */
19159   MPING (CONTROL_PING, mp_ping);
19160   S (mp_ping);
19161
19162   /* Wait for a reply... */
19163   W (ret);
19164   return ret;
19165 }
19166
19167 #define api_lisp_locator_set_dump api_one_locator_set_dump
19168
19169 static int
19170 api_one_eid_table_map_dump (vat_main_t * vam)
19171 {
19172   u8 is_l2 = 0;
19173   u8 mode_set = 0;
19174   unformat_input_t *input = vam->input;
19175   vl_api_one_eid_table_map_dump_t *mp;
19176   vl_api_control_ping_t *mp_ping;
19177   int ret;
19178
19179   /* Parse args required to build the message */
19180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19181     {
19182       if (unformat (input, "l2"))
19183         {
19184           is_l2 = 1;
19185           mode_set = 1;
19186         }
19187       else if (unformat (input, "l3"))
19188         {
19189           is_l2 = 0;
19190           mode_set = 1;
19191         }
19192       else
19193         {
19194           errmsg ("parse error '%U'", format_unformat_error, input);
19195           return -99;
19196         }
19197     }
19198
19199   if (!mode_set)
19200     {
19201       errmsg ("expected one of 'l2' or 'l3' parameter!");
19202       return -99;
19203     }
19204
19205   if (!vam->json_output)
19206     {
19207       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19208     }
19209
19210   M (ONE_EID_TABLE_MAP_DUMP, mp);
19211   mp->is_l2 = is_l2;
19212
19213   /* send it... */
19214   S (mp);
19215
19216   /* Use a control ping for synchronization */
19217   MPING (CONTROL_PING, mp_ping);
19218   S (mp_ping);
19219
19220   /* Wait for a reply... */
19221   W (ret);
19222   return ret;
19223 }
19224
19225 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19226
19227 static int
19228 api_one_eid_table_vni_dump (vat_main_t * vam)
19229 {
19230   vl_api_one_eid_table_vni_dump_t *mp;
19231   vl_api_control_ping_t *mp_ping;
19232   int ret;
19233
19234   if (!vam->json_output)
19235     {
19236       print (vam->ofp, "VNI");
19237     }
19238
19239   M (ONE_EID_TABLE_VNI_DUMP, mp);
19240
19241   /* send it... */
19242   S (mp);
19243
19244   /* Use a control ping for synchronization */
19245   MPING (CONTROL_PING, mp_ping);
19246   S (mp_ping);
19247
19248   /* Wait for a reply... */
19249   W (ret);
19250   return ret;
19251 }
19252
19253 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19254
19255 static int
19256 api_one_eid_table_dump (vat_main_t * vam)
19257 {
19258   unformat_input_t *i = vam->input;
19259   vl_api_one_eid_table_dump_t *mp;
19260   vl_api_control_ping_t *mp_ping;
19261   struct in_addr ip4;
19262   struct in6_addr ip6;
19263   u8 mac[6];
19264   u8 eid_type = ~0, eid_set = 0;
19265   u32 prefix_length = ~0, t, vni = 0;
19266   u8 filter = 0;
19267   int ret;
19268   lisp_nsh_api_t nsh;
19269
19270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19271     {
19272       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19273         {
19274           eid_set = 1;
19275           eid_type = 0;
19276           prefix_length = t;
19277         }
19278       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19279         {
19280           eid_set = 1;
19281           eid_type = 1;
19282           prefix_length = t;
19283         }
19284       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19285         {
19286           eid_set = 1;
19287           eid_type = 2;
19288         }
19289       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19290         {
19291           eid_set = 1;
19292           eid_type = 3;
19293         }
19294       else if (unformat (i, "vni %d", &t))
19295         {
19296           vni = t;
19297         }
19298       else if (unformat (i, "local"))
19299         {
19300           filter = 1;
19301         }
19302       else if (unformat (i, "remote"))
19303         {
19304           filter = 2;
19305         }
19306       else
19307         {
19308           errmsg ("parse error '%U'", format_unformat_error, i);
19309           return -99;
19310         }
19311     }
19312
19313   if (!vam->json_output)
19314     {
19315       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19316              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19317     }
19318
19319   M (ONE_EID_TABLE_DUMP, mp);
19320
19321   mp->filter = filter;
19322   if (eid_set)
19323     {
19324       mp->eid_set = 1;
19325       mp->vni = htonl (vni);
19326       mp->eid_type = eid_type;
19327       switch (eid_type)
19328         {
19329         case 0:
19330           mp->prefix_length = prefix_length;
19331           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19332           break;
19333         case 1:
19334           mp->prefix_length = prefix_length;
19335           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19336           break;
19337         case 2:
19338           clib_memcpy (mp->eid, mac, sizeof (mac));
19339           break;
19340         case 3:
19341           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19342           break;
19343         default:
19344           errmsg ("unknown EID type %d!", eid_type);
19345           return -99;
19346         }
19347     }
19348
19349   /* send it... */
19350   S (mp);
19351
19352   /* Use a control ping for synchronization */
19353   MPING (CONTROL_PING, mp_ping);
19354   S (mp_ping);
19355
19356   /* Wait for a reply... */
19357   W (ret);
19358   return ret;
19359 }
19360
19361 #define api_lisp_eid_table_dump api_one_eid_table_dump
19362
19363 static int
19364 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19365 {
19366   unformat_input_t *i = vam->input;
19367   vl_api_gpe_fwd_entries_get_t *mp;
19368   u8 vni_set = 0;
19369   u32 vni = ~0;
19370   int ret;
19371
19372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19373     {
19374       if (unformat (i, "vni %d", &vni))
19375         {
19376           vni_set = 1;
19377         }
19378       else
19379         {
19380           errmsg ("parse error '%U'", format_unformat_error, i);
19381           return -99;
19382         }
19383     }
19384
19385   if (!vni_set)
19386     {
19387       errmsg ("vni not set!");
19388       return -99;
19389     }
19390
19391   if (!vam->json_output)
19392     {
19393       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19394              "leid", "reid");
19395     }
19396
19397   M (GPE_FWD_ENTRIES_GET, mp);
19398   mp->vni = clib_host_to_net_u32 (vni);
19399
19400   /* send it... */
19401   S (mp);
19402
19403   /* Wait for a reply... */
19404   W (ret);
19405   return ret;
19406 }
19407
19408 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19409 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19410 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19411 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19412 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19413 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19414 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19415 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19416
19417 static int
19418 api_one_adjacencies_get (vat_main_t * vam)
19419 {
19420   unformat_input_t *i = vam->input;
19421   vl_api_one_adjacencies_get_t *mp;
19422   u8 vni_set = 0;
19423   u32 vni = ~0;
19424   int ret;
19425
19426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19427     {
19428       if (unformat (i, "vni %d", &vni))
19429         {
19430           vni_set = 1;
19431         }
19432       else
19433         {
19434           errmsg ("parse error '%U'", format_unformat_error, i);
19435           return -99;
19436         }
19437     }
19438
19439   if (!vni_set)
19440     {
19441       errmsg ("vni not set!");
19442       return -99;
19443     }
19444
19445   if (!vam->json_output)
19446     {
19447       print (vam->ofp, "%s %40s", "leid", "reid");
19448     }
19449
19450   M (ONE_ADJACENCIES_GET, mp);
19451   mp->vni = clib_host_to_net_u32 (vni);
19452
19453   /* send it... */
19454   S (mp);
19455
19456   /* Wait for a reply... */
19457   W (ret);
19458   return ret;
19459 }
19460
19461 #define api_lisp_adjacencies_get api_one_adjacencies_get
19462
19463 static int
19464 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19465 {
19466   unformat_input_t *i = vam->input;
19467   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19468   int ret;
19469   u8 ip_family_set = 0, is_ip4 = 1;
19470
19471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19472     {
19473       if (unformat (i, "ip4"))
19474         {
19475           ip_family_set = 1;
19476           is_ip4 = 1;
19477         }
19478       else if (unformat (i, "ip6"))
19479         {
19480           ip_family_set = 1;
19481           is_ip4 = 0;
19482         }
19483       else
19484         {
19485           errmsg ("parse error '%U'", format_unformat_error, i);
19486           return -99;
19487         }
19488     }
19489
19490   if (!ip_family_set)
19491     {
19492       errmsg ("ip family not set!");
19493       return -99;
19494     }
19495
19496   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19497   mp->is_ip4 = is_ip4;
19498
19499   /* send it... */
19500   S (mp);
19501
19502   /* Wait for a reply... */
19503   W (ret);
19504   return ret;
19505 }
19506
19507 static int
19508 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19509 {
19510   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19511   int ret;
19512
19513   if (!vam->json_output)
19514     {
19515       print (vam->ofp, "VNIs");
19516     }
19517
19518   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19519
19520   /* send it... */
19521   S (mp);
19522
19523   /* Wait for a reply... */
19524   W (ret);
19525   return ret;
19526 }
19527
19528 static int
19529 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19530 {
19531   unformat_input_t *i = vam->input;
19532   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19533   int ret = 0;
19534   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19535   struct in_addr ip4;
19536   struct in6_addr ip6;
19537   u32 table_id = 0, nh_sw_if_index = ~0;
19538
19539   memset (&ip4, 0, sizeof (ip4));
19540   memset (&ip6, 0, sizeof (ip6));
19541
19542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19543     {
19544       if (unformat (i, "del"))
19545         is_add = 0;
19546       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19547                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19548         {
19549           ip_set = 1;
19550           is_ip4 = 1;
19551         }
19552       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19553                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19554         {
19555           ip_set = 1;
19556           is_ip4 = 0;
19557         }
19558       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19559         {
19560           ip_set = 1;
19561           is_ip4 = 1;
19562           nh_sw_if_index = ~0;
19563         }
19564       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19565         {
19566           ip_set = 1;
19567           is_ip4 = 0;
19568           nh_sw_if_index = ~0;
19569         }
19570       else if (unformat (i, "table %d", &table_id))
19571         ;
19572       else
19573         {
19574           errmsg ("parse error '%U'", format_unformat_error, i);
19575           return -99;
19576         }
19577     }
19578
19579   if (!ip_set)
19580     {
19581       errmsg ("nh addr not set!");
19582       return -99;
19583     }
19584
19585   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19586   mp->is_add = is_add;
19587   mp->table_id = clib_host_to_net_u32 (table_id);
19588   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19589   mp->is_ip4 = is_ip4;
19590   if (is_ip4)
19591     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19592   else
19593     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19594
19595   /* send it... */
19596   S (mp);
19597
19598   /* Wait for a reply... */
19599   W (ret);
19600   return ret;
19601 }
19602
19603 static int
19604 api_one_map_server_dump (vat_main_t * vam)
19605 {
19606   vl_api_one_map_server_dump_t *mp;
19607   vl_api_control_ping_t *mp_ping;
19608   int ret;
19609
19610   if (!vam->json_output)
19611     {
19612       print (vam->ofp, "%=20s", "Map server");
19613     }
19614
19615   M (ONE_MAP_SERVER_DUMP, mp);
19616   /* send it... */
19617   S (mp);
19618
19619   /* Use a control ping for synchronization */
19620   MPING (CONTROL_PING, mp_ping);
19621   S (mp_ping);
19622
19623   /* Wait for a reply... */
19624   W (ret);
19625   return ret;
19626 }
19627
19628 #define api_lisp_map_server_dump api_one_map_server_dump
19629
19630 static int
19631 api_one_map_resolver_dump (vat_main_t * vam)
19632 {
19633   vl_api_one_map_resolver_dump_t *mp;
19634   vl_api_control_ping_t *mp_ping;
19635   int ret;
19636
19637   if (!vam->json_output)
19638     {
19639       print (vam->ofp, "%=20s", "Map resolver");
19640     }
19641
19642   M (ONE_MAP_RESOLVER_DUMP, mp);
19643   /* send it... */
19644   S (mp);
19645
19646   /* Use a control ping for synchronization */
19647   MPING (CONTROL_PING, mp_ping);
19648   S (mp_ping);
19649
19650   /* Wait for a reply... */
19651   W (ret);
19652   return ret;
19653 }
19654
19655 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19656
19657 static int
19658 api_one_stats_flush (vat_main_t * vam)
19659 {
19660   vl_api_one_stats_flush_t *mp;
19661   int ret = 0;
19662
19663   M (ONE_STATS_FLUSH, mp);
19664   S (mp);
19665   W (ret);
19666   return ret;
19667 }
19668
19669 static int
19670 api_one_stats_dump (vat_main_t * vam)
19671 {
19672   vl_api_one_stats_dump_t *mp;
19673   vl_api_control_ping_t *mp_ping;
19674   int ret;
19675
19676   M (ONE_STATS_DUMP, mp);
19677   /* send it... */
19678   S (mp);
19679
19680   /* Use a control ping for synchronization */
19681   MPING (CONTROL_PING, mp_ping);
19682   S (mp_ping);
19683
19684   /* Wait for a reply... */
19685   W (ret);
19686   return ret;
19687 }
19688
19689 static int
19690 api_show_one_status (vat_main_t * vam)
19691 {
19692   vl_api_show_one_status_t *mp;
19693   int ret;
19694
19695   if (!vam->json_output)
19696     {
19697       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19698     }
19699
19700   M (SHOW_ONE_STATUS, mp);
19701   /* send it... */
19702   S (mp);
19703   /* Wait for a reply... */
19704   W (ret);
19705   return ret;
19706 }
19707
19708 #define api_show_lisp_status api_show_one_status
19709
19710 static int
19711 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19712 {
19713   vl_api_gpe_fwd_entry_path_dump_t *mp;
19714   vl_api_control_ping_t *mp_ping;
19715   unformat_input_t *i = vam->input;
19716   u32 fwd_entry_index = ~0;
19717   int ret;
19718
19719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19720     {
19721       if (unformat (i, "index %d", &fwd_entry_index))
19722         ;
19723       else
19724         break;
19725     }
19726
19727   if (~0 == fwd_entry_index)
19728     {
19729       errmsg ("no index specified!");
19730       return -99;
19731     }
19732
19733   if (!vam->json_output)
19734     {
19735       print (vam->ofp, "first line");
19736     }
19737
19738   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19739
19740   /* send it... */
19741   S (mp);
19742   /* Use a control ping for synchronization */
19743   MPING (CONTROL_PING, mp_ping);
19744   S (mp_ping);
19745
19746   /* Wait for a reply... */
19747   W (ret);
19748   return ret;
19749 }
19750
19751 static int
19752 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19753 {
19754   vl_api_one_get_map_request_itr_rlocs_t *mp;
19755   int ret;
19756
19757   if (!vam->json_output)
19758     {
19759       print (vam->ofp, "%=20s", "itr-rlocs:");
19760     }
19761
19762   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19763   /* send it... */
19764   S (mp);
19765   /* Wait for a reply... */
19766   W (ret);
19767   return ret;
19768 }
19769
19770 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19771
19772 static int
19773 api_af_packet_create (vat_main_t * vam)
19774 {
19775   unformat_input_t *i = vam->input;
19776   vl_api_af_packet_create_t *mp;
19777   u8 *host_if_name = 0;
19778   u8 hw_addr[6];
19779   u8 random_hw_addr = 1;
19780   int ret;
19781
19782   memset (hw_addr, 0, sizeof (hw_addr));
19783
19784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19785     {
19786       if (unformat (i, "name %s", &host_if_name))
19787         vec_add1 (host_if_name, 0);
19788       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19789         random_hw_addr = 0;
19790       else
19791         break;
19792     }
19793
19794   if (!vec_len (host_if_name))
19795     {
19796       errmsg ("host-interface name must be specified");
19797       return -99;
19798     }
19799
19800   if (vec_len (host_if_name) > 64)
19801     {
19802       errmsg ("host-interface name too long");
19803       return -99;
19804     }
19805
19806   M (AF_PACKET_CREATE, mp);
19807
19808   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19809   clib_memcpy (mp->hw_addr, hw_addr, 6);
19810   mp->use_random_hw_addr = random_hw_addr;
19811   vec_free (host_if_name);
19812
19813   S (mp);
19814
19815   /* *INDENT-OFF* */
19816   W2 (ret,
19817       ({
19818         if (ret == 0)
19819           fprintf (vam->ofp ? vam->ofp : stderr,
19820                    " new sw_if_index = %d\n", vam->sw_if_index);
19821       }));
19822   /* *INDENT-ON* */
19823   return ret;
19824 }
19825
19826 static int
19827 api_af_packet_delete (vat_main_t * vam)
19828 {
19829   unformat_input_t *i = vam->input;
19830   vl_api_af_packet_delete_t *mp;
19831   u8 *host_if_name = 0;
19832   int ret;
19833
19834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19835     {
19836       if (unformat (i, "name %s", &host_if_name))
19837         vec_add1 (host_if_name, 0);
19838       else
19839         break;
19840     }
19841
19842   if (!vec_len (host_if_name))
19843     {
19844       errmsg ("host-interface name must be specified");
19845       return -99;
19846     }
19847
19848   if (vec_len (host_if_name) > 64)
19849     {
19850       errmsg ("host-interface name too long");
19851       return -99;
19852     }
19853
19854   M (AF_PACKET_DELETE, mp);
19855
19856   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19857   vec_free (host_if_name);
19858
19859   S (mp);
19860   W (ret);
19861   return ret;
19862 }
19863
19864 static void vl_api_af_packet_details_t_handler
19865   (vl_api_af_packet_details_t * mp)
19866 {
19867   vat_main_t *vam = &vat_main;
19868
19869   print (vam->ofp, "%-16s %d",
19870          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19871 }
19872
19873 static void vl_api_af_packet_details_t_handler_json
19874   (vl_api_af_packet_details_t * mp)
19875 {
19876   vat_main_t *vam = &vat_main;
19877   vat_json_node_t *node = NULL;
19878
19879   if (VAT_JSON_ARRAY != vam->json_tree.type)
19880     {
19881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19882       vat_json_init_array (&vam->json_tree);
19883     }
19884   node = vat_json_array_add (&vam->json_tree);
19885
19886   vat_json_init_object (node);
19887   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19888   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19889 }
19890
19891 static int
19892 api_af_packet_dump (vat_main_t * vam)
19893 {
19894   vl_api_af_packet_dump_t *mp;
19895   vl_api_control_ping_t *mp_ping;
19896   int ret;
19897
19898   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19899   /* Get list of tap interfaces */
19900   M (AF_PACKET_DUMP, mp);
19901   S (mp);
19902
19903   /* Use a control ping for synchronization */
19904   MPING (CONTROL_PING, mp_ping);
19905   S (mp_ping);
19906
19907   W (ret);
19908   return ret;
19909 }
19910
19911 static int
19912 api_policer_add_del (vat_main_t * vam)
19913 {
19914   unformat_input_t *i = vam->input;
19915   vl_api_policer_add_del_t *mp;
19916   u8 is_add = 1;
19917   u8 *name = 0;
19918   u32 cir = 0;
19919   u32 eir = 0;
19920   u64 cb = 0;
19921   u64 eb = 0;
19922   u8 rate_type = 0;
19923   u8 round_type = 0;
19924   u8 type = 0;
19925   u8 color_aware = 0;
19926   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19927   int ret;
19928
19929   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19930   conform_action.dscp = 0;
19931   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19932   exceed_action.dscp = 0;
19933   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19934   violate_action.dscp = 0;
19935
19936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19937     {
19938       if (unformat (i, "del"))
19939         is_add = 0;
19940       else if (unformat (i, "name %s", &name))
19941         vec_add1 (name, 0);
19942       else if (unformat (i, "cir %u", &cir))
19943         ;
19944       else if (unformat (i, "eir %u", &eir))
19945         ;
19946       else if (unformat (i, "cb %u", &cb))
19947         ;
19948       else if (unformat (i, "eb %u", &eb))
19949         ;
19950       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19951                          &rate_type))
19952         ;
19953       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19954                          &round_type))
19955         ;
19956       else if (unformat (i, "type %U", unformat_policer_type, &type))
19957         ;
19958       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19959                          &conform_action))
19960         ;
19961       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19962                          &exceed_action))
19963         ;
19964       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19965                          &violate_action))
19966         ;
19967       else if (unformat (i, "color-aware"))
19968         color_aware = 1;
19969       else
19970         break;
19971     }
19972
19973   if (!vec_len (name))
19974     {
19975       errmsg ("policer name must be specified");
19976       return -99;
19977     }
19978
19979   if (vec_len (name) > 64)
19980     {
19981       errmsg ("policer name too long");
19982       return -99;
19983     }
19984
19985   M (POLICER_ADD_DEL, mp);
19986
19987   clib_memcpy (mp->name, name, vec_len (name));
19988   vec_free (name);
19989   mp->is_add = is_add;
19990   mp->cir = ntohl (cir);
19991   mp->eir = ntohl (eir);
19992   mp->cb = clib_net_to_host_u64 (cb);
19993   mp->eb = clib_net_to_host_u64 (eb);
19994   mp->rate_type = rate_type;
19995   mp->round_type = round_type;
19996   mp->type = type;
19997   mp->conform_action_type = conform_action.action_type;
19998   mp->conform_dscp = conform_action.dscp;
19999   mp->exceed_action_type = exceed_action.action_type;
20000   mp->exceed_dscp = exceed_action.dscp;
20001   mp->violate_action_type = violate_action.action_type;
20002   mp->violate_dscp = violate_action.dscp;
20003   mp->color_aware = color_aware;
20004
20005   S (mp);
20006   W (ret);
20007   return ret;
20008 }
20009
20010 static int
20011 api_policer_dump (vat_main_t * vam)
20012 {
20013   unformat_input_t *i = vam->input;
20014   vl_api_policer_dump_t *mp;
20015   vl_api_control_ping_t *mp_ping;
20016   u8 *match_name = 0;
20017   u8 match_name_valid = 0;
20018   int ret;
20019
20020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20021     {
20022       if (unformat (i, "name %s", &match_name))
20023         {
20024           vec_add1 (match_name, 0);
20025           match_name_valid = 1;
20026         }
20027       else
20028         break;
20029     }
20030
20031   M (POLICER_DUMP, mp);
20032   mp->match_name_valid = match_name_valid;
20033   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20034   vec_free (match_name);
20035   /* send it... */
20036   S (mp);
20037
20038   /* Use a control ping for synchronization */
20039   MPING (CONTROL_PING, mp_ping);
20040   S (mp_ping);
20041
20042   /* Wait for a reply... */
20043   W (ret);
20044   return ret;
20045 }
20046
20047 static int
20048 api_policer_classify_set_interface (vat_main_t * vam)
20049 {
20050   unformat_input_t *i = vam->input;
20051   vl_api_policer_classify_set_interface_t *mp;
20052   u32 sw_if_index;
20053   int sw_if_index_set;
20054   u32 ip4_table_index = ~0;
20055   u32 ip6_table_index = ~0;
20056   u32 l2_table_index = ~0;
20057   u8 is_add = 1;
20058   int ret;
20059
20060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20061     {
20062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20063         sw_if_index_set = 1;
20064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20065         sw_if_index_set = 1;
20066       else if (unformat (i, "del"))
20067         is_add = 0;
20068       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20069         ;
20070       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20071         ;
20072       else if (unformat (i, "l2-table %d", &l2_table_index))
20073         ;
20074       else
20075         {
20076           clib_warning ("parse error '%U'", format_unformat_error, i);
20077           return -99;
20078         }
20079     }
20080
20081   if (sw_if_index_set == 0)
20082     {
20083       errmsg ("missing interface name or sw_if_index");
20084       return -99;
20085     }
20086
20087   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20088
20089   mp->sw_if_index = ntohl (sw_if_index);
20090   mp->ip4_table_index = ntohl (ip4_table_index);
20091   mp->ip6_table_index = ntohl (ip6_table_index);
20092   mp->l2_table_index = ntohl (l2_table_index);
20093   mp->is_add = is_add;
20094
20095   S (mp);
20096   W (ret);
20097   return ret;
20098 }
20099
20100 static int
20101 api_policer_classify_dump (vat_main_t * vam)
20102 {
20103   unformat_input_t *i = vam->input;
20104   vl_api_policer_classify_dump_t *mp;
20105   vl_api_control_ping_t *mp_ping;
20106   u8 type = POLICER_CLASSIFY_N_TABLES;
20107   int ret;
20108
20109   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20110     ;
20111   else
20112     {
20113       errmsg ("classify table type must be specified");
20114       return -99;
20115     }
20116
20117   if (!vam->json_output)
20118     {
20119       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20120     }
20121
20122   M (POLICER_CLASSIFY_DUMP, mp);
20123   mp->type = type;
20124   /* send it... */
20125   S (mp);
20126
20127   /* Use a control ping for synchronization */
20128   MPING (CONTROL_PING, mp_ping);
20129   S (mp_ping);
20130
20131   /* Wait for a reply... */
20132   W (ret);
20133   return ret;
20134 }
20135
20136 static int
20137 api_netmap_create (vat_main_t * vam)
20138 {
20139   unformat_input_t *i = vam->input;
20140   vl_api_netmap_create_t *mp;
20141   u8 *if_name = 0;
20142   u8 hw_addr[6];
20143   u8 random_hw_addr = 1;
20144   u8 is_pipe = 0;
20145   u8 is_master = 0;
20146   int ret;
20147
20148   memset (hw_addr, 0, sizeof (hw_addr));
20149
20150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20151     {
20152       if (unformat (i, "name %s", &if_name))
20153         vec_add1 (if_name, 0);
20154       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20155         random_hw_addr = 0;
20156       else if (unformat (i, "pipe"))
20157         is_pipe = 1;
20158       else if (unformat (i, "master"))
20159         is_master = 1;
20160       else if (unformat (i, "slave"))
20161         is_master = 0;
20162       else
20163         break;
20164     }
20165
20166   if (!vec_len (if_name))
20167     {
20168       errmsg ("interface name must be specified");
20169       return -99;
20170     }
20171
20172   if (vec_len (if_name) > 64)
20173     {
20174       errmsg ("interface name too long");
20175       return -99;
20176     }
20177
20178   M (NETMAP_CREATE, mp);
20179
20180   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20181   clib_memcpy (mp->hw_addr, hw_addr, 6);
20182   mp->use_random_hw_addr = random_hw_addr;
20183   mp->is_pipe = is_pipe;
20184   mp->is_master = is_master;
20185   vec_free (if_name);
20186
20187   S (mp);
20188   W (ret);
20189   return ret;
20190 }
20191
20192 static int
20193 api_netmap_delete (vat_main_t * vam)
20194 {
20195   unformat_input_t *i = vam->input;
20196   vl_api_netmap_delete_t *mp;
20197   u8 *if_name = 0;
20198   int ret;
20199
20200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20201     {
20202       if (unformat (i, "name %s", &if_name))
20203         vec_add1 (if_name, 0);
20204       else
20205         break;
20206     }
20207
20208   if (!vec_len (if_name))
20209     {
20210       errmsg ("interface name must be specified");
20211       return -99;
20212     }
20213
20214   if (vec_len (if_name) > 64)
20215     {
20216       errmsg ("interface name too long");
20217       return -99;
20218     }
20219
20220   M (NETMAP_DELETE, mp);
20221
20222   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20223   vec_free (if_name);
20224
20225   S (mp);
20226   W (ret);
20227   return ret;
20228 }
20229
20230 static void
20231 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20232 {
20233   if (fp->afi == IP46_TYPE_IP6)
20234     print (vam->ofp,
20235            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20236            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20237            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20238            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20239            format_ip6_address, fp->next_hop);
20240   else if (fp->afi == IP46_TYPE_IP4)
20241     print (vam->ofp,
20242            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20243            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20244            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20245            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20246            format_ip4_address, fp->next_hop);
20247 }
20248
20249 static void
20250 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20251                                  vl_api_fib_path_t * fp)
20252 {
20253   struct in_addr ip4;
20254   struct in6_addr ip6;
20255
20256   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20257   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20258   vat_json_object_add_uint (node, "is_local", fp->is_local);
20259   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20260   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20261   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20262   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20263   if (fp->afi == IP46_TYPE_IP4)
20264     {
20265       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20266       vat_json_object_add_ip4 (node, "next_hop", ip4);
20267     }
20268   else if (fp->afi == IP46_TYPE_IP6)
20269     {
20270       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20271       vat_json_object_add_ip6 (node, "next_hop", ip6);
20272     }
20273 }
20274
20275 static void
20276 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20277 {
20278   vat_main_t *vam = &vat_main;
20279   int count = ntohl (mp->mt_count);
20280   vl_api_fib_path_t *fp;
20281   i32 i;
20282
20283   print (vam->ofp, "[%d]: sw_if_index %d via:",
20284          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20285   fp = mp->mt_paths;
20286   for (i = 0; i < count; i++)
20287     {
20288       vl_api_mpls_fib_path_print (vam, fp);
20289       fp++;
20290     }
20291
20292   print (vam->ofp, "");
20293 }
20294
20295 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20296 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20297
20298 static void
20299 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20300 {
20301   vat_main_t *vam = &vat_main;
20302   vat_json_node_t *node = NULL;
20303   int count = ntohl (mp->mt_count);
20304   vl_api_fib_path_t *fp;
20305   i32 i;
20306
20307   if (VAT_JSON_ARRAY != vam->json_tree.type)
20308     {
20309       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20310       vat_json_init_array (&vam->json_tree);
20311     }
20312   node = vat_json_array_add (&vam->json_tree);
20313
20314   vat_json_init_object (node);
20315   vat_json_object_add_uint (node, "tunnel_index",
20316                             ntohl (mp->mt_tunnel_index));
20317   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20318
20319   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20320
20321   fp = mp->mt_paths;
20322   for (i = 0; i < count; i++)
20323     {
20324       vl_api_mpls_fib_path_json_print (node, fp);
20325       fp++;
20326     }
20327 }
20328
20329 static int
20330 api_mpls_tunnel_dump (vat_main_t * vam)
20331 {
20332   vl_api_mpls_tunnel_dump_t *mp;
20333   vl_api_control_ping_t *mp_ping;
20334   i32 index = -1;
20335   int ret;
20336
20337   /* Parse args required to build the message */
20338   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20339     {
20340       if (!unformat (vam->input, "tunnel_index %d", &index))
20341         {
20342           index = -1;
20343           break;
20344         }
20345     }
20346
20347   print (vam->ofp, "  tunnel_index %d", index);
20348
20349   M (MPLS_TUNNEL_DUMP, mp);
20350   mp->tunnel_index = htonl (index);
20351   S (mp);
20352
20353   /* Use a control ping for synchronization */
20354   MPING (CONTROL_PING, mp_ping);
20355   S (mp_ping);
20356
20357   W (ret);
20358   return ret;
20359 }
20360
20361 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20362 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20363
20364
20365 static void
20366 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20367 {
20368   vat_main_t *vam = &vat_main;
20369   int count = ntohl (mp->count);
20370   vl_api_fib_path_t *fp;
20371   int i;
20372
20373   print (vam->ofp,
20374          "table-id %d, label %u, ess_bit %u",
20375          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20376   fp = mp->path;
20377   for (i = 0; i < count; i++)
20378     {
20379       vl_api_mpls_fib_path_print (vam, fp);
20380       fp++;
20381     }
20382 }
20383
20384 static void vl_api_mpls_fib_details_t_handler_json
20385   (vl_api_mpls_fib_details_t * mp)
20386 {
20387   vat_main_t *vam = &vat_main;
20388   int count = ntohl (mp->count);
20389   vat_json_node_t *node = NULL;
20390   vl_api_fib_path_t *fp;
20391   int i;
20392
20393   if (VAT_JSON_ARRAY != vam->json_tree.type)
20394     {
20395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20396       vat_json_init_array (&vam->json_tree);
20397     }
20398   node = vat_json_array_add (&vam->json_tree);
20399
20400   vat_json_init_object (node);
20401   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20402   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20403   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20404   vat_json_object_add_uint (node, "path_count", count);
20405   fp = mp->path;
20406   for (i = 0; i < count; i++)
20407     {
20408       vl_api_mpls_fib_path_json_print (node, fp);
20409       fp++;
20410     }
20411 }
20412
20413 static int
20414 api_mpls_fib_dump (vat_main_t * vam)
20415 {
20416   vl_api_mpls_fib_dump_t *mp;
20417   vl_api_control_ping_t *mp_ping;
20418   int ret;
20419
20420   M (MPLS_FIB_DUMP, mp);
20421   S (mp);
20422
20423   /* Use a control ping for synchronization */
20424   MPING (CONTROL_PING, mp_ping);
20425   S (mp_ping);
20426
20427   W (ret);
20428   return ret;
20429 }
20430
20431 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20432 #define vl_api_ip_fib_details_t_print vl_noop_handler
20433
20434 static void
20435 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20436 {
20437   vat_main_t *vam = &vat_main;
20438   int count = ntohl (mp->count);
20439   vl_api_fib_path_t *fp;
20440   int i;
20441
20442   print (vam->ofp,
20443          "table-id %d, prefix %U/%d",
20444          ntohl (mp->table_id), format_ip4_address, mp->address,
20445          mp->address_length);
20446   fp = mp->path;
20447   for (i = 0; i < count; i++)
20448     {
20449       if (fp->afi == IP46_TYPE_IP6)
20450         print (vam->ofp,
20451                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20452                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20453                "next_hop_table %d",
20454                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20455                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20456                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20457       else if (fp->afi == IP46_TYPE_IP4)
20458         print (vam->ofp,
20459                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20460                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20461                "next_hop_table %d",
20462                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20463                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20464                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20465       fp++;
20466     }
20467 }
20468
20469 static void vl_api_ip_fib_details_t_handler_json
20470   (vl_api_ip_fib_details_t * mp)
20471 {
20472   vat_main_t *vam = &vat_main;
20473   int count = ntohl (mp->count);
20474   vat_json_node_t *node = NULL;
20475   struct in_addr ip4;
20476   struct in6_addr ip6;
20477   vl_api_fib_path_t *fp;
20478   int i;
20479
20480   if (VAT_JSON_ARRAY != vam->json_tree.type)
20481     {
20482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20483       vat_json_init_array (&vam->json_tree);
20484     }
20485   node = vat_json_array_add (&vam->json_tree);
20486
20487   vat_json_init_object (node);
20488   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20489   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20490   vat_json_object_add_ip4 (node, "prefix", ip4);
20491   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20492   vat_json_object_add_uint (node, "path_count", count);
20493   fp = mp->path;
20494   for (i = 0; i < count; i++)
20495     {
20496       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20497       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20498       vat_json_object_add_uint (node, "is_local", fp->is_local);
20499       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20500       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20501       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20502       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20503       if (fp->afi == IP46_TYPE_IP4)
20504         {
20505           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20506           vat_json_object_add_ip4 (node, "next_hop", ip4);
20507         }
20508       else if (fp->afi == IP46_TYPE_IP6)
20509         {
20510           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20511           vat_json_object_add_ip6 (node, "next_hop", ip6);
20512         }
20513     }
20514 }
20515
20516 static int
20517 api_ip_fib_dump (vat_main_t * vam)
20518 {
20519   vl_api_ip_fib_dump_t *mp;
20520   vl_api_control_ping_t *mp_ping;
20521   int ret;
20522
20523   M (IP_FIB_DUMP, mp);
20524   S (mp);
20525
20526   /* Use a control ping for synchronization */
20527   MPING (CONTROL_PING, mp_ping);
20528   S (mp_ping);
20529
20530   W (ret);
20531   return ret;
20532 }
20533
20534 static int
20535 api_ip_mfib_dump (vat_main_t * vam)
20536 {
20537   vl_api_ip_mfib_dump_t *mp;
20538   vl_api_control_ping_t *mp_ping;
20539   int ret;
20540
20541   M (IP_MFIB_DUMP, mp);
20542   S (mp);
20543
20544   /* Use a control ping for synchronization */
20545   MPING (CONTROL_PING, mp_ping);
20546   S (mp_ping);
20547
20548   W (ret);
20549   return ret;
20550 }
20551
20552 static void vl_api_ip_neighbor_details_t_handler
20553   (vl_api_ip_neighbor_details_t * mp)
20554 {
20555   vat_main_t *vam = &vat_main;
20556
20557   print (vam->ofp, "%c %U %U",
20558          (mp->is_static) ? 'S' : 'D',
20559          format_ethernet_address, &mp->mac_address,
20560          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20561          &mp->ip_address);
20562 }
20563
20564 static void vl_api_ip_neighbor_details_t_handler_json
20565   (vl_api_ip_neighbor_details_t * mp)
20566 {
20567
20568   vat_main_t *vam = &vat_main;
20569   vat_json_node_t *node;
20570   struct in_addr ip4;
20571   struct in6_addr ip6;
20572
20573   if (VAT_JSON_ARRAY != vam->json_tree.type)
20574     {
20575       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20576       vat_json_init_array (&vam->json_tree);
20577     }
20578   node = vat_json_array_add (&vam->json_tree);
20579
20580   vat_json_init_object (node);
20581   vat_json_object_add_string_copy (node, "flag",
20582                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20583                                    "dynamic");
20584
20585   vat_json_object_add_string_copy (node, "link_layer",
20586                                    format (0, "%U", format_ethernet_address,
20587                                            &mp->mac_address));
20588
20589   if (mp->is_ipv6)
20590     {
20591       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20592       vat_json_object_add_ip6 (node, "ip_address", ip6);
20593     }
20594   else
20595     {
20596       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20597       vat_json_object_add_ip4 (node, "ip_address", ip4);
20598     }
20599 }
20600
20601 static int
20602 api_ip_neighbor_dump (vat_main_t * vam)
20603 {
20604   unformat_input_t *i = vam->input;
20605   vl_api_ip_neighbor_dump_t *mp;
20606   vl_api_control_ping_t *mp_ping;
20607   u8 is_ipv6 = 0;
20608   u32 sw_if_index = ~0;
20609   int ret;
20610
20611   /* Parse args required to build the message */
20612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20613     {
20614       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20615         ;
20616       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20617         ;
20618       else if (unformat (i, "ip6"))
20619         is_ipv6 = 1;
20620       else
20621         break;
20622     }
20623
20624   if (sw_if_index == ~0)
20625     {
20626       errmsg ("missing interface name or sw_if_index");
20627       return -99;
20628     }
20629
20630   M (IP_NEIGHBOR_DUMP, mp);
20631   mp->is_ipv6 = (u8) is_ipv6;
20632   mp->sw_if_index = ntohl (sw_if_index);
20633   S (mp);
20634
20635   /* Use a control ping for synchronization */
20636   MPING (CONTROL_PING, mp_ping);
20637   S (mp_ping);
20638
20639   W (ret);
20640   return ret;
20641 }
20642
20643 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20644 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20645
20646 static void
20647 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20648 {
20649   vat_main_t *vam = &vat_main;
20650   int count = ntohl (mp->count);
20651   vl_api_fib_path_t *fp;
20652   int i;
20653
20654   print (vam->ofp,
20655          "table-id %d, prefix %U/%d",
20656          ntohl (mp->table_id), format_ip6_address, mp->address,
20657          mp->address_length);
20658   fp = mp->path;
20659   for (i = 0; i < count; i++)
20660     {
20661       if (fp->afi == IP46_TYPE_IP6)
20662         print (vam->ofp,
20663                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20664                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20665                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20666                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20667                format_ip6_address, fp->next_hop);
20668       else if (fp->afi == IP46_TYPE_IP4)
20669         print (vam->ofp,
20670                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20671                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20672                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20673                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20674                format_ip4_address, fp->next_hop);
20675       fp++;
20676     }
20677 }
20678
20679 static void vl_api_ip6_fib_details_t_handler_json
20680   (vl_api_ip6_fib_details_t * mp)
20681 {
20682   vat_main_t *vam = &vat_main;
20683   int count = ntohl (mp->count);
20684   vat_json_node_t *node = NULL;
20685   struct in_addr ip4;
20686   struct in6_addr ip6;
20687   vl_api_fib_path_t *fp;
20688   int i;
20689
20690   if (VAT_JSON_ARRAY != vam->json_tree.type)
20691     {
20692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20693       vat_json_init_array (&vam->json_tree);
20694     }
20695   node = vat_json_array_add (&vam->json_tree);
20696
20697   vat_json_init_object (node);
20698   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20699   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20700   vat_json_object_add_ip6 (node, "prefix", ip6);
20701   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20702   vat_json_object_add_uint (node, "path_count", count);
20703   fp = mp->path;
20704   for (i = 0; i < count; i++)
20705     {
20706       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20707       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20708       vat_json_object_add_uint (node, "is_local", fp->is_local);
20709       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20710       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20711       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20712       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20713       if (fp->afi == IP46_TYPE_IP4)
20714         {
20715           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20716           vat_json_object_add_ip4 (node, "next_hop", ip4);
20717         }
20718       else if (fp->afi == IP46_TYPE_IP6)
20719         {
20720           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20721           vat_json_object_add_ip6 (node, "next_hop", ip6);
20722         }
20723     }
20724 }
20725
20726 static int
20727 api_ip6_fib_dump (vat_main_t * vam)
20728 {
20729   vl_api_ip6_fib_dump_t *mp;
20730   vl_api_control_ping_t *mp_ping;
20731   int ret;
20732
20733   M (IP6_FIB_DUMP, mp);
20734   S (mp);
20735
20736   /* Use a control ping for synchronization */
20737   MPING (CONTROL_PING, mp_ping);
20738   S (mp_ping);
20739
20740   W (ret);
20741   return ret;
20742 }
20743
20744 static int
20745 api_ip6_mfib_dump (vat_main_t * vam)
20746 {
20747   vl_api_ip6_mfib_dump_t *mp;
20748   vl_api_control_ping_t *mp_ping;
20749   int ret;
20750
20751   M (IP6_MFIB_DUMP, mp);
20752   S (mp);
20753
20754   /* Use a control ping for synchronization */
20755   MPING (CONTROL_PING, mp_ping);
20756   S (mp_ping);
20757
20758   W (ret);
20759   return ret;
20760 }
20761
20762 int
20763 api_classify_table_ids (vat_main_t * vam)
20764 {
20765   vl_api_classify_table_ids_t *mp;
20766   int ret;
20767
20768   /* Construct the API message */
20769   M (CLASSIFY_TABLE_IDS, mp);
20770   mp->context = 0;
20771
20772   S (mp);
20773   W (ret);
20774   return ret;
20775 }
20776
20777 int
20778 api_classify_table_by_interface (vat_main_t * vam)
20779 {
20780   unformat_input_t *input = vam->input;
20781   vl_api_classify_table_by_interface_t *mp;
20782
20783   u32 sw_if_index = ~0;
20784   int ret;
20785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20786     {
20787       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20788         ;
20789       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20790         ;
20791       else
20792         break;
20793     }
20794   if (sw_if_index == ~0)
20795     {
20796       errmsg ("missing interface name or sw_if_index");
20797       return -99;
20798     }
20799
20800   /* Construct the API message */
20801   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20802   mp->context = 0;
20803   mp->sw_if_index = ntohl (sw_if_index);
20804
20805   S (mp);
20806   W (ret);
20807   return ret;
20808 }
20809
20810 int
20811 api_classify_table_info (vat_main_t * vam)
20812 {
20813   unformat_input_t *input = vam->input;
20814   vl_api_classify_table_info_t *mp;
20815
20816   u32 table_id = ~0;
20817   int ret;
20818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20819     {
20820       if (unformat (input, "table_id %d", &table_id))
20821         ;
20822       else
20823         break;
20824     }
20825   if (table_id == ~0)
20826     {
20827       errmsg ("missing table id");
20828       return -99;
20829     }
20830
20831   /* Construct the API message */
20832   M (CLASSIFY_TABLE_INFO, mp);
20833   mp->context = 0;
20834   mp->table_id = ntohl (table_id);
20835
20836   S (mp);
20837   W (ret);
20838   return ret;
20839 }
20840
20841 int
20842 api_classify_session_dump (vat_main_t * vam)
20843 {
20844   unformat_input_t *input = vam->input;
20845   vl_api_classify_session_dump_t *mp;
20846   vl_api_control_ping_t *mp_ping;
20847
20848   u32 table_id = ~0;
20849   int ret;
20850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20851     {
20852       if (unformat (input, "table_id %d", &table_id))
20853         ;
20854       else
20855         break;
20856     }
20857   if (table_id == ~0)
20858     {
20859       errmsg ("missing table id");
20860       return -99;
20861     }
20862
20863   /* Construct the API message */
20864   M (CLASSIFY_SESSION_DUMP, mp);
20865   mp->context = 0;
20866   mp->table_id = ntohl (table_id);
20867   S (mp);
20868
20869   /* Use a control ping for synchronization */
20870   MPING (CONTROL_PING, mp_ping);
20871   S (mp_ping);
20872
20873   W (ret);
20874   return ret;
20875 }
20876
20877 static void
20878 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20879 {
20880   vat_main_t *vam = &vat_main;
20881
20882   print (vam->ofp, "collector_address %U, collector_port %d, "
20883          "src_address %U, vrf_id %d, path_mtu %u, "
20884          "template_interval %u, udp_checksum %d",
20885          format_ip4_address, mp->collector_address,
20886          ntohs (mp->collector_port),
20887          format_ip4_address, mp->src_address,
20888          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20889          ntohl (mp->template_interval), mp->udp_checksum);
20890
20891   vam->retval = 0;
20892   vam->result_ready = 1;
20893 }
20894
20895 static void
20896   vl_api_ipfix_exporter_details_t_handler_json
20897   (vl_api_ipfix_exporter_details_t * mp)
20898 {
20899   vat_main_t *vam = &vat_main;
20900   vat_json_node_t node;
20901   struct in_addr collector_address;
20902   struct in_addr src_address;
20903
20904   vat_json_init_object (&node);
20905   clib_memcpy (&collector_address, &mp->collector_address,
20906                sizeof (collector_address));
20907   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20908   vat_json_object_add_uint (&node, "collector_port",
20909                             ntohs (mp->collector_port));
20910   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20911   vat_json_object_add_ip4 (&node, "src_address", src_address);
20912   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20913   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20914   vat_json_object_add_uint (&node, "template_interval",
20915                             ntohl (mp->template_interval));
20916   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20917
20918   vat_json_print (vam->ofp, &node);
20919   vat_json_free (&node);
20920   vam->retval = 0;
20921   vam->result_ready = 1;
20922 }
20923
20924 int
20925 api_ipfix_exporter_dump (vat_main_t * vam)
20926 {
20927   vl_api_ipfix_exporter_dump_t *mp;
20928   int ret;
20929
20930   /* Construct the API message */
20931   M (IPFIX_EXPORTER_DUMP, mp);
20932   mp->context = 0;
20933
20934   S (mp);
20935   W (ret);
20936   return ret;
20937 }
20938
20939 static int
20940 api_ipfix_classify_stream_dump (vat_main_t * vam)
20941 {
20942   vl_api_ipfix_classify_stream_dump_t *mp;
20943   int ret;
20944
20945   /* Construct the API message */
20946   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20947   mp->context = 0;
20948
20949   S (mp);
20950   W (ret);
20951   return ret;
20952   /* NOTREACHED */
20953   return 0;
20954 }
20955
20956 static void
20957   vl_api_ipfix_classify_stream_details_t_handler
20958   (vl_api_ipfix_classify_stream_details_t * mp)
20959 {
20960   vat_main_t *vam = &vat_main;
20961   print (vam->ofp, "domain_id %d, src_port %d",
20962          ntohl (mp->domain_id), ntohs (mp->src_port));
20963   vam->retval = 0;
20964   vam->result_ready = 1;
20965 }
20966
20967 static void
20968   vl_api_ipfix_classify_stream_details_t_handler_json
20969   (vl_api_ipfix_classify_stream_details_t * mp)
20970 {
20971   vat_main_t *vam = &vat_main;
20972   vat_json_node_t node;
20973
20974   vat_json_init_object (&node);
20975   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20976   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20977
20978   vat_json_print (vam->ofp, &node);
20979   vat_json_free (&node);
20980   vam->retval = 0;
20981   vam->result_ready = 1;
20982 }
20983
20984 static int
20985 api_ipfix_classify_table_dump (vat_main_t * vam)
20986 {
20987   vl_api_ipfix_classify_table_dump_t *mp;
20988   vl_api_control_ping_t *mp_ping;
20989   int ret;
20990
20991   if (!vam->json_output)
20992     {
20993       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20994              "transport_protocol");
20995     }
20996
20997   /* Construct the API message */
20998   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20999
21000   /* send it... */
21001   S (mp);
21002
21003   /* Use a control ping for synchronization */
21004   MPING (CONTROL_PING, mp_ping);
21005   S (mp_ping);
21006
21007   W (ret);
21008   return ret;
21009 }
21010
21011 static void
21012   vl_api_ipfix_classify_table_details_t_handler
21013   (vl_api_ipfix_classify_table_details_t * mp)
21014 {
21015   vat_main_t *vam = &vat_main;
21016   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21017          mp->transport_protocol);
21018 }
21019
21020 static void
21021   vl_api_ipfix_classify_table_details_t_handler_json
21022   (vl_api_ipfix_classify_table_details_t * mp)
21023 {
21024   vat_json_node_t *node = NULL;
21025   vat_main_t *vam = &vat_main;
21026
21027   if (VAT_JSON_ARRAY != vam->json_tree.type)
21028     {
21029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21030       vat_json_init_array (&vam->json_tree);
21031     }
21032
21033   node = vat_json_array_add (&vam->json_tree);
21034   vat_json_init_object (node);
21035
21036   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21037   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21038   vat_json_object_add_uint (node, "transport_protocol",
21039                             mp->transport_protocol);
21040 }
21041
21042 static int
21043 api_sw_interface_span_enable_disable (vat_main_t * vam)
21044 {
21045   unformat_input_t *i = vam->input;
21046   vl_api_sw_interface_span_enable_disable_t *mp;
21047   u32 src_sw_if_index = ~0;
21048   u32 dst_sw_if_index = ~0;
21049   u8 state = 3;
21050   int ret;
21051   u8 is_l2 = 0;
21052
21053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21054     {
21055       if (unformat
21056           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21057         ;
21058       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21059         ;
21060       else
21061         if (unformat
21062             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21063         ;
21064       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21065         ;
21066       else if (unformat (i, "disable"))
21067         state = 0;
21068       else if (unformat (i, "rx"))
21069         state = 1;
21070       else if (unformat (i, "tx"))
21071         state = 2;
21072       else if (unformat (i, "both"))
21073         state = 3;
21074       else if (unformat (i, "l2"))
21075         is_l2 = 1;
21076       else
21077         break;
21078     }
21079
21080   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21081
21082   mp->sw_if_index_from = htonl (src_sw_if_index);
21083   mp->sw_if_index_to = htonl (dst_sw_if_index);
21084   mp->state = state;
21085   mp->is_l2 = is_l2;
21086
21087   S (mp);
21088   W (ret);
21089   return ret;
21090 }
21091
21092 static void
21093 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21094                                             * mp)
21095 {
21096   vat_main_t *vam = &vat_main;
21097   u8 *sw_if_from_name = 0;
21098   u8 *sw_if_to_name = 0;
21099   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21100   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21101   char *states[] = { "none", "rx", "tx", "both" };
21102   hash_pair_t *p;
21103
21104   /* *INDENT-OFF* */
21105   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21106   ({
21107     if ((u32) p->value[0] == sw_if_index_from)
21108       {
21109         sw_if_from_name = (u8 *)(p->key);
21110         if (sw_if_to_name)
21111           break;
21112       }
21113     if ((u32) p->value[0] == sw_if_index_to)
21114       {
21115         sw_if_to_name = (u8 *)(p->key);
21116         if (sw_if_from_name)
21117           break;
21118       }
21119   }));
21120   /* *INDENT-ON* */
21121   print (vam->ofp, "%20s => %20s (%s) %s",
21122          sw_if_from_name, sw_if_to_name, states[mp->state],
21123          mp->is_l2 ? "l2" : "device");
21124 }
21125
21126 static void
21127   vl_api_sw_interface_span_details_t_handler_json
21128   (vl_api_sw_interface_span_details_t * mp)
21129 {
21130   vat_main_t *vam = &vat_main;
21131   vat_json_node_t *node = NULL;
21132   u8 *sw_if_from_name = 0;
21133   u8 *sw_if_to_name = 0;
21134   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21135   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21136   hash_pair_t *p;
21137
21138   /* *INDENT-OFF* */
21139   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21140   ({
21141     if ((u32) p->value[0] == sw_if_index_from)
21142       {
21143         sw_if_from_name = (u8 *)(p->key);
21144         if (sw_if_to_name)
21145           break;
21146       }
21147     if ((u32) p->value[0] == sw_if_index_to)
21148       {
21149         sw_if_to_name = (u8 *)(p->key);
21150         if (sw_if_from_name)
21151           break;
21152       }
21153   }));
21154   /* *INDENT-ON* */
21155
21156   if (VAT_JSON_ARRAY != vam->json_tree.type)
21157     {
21158       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21159       vat_json_init_array (&vam->json_tree);
21160     }
21161   node = vat_json_array_add (&vam->json_tree);
21162
21163   vat_json_init_object (node);
21164   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21165   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21166   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21167   if (0 != sw_if_to_name)
21168     {
21169       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21170     }
21171   vat_json_object_add_uint (node, "state", mp->state);
21172   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21173 }
21174
21175 static int
21176 api_sw_interface_span_dump (vat_main_t * vam)
21177 {
21178   unformat_input_t *input = vam->input;
21179   vl_api_sw_interface_span_dump_t *mp;
21180   vl_api_control_ping_t *mp_ping;
21181   u8 is_l2 = 0;
21182   int ret;
21183
21184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21185     {
21186       if (unformat (input, "l2"))
21187         is_l2 = 1;
21188       else
21189         break;
21190     }
21191
21192   M (SW_INTERFACE_SPAN_DUMP, mp);
21193   mp->is_l2 = is_l2;
21194   S (mp);
21195
21196   /* Use a control ping for synchronization */
21197   MPING (CONTROL_PING, mp_ping);
21198   S (mp_ping);
21199
21200   W (ret);
21201   return ret;
21202 }
21203
21204 int
21205 api_pg_create_interface (vat_main_t * vam)
21206 {
21207   unformat_input_t *input = vam->input;
21208   vl_api_pg_create_interface_t *mp;
21209
21210   u32 if_id = ~0;
21211   int ret;
21212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21213     {
21214       if (unformat (input, "if_id %d", &if_id))
21215         ;
21216       else
21217         break;
21218     }
21219   if (if_id == ~0)
21220     {
21221       errmsg ("missing pg interface index");
21222       return -99;
21223     }
21224
21225   /* Construct the API message */
21226   M (PG_CREATE_INTERFACE, mp);
21227   mp->context = 0;
21228   mp->interface_id = ntohl (if_id);
21229
21230   S (mp);
21231   W (ret);
21232   return ret;
21233 }
21234
21235 int
21236 api_pg_capture (vat_main_t * vam)
21237 {
21238   unformat_input_t *input = vam->input;
21239   vl_api_pg_capture_t *mp;
21240
21241   u32 if_id = ~0;
21242   u8 enable = 1;
21243   u32 count = 1;
21244   u8 pcap_file_set = 0;
21245   u8 *pcap_file = 0;
21246   int ret;
21247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21248     {
21249       if (unformat (input, "if_id %d", &if_id))
21250         ;
21251       else if (unformat (input, "pcap %s", &pcap_file))
21252         pcap_file_set = 1;
21253       else if (unformat (input, "count %d", &count))
21254         ;
21255       else if (unformat (input, "disable"))
21256         enable = 0;
21257       else
21258         break;
21259     }
21260   if (if_id == ~0)
21261     {
21262       errmsg ("missing pg interface index");
21263       return -99;
21264     }
21265   if (pcap_file_set > 0)
21266     {
21267       if (vec_len (pcap_file) > 255)
21268         {
21269           errmsg ("pcap file name is too long");
21270           return -99;
21271         }
21272     }
21273
21274   u32 name_len = vec_len (pcap_file);
21275   /* Construct the API message */
21276   M (PG_CAPTURE, mp);
21277   mp->context = 0;
21278   mp->interface_id = ntohl (if_id);
21279   mp->is_enabled = enable;
21280   mp->count = ntohl (count);
21281   mp->pcap_name_length = ntohl (name_len);
21282   if (pcap_file_set != 0)
21283     {
21284       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21285     }
21286   vec_free (pcap_file);
21287
21288   S (mp);
21289   W (ret);
21290   return ret;
21291 }
21292
21293 int
21294 api_pg_enable_disable (vat_main_t * vam)
21295 {
21296   unformat_input_t *input = vam->input;
21297   vl_api_pg_enable_disable_t *mp;
21298
21299   u8 enable = 1;
21300   u8 stream_name_set = 0;
21301   u8 *stream_name = 0;
21302   int ret;
21303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21304     {
21305       if (unformat (input, "stream %s", &stream_name))
21306         stream_name_set = 1;
21307       else if (unformat (input, "disable"))
21308         enable = 0;
21309       else
21310         break;
21311     }
21312
21313   if (stream_name_set > 0)
21314     {
21315       if (vec_len (stream_name) > 255)
21316         {
21317           errmsg ("stream name too long");
21318           return -99;
21319         }
21320     }
21321
21322   u32 name_len = vec_len (stream_name);
21323   /* Construct the API message */
21324   M (PG_ENABLE_DISABLE, mp);
21325   mp->context = 0;
21326   mp->is_enabled = enable;
21327   if (stream_name_set != 0)
21328     {
21329       mp->stream_name_length = ntohl (name_len);
21330       clib_memcpy (mp->stream_name, stream_name, name_len);
21331     }
21332   vec_free (stream_name);
21333
21334   S (mp);
21335   W (ret);
21336   return ret;
21337 }
21338
21339 int
21340 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21341 {
21342   unformat_input_t *input = vam->input;
21343   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21344
21345   u16 *low_ports = 0;
21346   u16 *high_ports = 0;
21347   u16 this_low;
21348   u16 this_hi;
21349   ip4_address_t ip4_addr;
21350   ip6_address_t ip6_addr;
21351   u32 length;
21352   u32 tmp, tmp2;
21353   u8 prefix_set = 0;
21354   u32 vrf_id = ~0;
21355   u8 is_add = 1;
21356   u8 is_ipv6 = 0;
21357   int ret;
21358
21359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21360     {
21361       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21362         {
21363           prefix_set = 1;
21364         }
21365       else
21366         if (unformat
21367             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21368         {
21369           prefix_set = 1;
21370           is_ipv6 = 1;
21371         }
21372       else if (unformat (input, "vrf %d", &vrf_id))
21373         ;
21374       else if (unformat (input, "del"))
21375         is_add = 0;
21376       else if (unformat (input, "port %d", &tmp))
21377         {
21378           if (tmp == 0 || tmp > 65535)
21379             {
21380               errmsg ("port %d out of range", tmp);
21381               return -99;
21382             }
21383           this_low = tmp;
21384           this_hi = this_low + 1;
21385           vec_add1 (low_ports, this_low);
21386           vec_add1 (high_ports, this_hi);
21387         }
21388       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21389         {
21390           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21391             {
21392               errmsg ("incorrect range parameters");
21393               return -99;
21394             }
21395           this_low = tmp;
21396           /* Note: in debug CLI +1 is added to high before
21397              passing to real fn that does "the work"
21398              (ip_source_and_port_range_check_add_del).
21399              This fn is a wrapper around the binary API fn a
21400              control plane will call, which expects this increment
21401              to have occurred. Hence letting the binary API control
21402              plane fn do the increment for consistency between VAT
21403              and other control planes.
21404            */
21405           this_hi = tmp2;
21406           vec_add1 (low_ports, this_low);
21407           vec_add1 (high_ports, this_hi);
21408         }
21409       else
21410         break;
21411     }
21412
21413   if (prefix_set == 0)
21414     {
21415       errmsg ("<address>/<mask> not specified");
21416       return -99;
21417     }
21418
21419   if (vrf_id == ~0)
21420     {
21421       errmsg ("VRF ID required, not specified");
21422       return -99;
21423     }
21424
21425   if (vrf_id == 0)
21426     {
21427       errmsg
21428         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21429       return -99;
21430     }
21431
21432   if (vec_len (low_ports) == 0)
21433     {
21434       errmsg ("At least one port or port range required");
21435       return -99;
21436     }
21437
21438   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21439
21440   mp->is_add = is_add;
21441
21442   if (is_ipv6)
21443     {
21444       mp->is_ipv6 = 1;
21445       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21446     }
21447   else
21448     {
21449       mp->is_ipv6 = 0;
21450       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21451     }
21452
21453   mp->mask_length = length;
21454   mp->number_of_ranges = vec_len (low_ports);
21455
21456   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21457   vec_free (low_ports);
21458
21459   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21460   vec_free (high_ports);
21461
21462   mp->vrf_id = ntohl (vrf_id);
21463
21464   S (mp);
21465   W (ret);
21466   return ret;
21467 }
21468
21469 int
21470 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21471 {
21472   unformat_input_t *input = vam->input;
21473   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21474   u32 sw_if_index = ~0;
21475   int vrf_set = 0;
21476   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21477   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21478   u8 is_add = 1;
21479   int ret;
21480
21481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21482     {
21483       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21484         ;
21485       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21486         ;
21487       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21488         vrf_set = 1;
21489       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21490         vrf_set = 1;
21491       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21492         vrf_set = 1;
21493       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21494         vrf_set = 1;
21495       else if (unformat (input, "del"))
21496         is_add = 0;
21497       else
21498         break;
21499     }
21500
21501   if (sw_if_index == ~0)
21502     {
21503       errmsg ("Interface required but not specified");
21504       return -99;
21505     }
21506
21507   if (vrf_set == 0)
21508     {
21509       errmsg ("VRF ID required but not specified");
21510       return -99;
21511     }
21512
21513   if (tcp_out_vrf_id == 0
21514       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21515     {
21516       errmsg
21517         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21518       return -99;
21519     }
21520
21521   /* Construct the API message */
21522   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21523
21524   mp->sw_if_index = ntohl (sw_if_index);
21525   mp->is_add = is_add;
21526   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21527   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21528   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21529   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21530
21531   /* send it... */
21532   S (mp);
21533
21534   /* Wait for a reply... */
21535   W (ret);
21536   return ret;
21537 }
21538
21539 static int
21540 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21541 {
21542   unformat_input_t *i = vam->input;
21543   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21544   u32 local_sa_id = 0;
21545   u32 remote_sa_id = 0;
21546   ip4_address_t src_address;
21547   ip4_address_t dst_address;
21548   u8 is_add = 1;
21549   int ret;
21550
21551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21552     {
21553       if (unformat (i, "local_sa %d", &local_sa_id))
21554         ;
21555       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21556         ;
21557       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21558         ;
21559       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21560         ;
21561       else if (unformat (i, "del"))
21562         is_add = 0;
21563       else
21564         {
21565           clib_warning ("parse error '%U'", format_unformat_error, i);
21566           return -99;
21567         }
21568     }
21569
21570   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21571
21572   mp->local_sa_id = ntohl (local_sa_id);
21573   mp->remote_sa_id = ntohl (remote_sa_id);
21574   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21575   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21576   mp->is_add = is_add;
21577
21578   S (mp);
21579   W (ret);
21580   return ret;
21581 }
21582
21583 static int
21584 api_punt (vat_main_t * vam)
21585 {
21586   unformat_input_t *i = vam->input;
21587   vl_api_punt_t *mp;
21588   u32 ipv = ~0;
21589   u32 protocol = ~0;
21590   u32 port = ~0;
21591   int is_add = 1;
21592   int ret;
21593
21594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21595     {
21596       if (unformat (i, "ip %d", &ipv))
21597         ;
21598       else if (unformat (i, "protocol %d", &protocol))
21599         ;
21600       else if (unformat (i, "port %d", &port))
21601         ;
21602       else if (unformat (i, "del"))
21603         is_add = 0;
21604       else
21605         {
21606           clib_warning ("parse error '%U'", format_unformat_error, i);
21607           return -99;
21608         }
21609     }
21610
21611   M (PUNT, mp);
21612
21613   mp->is_add = (u8) is_add;
21614   mp->ipv = (u8) ipv;
21615   mp->l4_protocol = (u8) protocol;
21616   mp->l4_port = htons ((u16) port);
21617
21618   S (mp);
21619   W (ret);
21620   return ret;
21621 }
21622
21623 static void vl_api_ipsec_gre_tunnel_details_t_handler
21624   (vl_api_ipsec_gre_tunnel_details_t * mp)
21625 {
21626   vat_main_t *vam = &vat_main;
21627
21628   print (vam->ofp, "%11d%15U%15U%14d%14d",
21629          ntohl (mp->sw_if_index),
21630          format_ip4_address, &mp->src_address,
21631          format_ip4_address, &mp->dst_address,
21632          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21633 }
21634
21635 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21636   (vl_api_ipsec_gre_tunnel_details_t * mp)
21637 {
21638   vat_main_t *vam = &vat_main;
21639   vat_json_node_t *node = NULL;
21640   struct in_addr ip4;
21641
21642   if (VAT_JSON_ARRAY != vam->json_tree.type)
21643     {
21644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21645       vat_json_init_array (&vam->json_tree);
21646     }
21647   node = vat_json_array_add (&vam->json_tree);
21648
21649   vat_json_init_object (node);
21650   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21651   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21652   vat_json_object_add_ip4 (node, "src_address", ip4);
21653   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21654   vat_json_object_add_ip4 (node, "dst_address", ip4);
21655   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21656   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21657 }
21658
21659 static int
21660 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21661 {
21662   unformat_input_t *i = vam->input;
21663   vl_api_ipsec_gre_tunnel_dump_t *mp;
21664   vl_api_control_ping_t *mp_ping;
21665   u32 sw_if_index;
21666   u8 sw_if_index_set = 0;
21667   int ret;
21668
21669   /* Parse args required to build the message */
21670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21671     {
21672       if (unformat (i, "sw_if_index %d", &sw_if_index))
21673         sw_if_index_set = 1;
21674       else
21675         break;
21676     }
21677
21678   if (sw_if_index_set == 0)
21679     {
21680       sw_if_index = ~0;
21681     }
21682
21683   if (!vam->json_output)
21684     {
21685       print (vam->ofp, "%11s%15s%15s%14s%14s",
21686              "sw_if_index", "src_address", "dst_address",
21687              "local_sa_id", "remote_sa_id");
21688     }
21689
21690   /* Get list of gre-tunnel interfaces */
21691   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21692
21693   mp->sw_if_index = htonl (sw_if_index);
21694
21695   S (mp);
21696
21697   /* Use a control ping for synchronization */
21698   MPING (CONTROL_PING, mp_ping);
21699   S (mp_ping);
21700
21701   W (ret);
21702   return ret;
21703 }
21704
21705 static int
21706 api_delete_subif (vat_main_t * vam)
21707 {
21708   unformat_input_t *i = vam->input;
21709   vl_api_delete_subif_t *mp;
21710   u32 sw_if_index = ~0;
21711   int ret;
21712
21713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21714     {
21715       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21716         ;
21717       if (unformat (i, "sw_if_index %d", &sw_if_index))
21718         ;
21719       else
21720         break;
21721     }
21722
21723   if (sw_if_index == ~0)
21724     {
21725       errmsg ("missing sw_if_index");
21726       return -99;
21727     }
21728
21729   /* Construct the API message */
21730   M (DELETE_SUBIF, mp);
21731   mp->sw_if_index = ntohl (sw_if_index);
21732
21733   S (mp);
21734   W (ret);
21735   return ret;
21736 }
21737
21738 #define foreach_pbb_vtr_op      \
21739 _("disable",  L2_VTR_DISABLED)  \
21740 _("pop",  L2_VTR_POP_2)         \
21741 _("push",  L2_VTR_PUSH_2)
21742
21743 static int
21744 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21745 {
21746   unformat_input_t *i = vam->input;
21747   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21748   u32 sw_if_index = ~0, vtr_op = ~0;
21749   u16 outer_tag = ~0;
21750   u8 dmac[6], smac[6];
21751   u8 dmac_set = 0, smac_set = 0;
21752   u16 vlanid = 0;
21753   u32 sid = ~0;
21754   u32 tmp;
21755   int ret;
21756
21757   /* Shut up coverity */
21758   memset (dmac, 0, sizeof (dmac));
21759   memset (smac, 0, sizeof (smac));
21760
21761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21762     {
21763       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21764         ;
21765       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21766         ;
21767       else if (unformat (i, "vtr_op %d", &vtr_op))
21768         ;
21769 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21770       foreach_pbb_vtr_op
21771 #undef _
21772         else if (unformat (i, "translate_pbb_stag"))
21773         {
21774           if (unformat (i, "%d", &tmp))
21775             {
21776               vtr_op = L2_VTR_TRANSLATE_2_1;
21777               outer_tag = tmp;
21778             }
21779           else
21780             {
21781               errmsg
21782                 ("translate_pbb_stag operation requires outer tag definition");
21783               return -99;
21784             }
21785         }
21786       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21787         dmac_set++;
21788       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21789         smac_set++;
21790       else if (unformat (i, "sid %d", &sid))
21791         ;
21792       else if (unformat (i, "vlanid %d", &tmp))
21793         vlanid = tmp;
21794       else
21795         {
21796           clib_warning ("parse error '%U'", format_unformat_error, i);
21797           return -99;
21798         }
21799     }
21800
21801   if ((sw_if_index == ~0) || (vtr_op == ~0))
21802     {
21803       errmsg ("missing sw_if_index or vtr operation");
21804       return -99;
21805     }
21806   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21807       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21808     {
21809       errmsg
21810         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21811       return -99;
21812     }
21813
21814   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21815   mp->sw_if_index = ntohl (sw_if_index);
21816   mp->vtr_op = ntohl (vtr_op);
21817   mp->outer_tag = ntohs (outer_tag);
21818   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21819   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21820   mp->b_vlanid = ntohs (vlanid);
21821   mp->i_sid = ntohl (sid);
21822
21823   S (mp);
21824   W (ret);
21825   return ret;
21826 }
21827
21828 static int
21829 api_flow_classify_set_interface (vat_main_t * vam)
21830 {
21831   unformat_input_t *i = vam->input;
21832   vl_api_flow_classify_set_interface_t *mp;
21833   u32 sw_if_index;
21834   int sw_if_index_set;
21835   u32 ip4_table_index = ~0;
21836   u32 ip6_table_index = ~0;
21837   u8 is_add = 1;
21838   int ret;
21839
21840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21841     {
21842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21843         sw_if_index_set = 1;
21844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21845         sw_if_index_set = 1;
21846       else if (unformat (i, "del"))
21847         is_add = 0;
21848       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21849         ;
21850       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21851         ;
21852       else
21853         {
21854           clib_warning ("parse error '%U'", format_unformat_error, i);
21855           return -99;
21856         }
21857     }
21858
21859   if (sw_if_index_set == 0)
21860     {
21861       errmsg ("missing interface name or sw_if_index");
21862       return -99;
21863     }
21864
21865   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21866
21867   mp->sw_if_index = ntohl (sw_if_index);
21868   mp->ip4_table_index = ntohl (ip4_table_index);
21869   mp->ip6_table_index = ntohl (ip6_table_index);
21870   mp->is_add = is_add;
21871
21872   S (mp);
21873   W (ret);
21874   return ret;
21875 }
21876
21877 static int
21878 api_flow_classify_dump (vat_main_t * vam)
21879 {
21880   unformat_input_t *i = vam->input;
21881   vl_api_flow_classify_dump_t *mp;
21882   vl_api_control_ping_t *mp_ping;
21883   u8 type = FLOW_CLASSIFY_N_TABLES;
21884   int ret;
21885
21886   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21887     ;
21888   else
21889     {
21890       errmsg ("classify table type must be specified");
21891       return -99;
21892     }
21893
21894   if (!vam->json_output)
21895     {
21896       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21897     }
21898
21899   M (FLOW_CLASSIFY_DUMP, mp);
21900   mp->type = type;
21901   /* send it... */
21902   S (mp);
21903
21904   /* Use a control ping for synchronization */
21905   MPING (CONTROL_PING, mp_ping);
21906   S (mp_ping);
21907
21908   /* Wait for a reply... */
21909   W (ret);
21910   return ret;
21911 }
21912
21913 static int
21914 api_feature_enable_disable (vat_main_t * vam)
21915 {
21916   unformat_input_t *i = vam->input;
21917   vl_api_feature_enable_disable_t *mp;
21918   u8 *arc_name = 0;
21919   u8 *feature_name = 0;
21920   u32 sw_if_index = ~0;
21921   u8 enable = 1;
21922   int ret;
21923
21924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21925     {
21926       if (unformat (i, "arc_name %s", &arc_name))
21927         ;
21928       else if (unformat (i, "feature_name %s", &feature_name))
21929         ;
21930       else
21931         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21932         ;
21933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21934         ;
21935       else if (unformat (i, "disable"))
21936         enable = 0;
21937       else
21938         break;
21939     }
21940
21941   if (arc_name == 0)
21942     {
21943       errmsg ("missing arc name");
21944       return -99;
21945     }
21946   if (vec_len (arc_name) > 63)
21947     {
21948       errmsg ("arc name too long");
21949     }
21950
21951   if (feature_name == 0)
21952     {
21953       errmsg ("missing feature name");
21954       return -99;
21955     }
21956   if (vec_len (feature_name) > 63)
21957     {
21958       errmsg ("feature name too long");
21959     }
21960
21961   if (sw_if_index == ~0)
21962     {
21963       errmsg ("missing interface name or sw_if_index");
21964       return -99;
21965     }
21966
21967   /* Construct the API message */
21968   M (FEATURE_ENABLE_DISABLE, mp);
21969   mp->sw_if_index = ntohl (sw_if_index);
21970   mp->enable = enable;
21971   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21972   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21973   vec_free (arc_name);
21974   vec_free (feature_name);
21975
21976   S (mp);
21977   W (ret);
21978   return ret;
21979 }
21980
21981 static int
21982 api_sw_interface_tag_add_del (vat_main_t * vam)
21983 {
21984   unformat_input_t *i = vam->input;
21985   vl_api_sw_interface_tag_add_del_t *mp;
21986   u32 sw_if_index = ~0;
21987   u8 *tag = 0;
21988   u8 enable = 1;
21989   int ret;
21990
21991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21992     {
21993       if (unformat (i, "tag %s", &tag))
21994         ;
21995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21996         ;
21997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21998         ;
21999       else if (unformat (i, "del"))
22000         enable = 0;
22001       else
22002         break;
22003     }
22004
22005   if (sw_if_index == ~0)
22006     {
22007       errmsg ("missing interface name or sw_if_index");
22008       return -99;
22009     }
22010
22011   if (enable && (tag == 0))
22012     {
22013       errmsg ("no tag specified");
22014       return -99;
22015     }
22016
22017   /* Construct the API message */
22018   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22019   mp->sw_if_index = ntohl (sw_if_index);
22020   mp->is_add = enable;
22021   if (enable)
22022     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22023   vec_free (tag);
22024
22025   S (mp);
22026   W (ret);
22027   return ret;
22028 }
22029
22030 static void vl_api_l2_xconnect_details_t_handler
22031   (vl_api_l2_xconnect_details_t * mp)
22032 {
22033   vat_main_t *vam = &vat_main;
22034
22035   print (vam->ofp, "%15d%15d",
22036          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22037 }
22038
22039 static void vl_api_l2_xconnect_details_t_handler_json
22040   (vl_api_l2_xconnect_details_t * mp)
22041 {
22042   vat_main_t *vam = &vat_main;
22043   vat_json_node_t *node = NULL;
22044
22045   if (VAT_JSON_ARRAY != vam->json_tree.type)
22046     {
22047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22048       vat_json_init_array (&vam->json_tree);
22049     }
22050   node = vat_json_array_add (&vam->json_tree);
22051
22052   vat_json_init_object (node);
22053   vat_json_object_add_uint (node, "rx_sw_if_index",
22054                             ntohl (mp->rx_sw_if_index));
22055   vat_json_object_add_uint (node, "tx_sw_if_index",
22056                             ntohl (mp->tx_sw_if_index));
22057 }
22058
22059 static int
22060 api_l2_xconnect_dump (vat_main_t * vam)
22061 {
22062   vl_api_l2_xconnect_dump_t *mp;
22063   vl_api_control_ping_t *mp_ping;
22064   int ret;
22065
22066   if (!vam->json_output)
22067     {
22068       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22069     }
22070
22071   M (L2_XCONNECT_DUMP, mp);
22072
22073   S (mp);
22074
22075   /* Use a control ping for synchronization */
22076   MPING (CONTROL_PING, mp_ping);
22077   S (mp_ping);
22078
22079   W (ret);
22080   return ret;
22081 }
22082
22083 static int
22084 api_hw_interface_set_mtu (vat_main_t * vam)
22085 {
22086   unformat_input_t *i = vam->input;
22087   vl_api_hw_interface_set_mtu_t *mp;
22088   u32 sw_if_index = ~0;
22089   u32 mtu = 0;
22090   int ret;
22091
22092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22093     {
22094       if (unformat (i, "mtu %d", &mtu))
22095         ;
22096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22097         ;
22098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22099         ;
22100       else
22101         break;
22102     }
22103
22104   if (sw_if_index == ~0)
22105     {
22106       errmsg ("missing interface name or sw_if_index");
22107       return -99;
22108     }
22109
22110   if (mtu == 0)
22111     {
22112       errmsg ("no mtu specified");
22113       return -99;
22114     }
22115
22116   /* Construct the API message */
22117   M (HW_INTERFACE_SET_MTU, mp);
22118   mp->sw_if_index = ntohl (sw_if_index);
22119   mp->mtu = ntohs ((u16) mtu);
22120
22121   S (mp);
22122   W (ret);
22123   return ret;
22124 }
22125
22126 static int
22127 api_p2p_ethernet_add (vat_main_t * vam)
22128 {
22129   unformat_input_t *i = vam->input;
22130   vl_api_p2p_ethernet_add_t *mp;
22131   u32 parent_if_index = ~0;
22132   u32 sub_id = ~0;
22133   u8 remote_mac[6];
22134   u8 mac_set = 0;
22135   int ret;
22136
22137   memset (remote_mac, 0, sizeof (remote_mac));
22138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22139     {
22140       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22141         ;
22142       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22143         ;
22144       else
22145         if (unformat
22146             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22147         mac_set++;
22148       else if (unformat (i, "sub_id %d", &sub_id))
22149         ;
22150       else
22151         {
22152           clib_warning ("parse error '%U'", format_unformat_error, i);
22153           return -99;
22154         }
22155     }
22156
22157   if (parent_if_index == ~0)
22158     {
22159       errmsg ("missing interface name or sw_if_index");
22160       return -99;
22161     }
22162   if (mac_set == 0)
22163     {
22164       errmsg ("missing remote mac address");
22165       return -99;
22166     }
22167   if (sub_id == ~0)
22168     {
22169       errmsg ("missing sub-interface id");
22170       return -99;
22171     }
22172
22173   M (P2P_ETHERNET_ADD, mp);
22174   mp->parent_if_index = ntohl (parent_if_index);
22175   mp->subif_id = ntohl (sub_id);
22176   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22177
22178   S (mp);
22179   W (ret);
22180   return ret;
22181 }
22182
22183 static int
22184 api_p2p_ethernet_del (vat_main_t * vam)
22185 {
22186   unformat_input_t *i = vam->input;
22187   vl_api_p2p_ethernet_del_t *mp;
22188   u32 parent_if_index = ~0;
22189   u8 remote_mac[6];
22190   u8 mac_set = 0;
22191   int ret;
22192
22193   memset (remote_mac, 0, sizeof (remote_mac));
22194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22195     {
22196       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22197         ;
22198       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22199         ;
22200       else
22201         if (unformat
22202             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22203         mac_set++;
22204       else
22205         {
22206           clib_warning ("parse error '%U'", format_unformat_error, i);
22207           return -99;
22208         }
22209     }
22210
22211   if (parent_if_index == ~0)
22212     {
22213       errmsg ("missing interface name or sw_if_index");
22214       return -99;
22215     }
22216   if (mac_set == 0)
22217     {
22218       errmsg ("missing remote mac address");
22219       return -99;
22220     }
22221
22222   M (P2P_ETHERNET_DEL, mp);
22223   mp->parent_if_index = ntohl (parent_if_index);
22224   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22225
22226   S (mp);
22227   W (ret);
22228   return ret;
22229 }
22230
22231 static int
22232 api_lldp_config (vat_main_t * vam)
22233 {
22234   unformat_input_t *i = vam->input;
22235   vl_api_lldp_config_t *mp;
22236   int tx_hold = 0;
22237   int tx_interval = 0;
22238   u8 *sys_name = NULL;
22239   int ret;
22240
22241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22242     {
22243       if (unformat (i, "system-name %s", &sys_name))
22244         ;
22245       else if (unformat (i, "tx-hold %d", &tx_hold))
22246         ;
22247       else if (unformat (i, "tx-interval %d", &tx_interval))
22248         ;
22249       else
22250         {
22251           clib_warning ("parse error '%U'", format_unformat_error, i);
22252           return -99;
22253         }
22254     }
22255
22256   vec_add1 (sys_name, 0);
22257
22258   M (LLDP_CONFIG, mp);
22259   mp->tx_hold = htonl (tx_hold);
22260   mp->tx_interval = htonl (tx_interval);
22261   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22262   vec_free (sys_name);
22263
22264   S (mp);
22265   W (ret);
22266   return ret;
22267 }
22268
22269 static int
22270 api_sw_interface_set_lldp (vat_main_t * vam)
22271 {
22272   unformat_input_t *i = vam->input;
22273   vl_api_sw_interface_set_lldp_t *mp;
22274   u32 sw_if_index = ~0;
22275   u32 enable = 1;
22276   u8 *port_desc = NULL, *mgmt_oid = NULL;
22277   ip4_address_t ip4_addr;
22278   ip6_address_t ip6_addr;
22279   int ret;
22280
22281   memset (&ip4_addr, 0, sizeof (ip4_addr));
22282   memset (&ip6_addr, 0, sizeof (ip6_addr));
22283
22284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22285     {
22286       if (unformat (i, "disable"))
22287         enable = 0;
22288       else
22289         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22290         ;
22291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22292         ;
22293       else if (unformat (i, "port-desc %s", &port_desc))
22294         ;
22295       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22296         ;
22297       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22298         ;
22299       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22300         ;
22301       else
22302         break;
22303     }
22304
22305   if (sw_if_index == ~0)
22306     {
22307       errmsg ("missing interface name or sw_if_index");
22308       return -99;
22309     }
22310
22311   /* Construct the API message */
22312   vec_add1 (port_desc, 0);
22313   vec_add1 (mgmt_oid, 0);
22314   M (SW_INTERFACE_SET_LLDP, mp);
22315   mp->sw_if_index = ntohl (sw_if_index);
22316   mp->enable = enable;
22317   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22318   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22319   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22320   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22321   vec_free (port_desc);
22322   vec_free (mgmt_oid);
22323
22324   S (mp);
22325   W (ret);
22326   return ret;
22327 }
22328
22329 static int
22330 api_tcp_configure_src_addresses (vat_main_t * vam)
22331 {
22332   vl_api_tcp_configure_src_addresses_t *mp;
22333   unformat_input_t *i = vam->input;
22334   ip4_address_t v4first, v4last;
22335   ip6_address_t v6first, v6last;
22336   u8 range_set = 0;
22337   u32 vrf_id = 0;
22338   int ret;
22339
22340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22341     {
22342       if (unformat (i, "%U - %U",
22343                     unformat_ip4_address, &v4first,
22344                     unformat_ip4_address, &v4last))
22345         {
22346           if (range_set)
22347             {
22348               errmsg ("one range per message (range already set)");
22349               return -99;
22350             }
22351           range_set = 1;
22352         }
22353       else if (unformat (i, "%U - %U",
22354                          unformat_ip6_address, &v6first,
22355                          unformat_ip6_address, &v6last))
22356         {
22357           if (range_set)
22358             {
22359               errmsg ("one range per message (range already set)");
22360               return -99;
22361             }
22362           range_set = 2;
22363         }
22364       else if (unformat (i, "vrf %d", &vrf_id))
22365         ;
22366       else
22367         break;
22368     }
22369
22370   if (range_set == 0)
22371     {
22372       errmsg ("address range not set");
22373       return -99;
22374     }
22375
22376   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22377   mp->vrf_id = ntohl (vrf_id);
22378   /* ipv6? */
22379   if (range_set == 2)
22380     {
22381       mp->is_ipv6 = 1;
22382       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22383       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22384     }
22385   else
22386     {
22387       mp->is_ipv6 = 0;
22388       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22389       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22390     }
22391   S (mp);
22392   W (ret);
22393   return ret;
22394 }
22395
22396 static void vl_api_app_namespace_add_del_reply_t_handler
22397   (vl_api_app_namespace_add_del_reply_t * mp)
22398 {
22399   vat_main_t *vam = &vat_main;
22400   i32 retval = ntohl (mp->retval);
22401   if (vam->async_mode)
22402     {
22403       vam->async_errors += (retval < 0);
22404     }
22405   else
22406     {
22407       vam->retval = retval;
22408       if (retval == 0)
22409         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22410       vam->result_ready = 1;
22411     }
22412 }
22413
22414 static void vl_api_app_namespace_add_del_reply_t_handler_json
22415   (vl_api_app_namespace_add_del_reply_t * mp)
22416 {
22417   vat_main_t *vam = &vat_main;
22418   vat_json_node_t node;
22419
22420   vat_json_init_object (&node);
22421   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22422   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22423
22424   vat_json_print (vam->ofp, &node);
22425   vat_json_free (&node);
22426
22427   vam->retval = ntohl (mp->retval);
22428   vam->result_ready = 1;
22429 }
22430
22431 static int
22432 api_app_namespace_add_del (vat_main_t * vam)
22433 {
22434   vl_api_app_namespace_add_del_t *mp;
22435   unformat_input_t *i = vam->input;
22436   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22437   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22438   u64 secret;
22439   int ret;
22440
22441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22442     {
22443       if (unformat (i, "id %_%v%_", &ns_id))
22444         ;
22445       else if (unformat (i, "secret %lu", &secret))
22446         secret_set = 1;
22447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22448         sw_if_index_set = 1;
22449       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22450         ;
22451       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22452         ;
22453       else
22454         break;
22455     }
22456   if (!ns_id || !secret_set || !sw_if_index_set)
22457     {
22458       errmsg ("namespace id, secret and sw_if_index must be set");
22459       return -99;
22460     }
22461   if (vec_len (ns_id) > 64)
22462     {
22463       errmsg ("namespace id too long");
22464       return -99;
22465     }
22466   M (APP_NAMESPACE_ADD_DEL, mp);
22467
22468   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22469   mp->namespace_id_len = vec_len (ns_id);
22470   mp->secret = clib_host_to_net_u64 (secret);
22471   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22472   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22473   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22474   vec_free (ns_id);
22475   S (mp);
22476   W (ret);
22477   return ret;
22478 }
22479
22480 static int
22481 api_sock_init_shm (vat_main_t * vam)
22482 {
22483 #if VPP_API_TEST_BUILTIN == 0
22484   unformat_input_t *i = vam->input;
22485   vl_api_shm_elem_config_t *config = 0;
22486   u64 size = 64 << 20;
22487   int rv;
22488
22489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22490     {
22491       if (unformat (i, "size %U", unformat_memory_size, &size))
22492         ;
22493       else
22494         break;
22495     }
22496
22497   /*
22498    * Canned custom ring allocator config.
22499    * Should probably parse all of this
22500    */
22501   vec_validate (config, 6);
22502   config[0].type = VL_API_VLIB_RING;
22503   config[0].size = 256;
22504   config[0].count = 32;
22505
22506   config[1].type = VL_API_VLIB_RING;
22507   config[1].size = 1024;
22508   config[1].count = 16;
22509
22510   config[2].type = VL_API_VLIB_RING;
22511   config[2].size = 4096;
22512   config[2].count = 2;
22513
22514   config[3].type = VL_API_CLIENT_RING;
22515   config[3].size = 256;
22516   config[3].count = 32;
22517
22518   config[4].type = VL_API_CLIENT_RING;
22519   config[4].size = 1024;
22520   config[4].count = 16;
22521
22522   config[5].type = VL_API_CLIENT_RING;
22523   config[5].size = 4096;
22524   config[5].count = 2;
22525
22526   config[6].type = VL_API_QUEUE;
22527   config[6].count = 128;
22528   config[6].size = sizeof (uword);
22529
22530   rv = vl_socket_client_init_shm (config);
22531   if (!rv)
22532     vam->client_index_invalid = 1;
22533   return rv;
22534 #else
22535   return -99;
22536 #endif
22537 }
22538
22539 static int
22540 api_dns_enable_disable (vat_main_t * vam)
22541 {
22542   unformat_input_t *line_input = vam->input;
22543   vl_api_dns_enable_disable_t *mp;
22544   u8 enable_disable = 1;
22545   int ret;
22546
22547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22548     {
22549       if (unformat (line_input, "disable"))
22550         enable_disable = 0;
22551       if (unformat (line_input, "enable"))
22552         enable_disable = 1;
22553       else
22554         break;
22555     }
22556
22557   /* Construct the API message */
22558   M (DNS_ENABLE_DISABLE, mp);
22559   mp->enable = enable_disable;
22560
22561   /* send it... */
22562   S (mp);
22563   /* Wait for the reply */
22564   W (ret);
22565   return ret;
22566 }
22567
22568 static int
22569 api_dns_resolve_name (vat_main_t * vam)
22570 {
22571   unformat_input_t *line_input = vam->input;
22572   vl_api_dns_resolve_name_t *mp;
22573   u8 *name = 0;
22574   int ret;
22575
22576   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22577     {
22578       if (unformat (line_input, "%s", &name))
22579         ;
22580       else
22581         break;
22582     }
22583
22584   if (vec_len (name) > 127)
22585     {
22586       errmsg ("name too long");
22587       return -99;
22588     }
22589
22590   /* Construct the API message */
22591   M (DNS_RESOLVE_NAME, mp);
22592   memcpy (mp->name, name, vec_len (name));
22593   vec_free (name);
22594
22595   /* send it... */
22596   S (mp);
22597   /* Wait for the reply */
22598   W (ret);
22599   return ret;
22600 }
22601
22602 static int
22603 api_dns_resolve_ip (vat_main_t * vam)
22604 {
22605   unformat_input_t *line_input = vam->input;
22606   vl_api_dns_resolve_ip_t *mp;
22607   int is_ip6 = -1;
22608   ip4_address_t addr4;
22609   ip6_address_t addr6;
22610   int ret;
22611
22612   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22613     {
22614       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22615         is_ip6 = 1;
22616       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22617         is_ip6 = 0;
22618       else
22619         break;
22620     }
22621
22622   if (is_ip6 == -1)
22623     {
22624       errmsg ("missing address");
22625       return -99;
22626     }
22627
22628   /* Construct the API message */
22629   M (DNS_RESOLVE_IP, mp);
22630   mp->is_ip6 = is_ip6;
22631   if (is_ip6)
22632     memcpy (mp->address, &addr6, sizeof (addr6));
22633   else
22634     memcpy (mp->address, &addr4, sizeof (addr4));
22635
22636   /* send it... */
22637   S (mp);
22638   /* Wait for the reply */
22639   W (ret);
22640   return ret;
22641 }
22642
22643 static int
22644 api_dns_name_server_add_del (vat_main_t * vam)
22645 {
22646   unformat_input_t *i = vam->input;
22647   vl_api_dns_name_server_add_del_t *mp;
22648   u8 is_add = 1;
22649   ip6_address_t ip6_server;
22650   ip4_address_t ip4_server;
22651   int ip6_set = 0;
22652   int ip4_set = 0;
22653   int ret = 0;
22654
22655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22656     {
22657       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22658         ip6_set = 1;
22659       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22660         ip4_set = 1;
22661       else if (unformat (i, "del"))
22662         is_add = 0;
22663       else
22664         {
22665           clib_warning ("parse error '%U'", format_unformat_error, i);
22666           return -99;
22667         }
22668     }
22669
22670   if (ip4_set && ip6_set)
22671     {
22672       errmsg ("Only one server address allowed per message");
22673       return -99;
22674     }
22675   if ((ip4_set + ip6_set) == 0)
22676     {
22677       errmsg ("Server address required");
22678       return -99;
22679     }
22680
22681   /* Construct the API message */
22682   M (DNS_NAME_SERVER_ADD_DEL, mp);
22683
22684   if (ip6_set)
22685     {
22686       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22687       mp->is_ip6 = 1;
22688     }
22689   else
22690     {
22691       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22692       mp->is_ip6 = 0;
22693     }
22694
22695   mp->is_add = is_add;
22696
22697   /* send it... */
22698   S (mp);
22699
22700   /* Wait for a reply, return good/bad news  */
22701   W (ret);
22702   return ret;
22703 }
22704
22705 static void
22706 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22707 {
22708   vat_main_t *vam = &vat_main;
22709
22710   if (mp->is_ip4)
22711     {
22712       print (vam->ofp,
22713              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22714              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22715              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22716              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22717              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22718              clib_net_to_host_u32 (mp->action_index), mp->tag);
22719     }
22720   else
22721     {
22722       print (vam->ofp,
22723              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22724              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22725              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22726              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22727              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22728              clib_net_to_host_u32 (mp->action_index), mp->tag);
22729     }
22730 }
22731
22732 static void
22733 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22734                                              mp)
22735 {
22736   vat_main_t *vam = &vat_main;
22737   vat_json_node_t *node = NULL;
22738   struct in6_addr ip6;
22739   struct in_addr ip4;
22740
22741   if (VAT_JSON_ARRAY != vam->json_tree.type)
22742     {
22743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22744       vat_json_init_array (&vam->json_tree);
22745     }
22746   node = vat_json_array_add (&vam->json_tree);
22747   vat_json_init_object (node);
22748
22749   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22750   vat_json_object_add_uint (node, "appns_index",
22751                             clib_net_to_host_u32 (mp->appns_index));
22752   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22753   vat_json_object_add_uint (node, "scope", mp->scope);
22754   vat_json_object_add_uint (node, "action_index",
22755                             clib_net_to_host_u32 (mp->action_index));
22756   vat_json_object_add_uint (node, "lcl_port",
22757                             clib_net_to_host_u16 (mp->lcl_port));
22758   vat_json_object_add_uint (node, "rmt_port",
22759                             clib_net_to_host_u16 (mp->rmt_port));
22760   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22761   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22762   vat_json_object_add_string_copy (node, "tag", mp->tag);
22763   if (mp->is_ip4)
22764     {
22765       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22766       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22767       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22768       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22769     }
22770   else
22771     {
22772       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22773       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22774       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22775       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22776     }
22777 }
22778
22779 static int
22780 api_session_rule_add_del (vat_main_t * vam)
22781 {
22782   vl_api_session_rule_add_del_t *mp;
22783   unformat_input_t *i = vam->input;
22784   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22785   u32 appns_index = 0, scope = 0;
22786   ip4_address_t lcl_ip4, rmt_ip4;
22787   ip6_address_t lcl_ip6, rmt_ip6;
22788   u8 is_ip4 = 1, conn_set = 0;
22789   u8 is_add = 1, *tag = 0;
22790   int ret;
22791
22792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22793     {
22794       if (unformat (i, "del"))
22795         is_add = 0;
22796       else if (unformat (i, "add"))
22797         ;
22798       else if (unformat (i, "proto tcp"))
22799         proto = 0;
22800       else if (unformat (i, "proto udp"))
22801         proto = 1;
22802       else if (unformat (i, "appns %d", &appns_index))
22803         ;
22804       else if (unformat (i, "scope %d", &scope))
22805         ;
22806       else if (unformat (i, "tag %_%v%_", &tag))
22807         ;
22808       else
22809         if (unformat
22810             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22811              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22812              &rmt_port))
22813         {
22814           is_ip4 = 1;
22815           conn_set = 1;
22816         }
22817       else
22818         if (unformat
22819             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22820              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22821              &rmt_port))
22822         {
22823           is_ip4 = 0;
22824           conn_set = 1;
22825         }
22826       else if (unformat (i, "action %d", &action))
22827         ;
22828       else
22829         break;
22830     }
22831   if (proto == ~0 || !conn_set || action == ~0)
22832     {
22833       errmsg ("transport proto, connection and action must be set");
22834       return -99;
22835     }
22836
22837   if (scope > 3)
22838     {
22839       errmsg ("scope should be 0-3");
22840       return -99;
22841     }
22842
22843   M (SESSION_RULE_ADD_DEL, mp);
22844
22845   mp->is_ip4 = is_ip4;
22846   mp->transport_proto = proto;
22847   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22848   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22849   mp->lcl_plen = lcl_plen;
22850   mp->rmt_plen = rmt_plen;
22851   mp->action_index = clib_host_to_net_u32 (action);
22852   mp->appns_index = clib_host_to_net_u32 (appns_index);
22853   mp->scope = scope;
22854   mp->is_add = is_add;
22855   if (is_ip4)
22856     {
22857       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22858       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22859     }
22860   else
22861     {
22862       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22863       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22864     }
22865   if (tag)
22866     {
22867       clib_memcpy (mp->tag, tag, vec_len (tag));
22868       vec_free (tag);
22869     }
22870
22871   S (mp);
22872   W (ret);
22873   return ret;
22874 }
22875
22876 static int
22877 api_session_rules_dump (vat_main_t * vam)
22878 {
22879   vl_api_session_rules_dump_t *mp;
22880   vl_api_control_ping_t *mp_ping;
22881   int ret;
22882
22883   if (!vam->json_output)
22884     {
22885       print (vam->ofp, "%=20s", "Session Rules");
22886     }
22887
22888   M (SESSION_RULES_DUMP, mp);
22889   /* send it... */
22890   S (mp);
22891
22892   /* Use a control ping for synchronization */
22893   MPING (CONTROL_PING, mp_ping);
22894   S (mp_ping);
22895
22896   /* Wait for a reply... */
22897   W (ret);
22898   return ret;
22899 }
22900
22901 static int
22902 api_ip_container_proxy_add_del (vat_main_t * vam)
22903 {
22904   vl_api_ip_container_proxy_add_del_t *mp;
22905   unformat_input_t *i = vam->input;
22906   u32 plen = ~0, sw_if_index = ~0;
22907   ip4_address_t ip4;
22908   ip6_address_t ip6;
22909   u8 is_ip4 = 1;
22910   u8 is_add = 1;
22911   int ret;
22912
22913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22914     {
22915       if (unformat (i, "del"))
22916         is_add = 0;
22917       else if (unformat (i, "add"))
22918         ;
22919       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22920         {
22921           is_ip4 = 1;
22922           plen = 32;
22923         }
22924       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22925         {
22926           is_ip4 = 0;
22927           plen = 128;
22928         }
22929       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22930         ;
22931       else
22932         break;
22933     }
22934   if (sw_if_index == ~0 || plen == ~0)
22935     {
22936       errmsg ("address and sw_if_index must be set");
22937       return -99;
22938     }
22939
22940   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22941
22942   mp->is_ip4 = is_ip4;
22943   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22944   mp->plen = plen;
22945   mp->is_add = is_add;
22946   if (is_ip4)
22947     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22948   else
22949     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22950
22951   S (mp);
22952   W (ret);
22953   return ret;
22954 }
22955
22956 static int
22957 api_qos_record_enable_disable (vat_main_t * vam)
22958 {
22959   unformat_input_t *i = vam->input;
22960   vl_api_qos_record_enable_disable_t *mp;
22961   u32 sw_if_index, qs = 0xff;
22962   u8 sw_if_index_set = 0;
22963   u8 enable = 1;
22964   int ret;
22965
22966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22967     {
22968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22969         sw_if_index_set = 1;
22970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22971         sw_if_index_set = 1;
22972       else if (unformat (i, "%U", unformat_qos_source, &qs))
22973         ;
22974       else if (unformat (i, "disable"))
22975         enable = 0;
22976       else
22977         {
22978           clib_warning ("parse error '%U'", format_unformat_error, i);
22979           return -99;
22980         }
22981     }
22982
22983   if (sw_if_index_set == 0)
22984     {
22985       errmsg ("missing interface name or sw_if_index");
22986       return -99;
22987     }
22988   if (qs == 0xff)
22989     {
22990       errmsg ("input location must be specified");
22991       return -99;
22992     }
22993
22994   M (QOS_RECORD_ENABLE_DISABLE, mp);
22995
22996   mp->sw_if_index = ntohl (sw_if_index);
22997   mp->input_source = qs;
22998   mp->enable = enable;
22999
23000   S (mp);
23001   W (ret);
23002   return ret;
23003 }
23004
23005
23006 static int
23007 q_or_quit (vat_main_t * vam)
23008 {
23009 #if VPP_API_TEST_BUILTIN == 0
23010   longjmp (vam->jump_buf, 1);
23011 #endif
23012   return 0;                     /* not so much */
23013 }
23014
23015 static int
23016 q (vat_main_t * vam)
23017 {
23018   return q_or_quit (vam);
23019 }
23020
23021 static int
23022 quit (vat_main_t * vam)
23023 {
23024   return q_or_quit (vam);
23025 }
23026
23027 static int
23028 comment (vat_main_t * vam)
23029 {
23030   return 0;
23031 }
23032
23033 static int
23034 statseg (vat_main_t * vam)
23035 {
23036   ssvm_private_t *ssvmp = &vam->stat_segment;
23037   ssvm_shared_header_t *shared_header = ssvmp->sh;
23038   vlib_counter_t **counters;
23039   u64 thread0_index1_packets;
23040   u64 thread0_index1_bytes;
23041   f64 vector_rate, input_rate;
23042   uword *p;
23043
23044   uword *counter_vector_by_name;
23045   if (vam->stat_segment_lockp == 0)
23046     {
23047       errmsg ("Stat segment not mapped...");
23048       return -99;
23049     }
23050
23051   /* look up "/if/rx for sw_if_index 1 as a test */
23052
23053   clib_spinlock_lock (vam->stat_segment_lockp);
23054
23055   counter_vector_by_name = (uword *) shared_header->opaque[1];
23056
23057   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23058   if (p == 0)
23059     {
23060       clib_spinlock_unlock (vam->stat_segment_lockp);
23061       errmsg ("/if/tx not found?");
23062       return -99;
23063     }
23064
23065   /* Fish per-thread vector of combined counters from shared memory */
23066   counters = (vlib_counter_t **) p[0];
23067
23068   if (vec_len (counters[0]) < 2)
23069     {
23070       clib_spinlock_unlock (vam->stat_segment_lockp);
23071       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23072       return -99;
23073     }
23074
23075   /* Read thread 0 sw_if_index 1 counter */
23076   thread0_index1_packets = counters[0][1].packets;
23077   thread0_index1_bytes = counters[0][1].bytes;
23078
23079   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23080   if (p == 0)
23081     {
23082       clib_spinlock_unlock (vam->stat_segment_lockp);
23083       errmsg ("vector_rate not found?");
23084       return -99;
23085     }
23086
23087   vector_rate = *(f64 *) (p[0]);
23088   p = hash_get_mem (counter_vector_by_name, "input_rate");
23089   if (p == 0)
23090     {
23091       clib_spinlock_unlock (vam->stat_segment_lockp);
23092       errmsg ("input_rate not found?");
23093       return -99;
23094     }
23095   input_rate = *(f64 *) (p[0]);
23096
23097   clib_spinlock_unlock (vam->stat_segment_lockp);
23098
23099   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23100          vector_rate, input_rate);
23101   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23102          thread0_index1_packets, thread0_index1_bytes);
23103
23104   return 0;
23105 }
23106
23107 static int
23108 cmd_cmp (void *a1, void *a2)
23109 {
23110   u8 **c1 = a1;
23111   u8 **c2 = a2;
23112
23113   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23114 }
23115
23116 static int
23117 help (vat_main_t * vam)
23118 {
23119   u8 **cmds = 0;
23120   u8 *name = 0;
23121   hash_pair_t *p;
23122   unformat_input_t *i = vam->input;
23123   int j;
23124
23125   if (unformat (i, "%s", &name))
23126     {
23127       uword *hs;
23128
23129       vec_add1 (name, 0);
23130
23131       hs = hash_get_mem (vam->help_by_name, name);
23132       if (hs)
23133         print (vam->ofp, "usage: %s %s", name, hs[0]);
23134       else
23135         print (vam->ofp, "No such msg / command '%s'", name);
23136       vec_free (name);
23137       return 0;
23138     }
23139
23140   print (vam->ofp, "Help is available for the following:");
23141
23142     /* *INDENT-OFF* */
23143     hash_foreach_pair (p, vam->function_by_name,
23144     ({
23145       vec_add1 (cmds, (u8 *)(p->key));
23146     }));
23147     /* *INDENT-ON* */
23148
23149   vec_sort_with_function (cmds, cmd_cmp);
23150
23151   for (j = 0; j < vec_len (cmds); j++)
23152     print (vam->ofp, "%s", cmds[j]);
23153
23154   vec_free (cmds);
23155   return 0;
23156 }
23157
23158 static int
23159 set (vat_main_t * vam)
23160 {
23161   u8 *name = 0, *value = 0;
23162   unformat_input_t *i = vam->input;
23163
23164   if (unformat (i, "%s", &name))
23165     {
23166       /* The input buffer is a vector, not a string. */
23167       value = vec_dup (i->buffer);
23168       vec_delete (value, i->index, 0);
23169       /* Almost certainly has a trailing newline */
23170       if (value[vec_len (value) - 1] == '\n')
23171         value[vec_len (value) - 1] = 0;
23172       /* Make sure it's a proper string, one way or the other */
23173       vec_add1 (value, 0);
23174       (void) clib_macro_set_value (&vam->macro_main,
23175                                    (char *) name, (char *) value);
23176     }
23177   else
23178     errmsg ("usage: set <name> <value>");
23179
23180   vec_free (name);
23181   vec_free (value);
23182   return 0;
23183 }
23184
23185 static int
23186 unset (vat_main_t * vam)
23187 {
23188   u8 *name = 0;
23189
23190   if (unformat (vam->input, "%s", &name))
23191     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23192       errmsg ("unset: %s wasn't set", name);
23193   vec_free (name);
23194   return 0;
23195 }
23196
23197 typedef struct
23198 {
23199   u8 *name;
23200   u8 *value;
23201 } macro_sort_t;
23202
23203
23204 static int
23205 macro_sort_cmp (void *a1, void *a2)
23206 {
23207   macro_sort_t *s1 = a1;
23208   macro_sort_t *s2 = a2;
23209
23210   return strcmp ((char *) (s1->name), (char *) (s2->name));
23211 }
23212
23213 static int
23214 dump_macro_table (vat_main_t * vam)
23215 {
23216   macro_sort_t *sort_me = 0, *sm;
23217   int i;
23218   hash_pair_t *p;
23219
23220     /* *INDENT-OFF* */
23221     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23222     ({
23223       vec_add2 (sort_me, sm, 1);
23224       sm->name = (u8 *)(p->key);
23225       sm->value = (u8 *) (p->value[0]);
23226     }));
23227     /* *INDENT-ON* */
23228
23229   vec_sort_with_function (sort_me, macro_sort_cmp);
23230
23231   if (vec_len (sort_me))
23232     print (vam->ofp, "%-15s%s", "Name", "Value");
23233   else
23234     print (vam->ofp, "The macro table is empty...");
23235
23236   for (i = 0; i < vec_len (sort_me); i++)
23237     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23238   return 0;
23239 }
23240
23241 static int
23242 dump_node_table (vat_main_t * vam)
23243 {
23244   int i, j;
23245   vlib_node_t *node, *next_node;
23246
23247   if (vec_len (vam->graph_nodes) == 0)
23248     {
23249       print (vam->ofp, "Node table empty, issue get_node_graph...");
23250       return 0;
23251     }
23252
23253   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23254     {
23255       node = vam->graph_nodes[0][i];
23256       print (vam->ofp, "[%d] %s", i, node->name);
23257       for (j = 0; j < vec_len (node->next_nodes); j++)
23258         {
23259           if (node->next_nodes[j] != ~0)
23260             {
23261               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23262               print (vam->ofp, "  [%d] %s", j, next_node->name);
23263             }
23264         }
23265     }
23266   return 0;
23267 }
23268
23269 static int
23270 value_sort_cmp (void *a1, void *a2)
23271 {
23272   name_sort_t *n1 = a1;
23273   name_sort_t *n2 = a2;
23274
23275   if (n1->value < n2->value)
23276     return -1;
23277   if (n1->value > n2->value)
23278     return 1;
23279   return 0;
23280 }
23281
23282
23283 static int
23284 dump_msg_api_table (vat_main_t * vam)
23285 {
23286   api_main_t *am = &api_main;
23287   name_sort_t *nses = 0, *ns;
23288   hash_pair_t *hp;
23289   int i;
23290
23291   /* *INDENT-OFF* */
23292   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23293   ({
23294     vec_add2 (nses, ns, 1);
23295     ns->name = (u8 *)(hp->key);
23296     ns->value = (u32) hp->value[0];
23297   }));
23298   /* *INDENT-ON* */
23299
23300   vec_sort_with_function (nses, value_sort_cmp);
23301
23302   for (i = 0; i < vec_len (nses); i++)
23303     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23304   vec_free (nses);
23305   return 0;
23306 }
23307
23308 static int
23309 get_msg_id (vat_main_t * vam)
23310 {
23311   u8 *name_and_crc;
23312   u32 message_index;
23313
23314   if (unformat (vam->input, "%s", &name_and_crc))
23315     {
23316       message_index = vl_msg_api_get_msg_index (name_and_crc);
23317       if (message_index == ~0)
23318         {
23319           print (vam->ofp, " '%s' not found", name_and_crc);
23320           return 0;
23321         }
23322       print (vam->ofp, " '%s' has message index %d",
23323              name_and_crc, message_index);
23324       return 0;
23325     }
23326   errmsg ("name_and_crc required...");
23327   return 0;
23328 }
23329
23330 static int
23331 search_node_table (vat_main_t * vam)
23332 {
23333   unformat_input_t *line_input = vam->input;
23334   u8 *node_to_find;
23335   int j;
23336   vlib_node_t *node, *next_node;
23337   uword *p;
23338
23339   if (vam->graph_node_index_by_name == 0)
23340     {
23341       print (vam->ofp, "Node table empty, issue get_node_graph...");
23342       return 0;
23343     }
23344
23345   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23346     {
23347       if (unformat (line_input, "%s", &node_to_find))
23348         {
23349           vec_add1 (node_to_find, 0);
23350           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23351           if (p == 0)
23352             {
23353               print (vam->ofp, "%s not found...", node_to_find);
23354               goto out;
23355             }
23356           node = vam->graph_nodes[0][p[0]];
23357           print (vam->ofp, "[%d] %s", p[0], node->name);
23358           for (j = 0; j < vec_len (node->next_nodes); j++)
23359             {
23360               if (node->next_nodes[j] != ~0)
23361                 {
23362                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23363                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23364                 }
23365             }
23366         }
23367
23368       else
23369         {
23370           clib_warning ("parse error '%U'", format_unformat_error,
23371                         line_input);
23372           return -99;
23373         }
23374
23375     out:
23376       vec_free (node_to_find);
23377
23378     }
23379
23380   return 0;
23381 }
23382
23383
23384 static int
23385 script (vat_main_t * vam)
23386 {
23387 #if (VPP_API_TEST_BUILTIN==0)
23388   u8 *s = 0;
23389   char *save_current_file;
23390   unformat_input_t save_input;
23391   jmp_buf save_jump_buf;
23392   u32 save_line_number;
23393
23394   FILE *new_fp, *save_ifp;
23395
23396   if (unformat (vam->input, "%s", &s))
23397     {
23398       new_fp = fopen ((char *) s, "r");
23399       if (new_fp == 0)
23400         {
23401           errmsg ("Couldn't open script file %s", s);
23402           vec_free (s);
23403           return -99;
23404         }
23405     }
23406   else
23407     {
23408       errmsg ("Missing script name");
23409       return -99;
23410     }
23411
23412   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23413   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23414   save_ifp = vam->ifp;
23415   save_line_number = vam->input_line_number;
23416   save_current_file = (char *) vam->current_file;
23417
23418   vam->input_line_number = 0;
23419   vam->ifp = new_fp;
23420   vam->current_file = s;
23421   do_one_file (vam);
23422
23423   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23424   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23425   vam->ifp = save_ifp;
23426   vam->input_line_number = save_line_number;
23427   vam->current_file = (u8 *) save_current_file;
23428   vec_free (s);
23429
23430   return 0;
23431 #else
23432   clib_warning ("use the exec command...");
23433   return -99;
23434 #endif
23435 }
23436
23437 static int
23438 echo (vat_main_t * vam)
23439 {
23440   print (vam->ofp, "%v", vam->input->buffer);
23441   return 0;
23442 }
23443
23444 /* List of API message constructors, CLI names map to api_xxx */
23445 #define foreach_vpe_api_msg                                             \
23446 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23447 _(sw_interface_dump,"")                                                 \
23448 _(sw_interface_set_flags,                                               \
23449   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23450 _(sw_interface_add_del_address,                                         \
23451   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23452 _(sw_interface_set_rx_mode,                                             \
23453   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23454 _(sw_interface_set_rx_placement,                                        \
23455   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23456 _(sw_interface_set_table,                                               \
23457   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23458 _(sw_interface_set_mpls_enable,                                         \
23459   "<intfc> | sw_if_index [disable | dis]")                              \
23460 _(sw_interface_set_vpath,                                               \
23461   "<intfc> | sw_if_index <id> enable | disable")                        \
23462 _(sw_interface_set_vxlan_bypass,                                        \
23463   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23464 _(sw_interface_set_geneve_bypass,                                       \
23465   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23466 _(sw_interface_set_l2_xconnect,                                         \
23467   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23468   "enable | disable")                                                   \
23469 _(sw_interface_set_l2_bridge,                                           \
23470   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23471   "[shg <split-horizon-group>] [bvi]\n"                                 \
23472   "enable | disable")                                                   \
23473 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23474 _(bridge_domain_add_del,                                                \
23475   "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") \
23476 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23477 _(l2fib_add_del,                                                        \
23478   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23479 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23480 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23481 _(l2_flags,                                                             \
23482   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23483 _(bridge_flags,                                                         \
23484   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23485 _(tap_connect,                                                          \
23486   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23487 _(tap_modify,                                                           \
23488   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23489 _(tap_delete,                                                           \
23490   "<vpp-if-name> | sw_if_index <id>")                                   \
23491 _(sw_interface_tap_dump, "")                                            \
23492 _(tap_create_v2,                                                        \
23493   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23494 _(tap_delete_v2,                                                        \
23495   "<vpp-if-name> | sw_if_index <id>")                                   \
23496 _(sw_interface_tap_v2_dump, "")                                         \
23497 _(bond_create,                                                          \
23498   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23499   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23500 _(bond_delete,                                                          \
23501   "<vpp-if-name> | sw_if_index <id>")                                   \
23502 _(bond_enslave,                                                         \
23503   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23504 _(bond_detach_slave,                                                    \
23505   "sw_if_index <n>")                                                    \
23506 _(sw_interface_bond_dump, "")                                           \
23507 _(sw_interface_slave_dump,                                              \
23508   "<vpp-if-name> | sw_if_index <id>")                                   \
23509 _(ip_table_add_del,                                                     \
23510   "table <n> [ipv6] [add | del]\n")                                     \
23511 _(ip_add_del_route,                                                     \
23512   "<addr>/<mask> via <addr | via-label <n>> [table-id <n>]\n"           \
23513   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23514   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23515   "[multipath] [count <n>]")                                            \
23516 _(ip_mroute_add_del,                                                    \
23517   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23518   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23519 _(mpls_table_add_del,                                                   \
23520   "table <n> [add | del]\n")                                            \
23521 _(mpls_route_add_del,                                                   \
23522   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23523   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23524   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23525   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23526   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23527 _(mpls_ip_bind_unbind,                                                  \
23528   "<label> <addr/len>")                                                 \
23529 _(mpls_tunnel_add_del,                                                  \
23530   " via <addr> [table-id <n>]\n"                                        \
23531   "sw_if_index <id>] [l2]  [del]")                                      \
23532 _(sr_mpls_policy_add,                                                   \
23533   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23534 _(sr_mpls_policy_del,                                                   \
23535   "bsid <id>")                                                          \
23536 _(bier_table_add_del,                                                   \
23537   "<label> <sub-domain> <set> <bsl> [del]")                             \
23538 _(bier_route_add_del,                                                   \
23539   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23540   "[<intfc> | sw_if_index <id>]"                                        \
23541   "[weight <n>] [del] [multipath]")                                     \
23542 _(proxy_arp_add_del,                                                    \
23543   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23544 _(proxy_arp_intfc_enable_disable,                                       \
23545   "<intfc> | sw_if_index <id> enable | disable")                        \
23546 _(sw_interface_set_unnumbered,                                          \
23547   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23548 _(ip_neighbor_add_del,                                                  \
23549   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23550   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23551 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23552 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23553   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23554   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23555   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23556 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23557 _(reset_fib, "vrf <n> [ipv6]")                                          \
23558 _(dhcp_proxy_config,                                                    \
23559   "svr <v46-address> src <v46-address>\n"                               \
23560    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23561 _(dhcp_proxy_set_vss,                                                   \
23562   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23563 _(dhcp_proxy_dump, "ip6")                                               \
23564 _(dhcp_client_config,                                                   \
23565   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23566 _(set_ip_flow_hash,                                                     \
23567   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23568 _(sw_interface_ip6_enable_disable,                                      \
23569   "<intfc> | sw_if_index <id> enable | disable")                        \
23570 _(sw_interface_ip6_set_link_local_address,                              \
23571   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23572 _(ip6nd_proxy_add_del,                                                  \
23573   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23574 _(ip6nd_proxy_dump, "")                                                 \
23575 _(sw_interface_ip6nd_ra_prefix,                                         \
23576   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23577   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23578   "[nolink] [isno]")                                                    \
23579 _(sw_interface_ip6nd_ra_config,                                         \
23580   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23581   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23582   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23583 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23584 _(l2_patch_add_del,                                                     \
23585   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23586   "enable | disable")                                                   \
23587 _(sr_localsid_add_del,                                                  \
23588   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23589   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23590 _(classify_add_del_table,                                               \
23591   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23592   " [del] [del-chain] mask <mask-value>\n"                              \
23593   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23594   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23595 _(classify_add_del_session,                                             \
23596   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23597   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23598   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23599   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23600 _(classify_set_interface_ip_table,                                      \
23601   "<intfc> | sw_if_index <nn> table <nn>")                              \
23602 _(classify_set_interface_l2_tables,                                     \
23603   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23604   "  [other-table <nn>]")                                               \
23605 _(get_node_index, "node <node-name")                                    \
23606 _(add_node_next, "node <node-name> next <next-node-name>")              \
23607 _(l2tpv3_create_tunnel,                                                 \
23608   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23609   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23610   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23611 _(l2tpv3_set_tunnel_cookies,                                            \
23612   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23613   "[new_remote_cookie <nn>]\n")                                         \
23614 _(l2tpv3_interface_enable_disable,                                      \
23615   "<intfc> | sw_if_index <nn> enable | disable")                        \
23616 _(l2tpv3_set_lookup_key,                                                \
23617   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23618 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23619 _(vxlan_offload_rx,                                                     \
23620   "hw { <interface name> | hw_if_index <nn>} "                          \
23621   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23622 _(vxlan_add_del_tunnel,                                                 \
23623   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23624   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23625   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23626 _(geneve_add_del_tunnel,                                                \
23627   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23628   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23629   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23630 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23631 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23632 _(gre_add_del_tunnel,                                                   \
23633   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23634   "[teb | erspan <session-id>] [del]")                                  \
23635 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23636 _(l2_fib_clear_table, "")                                               \
23637 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23638 _(l2_interface_vlan_tag_rewrite,                                        \
23639   "<intfc> | sw_if_index <nn> \n"                                       \
23640   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23641   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23642 _(create_vhost_user_if,                                                 \
23643         "socket <filename> [server] [renumber <dev_instance>] "         \
23644         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23645         "[mac <mac_address>]")                                          \
23646 _(modify_vhost_user_if,                                                 \
23647         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23648         "[server] [renumber <dev_instance>]")                           \
23649 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23650 _(sw_interface_vhost_user_dump, "")                                     \
23651 _(show_version, "")                                                     \
23652 _(vxlan_gpe_add_del_tunnel,                                             \
23653   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23654   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23655   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23656   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23657 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23658 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23659 _(interface_name_renumber,                                              \
23660   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23661 _(input_acl_set_interface,                                              \
23662   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23663   "  [l2-table <nn>] [del]")                                            \
23664 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23665 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23666   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23667 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23668 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23669 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23670 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23671 _(ip_dump, "ipv4 | ipv6")                                               \
23672 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23673 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23674   "  spid_id <n> ")                                                     \
23675 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23676   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23677   "  integ_alg <alg> integ_key <hex>")                                  \
23678 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23679   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23680   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23681   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23682 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23683 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23684   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23685   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23686   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23687   "  [instance <n>]")     \
23688 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23689 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23690   "  <alg> <hex>\n")                                                    \
23691 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23692 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23693 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23694   "(auth_data 0x<data> | auth_data <data>)")                            \
23695 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23696   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23697 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23698   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23699   "(local|remote)")                                                     \
23700 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23701 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23702 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23703 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23704 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23705 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23706 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23707 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23708 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23709 _(delete_loopback,"sw_if_index <nn>")                                   \
23710 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23711 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23712 _(want_interface_events,  "enable|disable")                             \
23713 _(want_stats,"enable|disable")                                          \
23714 _(get_first_msg_id, "client <name>")                                    \
23715 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23716 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23717   "fib-id <nn> [ip4][ip6][default]")                                    \
23718 _(get_node_graph, " ")                                                  \
23719 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23720 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23721 _(ioam_disable, "")                                                     \
23722 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23723                             " sw_if_index <sw_if_index> p <priority> "  \
23724                             "w <weight>] [del]")                        \
23725 _(one_add_del_locator, "locator-set <locator_name> "                    \
23726                         "iface <intf> | sw_if_index <sw_if_index> "     \
23727                         "p <priority> w <weight> [del]")                \
23728 _(one_add_del_local_eid,"vni <vni> eid "                                \
23729                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23730                          "locator-set <locator_name> [del]"             \
23731                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23732 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23733 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23734 _(one_enable_disable, "enable|disable")                                 \
23735 _(one_map_register_enable_disable, "enable|disable")                    \
23736 _(one_map_register_fallback_threshold, "<value>")                       \
23737 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23738 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23739                                "[seid <seid>] "                         \
23740                                "rloc <locator> p <prio> "               \
23741                                "w <weight> [rloc <loc> ... ] "          \
23742                                "action <action> [del-all]")             \
23743 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23744                           "<local-eid>")                                \
23745 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23746 _(one_use_petr, "ip-address> | disable")                                \
23747 _(one_map_request_mode, "src-dst|dst-only")                             \
23748 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23749 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23750 _(one_locator_set_dump, "[local | remote]")                             \
23751 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23752 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23753                        "[local] | [remote]")                            \
23754 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23755 _(one_ndp_bd_get, "")                                                   \
23756 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23757 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23758 _(one_l2_arp_bd_get, "")                                                \
23759 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23760 _(one_stats_enable_disable, "enable|disalbe")                           \
23761 _(show_one_stats_enable_disable, "")                                    \
23762 _(one_eid_table_vni_dump, "")                                           \
23763 _(one_eid_table_map_dump, "l2|l3")                                      \
23764 _(one_map_resolver_dump, "")                                            \
23765 _(one_map_server_dump, "")                                              \
23766 _(one_adjacencies_get, "vni <vni>")                                     \
23767 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23768 _(show_one_rloc_probe_state, "")                                        \
23769 _(show_one_map_register_state, "")                                      \
23770 _(show_one_status, "")                                                  \
23771 _(one_stats_dump, "")                                                   \
23772 _(one_stats_flush, "")                                                  \
23773 _(one_get_map_request_itr_rlocs, "")                                    \
23774 _(one_map_register_set_ttl, "<ttl>")                                    \
23775 _(one_set_transport_protocol, "udp|api")                                \
23776 _(one_get_transport_protocol, "")                                       \
23777 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23778 _(one_show_xtr_mode, "")                                                \
23779 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23780 _(one_show_pitr_mode, "")                                               \
23781 _(one_enable_disable_petr_mode, "enable|disable")                       \
23782 _(one_show_petr_mode, "")                                               \
23783 _(show_one_nsh_mapping, "")                                             \
23784 _(show_one_pitr, "")                                                    \
23785 _(show_one_use_petr, "")                                                \
23786 _(show_one_map_request_mode, "")                                        \
23787 _(show_one_map_register_ttl, "")                                        \
23788 _(show_one_map_register_fallback_threshold, "")                         \
23789 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23790                             " sw_if_index <sw_if_index> p <priority> "  \
23791                             "w <weight>] [del]")                        \
23792 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23793                         "iface <intf> | sw_if_index <sw_if_index> "     \
23794                         "p <priority> w <weight> [del]")                \
23795 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23796                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23797                          "locator-set <locator_name> [del]"             \
23798                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23799 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23800 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23801 _(lisp_enable_disable, "enable|disable")                                \
23802 _(lisp_map_register_enable_disable, "enable|disable")                   \
23803 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23804 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23805                                "[seid <seid>] "                         \
23806                                "rloc <locator> p <prio> "               \
23807                                "w <weight> [rloc <loc> ... ] "          \
23808                                "action <action> [del-all]")             \
23809 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23810                           "<local-eid>")                                \
23811 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23812 _(lisp_use_petr, "<ip-address> | disable")                              \
23813 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23814 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23815 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23816 _(lisp_locator_set_dump, "[local | remote]")                            \
23817 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23818 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23819                        "[local] | [remote]")                            \
23820 _(lisp_eid_table_vni_dump, "")                                          \
23821 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23822 _(lisp_map_resolver_dump, "")                                           \
23823 _(lisp_map_server_dump, "")                                             \
23824 _(lisp_adjacencies_get, "vni <vni>")                                    \
23825 _(gpe_fwd_entry_vnis_get, "")                                           \
23826 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23827 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23828                                 "[table <table-id>]")                   \
23829 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23830 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23831 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23832 _(gpe_get_encap_mode, "")                                               \
23833 _(lisp_gpe_add_del_iface, "up|down")                                    \
23834 _(lisp_gpe_enable_disable, "enable|disable")                            \
23835 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23836   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23837 _(show_lisp_rloc_probe_state, "")                                       \
23838 _(show_lisp_map_register_state, "")                                     \
23839 _(show_lisp_status, "")                                                 \
23840 _(lisp_get_map_request_itr_rlocs, "")                                   \
23841 _(show_lisp_pitr, "")                                                   \
23842 _(show_lisp_use_petr, "")                                               \
23843 _(show_lisp_map_request_mode, "")                                       \
23844 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23845 _(af_packet_delete, "name <host interface name>")                       \
23846 _(af_packet_dump, "")                                                   \
23847 _(policer_add_del, "name <policer name> <params> [del]")                \
23848 _(policer_dump, "[name <policer name>]")                                \
23849 _(policer_classify_set_interface,                                       \
23850   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23851   "  [l2-table <nn>] [del]")                                            \
23852 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23853 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23854     "[master|slave]")                                                   \
23855 _(netmap_delete, "name <interface name>")                               \
23856 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23857 _(mpls_fib_dump, "")                                                    \
23858 _(classify_table_ids, "")                                               \
23859 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23860 _(classify_table_info, "table_id <nn>")                                 \
23861 _(classify_session_dump, "table_id <nn>")                               \
23862 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23863     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23864     "[template_interval <nn>] [udp_checksum]")                          \
23865 _(ipfix_exporter_dump, "")                                              \
23866 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23867 _(ipfix_classify_stream_dump, "")                                       \
23868 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23869 _(ipfix_classify_table_dump, "")                                        \
23870 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23871 _(sw_interface_span_dump, "[l2]")                                           \
23872 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23873 _(pg_create_interface, "if_id <nn>")                                    \
23874 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23875 _(pg_enable_disable, "[stream <id>] disable")                           \
23876 _(ip_source_and_port_range_check_add_del,                               \
23877   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23878 _(ip_source_and_port_range_check_interface_add_del,                     \
23879   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23880   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23881 _(ipsec_gre_add_del_tunnel,                                             \
23882   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23883 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23884 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23885 _(l2_interface_pbb_tag_rewrite,                                         \
23886   "<intfc> | sw_if_index <nn> \n"                                       \
23887   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23888   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23889 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23890 _(flow_classify_set_interface,                                          \
23891   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23892 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23893 _(ip_fib_dump, "")                                                      \
23894 _(ip_mfib_dump, "")                                                     \
23895 _(ip6_fib_dump, "")                                                     \
23896 _(ip6_mfib_dump, "")                                                    \
23897 _(feature_enable_disable, "arc_name <arc_name> "                        \
23898   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23899 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23900 "[disable]")                                                            \
23901 _(l2_xconnect_dump, "")                                                 \
23902 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23903 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23904 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23905 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23906 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23907 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23908 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23909   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23910 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23911 _(sock_init_shm, "size <nnn>")                                          \
23912 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23913 _(dns_enable_disable, "[enable][disable]")                              \
23914 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23915 _(dns_resolve_name, "<hostname>")                                       \
23916 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23917 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23918 _(dns_resolve_name, "<hostname>")                                       \
23919 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23920   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23921 _(session_rules_dump, "")                                               \
23922 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23923 _(output_acl_set_interface,                                             \
23924   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23925   "  [l2-table <nn>] [del]")                                            \
23926 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23927
23928 /* List of command functions, CLI names map directly to functions */
23929 #define foreach_cli_function                                    \
23930 _(comment, "usage: comment <ignore-rest-of-line>")              \
23931 _(dump_interface_table, "usage: dump_interface_table")          \
23932 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23933 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23934 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23935 _(dump_stats_table, "usage: dump_stats_table")                  \
23936 _(dump_macro_table, "usage: dump_macro_table ")                 \
23937 _(dump_node_table, "usage: dump_node_table")                    \
23938 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23939 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23940 _(echo, "usage: echo <message>")                                \
23941 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23942 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23943 _(help, "usage: help")                                          \
23944 _(q, "usage: quit")                                             \
23945 _(quit, "usage: quit")                                          \
23946 _(search_node_table, "usage: search_node_table <name>...")      \
23947 _(set, "usage: set <variable-name> <value>")                    \
23948 _(script, "usage: script <file-name>")                          \
23949 _(statseg, "usage: statseg");                                   \
23950 _(unset, "usage: unset <variable-name>")
23951
23952 #define _(N,n)                                  \
23953     static void vl_api_##n##_t_handler_uni      \
23954     (vl_api_##n##_t * mp)                       \
23955     {                                           \
23956         vat_main_t * vam = &vat_main;           \
23957         if (vam->json_output) {                 \
23958             vl_api_##n##_t_handler_json(mp);    \
23959         } else {                                \
23960             vl_api_##n##_t_handler(mp);         \
23961         }                                       \
23962     }
23963 foreach_vpe_api_reply_msg;
23964 #if VPP_API_TEST_BUILTIN == 0
23965 foreach_standalone_reply_msg;
23966 #endif
23967 #undef _
23968
23969 void
23970 vat_api_hookup (vat_main_t * vam)
23971 {
23972 #define _(N,n)                                                  \
23973     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23974                            vl_api_##n##_t_handler_uni,          \
23975                            vl_noop_handler,                     \
23976                            vl_api_##n##_t_endian,               \
23977                            vl_api_##n##_t_print,                \
23978                            sizeof(vl_api_##n##_t), 1);
23979   foreach_vpe_api_reply_msg;
23980 #if VPP_API_TEST_BUILTIN == 0
23981   foreach_standalone_reply_msg;
23982 #endif
23983 #undef _
23984
23985 #if (VPP_API_TEST_BUILTIN==0)
23986   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23987
23988   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23989
23990   vam->function_by_name = hash_create_string (0, sizeof (uword));
23991
23992   vam->help_by_name = hash_create_string (0, sizeof (uword));
23993 #endif
23994
23995   /* API messages we can send */
23996 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23997   foreach_vpe_api_msg;
23998 #undef _
23999
24000   /* Help strings */
24001 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24002   foreach_vpe_api_msg;
24003 #undef _
24004
24005   /* CLI functions */
24006 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24007   foreach_cli_function;
24008 #undef _
24009
24010   /* Help strings */
24011 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24012   foreach_cli_function;
24013 #undef _
24014 }
24015
24016 #if VPP_API_TEST_BUILTIN
24017 static clib_error_t *
24018 vat_api_hookup_shim (vlib_main_t * vm)
24019 {
24020   vat_api_hookup (&vat_main);
24021   return 0;
24022 }
24023
24024 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24025 #endif
24026
24027 /*
24028  * fd.io coding-style-patch-verification: ON
24029  *
24030  * Local Variables:
24031  * eval: (c-set-style "gnu")
24032  * End:
24033  */