Add more CLI options to vpp_api_test for calling ip_add_del_route
[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   memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8490   memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8491   /* Parse args required to build the message */
8492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8493     {
8494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8495         ;
8496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8497         ;
8498       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8499         {
8500           address_set = 1;
8501           is_ipv6 = 0;
8502         }
8503       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8504         {
8505           address_set = 1;
8506           is_ipv6 = 1;
8507         }
8508       else if (unformat (i, "/%d", &dst_address_length))
8509         {
8510           address_length_set = 1;
8511         }
8512
8513       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8514                                          &v4_next_hop_address))
8515         {
8516           next_hop_set = 1;
8517         }
8518       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8519                                          &v6_next_hop_address))
8520         {
8521           next_hop_set = 1;
8522         }
8523       else
8524         if (unformat
8525             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8526         {
8527           next_hop_set = 1;
8528         }
8529       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8530         {
8531           next_hop_set = 1;
8532         }
8533       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8534         ;
8535       else if (unformat (i, "weight %d", &next_hop_weight))
8536         ;
8537       else if (unformat (i, "drop"))
8538         {
8539           is_drop = 1;
8540         }
8541       else if (unformat (i, "null-send-unreach"))
8542         {
8543           is_unreach = 1;
8544         }
8545       else if (unformat (i, "null-send-prohibit"))
8546         {
8547           is_prohibit = 1;
8548         }
8549       else if (unformat (i, "local"))
8550         {
8551           is_local = 1;
8552         }
8553       else if (unformat (i, "classify %d", &classify_table_index))
8554         {
8555           is_classify = 1;
8556         }
8557       else if (unformat (i, "del"))
8558         is_add = 0;
8559       else if (unformat (i, "add"))
8560         is_add = 1;
8561       else if (unformat (i, "resolve-via-host"))
8562         resolve_host = 1;
8563       else if (unformat (i, "resolve-via-attached"))
8564         resolve_attached = 1;
8565       else if (unformat (i, "multipath"))
8566         is_multipath = 1;
8567       else if (unformat (i, "vrf %d", &vrf_id))
8568         ;
8569       else if (unformat (i, "count %d", &count))
8570         ;
8571       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8572         ;
8573       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8574         ;
8575       else if (unformat (i, "out-label %d", &next_hop_out_label))
8576         {
8577           vl_api_fib_mpls_label_t fib_label = {
8578             .label = ntohl (next_hop_out_label),
8579             .ttl = 64,
8580             .exp = 0,
8581           };
8582           vec_add1 (next_hop_out_label_stack, fib_label);
8583         }
8584       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8585         ;
8586       else if (unformat (i, "random"))
8587         random_add_del = 1;
8588       else if (unformat (i, "seed %d", &random_seed))
8589         ;
8590       else
8591         {
8592           clib_warning ("parse error '%U'", format_unformat_error, i);
8593           return -99;
8594         }
8595     }
8596
8597   if (!next_hop_set && !is_drop && !is_local &&
8598       !is_classify && !is_unreach && !is_prohibit &&
8599       MPLS_LABEL_INVALID == next_hop_via_label)
8600     {
8601       errmsg
8602         ("next hop / local / drop / unreach / prohibit / classify not set");
8603       return -99;
8604     }
8605
8606   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8607     {
8608       errmsg ("next hop and next-hop via label set");
8609       return -99;
8610     }
8611   if (address_set == 0)
8612     {
8613       errmsg ("missing addresses");
8614       return -99;
8615     }
8616
8617   if (address_length_set == 0)
8618     {
8619       errmsg ("missing address length");
8620       return -99;
8621     }
8622
8623   /* Generate a pile of unique, random routes */
8624   if (random_add_del)
8625     {
8626       u32 this_random_address;
8627       random_hash = hash_create (count, sizeof (uword));
8628
8629       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8630       for (j = 0; j <= count; j++)
8631         {
8632           do
8633             {
8634               this_random_address = random_u32 (&random_seed);
8635               this_random_address =
8636                 clib_host_to_net_u32 (this_random_address);
8637             }
8638           while (hash_get (random_hash, this_random_address));
8639           vec_add1 (random_vector, this_random_address);
8640           hash_set (random_hash, this_random_address, 1);
8641         }
8642       hash_free (random_hash);
8643       v4_dst_address.as_u32 = random_vector[0];
8644     }
8645
8646   if (count > 1)
8647     {
8648       /* Turn on async mode */
8649       vam->async_mode = 1;
8650       vam->async_errors = 0;
8651       before = vat_time_now (vam);
8652     }
8653
8654   for (j = 0; j < count; j++)
8655     {
8656       /* Construct the API message */
8657       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8658           vec_len (next_hop_out_label_stack));
8659
8660       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8661       mp->table_id = ntohl (vrf_id);
8662
8663       mp->is_add = is_add;
8664       mp->is_drop = is_drop;
8665       mp->is_unreach = is_unreach;
8666       mp->is_prohibit = is_prohibit;
8667       mp->is_ipv6 = is_ipv6;
8668       mp->is_local = is_local;
8669       mp->is_classify = is_classify;
8670       mp->is_multipath = is_multipath;
8671       mp->is_resolve_host = resolve_host;
8672       mp->is_resolve_attached = resolve_attached;
8673       mp->next_hop_weight = next_hop_weight;
8674       mp->dst_address_length = dst_address_length;
8675       mp->next_hop_table_id = ntohl (next_hop_table_id);
8676       mp->classify_table_index = ntohl (classify_table_index);
8677       mp->next_hop_via_label = ntohl (next_hop_via_label);
8678       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8679       if (0 != mp->next_hop_n_out_labels)
8680         {
8681           memcpy (mp->next_hop_out_label_stack,
8682                   next_hop_out_label_stack,
8683                   (vec_len (next_hop_out_label_stack) *
8684                    sizeof (vl_api_fib_mpls_label_t)));
8685           vec_free (next_hop_out_label_stack);
8686         }
8687
8688       if (is_ipv6)
8689         {
8690           clib_memcpy (mp->dst_address, &v6_dst_address,
8691                        sizeof (v6_dst_address));
8692           if (next_hop_set)
8693             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8694                          sizeof (v6_next_hop_address));
8695           increment_v6_address (&v6_dst_address);
8696         }
8697       else
8698         {
8699           clib_memcpy (mp->dst_address, &v4_dst_address,
8700                        sizeof (v4_dst_address));
8701           if (next_hop_set)
8702             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8703                          sizeof (v4_next_hop_address));
8704           if (random_add_del)
8705             v4_dst_address.as_u32 = random_vector[j + 1];
8706           else
8707             increment_v4_address (&v4_dst_address);
8708         }
8709       /* send it... */
8710       S (mp);
8711       /* If we receive SIGTERM, stop now... */
8712       if (vam->do_exit)
8713         break;
8714     }
8715
8716   /* When testing multiple add/del ops, use a control-ping to sync */
8717   if (count > 1)
8718     {
8719       vl_api_control_ping_t *mp_ping;
8720       f64 after;
8721       f64 timeout;
8722
8723       /* Shut off async mode */
8724       vam->async_mode = 0;
8725
8726       MPING (CONTROL_PING, mp_ping);
8727       S (mp_ping);
8728
8729       timeout = vat_time_now (vam) + 1.0;
8730       while (vat_time_now (vam) < timeout)
8731         if (vam->result_ready == 1)
8732           goto out;
8733       vam->retval = -99;
8734
8735     out:
8736       if (vam->retval == -99)
8737         errmsg ("timeout");
8738
8739       if (vam->async_errors > 0)
8740         {
8741           errmsg ("%d asynchronous errors", vam->async_errors);
8742           vam->retval = -98;
8743         }
8744       vam->async_errors = 0;
8745       after = vat_time_now (vam);
8746
8747       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8748       if (j > 0)
8749         count = j;
8750
8751       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8752              count, after - before, count / (after - before));
8753     }
8754   else
8755     {
8756       int ret;
8757
8758       /* Wait for a reply... */
8759       W (ret);
8760       return ret;
8761     }
8762
8763   /* Return the good/bad news */
8764   return (vam->retval);
8765 }
8766
8767 static int
8768 api_ip_mroute_add_del (vat_main_t * vam)
8769 {
8770   unformat_input_t *i = vam->input;
8771   vl_api_ip_mroute_add_del_t *mp;
8772   u32 sw_if_index = ~0, vrf_id = 0;
8773   u8 is_ipv6 = 0;
8774   u8 is_local = 0;
8775   u8 is_add = 1;
8776   u8 address_set = 0;
8777   u32 grp_address_length = 0;
8778   ip4_address_t v4_grp_address, v4_src_address;
8779   ip6_address_t v6_grp_address, v6_src_address;
8780   mfib_itf_flags_t iflags = 0;
8781   mfib_entry_flags_t eflags = 0;
8782   int ret;
8783
8784   /* Parse args required to build the message */
8785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8786     {
8787       if (unformat (i, "sw_if_index %d", &sw_if_index))
8788         ;
8789       else if (unformat (i, "%U %U",
8790                          unformat_ip4_address, &v4_src_address,
8791                          unformat_ip4_address, &v4_grp_address))
8792         {
8793           grp_address_length = 64;
8794           address_set = 1;
8795           is_ipv6 = 0;
8796         }
8797       else if (unformat (i, "%U %U",
8798                          unformat_ip6_address, &v6_src_address,
8799                          unformat_ip6_address, &v6_grp_address))
8800         {
8801           grp_address_length = 256;
8802           address_set = 1;
8803           is_ipv6 = 1;
8804         }
8805       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8806         {
8807           memset (&v4_src_address, 0, sizeof (v4_src_address));
8808           grp_address_length = 32;
8809           address_set = 1;
8810           is_ipv6 = 0;
8811         }
8812       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8813         {
8814           memset (&v6_src_address, 0, sizeof (v6_src_address));
8815           grp_address_length = 128;
8816           address_set = 1;
8817           is_ipv6 = 1;
8818         }
8819       else if (unformat (i, "/%d", &grp_address_length))
8820         ;
8821       else if (unformat (i, "local"))
8822         {
8823           is_local = 1;
8824         }
8825       else if (unformat (i, "del"))
8826         is_add = 0;
8827       else if (unformat (i, "add"))
8828         is_add = 1;
8829       else if (unformat (i, "vrf %d", &vrf_id))
8830         ;
8831       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8832         ;
8833       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8834         ;
8835       else
8836         {
8837           clib_warning ("parse error '%U'", format_unformat_error, i);
8838           return -99;
8839         }
8840     }
8841
8842   if (address_set == 0)
8843     {
8844       errmsg ("missing addresses\n");
8845       return -99;
8846     }
8847
8848   /* Construct the API message */
8849   M (IP_MROUTE_ADD_DEL, mp);
8850
8851   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8852   mp->table_id = ntohl (vrf_id);
8853
8854   mp->is_add = is_add;
8855   mp->is_ipv6 = is_ipv6;
8856   mp->is_local = is_local;
8857   mp->itf_flags = ntohl (iflags);
8858   mp->entry_flags = ntohl (eflags);
8859   mp->grp_address_length = grp_address_length;
8860   mp->grp_address_length = ntohs (mp->grp_address_length);
8861
8862   if (is_ipv6)
8863     {
8864       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8865       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8866     }
8867   else
8868     {
8869       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8870       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8871
8872     }
8873
8874   /* send it... */
8875   S (mp);
8876   /* Wait for a reply... */
8877   W (ret);
8878   return ret;
8879 }
8880
8881 static int
8882 api_mpls_table_add_del (vat_main_t * vam)
8883 {
8884   unformat_input_t *i = vam->input;
8885   vl_api_mpls_table_add_del_t *mp;
8886   u32 table_id = ~0;
8887   u8 is_add = 1;
8888   int ret = 0;
8889
8890   /* Parse args required to build the message */
8891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8892     {
8893       if (unformat (i, "table %d", &table_id))
8894         ;
8895       else if (unformat (i, "del"))
8896         is_add = 0;
8897       else if (unformat (i, "add"))
8898         is_add = 1;
8899       else
8900         {
8901           clib_warning ("parse error '%U'", format_unformat_error, i);
8902           return -99;
8903         }
8904     }
8905
8906   if (~0 == table_id)
8907     {
8908       errmsg ("missing table-ID");
8909       return -99;
8910     }
8911
8912   /* Construct the API message */
8913   M (MPLS_TABLE_ADD_DEL, mp);
8914
8915   mp->mt_table_id = ntohl (table_id);
8916   mp->mt_is_add = is_add;
8917
8918   /* send it... */
8919   S (mp);
8920
8921   /* Wait for a reply... */
8922   W (ret);
8923
8924   return ret;
8925 }
8926
8927 static int
8928 api_mpls_route_add_del (vat_main_t * vam)
8929 {
8930   unformat_input_t *i = vam->input;
8931   vl_api_mpls_route_add_del_t *mp;
8932   u32 sw_if_index = ~0, table_id = 0;
8933   u8 is_add = 1;
8934   u32 next_hop_weight = 1;
8935   u8 is_multipath = 0;
8936   u32 next_hop_table_id = 0;
8937   u8 next_hop_set = 0;
8938   ip4_address_t v4_next_hop_address = {
8939     .as_u32 = 0,
8940   };
8941   ip6_address_t v6_next_hop_address = { {0} };
8942   int count = 1;
8943   int j;
8944   f64 before = 0;
8945   u32 classify_table_index = ~0;
8946   u8 is_classify = 0;
8947   u8 resolve_host = 0, resolve_attached = 0;
8948   u8 is_interface_rx = 0;
8949   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8950   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8951   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8952   mpls_label_t local_label = MPLS_LABEL_INVALID;
8953   u8 is_eos = 0;
8954   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8955
8956   /* Parse args required to build the message */
8957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8958     {
8959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8960         ;
8961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8962         ;
8963       else if (unformat (i, "%d", &local_label))
8964         ;
8965       else if (unformat (i, "eos"))
8966         is_eos = 1;
8967       else if (unformat (i, "non-eos"))
8968         is_eos = 0;
8969       else if (unformat (i, "via %U", unformat_ip4_address,
8970                          &v4_next_hop_address))
8971         {
8972           next_hop_set = 1;
8973           next_hop_proto = DPO_PROTO_IP4;
8974         }
8975       else if (unformat (i, "via %U", unformat_ip6_address,
8976                          &v6_next_hop_address))
8977         {
8978           next_hop_set = 1;
8979           next_hop_proto = DPO_PROTO_IP6;
8980         }
8981       else if (unformat (i, "weight %d", &next_hop_weight))
8982         ;
8983       else if (unformat (i, "classify %d", &classify_table_index))
8984         {
8985           is_classify = 1;
8986         }
8987       else if (unformat (i, "del"))
8988         is_add = 0;
8989       else if (unformat (i, "add"))
8990         is_add = 1;
8991       else if (unformat (i, "resolve-via-host"))
8992         resolve_host = 1;
8993       else if (unformat (i, "resolve-via-attached"))
8994         resolve_attached = 1;
8995       else if (unformat (i, "multipath"))
8996         is_multipath = 1;
8997       else if (unformat (i, "count %d", &count))
8998         ;
8999       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9000         {
9001           next_hop_set = 1;
9002           next_hop_proto = DPO_PROTO_IP4;
9003         }
9004       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9005         {
9006           next_hop_set = 1;
9007           next_hop_proto = DPO_PROTO_IP6;
9008         }
9009       else
9010         if (unformat
9011             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9012              &sw_if_index))
9013         {
9014           next_hop_set = 1;
9015           next_hop_proto = DPO_PROTO_ETHERNET;
9016           is_interface_rx = 1;
9017         }
9018       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9019         {
9020           next_hop_set = 1;
9021           next_hop_proto = DPO_PROTO_ETHERNET;
9022           is_interface_rx = 1;
9023         }
9024       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9025         next_hop_set = 1;
9026       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9027         next_hop_set = 1;
9028       else if (unformat (i, "out-label %d", &next_hop_out_label))
9029         {
9030           vl_api_fib_mpls_label_t fib_label = {
9031             .label = ntohl (next_hop_out_label),
9032             .ttl = 64,
9033             .exp = 0,
9034           };
9035           vec_add1 (next_hop_out_label_stack, fib_label);
9036         }
9037       else
9038         {
9039           clib_warning ("parse error '%U'", format_unformat_error, i);
9040           return -99;
9041         }
9042     }
9043
9044   if (!next_hop_set && !is_classify)
9045     {
9046       errmsg ("next hop / classify not set");
9047       return -99;
9048     }
9049
9050   if (MPLS_LABEL_INVALID == local_label)
9051     {
9052       errmsg ("missing label");
9053       return -99;
9054     }
9055
9056   if (count > 1)
9057     {
9058       /* Turn on async mode */
9059       vam->async_mode = 1;
9060       vam->async_errors = 0;
9061       before = vat_time_now (vam);
9062     }
9063
9064   for (j = 0; j < count; j++)
9065     {
9066       /* Construct the API message */
9067       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9068           vec_len (next_hop_out_label_stack));
9069
9070       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9071       mp->mr_table_id = ntohl (table_id);
9072
9073       mp->mr_is_add = is_add;
9074       mp->mr_next_hop_proto = next_hop_proto;
9075       mp->mr_is_classify = is_classify;
9076       mp->mr_is_multipath = is_multipath;
9077       mp->mr_is_resolve_host = resolve_host;
9078       mp->mr_is_resolve_attached = resolve_attached;
9079       mp->mr_is_interface_rx = is_interface_rx;
9080       mp->mr_next_hop_weight = next_hop_weight;
9081       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9082       mp->mr_classify_table_index = ntohl (classify_table_index);
9083       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9084       mp->mr_label = ntohl (local_label);
9085       mp->mr_eos = is_eos;
9086
9087       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9088       if (0 != mp->mr_next_hop_n_out_labels)
9089         {
9090           memcpy (mp->mr_next_hop_out_label_stack,
9091                   next_hop_out_label_stack,
9092                   vec_len (next_hop_out_label_stack) *
9093                   sizeof (vl_api_fib_mpls_label_t));
9094           vec_free (next_hop_out_label_stack);
9095         }
9096
9097       if (next_hop_set)
9098         {
9099           if (DPO_PROTO_IP4 == next_hop_proto)
9100             {
9101               clib_memcpy (mp->mr_next_hop,
9102                            &v4_next_hop_address,
9103                            sizeof (v4_next_hop_address));
9104             }
9105           else if (DPO_PROTO_IP6 == next_hop_proto)
9106
9107             {
9108               clib_memcpy (mp->mr_next_hop,
9109                            &v6_next_hop_address,
9110                            sizeof (v6_next_hop_address));
9111             }
9112         }
9113       local_label++;
9114
9115       /* send it... */
9116       S (mp);
9117       /* If we receive SIGTERM, stop now... */
9118       if (vam->do_exit)
9119         break;
9120     }
9121
9122   /* When testing multiple add/del ops, use a control-ping to sync */
9123   if (count > 1)
9124     {
9125       vl_api_control_ping_t *mp_ping;
9126       f64 after;
9127       f64 timeout;
9128
9129       /* Shut off async mode */
9130       vam->async_mode = 0;
9131
9132       MPING (CONTROL_PING, mp_ping);
9133       S (mp_ping);
9134
9135       timeout = vat_time_now (vam) + 1.0;
9136       while (vat_time_now (vam) < timeout)
9137         if (vam->result_ready == 1)
9138           goto out;
9139       vam->retval = -99;
9140
9141     out:
9142       if (vam->retval == -99)
9143         errmsg ("timeout");
9144
9145       if (vam->async_errors > 0)
9146         {
9147           errmsg ("%d asynchronous errors", vam->async_errors);
9148           vam->retval = -98;
9149         }
9150       vam->async_errors = 0;
9151       after = vat_time_now (vam);
9152
9153       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9154       if (j > 0)
9155         count = j;
9156
9157       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9158              count, after - before, count / (after - before));
9159     }
9160   else
9161     {
9162       int ret;
9163
9164       /* Wait for a reply... */
9165       W (ret);
9166       return ret;
9167     }
9168
9169   /* Return the good/bad news */
9170   return (vam->retval);
9171 }
9172
9173 static int
9174 api_mpls_ip_bind_unbind (vat_main_t * vam)
9175 {
9176   unformat_input_t *i = vam->input;
9177   vl_api_mpls_ip_bind_unbind_t *mp;
9178   u32 ip_table_id = 0;
9179   u8 is_bind = 1;
9180   u8 is_ip4 = 1;
9181   ip4_address_t v4_address;
9182   ip6_address_t v6_address;
9183   u32 address_length;
9184   u8 address_set = 0;
9185   mpls_label_t local_label = MPLS_LABEL_INVALID;
9186   int ret;
9187
9188   /* Parse args required to build the message */
9189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9190     {
9191       if (unformat (i, "%U/%d", unformat_ip4_address,
9192                     &v4_address, &address_length))
9193         {
9194           is_ip4 = 1;
9195           address_set = 1;
9196         }
9197       else if (unformat (i, "%U/%d", unformat_ip6_address,
9198                          &v6_address, &address_length))
9199         {
9200           is_ip4 = 0;
9201           address_set = 1;
9202         }
9203       else if (unformat (i, "%d", &local_label))
9204         ;
9205       else if (unformat (i, "table-id %d", &ip_table_id))
9206         ;
9207       else if (unformat (i, "unbind"))
9208         is_bind = 0;
9209       else if (unformat (i, "bind"))
9210         is_bind = 1;
9211       else
9212         {
9213           clib_warning ("parse error '%U'", format_unformat_error, i);
9214           return -99;
9215         }
9216     }
9217
9218   if (!address_set)
9219     {
9220       errmsg ("IP addres not set");
9221       return -99;
9222     }
9223
9224   if (MPLS_LABEL_INVALID == local_label)
9225     {
9226       errmsg ("missing label");
9227       return -99;
9228     }
9229
9230   /* Construct the API message */
9231   M (MPLS_IP_BIND_UNBIND, mp);
9232
9233   mp->mb_is_bind = is_bind;
9234   mp->mb_is_ip4 = is_ip4;
9235   mp->mb_ip_table_id = ntohl (ip_table_id);
9236   mp->mb_mpls_table_id = 0;
9237   mp->mb_label = ntohl (local_label);
9238   mp->mb_address_length = address_length;
9239
9240   if (is_ip4)
9241     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9242   else
9243     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9244
9245   /* send it... */
9246   S (mp);
9247
9248   /* Wait for a reply... */
9249   W (ret);
9250   return ret;
9251 }
9252
9253 static int
9254 api_sr_mpls_policy_add (vat_main_t * vam)
9255 {
9256   unformat_input_t *i = vam->input;
9257   vl_api_sr_mpls_policy_add_t *mp;
9258   u32 bsid = 0;
9259   u32 weight = 1;
9260   u8 type = 0;
9261   u8 n_segments = 0;
9262   u32 sid;
9263   u32 *segments = NULL;
9264   int ret;
9265
9266   /* Parse args required to build the message */
9267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9268     {
9269       if (unformat (i, "bsid %d", &bsid))
9270         ;
9271       else if (unformat (i, "weight %d", &weight))
9272         ;
9273       else if (unformat (i, "spray"))
9274         type = 1;
9275       else if (unformat (i, "next %d", &sid))
9276         {
9277           n_segments += 1;
9278           vec_add1 (segments, htonl (sid));
9279         }
9280       else
9281         {
9282           clib_warning ("parse error '%U'", format_unformat_error, i);
9283           return -99;
9284         }
9285     }
9286
9287   if (bsid == 0)
9288     {
9289       errmsg ("bsid not set");
9290       return -99;
9291     }
9292
9293   if (n_segments == 0)
9294     {
9295       errmsg ("no sid in segment stack");
9296       return -99;
9297     }
9298
9299   /* Construct the API message */
9300   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9301
9302   mp->bsid = htonl (bsid);
9303   mp->weight = htonl (weight);
9304   mp->type = type;
9305   mp->n_segments = n_segments;
9306   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9307   vec_free (segments);
9308
9309   /* send it... */
9310   S (mp);
9311
9312   /* Wait for a reply... */
9313   W (ret);
9314   return ret;
9315 }
9316
9317 static int
9318 api_sr_mpls_policy_del (vat_main_t * vam)
9319 {
9320   unformat_input_t *i = vam->input;
9321   vl_api_sr_mpls_policy_del_t *mp;
9322   u32 bsid = 0;
9323   int ret;
9324
9325   /* Parse args required to build the message */
9326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9327     {
9328       if (unformat (i, "bsid %d", &bsid))
9329         ;
9330       else
9331         {
9332           clib_warning ("parse error '%U'", format_unformat_error, i);
9333           return -99;
9334         }
9335     }
9336
9337   if (bsid == 0)
9338     {
9339       errmsg ("bsid not set");
9340       return -99;
9341     }
9342
9343   /* Construct the API message */
9344   M (SR_MPLS_POLICY_DEL, mp);
9345
9346   mp->bsid = htonl (bsid);
9347
9348   /* send it... */
9349   S (mp);
9350
9351   /* Wait for a reply... */
9352   W (ret);
9353   return ret;
9354 }
9355
9356 static int
9357 api_bier_table_add_del (vat_main_t * vam)
9358 {
9359   unformat_input_t *i = vam->input;
9360   vl_api_bier_table_add_del_t *mp;
9361   u8 is_add = 1;
9362   u32 set = 0, sub_domain = 0, hdr_len = 3;
9363   mpls_label_t local_label = MPLS_LABEL_INVALID;
9364   int ret;
9365
9366   /* Parse args required to build the message */
9367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9368     {
9369       if (unformat (i, "sub-domain %d", &sub_domain))
9370         ;
9371       else if (unformat (i, "set %d", &set))
9372         ;
9373       else if (unformat (i, "label %d", &local_label))
9374         ;
9375       else if (unformat (i, "hdr-len %d", &hdr_len))
9376         ;
9377       else if (unformat (i, "add"))
9378         is_add = 1;
9379       else if (unformat (i, "del"))
9380         is_add = 0;
9381       else
9382         {
9383           clib_warning ("parse error '%U'", format_unformat_error, i);
9384           return -99;
9385         }
9386     }
9387
9388   if (MPLS_LABEL_INVALID == local_label)
9389     {
9390       errmsg ("missing label\n");
9391       return -99;
9392     }
9393
9394   /* Construct the API message */
9395   M (BIER_TABLE_ADD_DEL, mp);
9396
9397   mp->bt_is_add = is_add;
9398   mp->bt_label = ntohl (local_label);
9399   mp->bt_tbl_id.bt_set = set;
9400   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9401   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9402
9403   /* send it... */
9404   S (mp);
9405
9406   /* Wait for a reply... */
9407   W (ret);
9408
9409   return (ret);
9410 }
9411
9412 static int
9413 api_bier_route_add_del (vat_main_t * vam)
9414 {
9415   unformat_input_t *i = vam->input;
9416   vl_api_bier_route_add_del_t *mp;
9417   u8 is_add = 1;
9418   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9419   ip4_address_t v4_next_hop_address;
9420   ip6_address_t v6_next_hop_address;
9421   u8 next_hop_set = 0;
9422   u8 next_hop_proto_is_ip4 = 1;
9423   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9424   int ret;
9425
9426   /* Parse args required to build the message */
9427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9428     {
9429       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9430         {
9431           next_hop_proto_is_ip4 = 1;
9432           next_hop_set = 1;
9433         }
9434       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9435         {
9436           next_hop_proto_is_ip4 = 0;
9437           next_hop_set = 1;
9438         }
9439       if (unformat (i, "sub-domain %d", &sub_domain))
9440         ;
9441       else if (unformat (i, "set %d", &set))
9442         ;
9443       else if (unformat (i, "hdr-len %d", &hdr_len))
9444         ;
9445       else if (unformat (i, "bp %d", &bp))
9446         ;
9447       else if (unformat (i, "add"))
9448         is_add = 1;
9449       else if (unformat (i, "del"))
9450         is_add = 0;
9451       else if (unformat (i, "out-label %d", &next_hop_out_label))
9452         ;
9453       else
9454         {
9455           clib_warning ("parse error '%U'", format_unformat_error, i);
9456           return -99;
9457         }
9458     }
9459
9460   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9461     {
9462       errmsg ("next hop / label set\n");
9463       return -99;
9464     }
9465   if (0 == bp)
9466     {
9467       errmsg ("bit=position not set\n");
9468       return -99;
9469     }
9470
9471   /* Construct the API message */
9472   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9473
9474   mp->br_is_add = is_add;
9475   mp->br_tbl_id.bt_set = set;
9476   mp->br_tbl_id.bt_sub_domain = sub_domain;
9477   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9478   mp->br_bp = ntohs (bp);
9479   mp->br_n_paths = 1;
9480   mp->br_paths[0].n_labels = 1;
9481   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9482   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9483
9484   if (next_hop_proto_is_ip4)
9485     {
9486       clib_memcpy (mp->br_paths[0].next_hop,
9487                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9488     }
9489   else
9490     {
9491       clib_memcpy (mp->br_paths[0].next_hop,
9492                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9493     }
9494
9495   /* send it... */
9496   S (mp);
9497
9498   /* Wait for a reply... */
9499   W (ret);
9500
9501   return (ret);
9502 }
9503
9504 static int
9505 api_proxy_arp_add_del (vat_main_t * vam)
9506 {
9507   unformat_input_t *i = vam->input;
9508   vl_api_proxy_arp_add_del_t *mp;
9509   u32 vrf_id = 0;
9510   u8 is_add = 1;
9511   ip4_address_t lo, hi;
9512   u8 range_set = 0;
9513   int ret;
9514
9515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9516     {
9517       if (unformat (i, "vrf %d", &vrf_id))
9518         ;
9519       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9520                          unformat_ip4_address, &hi))
9521         range_set = 1;
9522       else if (unformat (i, "del"))
9523         is_add = 0;
9524       else
9525         {
9526           clib_warning ("parse error '%U'", format_unformat_error, i);
9527           return -99;
9528         }
9529     }
9530
9531   if (range_set == 0)
9532     {
9533       errmsg ("address range not set");
9534       return -99;
9535     }
9536
9537   M (PROXY_ARP_ADD_DEL, mp);
9538
9539   mp->proxy.vrf_id = ntohl (vrf_id);
9540   mp->is_add = is_add;
9541   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9542   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9543
9544   S (mp);
9545   W (ret);
9546   return ret;
9547 }
9548
9549 static int
9550 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9551 {
9552   unformat_input_t *i = vam->input;
9553   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9554   u32 sw_if_index;
9555   u8 enable = 1;
9556   u8 sw_if_index_set = 0;
9557   int ret;
9558
9559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9562         sw_if_index_set = 1;
9563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9564         sw_if_index_set = 1;
9565       else if (unformat (i, "enable"))
9566         enable = 1;
9567       else if (unformat (i, "disable"))
9568         enable = 0;
9569       else
9570         {
9571           clib_warning ("parse error '%U'", format_unformat_error, i);
9572           return -99;
9573         }
9574     }
9575
9576   if (sw_if_index_set == 0)
9577     {
9578       errmsg ("missing interface name or sw_if_index");
9579       return -99;
9580     }
9581
9582   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9583
9584   mp->sw_if_index = ntohl (sw_if_index);
9585   mp->enable_disable = enable;
9586
9587   S (mp);
9588   W (ret);
9589   return ret;
9590 }
9591
9592 static int
9593 api_mpls_tunnel_add_del (vat_main_t * vam)
9594 {
9595   unformat_input_t *i = vam->input;
9596   vl_api_mpls_tunnel_add_del_t *mp;
9597
9598   u8 is_add = 1;
9599   u8 l2_only = 0;
9600   u32 sw_if_index = ~0;
9601   u32 next_hop_sw_if_index = ~0;
9602   u32 next_hop_proto_is_ip4 = 1;
9603
9604   u32 next_hop_table_id = 0;
9605   ip4_address_t v4_next_hop_address = {
9606     .as_u32 = 0,
9607   };
9608   ip6_address_t v6_next_hop_address = { {0} };
9609   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9610   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9611   int ret;
9612
9613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9614     {
9615       if (unformat (i, "add"))
9616         is_add = 1;
9617       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9618         is_add = 0;
9619       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9620         ;
9621       else if (unformat (i, "via %U",
9622                          unformat_ip4_address, &v4_next_hop_address))
9623         {
9624           next_hop_proto_is_ip4 = 1;
9625         }
9626       else if (unformat (i, "via %U",
9627                          unformat_ip6_address, &v6_next_hop_address))
9628         {
9629           next_hop_proto_is_ip4 = 0;
9630         }
9631       else if (unformat (i, "via-label %d", &next_hop_via_label))
9632         ;
9633       else if (unformat (i, "l2-only"))
9634         l2_only = 1;
9635       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9636         ;
9637       else if (unformat (i, "out-label %d", &next_hop_out_label))
9638         vec_add1 (labels, ntohl (next_hop_out_label));
9639       else
9640         {
9641           clib_warning ("parse error '%U'", format_unformat_error, i);
9642           return -99;
9643         }
9644     }
9645
9646   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9647
9648   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9649   mp->mt_sw_if_index = ntohl (sw_if_index);
9650   mp->mt_is_add = is_add;
9651   mp->mt_l2_only = l2_only;
9652   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9653   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9654   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9655
9656   mp->mt_next_hop_n_out_labels = vec_len (labels);
9657
9658   if (0 != mp->mt_next_hop_n_out_labels)
9659     {
9660       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9661                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9662       vec_free (labels);
9663     }
9664
9665   if (next_hop_proto_is_ip4)
9666     {
9667       clib_memcpy (mp->mt_next_hop,
9668                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9669     }
9670   else
9671     {
9672       clib_memcpy (mp->mt_next_hop,
9673                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9674     }
9675
9676   S (mp);
9677   W (ret);
9678   return ret;
9679 }
9680
9681 static int
9682 api_sw_interface_set_unnumbered (vat_main_t * vam)
9683 {
9684   unformat_input_t *i = vam->input;
9685   vl_api_sw_interface_set_unnumbered_t *mp;
9686   u32 sw_if_index;
9687   u32 unnum_sw_index = ~0;
9688   u8 is_add = 1;
9689   u8 sw_if_index_set = 0;
9690   int ret;
9691
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9695         sw_if_index_set = 1;
9696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9697         sw_if_index_set = 1;
9698       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9699         ;
9700       else if (unformat (i, "del"))
9701         is_add = 0;
9702       else
9703         {
9704           clib_warning ("parse error '%U'", format_unformat_error, i);
9705           return -99;
9706         }
9707     }
9708
9709   if (sw_if_index_set == 0)
9710     {
9711       errmsg ("missing interface name or sw_if_index");
9712       return -99;
9713     }
9714
9715   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9716
9717   mp->sw_if_index = ntohl (sw_if_index);
9718   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9719   mp->is_add = is_add;
9720
9721   S (mp);
9722   W (ret);
9723   return ret;
9724 }
9725
9726 static int
9727 api_ip_neighbor_add_del (vat_main_t * vam)
9728 {
9729   unformat_input_t *i = vam->input;
9730   vl_api_ip_neighbor_add_del_t *mp;
9731   u32 sw_if_index;
9732   u8 sw_if_index_set = 0;
9733   u8 is_add = 1;
9734   u8 is_static = 0;
9735   u8 is_no_fib_entry = 0;
9736   u8 mac_address[6];
9737   u8 mac_set = 0;
9738   u8 v4_address_set = 0;
9739   u8 v6_address_set = 0;
9740   ip4_address_t v4address;
9741   ip6_address_t v6address;
9742   int ret;
9743
9744   memset (mac_address, 0, sizeof (mac_address));
9745
9746   /* Parse args required to build the message */
9747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9750         {
9751           mac_set = 1;
9752         }
9753       else if (unformat (i, "del"))
9754         is_add = 0;
9755       else
9756         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9757         sw_if_index_set = 1;
9758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9759         sw_if_index_set = 1;
9760       else if (unformat (i, "is_static"))
9761         is_static = 1;
9762       else if (unformat (i, "no-fib-entry"))
9763         is_no_fib_entry = 1;
9764       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9765         v4_address_set = 1;
9766       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9767         v6_address_set = 1;
9768       else
9769         {
9770           clib_warning ("parse error '%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   if (sw_if_index_set == 0)
9776     {
9777       errmsg ("missing interface name or sw_if_index");
9778       return -99;
9779     }
9780   if (v4_address_set && v6_address_set)
9781     {
9782       errmsg ("both v4 and v6 addresses set");
9783       return -99;
9784     }
9785   if (!v4_address_set && !v6_address_set)
9786     {
9787       errmsg ("no address set");
9788       return -99;
9789     }
9790
9791   /* Construct the API message */
9792   M (IP_NEIGHBOR_ADD_DEL, mp);
9793
9794   mp->sw_if_index = ntohl (sw_if_index);
9795   mp->is_add = is_add;
9796   mp->is_static = is_static;
9797   mp->is_no_adj_fib = is_no_fib_entry;
9798   if (mac_set)
9799     clib_memcpy (mp->mac_address, mac_address, 6);
9800   if (v6_address_set)
9801     {
9802       mp->is_ipv6 = 1;
9803       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9804     }
9805   else
9806     {
9807       /* mp->is_ipv6 = 0; via memset in M macro above */
9808       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9809     }
9810
9811   /* send it... */
9812   S (mp);
9813
9814   /* Wait for a reply, return good/bad news  */
9815   W (ret);
9816   return ret;
9817 }
9818
9819 static int
9820 api_create_vlan_subif (vat_main_t * vam)
9821 {
9822   unformat_input_t *i = vam->input;
9823   vl_api_create_vlan_subif_t *mp;
9824   u32 sw_if_index;
9825   u8 sw_if_index_set = 0;
9826   u32 vlan_id;
9827   u8 vlan_id_set = 0;
9828   int ret;
9829
9830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9831     {
9832       if (unformat (i, "sw_if_index %d", &sw_if_index))
9833         sw_if_index_set = 1;
9834       else
9835         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9836         sw_if_index_set = 1;
9837       else if (unformat (i, "vlan %d", &vlan_id))
9838         vlan_id_set = 1;
9839       else
9840         {
9841           clib_warning ("parse error '%U'", format_unformat_error, i);
9842           return -99;
9843         }
9844     }
9845
9846   if (sw_if_index_set == 0)
9847     {
9848       errmsg ("missing interface name or sw_if_index");
9849       return -99;
9850     }
9851
9852   if (vlan_id_set == 0)
9853     {
9854       errmsg ("missing vlan_id");
9855       return -99;
9856     }
9857   M (CREATE_VLAN_SUBIF, mp);
9858
9859   mp->sw_if_index = ntohl (sw_if_index);
9860   mp->vlan_id = ntohl (vlan_id);
9861
9862   S (mp);
9863   W (ret);
9864   return ret;
9865 }
9866
9867 #define foreach_create_subif_bit                \
9868 _(no_tags)                                      \
9869 _(one_tag)                                      \
9870 _(two_tags)                                     \
9871 _(dot1ad)                                       \
9872 _(exact_match)                                  \
9873 _(default_sub)                                  \
9874 _(outer_vlan_id_any)                            \
9875 _(inner_vlan_id_any)
9876
9877 static int
9878 api_create_subif (vat_main_t * vam)
9879 {
9880   unformat_input_t *i = vam->input;
9881   vl_api_create_subif_t *mp;
9882   u32 sw_if_index;
9883   u8 sw_if_index_set = 0;
9884   u32 sub_id;
9885   u8 sub_id_set = 0;
9886   u32 no_tags = 0;
9887   u32 one_tag = 0;
9888   u32 two_tags = 0;
9889   u32 dot1ad = 0;
9890   u32 exact_match = 0;
9891   u32 default_sub = 0;
9892   u32 outer_vlan_id_any = 0;
9893   u32 inner_vlan_id_any = 0;
9894   u32 tmp;
9895   u16 outer_vlan_id = 0;
9896   u16 inner_vlan_id = 0;
9897   int ret;
9898
9899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9900     {
9901       if (unformat (i, "sw_if_index %d", &sw_if_index))
9902         sw_if_index_set = 1;
9903       else
9904         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9905         sw_if_index_set = 1;
9906       else if (unformat (i, "sub_id %d", &sub_id))
9907         sub_id_set = 1;
9908       else if (unformat (i, "outer_vlan_id %d", &tmp))
9909         outer_vlan_id = tmp;
9910       else if (unformat (i, "inner_vlan_id %d", &tmp))
9911         inner_vlan_id = tmp;
9912
9913 #define _(a) else if (unformat (i, #a)) a = 1 ;
9914       foreach_create_subif_bit
9915 #undef _
9916         else
9917         {
9918           clib_warning ("parse error '%U'", format_unformat_error, i);
9919           return -99;
9920         }
9921     }
9922
9923   if (sw_if_index_set == 0)
9924     {
9925       errmsg ("missing interface name or sw_if_index");
9926       return -99;
9927     }
9928
9929   if (sub_id_set == 0)
9930     {
9931       errmsg ("missing sub_id");
9932       return -99;
9933     }
9934   M (CREATE_SUBIF, mp);
9935
9936   mp->sw_if_index = ntohl (sw_if_index);
9937   mp->sub_id = ntohl (sub_id);
9938
9939 #define _(a) mp->a = a;
9940   foreach_create_subif_bit;
9941 #undef _
9942
9943   mp->outer_vlan_id = ntohs (outer_vlan_id);
9944   mp->inner_vlan_id = ntohs (inner_vlan_id);
9945
9946   S (mp);
9947   W (ret);
9948   return ret;
9949 }
9950
9951 static int
9952 api_oam_add_del (vat_main_t * vam)
9953 {
9954   unformat_input_t *i = vam->input;
9955   vl_api_oam_add_del_t *mp;
9956   u32 vrf_id = 0;
9957   u8 is_add = 1;
9958   ip4_address_t src, dst;
9959   u8 src_set = 0;
9960   u8 dst_set = 0;
9961   int ret;
9962
9963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (unformat (i, "vrf %d", &vrf_id))
9966         ;
9967       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9968         src_set = 1;
9969       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9970         dst_set = 1;
9971       else if (unformat (i, "del"))
9972         is_add = 0;
9973       else
9974         {
9975           clib_warning ("parse error '%U'", format_unformat_error, i);
9976           return -99;
9977         }
9978     }
9979
9980   if (src_set == 0)
9981     {
9982       errmsg ("missing src addr");
9983       return -99;
9984     }
9985
9986   if (dst_set == 0)
9987     {
9988       errmsg ("missing dst addr");
9989       return -99;
9990     }
9991
9992   M (OAM_ADD_DEL, mp);
9993
9994   mp->vrf_id = ntohl (vrf_id);
9995   mp->is_add = is_add;
9996   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9997   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9998
9999   S (mp);
10000   W (ret);
10001   return ret;
10002 }
10003
10004 static int
10005 api_reset_fib (vat_main_t * vam)
10006 {
10007   unformat_input_t *i = vam->input;
10008   vl_api_reset_fib_t *mp;
10009   u32 vrf_id = 0;
10010   u8 is_ipv6 = 0;
10011   u8 vrf_id_set = 0;
10012
10013   int ret;
10014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (i, "vrf %d", &vrf_id))
10017         vrf_id_set = 1;
10018       else if (unformat (i, "ipv6"))
10019         is_ipv6 = 1;
10020       else
10021         {
10022           clib_warning ("parse error '%U'", format_unformat_error, i);
10023           return -99;
10024         }
10025     }
10026
10027   if (vrf_id_set == 0)
10028     {
10029       errmsg ("missing vrf id");
10030       return -99;
10031     }
10032
10033   M (RESET_FIB, mp);
10034
10035   mp->vrf_id = ntohl (vrf_id);
10036   mp->is_ipv6 = is_ipv6;
10037
10038   S (mp);
10039   W (ret);
10040   return ret;
10041 }
10042
10043 static int
10044 api_dhcp_proxy_config (vat_main_t * vam)
10045 {
10046   unformat_input_t *i = vam->input;
10047   vl_api_dhcp_proxy_config_t *mp;
10048   u32 rx_vrf_id = 0;
10049   u32 server_vrf_id = 0;
10050   u8 is_add = 1;
10051   u8 v4_address_set = 0;
10052   u8 v6_address_set = 0;
10053   ip4_address_t v4address;
10054   ip6_address_t v6address;
10055   u8 v4_src_address_set = 0;
10056   u8 v6_src_address_set = 0;
10057   ip4_address_t v4srcaddress;
10058   ip6_address_t v6srcaddress;
10059   int ret;
10060
10061   /* Parse args required to build the message */
10062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10063     {
10064       if (unformat (i, "del"))
10065         is_add = 0;
10066       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10067         ;
10068       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10069         ;
10070       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10071         v4_address_set = 1;
10072       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10073         v6_address_set = 1;
10074       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10075         v4_src_address_set = 1;
10076       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10077         v6_src_address_set = 1;
10078       else
10079         break;
10080     }
10081
10082   if (v4_address_set && v6_address_set)
10083     {
10084       errmsg ("both v4 and v6 server addresses set");
10085       return -99;
10086     }
10087   if (!v4_address_set && !v6_address_set)
10088     {
10089       errmsg ("no server addresses set");
10090       return -99;
10091     }
10092
10093   if (v4_src_address_set && v6_src_address_set)
10094     {
10095       errmsg ("both v4 and v6  src addresses set");
10096       return -99;
10097     }
10098   if (!v4_src_address_set && !v6_src_address_set)
10099     {
10100       errmsg ("no src addresses set");
10101       return -99;
10102     }
10103
10104   if (!(v4_src_address_set && v4_address_set) &&
10105       !(v6_src_address_set && v6_address_set))
10106     {
10107       errmsg ("no matching server and src addresses set");
10108       return -99;
10109     }
10110
10111   /* Construct the API message */
10112   M (DHCP_PROXY_CONFIG, mp);
10113
10114   mp->is_add = is_add;
10115   mp->rx_vrf_id = ntohl (rx_vrf_id);
10116   mp->server_vrf_id = ntohl (server_vrf_id);
10117   if (v6_address_set)
10118     {
10119       mp->is_ipv6 = 1;
10120       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10121       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10122     }
10123   else
10124     {
10125       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10126       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10127     }
10128
10129   /* send it... */
10130   S (mp);
10131
10132   /* Wait for a reply, return good/bad news  */
10133   W (ret);
10134   return ret;
10135 }
10136
10137 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10138 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10139
10140 static void
10141 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10142 {
10143   vat_main_t *vam = &vat_main;
10144   u32 i, count = mp->count;
10145   vl_api_dhcp_server_t *s;
10146
10147   if (mp->is_ipv6)
10148     print (vam->ofp,
10149            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10150            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10151            ntohl (mp->rx_vrf_id),
10152            format_ip6_address, mp->dhcp_src_address,
10153            mp->vss_type, mp->vss_vpn_ascii_id,
10154            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10155   else
10156     print (vam->ofp,
10157            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10158            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10159            ntohl (mp->rx_vrf_id),
10160            format_ip4_address, mp->dhcp_src_address,
10161            mp->vss_type, mp->vss_vpn_ascii_id,
10162            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10163
10164   for (i = 0; i < count; i++)
10165     {
10166       s = &mp->servers[i];
10167
10168       if (mp->is_ipv6)
10169         print (vam->ofp,
10170                " Server Table-ID %d, Server Address %U",
10171                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10172       else
10173         print (vam->ofp,
10174                " Server Table-ID %d, Server Address %U",
10175                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10176     }
10177 }
10178
10179 static void vl_api_dhcp_proxy_details_t_handler_json
10180   (vl_api_dhcp_proxy_details_t * mp)
10181 {
10182   vat_main_t *vam = &vat_main;
10183   vat_json_node_t *node = NULL;
10184   u32 i, count = mp->count;
10185   struct in_addr ip4;
10186   struct in6_addr ip6;
10187   vl_api_dhcp_server_t *s;
10188
10189   if (VAT_JSON_ARRAY != vam->json_tree.type)
10190     {
10191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10192       vat_json_init_array (&vam->json_tree);
10193     }
10194   node = vat_json_array_add (&vam->json_tree);
10195
10196   vat_json_init_object (node);
10197   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10198   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10199                              sizeof (mp->vss_type));
10200   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10201                                    mp->vss_vpn_ascii_id);
10202   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10203   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10204
10205   if (mp->is_ipv6)
10206     {
10207       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10208       vat_json_object_add_ip6 (node, "src_address", ip6);
10209     }
10210   else
10211     {
10212       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10213       vat_json_object_add_ip4 (node, "src_address", ip4);
10214     }
10215
10216   for (i = 0; i < count; i++)
10217     {
10218       s = &mp->servers[i];
10219
10220       vat_json_object_add_uint (node, "server-table-id",
10221                                 ntohl (s->server_vrf_id));
10222
10223       if (mp->is_ipv6)
10224         {
10225           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10226           vat_json_object_add_ip4 (node, "src_address", ip4);
10227         }
10228       else
10229         {
10230           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10231           vat_json_object_add_ip6 (node, "server_address", ip6);
10232         }
10233     }
10234 }
10235
10236 static int
10237 api_dhcp_proxy_dump (vat_main_t * vam)
10238 {
10239   unformat_input_t *i = vam->input;
10240   vl_api_control_ping_t *mp_ping;
10241   vl_api_dhcp_proxy_dump_t *mp;
10242   u8 is_ipv6 = 0;
10243   int ret;
10244
10245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (i, "ipv6"))
10248         is_ipv6 = 1;
10249       else
10250         {
10251           clib_warning ("parse error '%U'", format_unformat_error, i);
10252           return -99;
10253         }
10254     }
10255
10256   M (DHCP_PROXY_DUMP, mp);
10257
10258   mp->is_ip6 = is_ipv6;
10259   S (mp);
10260
10261   /* Use a control ping for synchronization */
10262   MPING (CONTROL_PING, mp_ping);
10263   S (mp_ping);
10264
10265   W (ret);
10266   return ret;
10267 }
10268
10269 static int
10270 api_dhcp_proxy_set_vss (vat_main_t * vam)
10271 {
10272   unformat_input_t *i = vam->input;
10273   vl_api_dhcp_proxy_set_vss_t *mp;
10274   u8 is_ipv6 = 0;
10275   u8 is_add = 1;
10276   u32 tbl_id = ~0;
10277   u8 vss_type = VSS_TYPE_DEFAULT;
10278   u8 *vpn_ascii_id = 0;
10279   u32 oui = 0;
10280   u32 fib_id = 0;
10281   int ret;
10282
10283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10284     {
10285       if (unformat (i, "tbl_id %d", &tbl_id))
10286         ;
10287       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10288         vss_type = VSS_TYPE_ASCII;
10289       else if (unformat (i, "fib_id %d", &fib_id))
10290         vss_type = VSS_TYPE_VPN_ID;
10291       else if (unformat (i, "oui %d", &oui))
10292         vss_type = VSS_TYPE_VPN_ID;
10293       else if (unformat (i, "ipv6"))
10294         is_ipv6 = 1;
10295       else if (unformat (i, "del"))
10296         is_add = 0;
10297       else
10298         break;
10299     }
10300
10301   if (tbl_id == ~0)
10302     {
10303       errmsg ("missing tbl_id ");
10304       vec_free (vpn_ascii_id);
10305       return -99;
10306     }
10307
10308   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10309     {
10310       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10311       vec_free (vpn_ascii_id);
10312       return -99;
10313     }
10314
10315   M (DHCP_PROXY_SET_VSS, mp);
10316   mp->tbl_id = ntohl (tbl_id);
10317   mp->vss_type = vss_type;
10318   if (vpn_ascii_id)
10319     {
10320       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10321       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10322     }
10323   mp->vpn_index = ntohl (fib_id);
10324   mp->oui = ntohl (oui);
10325   mp->is_ipv6 = is_ipv6;
10326   mp->is_add = is_add;
10327
10328   S (mp);
10329   W (ret);
10330
10331   vec_free (vpn_ascii_id);
10332   return ret;
10333 }
10334
10335 static int
10336 api_dhcp_client_config (vat_main_t * vam)
10337 {
10338   unformat_input_t *i = vam->input;
10339   vl_api_dhcp_client_config_t *mp;
10340   u32 sw_if_index;
10341   u8 sw_if_index_set = 0;
10342   u8 is_add = 1;
10343   u8 *hostname = 0;
10344   u8 disable_event = 0;
10345   int ret;
10346
10347   /* Parse args required to build the message */
10348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10349     {
10350       if (unformat (i, "del"))
10351         is_add = 0;
10352       else
10353         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10354         sw_if_index_set = 1;
10355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10356         sw_if_index_set = 1;
10357       else if (unformat (i, "hostname %s", &hostname))
10358         ;
10359       else if (unformat (i, "disable_event"))
10360         disable_event = 1;
10361       else
10362         break;
10363     }
10364
10365   if (sw_if_index_set == 0)
10366     {
10367       errmsg ("missing interface name or sw_if_index");
10368       return -99;
10369     }
10370
10371   if (vec_len (hostname) > 63)
10372     {
10373       errmsg ("hostname too long");
10374     }
10375   vec_add1 (hostname, 0);
10376
10377   /* Construct the API message */
10378   M (DHCP_CLIENT_CONFIG, mp);
10379
10380   mp->is_add = is_add;
10381   mp->client.sw_if_index = htonl (sw_if_index);
10382   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10383   vec_free (hostname);
10384   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10385   mp->client.pid = htonl (getpid ());
10386
10387   /* send it... */
10388   S (mp);
10389
10390   /* Wait for a reply, return good/bad news  */
10391   W (ret);
10392   return ret;
10393 }
10394
10395 static int
10396 api_set_ip_flow_hash (vat_main_t * vam)
10397 {
10398   unformat_input_t *i = vam->input;
10399   vl_api_set_ip_flow_hash_t *mp;
10400   u32 vrf_id = 0;
10401   u8 is_ipv6 = 0;
10402   u8 vrf_id_set = 0;
10403   u8 src = 0;
10404   u8 dst = 0;
10405   u8 sport = 0;
10406   u8 dport = 0;
10407   u8 proto = 0;
10408   u8 reverse = 0;
10409   int ret;
10410
10411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10412     {
10413       if (unformat (i, "vrf %d", &vrf_id))
10414         vrf_id_set = 1;
10415       else if (unformat (i, "ipv6"))
10416         is_ipv6 = 1;
10417       else if (unformat (i, "src"))
10418         src = 1;
10419       else if (unformat (i, "dst"))
10420         dst = 1;
10421       else if (unformat (i, "sport"))
10422         sport = 1;
10423       else if (unformat (i, "dport"))
10424         dport = 1;
10425       else if (unformat (i, "proto"))
10426         proto = 1;
10427       else if (unformat (i, "reverse"))
10428         reverse = 1;
10429
10430       else
10431         {
10432           clib_warning ("parse error '%U'", format_unformat_error, i);
10433           return -99;
10434         }
10435     }
10436
10437   if (vrf_id_set == 0)
10438     {
10439       errmsg ("missing vrf id");
10440       return -99;
10441     }
10442
10443   M (SET_IP_FLOW_HASH, mp);
10444   mp->src = src;
10445   mp->dst = dst;
10446   mp->sport = sport;
10447   mp->dport = dport;
10448   mp->proto = proto;
10449   mp->reverse = reverse;
10450   mp->vrf_id = ntohl (vrf_id);
10451   mp->is_ipv6 = is_ipv6;
10452
10453   S (mp);
10454   W (ret);
10455   return ret;
10456 }
10457
10458 static int
10459 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10460 {
10461   unformat_input_t *i = vam->input;
10462   vl_api_sw_interface_ip6_enable_disable_t *mp;
10463   u32 sw_if_index;
10464   u8 sw_if_index_set = 0;
10465   u8 enable = 0;
10466   int ret;
10467
10468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10469     {
10470       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10471         sw_if_index_set = 1;
10472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10473         sw_if_index_set = 1;
10474       else if (unformat (i, "enable"))
10475         enable = 1;
10476       else if (unformat (i, "disable"))
10477         enable = 0;
10478       else
10479         {
10480           clib_warning ("parse error '%U'", format_unformat_error, i);
10481           return -99;
10482         }
10483     }
10484
10485   if (sw_if_index_set == 0)
10486     {
10487       errmsg ("missing interface name or sw_if_index");
10488       return -99;
10489     }
10490
10491   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10492
10493   mp->sw_if_index = ntohl (sw_if_index);
10494   mp->enable = enable;
10495
10496   S (mp);
10497   W (ret);
10498   return ret;
10499 }
10500
10501 static int
10502 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10503 {
10504   unformat_input_t *i = vam->input;
10505   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10506   u32 sw_if_index;
10507   u8 sw_if_index_set = 0;
10508   u8 v6_address_set = 0;
10509   ip6_address_t v6address;
10510   int ret;
10511
10512   /* Parse args required to build the message */
10513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10514     {
10515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10516         sw_if_index_set = 1;
10517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10518         sw_if_index_set = 1;
10519       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10520         v6_address_set = 1;
10521       else
10522         break;
10523     }
10524
10525   if (sw_if_index_set == 0)
10526     {
10527       errmsg ("missing interface name or sw_if_index");
10528       return -99;
10529     }
10530   if (!v6_address_set)
10531     {
10532       errmsg ("no address set");
10533       return -99;
10534     }
10535
10536   /* Construct the API message */
10537   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10538
10539   mp->sw_if_index = ntohl (sw_if_index);
10540   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10541
10542   /* send it... */
10543   S (mp);
10544
10545   /* Wait for a reply, return good/bad news  */
10546   W (ret);
10547   return ret;
10548 }
10549
10550 static int
10551 api_ip6nd_proxy_add_del (vat_main_t * vam)
10552 {
10553   unformat_input_t *i = vam->input;
10554   vl_api_ip6nd_proxy_add_del_t *mp;
10555   u32 sw_if_index = ~0;
10556   u8 v6_address_set = 0;
10557   ip6_address_t v6address;
10558   u8 is_del = 0;
10559   int ret;
10560
10561   /* Parse args required to build the message */
10562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10565         ;
10566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10567         ;
10568       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10569         v6_address_set = 1;
10570       if (unformat (i, "del"))
10571         is_del = 1;
10572       else
10573         {
10574           clib_warning ("parse error '%U'", format_unformat_error, i);
10575           return -99;
10576         }
10577     }
10578
10579   if (sw_if_index == ~0)
10580     {
10581       errmsg ("missing interface name or sw_if_index");
10582       return -99;
10583     }
10584   if (!v6_address_set)
10585     {
10586       errmsg ("no address set");
10587       return -99;
10588     }
10589
10590   /* Construct the API message */
10591   M (IP6ND_PROXY_ADD_DEL, mp);
10592
10593   mp->is_del = is_del;
10594   mp->sw_if_index = ntohl (sw_if_index);
10595   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10596
10597   /* send it... */
10598   S (mp);
10599
10600   /* Wait for a reply, return good/bad news  */
10601   W (ret);
10602   return ret;
10603 }
10604
10605 static int
10606 api_ip6nd_proxy_dump (vat_main_t * vam)
10607 {
10608   vl_api_ip6nd_proxy_dump_t *mp;
10609   vl_api_control_ping_t *mp_ping;
10610   int ret;
10611
10612   M (IP6ND_PROXY_DUMP, mp);
10613
10614   S (mp);
10615
10616   /* Use a control ping for synchronization */
10617   MPING (CONTROL_PING, mp_ping);
10618   S (mp_ping);
10619
10620   W (ret);
10621   return ret;
10622 }
10623
10624 static void vl_api_ip6nd_proxy_details_t_handler
10625   (vl_api_ip6nd_proxy_details_t * mp)
10626 {
10627   vat_main_t *vam = &vat_main;
10628
10629   print (vam->ofp, "host %U sw_if_index %d",
10630          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10631 }
10632
10633 static void vl_api_ip6nd_proxy_details_t_handler_json
10634   (vl_api_ip6nd_proxy_details_t * mp)
10635 {
10636   vat_main_t *vam = &vat_main;
10637   struct in6_addr ip6;
10638   vat_json_node_t *node = NULL;
10639
10640   if (VAT_JSON_ARRAY != vam->json_tree.type)
10641     {
10642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10643       vat_json_init_array (&vam->json_tree);
10644     }
10645   node = vat_json_array_add (&vam->json_tree);
10646
10647   vat_json_init_object (node);
10648   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10649
10650   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10651   vat_json_object_add_ip6 (node, "host", ip6);
10652 }
10653
10654 static int
10655 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10656 {
10657   unformat_input_t *i = vam->input;
10658   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10659   u32 sw_if_index;
10660   u8 sw_if_index_set = 0;
10661   u32 address_length = 0;
10662   u8 v6_address_set = 0;
10663   ip6_address_t v6address;
10664   u8 use_default = 0;
10665   u8 no_advertise = 0;
10666   u8 off_link = 0;
10667   u8 no_autoconfig = 0;
10668   u8 no_onlink = 0;
10669   u8 is_no = 0;
10670   u32 val_lifetime = 0;
10671   u32 pref_lifetime = 0;
10672   int ret;
10673
10674   /* Parse args required to build the message */
10675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10678         sw_if_index_set = 1;
10679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10680         sw_if_index_set = 1;
10681       else if (unformat (i, "%U/%d",
10682                          unformat_ip6_address, &v6address, &address_length))
10683         v6_address_set = 1;
10684       else if (unformat (i, "val_life %d", &val_lifetime))
10685         ;
10686       else if (unformat (i, "pref_life %d", &pref_lifetime))
10687         ;
10688       else if (unformat (i, "def"))
10689         use_default = 1;
10690       else if (unformat (i, "noadv"))
10691         no_advertise = 1;
10692       else if (unformat (i, "offl"))
10693         off_link = 1;
10694       else if (unformat (i, "noauto"))
10695         no_autoconfig = 1;
10696       else if (unformat (i, "nolink"))
10697         no_onlink = 1;
10698       else if (unformat (i, "isno"))
10699         is_no = 1;
10700       else
10701         {
10702           clib_warning ("parse error '%U'", format_unformat_error, i);
10703           return -99;
10704         }
10705     }
10706
10707   if (sw_if_index_set == 0)
10708     {
10709       errmsg ("missing interface name or sw_if_index");
10710       return -99;
10711     }
10712   if (!v6_address_set)
10713     {
10714       errmsg ("no address set");
10715       return -99;
10716     }
10717
10718   /* Construct the API message */
10719   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10720
10721   mp->sw_if_index = ntohl (sw_if_index);
10722   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10723   mp->address_length = address_length;
10724   mp->use_default = use_default;
10725   mp->no_advertise = no_advertise;
10726   mp->off_link = off_link;
10727   mp->no_autoconfig = no_autoconfig;
10728   mp->no_onlink = no_onlink;
10729   mp->is_no = is_no;
10730   mp->val_lifetime = ntohl (val_lifetime);
10731   mp->pref_lifetime = ntohl (pref_lifetime);
10732
10733   /* send it... */
10734   S (mp);
10735
10736   /* Wait for a reply, return good/bad news  */
10737   W (ret);
10738   return ret;
10739 }
10740
10741 static int
10742 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10743 {
10744   unformat_input_t *i = vam->input;
10745   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10746   u32 sw_if_index;
10747   u8 sw_if_index_set = 0;
10748   u8 suppress = 0;
10749   u8 managed = 0;
10750   u8 other = 0;
10751   u8 ll_option = 0;
10752   u8 send_unicast = 0;
10753   u8 cease = 0;
10754   u8 is_no = 0;
10755   u8 default_router = 0;
10756   u32 max_interval = 0;
10757   u32 min_interval = 0;
10758   u32 lifetime = 0;
10759   u32 initial_count = 0;
10760   u32 initial_interval = 0;
10761   int ret;
10762
10763
10764   /* Parse args required to build the message */
10765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10766     {
10767       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10768         sw_if_index_set = 1;
10769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10770         sw_if_index_set = 1;
10771       else if (unformat (i, "maxint %d", &max_interval))
10772         ;
10773       else if (unformat (i, "minint %d", &min_interval))
10774         ;
10775       else if (unformat (i, "life %d", &lifetime))
10776         ;
10777       else if (unformat (i, "count %d", &initial_count))
10778         ;
10779       else if (unformat (i, "interval %d", &initial_interval))
10780         ;
10781       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10782         suppress = 1;
10783       else if (unformat (i, "managed"))
10784         managed = 1;
10785       else if (unformat (i, "other"))
10786         other = 1;
10787       else if (unformat (i, "ll"))
10788         ll_option = 1;
10789       else if (unformat (i, "send"))
10790         send_unicast = 1;
10791       else if (unformat (i, "cease"))
10792         cease = 1;
10793       else if (unformat (i, "isno"))
10794         is_no = 1;
10795       else if (unformat (i, "def"))
10796         default_router = 1;
10797       else
10798         {
10799           clib_warning ("parse error '%U'", format_unformat_error, i);
10800           return -99;
10801         }
10802     }
10803
10804   if (sw_if_index_set == 0)
10805     {
10806       errmsg ("missing interface name or sw_if_index");
10807       return -99;
10808     }
10809
10810   /* Construct the API message */
10811   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10812
10813   mp->sw_if_index = ntohl (sw_if_index);
10814   mp->max_interval = ntohl (max_interval);
10815   mp->min_interval = ntohl (min_interval);
10816   mp->lifetime = ntohl (lifetime);
10817   mp->initial_count = ntohl (initial_count);
10818   mp->initial_interval = ntohl (initial_interval);
10819   mp->suppress = suppress;
10820   mp->managed = managed;
10821   mp->other = other;
10822   mp->ll_option = ll_option;
10823   mp->send_unicast = send_unicast;
10824   mp->cease = cease;
10825   mp->is_no = is_no;
10826   mp->default_router = default_router;
10827
10828   /* send it... */
10829   S (mp);
10830
10831   /* Wait for a reply, return good/bad news  */
10832   W (ret);
10833   return ret;
10834 }
10835
10836 static int
10837 api_set_arp_neighbor_limit (vat_main_t * vam)
10838 {
10839   unformat_input_t *i = vam->input;
10840   vl_api_set_arp_neighbor_limit_t *mp;
10841   u32 arp_nbr_limit;
10842   u8 limit_set = 0;
10843   u8 is_ipv6 = 0;
10844   int ret;
10845
10846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10847     {
10848       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10849         limit_set = 1;
10850       else if (unformat (i, "ipv6"))
10851         is_ipv6 = 1;
10852       else
10853         {
10854           clib_warning ("parse error '%U'", format_unformat_error, i);
10855           return -99;
10856         }
10857     }
10858
10859   if (limit_set == 0)
10860     {
10861       errmsg ("missing limit value");
10862       return -99;
10863     }
10864
10865   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10866
10867   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10868   mp->is_ipv6 = is_ipv6;
10869
10870   S (mp);
10871   W (ret);
10872   return ret;
10873 }
10874
10875 static int
10876 api_l2_patch_add_del (vat_main_t * vam)
10877 {
10878   unformat_input_t *i = vam->input;
10879   vl_api_l2_patch_add_del_t *mp;
10880   u32 rx_sw_if_index;
10881   u8 rx_sw_if_index_set = 0;
10882   u32 tx_sw_if_index;
10883   u8 tx_sw_if_index_set = 0;
10884   u8 is_add = 1;
10885   int ret;
10886
10887   /* Parse args required to build the message */
10888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10889     {
10890       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10891         rx_sw_if_index_set = 1;
10892       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10893         tx_sw_if_index_set = 1;
10894       else if (unformat (i, "rx"))
10895         {
10896           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10897             {
10898               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10899                             &rx_sw_if_index))
10900                 rx_sw_if_index_set = 1;
10901             }
10902           else
10903             break;
10904         }
10905       else if (unformat (i, "tx"))
10906         {
10907           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10908             {
10909               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10910                             &tx_sw_if_index))
10911                 tx_sw_if_index_set = 1;
10912             }
10913           else
10914             break;
10915         }
10916       else if (unformat (i, "del"))
10917         is_add = 0;
10918       else
10919         break;
10920     }
10921
10922   if (rx_sw_if_index_set == 0)
10923     {
10924       errmsg ("missing rx interface name or rx_sw_if_index");
10925       return -99;
10926     }
10927
10928   if (tx_sw_if_index_set == 0)
10929     {
10930       errmsg ("missing tx interface name or tx_sw_if_index");
10931       return -99;
10932     }
10933
10934   M (L2_PATCH_ADD_DEL, mp);
10935
10936   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10937   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10938   mp->is_add = is_add;
10939
10940   S (mp);
10941   W (ret);
10942   return ret;
10943 }
10944
10945 u8 is_del;
10946 u8 localsid_addr[16];
10947 u8 end_psp;
10948 u8 behavior;
10949 u32 sw_if_index;
10950 u32 vlan_index;
10951 u32 fib_table;
10952 u8 nh_addr[16];
10953
10954 static int
10955 api_sr_localsid_add_del (vat_main_t * vam)
10956 {
10957   unformat_input_t *i = vam->input;
10958   vl_api_sr_localsid_add_del_t *mp;
10959
10960   u8 is_del;
10961   ip6_address_t localsid;
10962   u8 end_psp = 0;
10963   u8 behavior = ~0;
10964   u32 sw_if_index;
10965   u32 fib_table = ~(u32) 0;
10966   ip6_address_t nh_addr6;
10967   ip4_address_t nh_addr4;
10968   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10969   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10970
10971   bool nexthop_set = 0;
10972
10973   int ret;
10974
10975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10976     {
10977       if (unformat (i, "del"))
10978         is_del = 1;
10979       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10980       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10981         nexthop_set = 1;
10982       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10983         nexthop_set = 1;
10984       else if (unformat (i, "behavior %u", &behavior));
10985       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10986       else if (unformat (i, "fib-table %u", &fib_table));
10987       else if (unformat (i, "end.psp %u", &behavior));
10988       else
10989         break;
10990     }
10991
10992   M (SR_LOCALSID_ADD_DEL, mp);
10993
10994   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10995   if (nexthop_set)
10996     {
10997       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10998       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10999     }
11000   mp->behavior = behavior;
11001   mp->sw_if_index = ntohl (sw_if_index);
11002   mp->fib_table = ntohl (fib_table);
11003   mp->end_psp = end_psp;
11004   mp->is_del = is_del;
11005
11006   S (mp);
11007   W (ret);
11008   return ret;
11009 }
11010
11011 static int
11012 api_ioam_enable (vat_main_t * vam)
11013 {
11014   unformat_input_t *input = vam->input;
11015   vl_api_ioam_enable_t *mp;
11016   u32 id = 0;
11017   int has_trace_option = 0;
11018   int has_pot_option = 0;
11019   int has_seqno_option = 0;
11020   int has_analyse_option = 0;
11021   int ret;
11022
11023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11024     {
11025       if (unformat (input, "trace"))
11026         has_trace_option = 1;
11027       else if (unformat (input, "pot"))
11028         has_pot_option = 1;
11029       else if (unformat (input, "seqno"))
11030         has_seqno_option = 1;
11031       else if (unformat (input, "analyse"))
11032         has_analyse_option = 1;
11033       else
11034         break;
11035     }
11036   M (IOAM_ENABLE, mp);
11037   mp->id = htons (id);
11038   mp->seqno = has_seqno_option;
11039   mp->analyse = has_analyse_option;
11040   mp->pot_enable = has_pot_option;
11041   mp->trace_enable = has_trace_option;
11042
11043   S (mp);
11044   W (ret);
11045   return ret;
11046 }
11047
11048
11049 static int
11050 api_ioam_disable (vat_main_t * vam)
11051 {
11052   vl_api_ioam_disable_t *mp;
11053   int ret;
11054
11055   M (IOAM_DISABLE, mp);
11056   S (mp);
11057   W (ret);
11058   return ret;
11059 }
11060
11061 #define foreach_tcp_proto_field                 \
11062 _(src_port)                                     \
11063 _(dst_port)
11064
11065 #define foreach_udp_proto_field                 \
11066 _(src_port)                                     \
11067 _(dst_port)
11068
11069 #define foreach_ip4_proto_field                 \
11070 _(src_address)                                  \
11071 _(dst_address)                                  \
11072 _(tos)                                          \
11073 _(length)                                       \
11074 _(fragment_id)                                  \
11075 _(ttl)                                          \
11076 _(protocol)                                     \
11077 _(checksum)
11078
11079 typedef struct
11080 {
11081   u16 src_port, dst_port;
11082 } tcpudp_header_t;
11083
11084 #if VPP_API_TEST_BUILTIN == 0
11085 uword
11086 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11087 {
11088   u8 **maskp = va_arg (*args, u8 **);
11089   u8 *mask = 0;
11090   u8 found_something = 0;
11091   tcp_header_t *tcp;
11092
11093 #define _(a) u8 a=0;
11094   foreach_tcp_proto_field;
11095 #undef _
11096
11097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11098     {
11099       if (0);
11100 #define _(a) else if (unformat (input, #a)) a=1;
11101       foreach_tcp_proto_field
11102 #undef _
11103         else
11104         break;
11105     }
11106
11107 #define _(a) found_something += a;
11108   foreach_tcp_proto_field;
11109 #undef _
11110
11111   if (found_something == 0)
11112     return 0;
11113
11114   vec_validate (mask, sizeof (*tcp) - 1);
11115
11116   tcp = (tcp_header_t *) mask;
11117
11118 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11119   foreach_tcp_proto_field;
11120 #undef _
11121
11122   *maskp = mask;
11123   return 1;
11124 }
11125
11126 uword
11127 unformat_udp_mask (unformat_input_t * input, va_list * args)
11128 {
11129   u8 **maskp = va_arg (*args, u8 **);
11130   u8 *mask = 0;
11131   u8 found_something = 0;
11132   udp_header_t *udp;
11133
11134 #define _(a) u8 a=0;
11135   foreach_udp_proto_field;
11136 #undef _
11137
11138   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11139     {
11140       if (0);
11141 #define _(a) else if (unformat (input, #a)) a=1;
11142       foreach_udp_proto_field
11143 #undef _
11144         else
11145         break;
11146     }
11147
11148 #define _(a) found_something += a;
11149   foreach_udp_proto_field;
11150 #undef _
11151
11152   if (found_something == 0)
11153     return 0;
11154
11155   vec_validate (mask, sizeof (*udp) - 1);
11156
11157   udp = (udp_header_t *) mask;
11158
11159 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11160   foreach_udp_proto_field;
11161 #undef _
11162
11163   *maskp = mask;
11164   return 1;
11165 }
11166
11167 uword
11168 unformat_l4_mask (unformat_input_t * input, va_list * args)
11169 {
11170   u8 **maskp = va_arg (*args, u8 **);
11171   u16 src_port = 0, dst_port = 0;
11172   tcpudp_header_t *tcpudp;
11173
11174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11175     {
11176       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11177         return 1;
11178       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11179         return 1;
11180       else if (unformat (input, "src_port"))
11181         src_port = 0xFFFF;
11182       else if (unformat (input, "dst_port"))
11183         dst_port = 0xFFFF;
11184       else
11185         return 0;
11186     }
11187
11188   if (!src_port && !dst_port)
11189     return 0;
11190
11191   u8 *mask = 0;
11192   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11193
11194   tcpudp = (tcpudp_header_t *) mask;
11195   tcpudp->src_port = src_port;
11196   tcpudp->dst_port = dst_port;
11197
11198   *maskp = mask;
11199
11200   return 1;
11201 }
11202
11203 uword
11204 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11205 {
11206   u8 **maskp = va_arg (*args, u8 **);
11207   u8 *mask = 0;
11208   u8 found_something = 0;
11209   ip4_header_t *ip;
11210
11211 #define _(a) u8 a=0;
11212   foreach_ip4_proto_field;
11213 #undef _
11214   u8 version = 0;
11215   u8 hdr_length = 0;
11216
11217
11218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11219     {
11220       if (unformat (input, "version"))
11221         version = 1;
11222       else if (unformat (input, "hdr_length"))
11223         hdr_length = 1;
11224       else if (unformat (input, "src"))
11225         src_address = 1;
11226       else if (unformat (input, "dst"))
11227         dst_address = 1;
11228       else if (unformat (input, "proto"))
11229         protocol = 1;
11230
11231 #define _(a) else if (unformat (input, #a)) a=1;
11232       foreach_ip4_proto_field
11233 #undef _
11234         else
11235         break;
11236     }
11237
11238 #define _(a) found_something += a;
11239   foreach_ip4_proto_field;
11240 #undef _
11241
11242   if (found_something == 0)
11243     return 0;
11244
11245   vec_validate (mask, sizeof (*ip) - 1);
11246
11247   ip = (ip4_header_t *) mask;
11248
11249 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11250   foreach_ip4_proto_field;
11251 #undef _
11252
11253   ip->ip_version_and_header_length = 0;
11254
11255   if (version)
11256     ip->ip_version_and_header_length |= 0xF0;
11257
11258   if (hdr_length)
11259     ip->ip_version_and_header_length |= 0x0F;
11260
11261   *maskp = mask;
11262   return 1;
11263 }
11264
11265 #define foreach_ip6_proto_field                 \
11266 _(src_address)                                  \
11267 _(dst_address)                                  \
11268 _(payload_length)                               \
11269 _(hop_limit)                                    \
11270 _(protocol)
11271
11272 uword
11273 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11274 {
11275   u8 **maskp = va_arg (*args, u8 **);
11276   u8 *mask = 0;
11277   u8 found_something = 0;
11278   ip6_header_t *ip;
11279   u32 ip_version_traffic_class_and_flow_label;
11280
11281 #define _(a) u8 a=0;
11282   foreach_ip6_proto_field;
11283 #undef _
11284   u8 version = 0;
11285   u8 traffic_class = 0;
11286   u8 flow_label = 0;
11287
11288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11289     {
11290       if (unformat (input, "version"))
11291         version = 1;
11292       else if (unformat (input, "traffic-class"))
11293         traffic_class = 1;
11294       else if (unformat (input, "flow-label"))
11295         flow_label = 1;
11296       else if (unformat (input, "src"))
11297         src_address = 1;
11298       else if (unformat (input, "dst"))
11299         dst_address = 1;
11300       else if (unformat (input, "proto"))
11301         protocol = 1;
11302
11303 #define _(a) else if (unformat (input, #a)) a=1;
11304       foreach_ip6_proto_field
11305 #undef _
11306         else
11307         break;
11308     }
11309
11310 #define _(a) found_something += a;
11311   foreach_ip6_proto_field;
11312 #undef _
11313
11314   if (found_something == 0)
11315     return 0;
11316
11317   vec_validate (mask, sizeof (*ip) - 1);
11318
11319   ip = (ip6_header_t *) mask;
11320
11321 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11322   foreach_ip6_proto_field;
11323 #undef _
11324
11325   ip_version_traffic_class_and_flow_label = 0;
11326
11327   if (version)
11328     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11329
11330   if (traffic_class)
11331     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11332
11333   if (flow_label)
11334     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11335
11336   ip->ip_version_traffic_class_and_flow_label =
11337     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11338
11339   *maskp = mask;
11340   return 1;
11341 }
11342
11343 uword
11344 unformat_l3_mask (unformat_input_t * input, va_list * args)
11345 {
11346   u8 **maskp = va_arg (*args, u8 **);
11347
11348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11349     {
11350       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11351         return 1;
11352       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11353         return 1;
11354       else
11355         break;
11356     }
11357   return 0;
11358 }
11359
11360 uword
11361 unformat_l2_mask (unformat_input_t * input, va_list * args)
11362 {
11363   u8 **maskp = va_arg (*args, u8 **);
11364   u8 *mask = 0;
11365   u8 src = 0;
11366   u8 dst = 0;
11367   u8 proto = 0;
11368   u8 tag1 = 0;
11369   u8 tag2 = 0;
11370   u8 ignore_tag1 = 0;
11371   u8 ignore_tag2 = 0;
11372   u8 cos1 = 0;
11373   u8 cos2 = 0;
11374   u8 dot1q = 0;
11375   u8 dot1ad = 0;
11376   int len = 14;
11377
11378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11379     {
11380       if (unformat (input, "src"))
11381         src = 1;
11382       else if (unformat (input, "dst"))
11383         dst = 1;
11384       else if (unformat (input, "proto"))
11385         proto = 1;
11386       else if (unformat (input, "tag1"))
11387         tag1 = 1;
11388       else if (unformat (input, "tag2"))
11389         tag2 = 1;
11390       else if (unformat (input, "ignore-tag1"))
11391         ignore_tag1 = 1;
11392       else if (unformat (input, "ignore-tag2"))
11393         ignore_tag2 = 1;
11394       else if (unformat (input, "cos1"))
11395         cos1 = 1;
11396       else if (unformat (input, "cos2"))
11397         cos2 = 1;
11398       else if (unformat (input, "dot1q"))
11399         dot1q = 1;
11400       else if (unformat (input, "dot1ad"))
11401         dot1ad = 1;
11402       else
11403         break;
11404     }
11405   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11406        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11407     return 0;
11408
11409   if (tag1 || ignore_tag1 || cos1 || dot1q)
11410     len = 18;
11411   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11412     len = 22;
11413
11414   vec_validate (mask, len - 1);
11415
11416   if (dst)
11417     memset (mask, 0xff, 6);
11418
11419   if (src)
11420     memset (mask + 6, 0xff, 6);
11421
11422   if (tag2 || dot1ad)
11423     {
11424       /* inner vlan tag */
11425       if (tag2)
11426         {
11427           mask[19] = 0xff;
11428           mask[18] = 0x0f;
11429         }
11430       if (cos2)
11431         mask[18] |= 0xe0;
11432       if (proto)
11433         mask[21] = mask[20] = 0xff;
11434       if (tag1)
11435         {
11436           mask[15] = 0xff;
11437           mask[14] = 0x0f;
11438         }
11439       if (cos1)
11440         mask[14] |= 0xe0;
11441       *maskp = mask;
11442       return 1;
11443     }
11444   if (tag1 | dot1q)
11445     {
11446       if (tag1)
11447         {
11448           mask[15] = 0xff;
11449           mask[14] = 0x0f;
11450         }
11451       if (cos1)
11452         mask[14] |= 0xe0;
11453       if (proto)
11454         mask[16] = mask[17] = 0xff;
11455
11456       *maskp = mask;
11457       return 1;
11458     }
11459   if (cos2)
11460     mask[18] |= 0xe0;
11461   if (cos1)
11462     mask[14] |= 0xe0;
11463   if (proto)
11464     mask[12] = mask[13] = 0xff;
11465
11466   *maskp = mask;
11467   return 1;
11468 }
11469
11470 uword
11471 unformat_classify_mask (unformat_input_t * input, va_list * args)
11472 {
11473   u8 **maskp = va_arg (*args, u8 **);
11474   u32 *skipp = va_arg (*args, u32 *);
11475   u32 *matchp = va_arg (*args, u32 *);
11476   u32 match;
11477   u8 *mask = 0;
11478   u8 *l2 = 0;
11479   u8 *l3 = 0;
11480   u8 *l4 = 0;
11481   int i;
11482
11483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11486         ;
11487       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11488         ;
11489       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11490         ;
11491       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11492         ;
11493       else
11494         break;
11495     }
11496
11497   if (l4 && !l3)
11498     {
11499       vec_free (mask);
11500       vec_free (l2);
11501       vec_free (l4);
11502       return 0;
11503     }
11504
11505   if (mask || l2 || l3 || l4)
11506     {
11507       if (l2 || l3 || l4)
11508         {
11509           /* "With a free Ethernet header in every package" */
11510           if (l2 == 0)
11511             vec_validate (l2, 13);
11512           mask = l2;
11513           if (vec_len (l3))
11514             {
11515               vec_append (mask, l3);
11516               vec_free (l3);
11517             }
11518           if (vec_len (l4))
11519             {
11520               vec_append (mask, l4);
11521               vec_free (l4);
11522             }
11523         }
11524
11525       /* Scan forward looking for the first significant mask octet */
11526       for (i = 0; i < vec_len (mask); i++)
11527         if (mask[i])
11528           break;
11529
11530       /* compute (skip, match) params */
11531       *skipp = i / sizeof (u32x4);
11532       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11533
11534       /* Pad mask to an even multiple of the vector size */
11535       while (vec_len (mask) % sizeof (u32x4))
11536         vec_add1 (mask, 0);
11537
11538       match = vec_len (mask) / sizeof (u32x4);
11539
11540       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11541         {
11542           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11543           if (*tmp || *(tmp + 1))
11544             break;
11545           match--;
11546         }
11547       if (match == 0)
11548         clib_warning ("BUG: match 0");
11549
11550       _vec_len (mask) = match * sizeof (u32x4);
11551
11552       *matchp = match;
11553       *maskp = mask;
11554
11555       return 1;
11556     }
11557
11558   return 0;
11559 }
11560 #endif /* VPP_API_TEST_BUILTIN */
11561
11562 #define foreach_l2_next                         \
11563 _(drop, DROP)                                   \
11564 _(ethernet, ETHERNET_INPUT)                     \
11565 _(ip4, IP4_INPUT)                               \
11566 _(ip6, IP6_INPUT)
11567
11568 uword
11569 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11570 {
11571   u32 *miss_next_indexp = va_arg (*args, u32 *);
11572   u32 next_index = 0;
11573   u32 tmp;
11574
11575 #define _(n,N) \
11576   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11577   foreach_l2_next;
11578 #undef _
11579
11580   if (unformat (input, "%d", &tmp))
11581     {
11582       next_index = tmp;
11583       goto out;
11584     }
11585
11586   return 0;
11587
11588 out:
11589   *miss_next_indexp = next_index;
11590   return 1;
11591 }
11592
11593 #define foreach_ip_next                         \
11594 _(drop, DROP)                                   \
11595 _(local, LOCAL)                                 \
11596 _(rewrite, REWRITE)
11597
11598 uword
11599 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11600 {
11601   u32 *miss_next_indexp = va_arg (*args, u32 *);
11602   u32 next_index = 0;
11603   u32 tmp;
11604
11605 #define _(n,N) \
11606   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11607   foreach_ip_next;
11608 #undef _
11609
11610   if (unformat (input, "%d", &tmp))
11611     {
11612       next_index = tmp;
11613       goto out;
11614     }
11615
11616   return 0;
11617
11618 out:
11619   *miss_next_indexp = next_index;
11620   return 1;
11621 }
11622
11623 #define foreach_acl_next                        \
11624 _(deny, DENY)
11625
11626 uword
11627 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11628 {
11629   u32 *miss_next_indexp = va_arg (*args, u32 *);
11630   u32 next_index = 0;
11631   u32 tmp;
11632
11633 #define _(n,N) \
11634   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11635   foreach_acl_next;
11636 #undef _
11637
11638   if (unformat (input, "permit"))
11639     {
11640       next_index = ~0;
11641       goto out;
11642     }
11643   else if (unformat (input, "%d", &tmp))
11644     {
11645       next_index = tmp;
11646       goto out;
11647     }
11648
11649   return 0;
11650
11651 out:
11652   *miss_next_indexp = next_index;
11653   return 1;
11654 }
11655
11656 uword
11657 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11658 {
11659   u32 *r = va_arg (*args, u32 *);
11660
11661   if (unformat (input, "conform-color"))
11662     *r = POLICE_CONFORM;
11663   else if (unformat (input, "exceed-color"))
11664     *r = POLICE_EXCEED;
11665   else
11666     return 0;
11667
11668   return 1;
11669 }
11670
11671 static int
11672 api_classify_add_del_table (vat_main_t * vam)
11673 {
11674   unformat_input_t *i = vam->input;
11675   vl_api_classify_add_del_table_t *mp;
11676
11677   u32 nbuckets = 2;
11678   u32 skip = ~0;
11679   u32 match = ~0;
11680   int is_add = 1;
11681   int del_chain = 0;
11682   u32 table_index = ~0;
11683   u32 next_table_index = ~0;
11684   u32 miss_next_index = ~0;
11685   u32 memory_size = 32 << 20;
11686   u8 *mask = 0;
11687   u32 current_data_flag = 0;
11688   int current_data_offset = 0;
11689   int ret;
11690
11691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11692     {
11693       if (unformat (i, "del"))
11694         is_add = 0;
11695       else if (unformat (i, "del-chain"))
11696         {
11697           is_add = 0;
11698           del_chain = 1;
11699         }
11700       else if (unformat (i, "buckets %d", &nbuckets))
11701         ;
11702       else if (unformat (i, "memory_size %d", &memory_size))
11703         ;
11704       else if (unformat (i, "skip %d", &skip))
11705         ;
11706       else if (unformat (i, "match %d", &match))
11707         ;
11708       else if (unformat (i, "table %d", &table_index))
11709         ;
11710       else if (unformat (i, "mask %U", unformat_classify_mask,
11711                          &mask, &skip, &match))
11712         ;
11713       else if (unformat (i, "next-table %d", &next_table_index))
11714         ;
11715       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11716                          &miss_next_index))
11717         ;
11718       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11719                          &miss_next_index))
11720         ;
11721       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11722                          &miss_next_index))
11723         ;
11724       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11725         ;
11726       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11727         ;
11728       else
11729         break;
11730     }
11731
11732   if (is_add && mask == 0)
11733     {
11734       errmsg ("Mask required");
11735       return -99;
11736     }
11737
11738   if (is_add && skip == ~0)
11739     {
11740       errmsg ("skip count required");
11741       return -99;
11742     }
11743
11744   if (is_add && match == ~0)
11745     {
11746       errmsg ("match count required");
11747       return -99;
11748     }
11749
11750   if (!is_add && table_index == ~0)
11751     {
11752       errmsg ("table index required for delete");
11753       return -99;
11754     }
11755
11756   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11757
11758   mp->is_add = is_add;
11759   mp->del_chain = del_chain;
11760   mp->table_index = ntohl (table_index);
11761   mp->nbuckets = ntohl (nbuckets);
11762   mp->memory_size = ntohl (memory_size);
11763   mp->skip_n_vectors = ntohl (skip);
11764   mp->match_n_vectors = ntohl (match);
11765   mp->next_table_index = ntohl (next_table_index);
11766   mp->miss_next_index = ntohl (miss_next_index);
11767   mp->current_data_flag = ntohl (current_data_flag);
11768   mp->current_data_offset = ntohl (current_data_offset);
11769   mp->mask_len = ntohl (vec_len (mask));
11770   clib_memcpy (mp->mask, mask, vec_len (mask));
11771
11772   vec_free (mask);
11773
11774   S (mp);
11775   W (ret);
11776   return ret;
11777 }
11778
11779 #if VPP_API_TEST_BUILTIN == 0
11780 uword
11781 unformat_l4_match (unformat_input_t * input, va_list * args)
11782 {
11783   u8 **matchp = va_arg (*args, u8 **);
11784
11785   u8 *proto_header = 0;
11786   int src_port = 0;
11787   int dst_port = 0;
11788
11789   tcpudp_header_t h;
11790
11791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11792     {
11793       if (unformat (input, "src_port %d", &src_port))
11794         ;
11795       else if (unformat (input, "dst_port %d", &dst_port))
11796         ;
11797       else
11798         return 0;
11799     }
11800
11801   h.src_port = clib_host_to_net_u16 (src_port);
11802   h.dst_port = clib_host_to_net_u16 (dst_port);
11803   vec_validate (proto_header, sizeof (h) - 1);
11804   memcpy (proto_header, &h, sizeof (h));
11805
11806   *matchp = proto_header;
11807
11808   return 1;
11809 }
11810
11811 uword
11812 unformat_ip4_match (unformat_input_t * input, va_list * args)
11813 {
11814   u8 **matchp = va_arg (*args, u8 **);
11815   u8 *match = 0;
11816   ip4_header_t *ip;
11817   int version = 0;
11818   u32 version_val;
11819   int hdr_length = 0;
11820   u32 hdr_length_val;
11821   int src = 0, dst = 0;
11822   ip4_address_t src_val, dst_val;
11823   int proto = 0;
11824   u32 proto_val;
11825   int tos = 0;
11826   u32 tos_val;
11827   int length = 0;
11828   u32 length_val;
11829   int fragment_id = 0;
11830   u32 fragment_id_val;
11831   int ttl = 0;
11832   int ttl_val;
11833   int checksum = 0;
11834   u32 checksum_val;
11835
11836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11837     {
11838       if (unformat (input, "version %d", &version_val))
11839         version = 1;
11840       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11841         hdr_length = 1;
11842       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11843         src = 1;
11844       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11845         dst = 1;
11846       else if (unformat (input, "proto %d", &proto_val))
11847         proto = 1;
11848       else if (unformat (input, "tos %d", &tos_val))
11849         tos = 1;
11850       else if (unformat (input, "length %d", &length_val))
11851         length = 1;
11852       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11853         fragment_id = 1;
11854       else if (unformat (input, "ttl %d", &ttl_val))
11855         ttl = 1;
11856       else if (unformat (input, "checksum %d", &checksum_val))
11857         checksum = 1;
11858       else
11859         break;
11860     }
11861
11862   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11863       + ttl + checksum == 0)
11864     return 0;
11865
11866   /*
11867    * Aligned because we use the real comparison functions
11868    */
11869   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11870
11871   ip = (ip4_header_t *) match;
11872
11873   /* These are realistically matched in practice */
11874   if (src)
11875     ip->src_address.as_u32 = src_val.as_u32;
11876
11877   if (dst)
11878     ip->dst_address.as_u32 = dst_val.as_u32;
11879
11880   if (proto)
11881     ip->protocol = proto_val;
11882
11883
11884   /* These are not, but they're included for completeness */
11885   if (version)
11886     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11887
11888   if (hdr_length)
11889     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11890
11891   if (tos)
11892     ip->tos = tos_val;
11893
11894   if (length)
11895     ip->length = clib_host_to_net_u16 (length_val);
11896
11897   if (ttl)
11898     ip->ttl = ttl_val;
11899
11900   if (checksum)
11901     ip->checksum = clib_host_to_net_u16 (checksum_val);
11902
11903   *matchp = match;
11904   return 1;
11905 }
11906
11907 uword
11908 unformat_ip6_match (unformat_input_t * input, va_list * args)
11909 {
11910   u8 **matchp = va_arg (*args, u8 **);
11911   u8 *match = 0;
11912   ip6_header_t *ip;
11913   int version = 0;
11914   u32 version_val;
11915   u8 traffic_class = 0;
11916   u32 traffic_class_val = 0;
11917   u8 flow_label = 0;
11918   u8 flow_label_val;
11919   int src = 0, dst = 0;
11920   ip6_address_t src_val, dst_val;
11921   int proto = 0;
11922   u32 proto_val;
11923   int payload_length = 0;
11924   u32 payload_length_val;
11925   int hop_limit = 0;
11926   int hop_limit_val;
11927   u32 ip_version_traffic_class_and_flow_label;
11928
11929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11930     {
11931       if (unformat (input, "version %d", &version_val))
11932         version = 1;
11933       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11934         traffic_class = 1;
11935       else if (unformat (input, "flow_label %d", &flow_label_val))
11936         flow_label = 1;
11937       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11938         src = 1;
11939       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11940         dst = 1;
11941       else if (unformat (input, "proto %d", &proto_val))
11942         proto = 1;
11943       else if (unformat (input, "payload_length %d", &payload_length_val))
11944         payload_length = 1;
11945       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11946         hop_limit = 1;
11947       else
11948         break;
11949     }
11950
11951   if (version + traffic_class + flow_label + src + dst + proto +
11952       payload_length + hop_limit == 0)
11953     return 0;
11954
11955   /*
11956    * Aligned because we use the real comparison functions
11957    */
11958   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11959
11960   ip = (ip6_header_t *) match;
11961
11962   if (src)
11963     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11964
11965   if (dst)
11966     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11967
11968   if (proto)
11969     ip->protocol = proto_val;
11970
11971   ip_version_traffic_class_and_flow_label = 0;
11972
11973   if (version)
11974     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11975
11976   if (traffic_class)
11977     ip_version_traffic_class_and_flow_label |=
11978       (traffic_class_val & 0xFF) << 20;
11979
11980   if (flow_label)
11981     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11982
11983   ip->ip_version_traffic_class_and_flow_label =
11984     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11985
11986   if (payload_length)
11987     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11988
11989   if (hop_limit)
11990     ip->hop_limit = hop_limit_val;
11991
11992   *matchp = match;
11993   return 1;
11994 }
11995
11996 uword
11997 unformat_l3_match (unformat_input_t * input, va_list * args)
11998 {
11999   u8 **matchp = va_arg (*args, u8 **);
12000
12001   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12002     {
12003       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12004         return 1;
12005       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12006         return 1;
12007       else
12008         break;
12009     }
12010   return 0;
12011 }
12012
12013 uword
12014 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12015 {
12016   u8 *tagp = va_arg (*args, u8 *);
12017   u32 tag;
12018
12019   if (unformat (input, "%d", &tag))
12020     {
12021       tagp[0] = (tag >> 8) & 0x0F;
12022       tagp[1] = tag & 0xFF;
12023       return 1;
12024     }
12025
12026   return 0;
12027 }
12028
12029 uword
12030 unformat_l2_match (unformat_input_t * input, va_list * args)
12031 {
12032   u8 **matchp = va_arg (*args, u8 **);
12033   u8 *match = 0;
12034   u8 src = 0;
12035   u8 src_val[6];
12036   u8 dst = 0;
12037   u8 dst_val[6];
12038   u8 proto = 0;
12039   u16 proto_val;
12040   u8 tag1 = 0;
12041   u8 tag1_val[2];
12042   u8 tag2 = 0;
12043   u8 tag2_val[2];
12044   int len = 14;
12045   u8 ignore_tag1 = 0;
12046   u8 ignore_tag2 = 0;
12047   u8 cos1 = 0;
12048   u8 cos2 = 0;
12049   u32 cos1_val = 0;
12050   u32 cos2_val = 0;
12051
12052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12053     {
12054       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12055         src = 1;
12056       else
12057         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12058         dst = 1;
12059       else if (unformat (input, "proto %U",
12060                          unformat_ethernet_type_host_byte_order, &proto_val))
12061         proto = 1;
12062       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12063         tag1 = 1;
12064       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12065         tag2 = 1;
12066       else if (unformat (input, "ignore-tag1"))
12067         ignore_tag1 = 1;
12068       else if (unformat (input, "ignore-tag2"))
12069         ignore_tag2 = 1;
12070       else if (unformat (input, "cos1 %d", &cos1_val))
12071         cos1 = 1;
12072       else if (unformat (input, "cos2 %d", &cos2_val))
12073         cos2 = 1;
12074       else
12075         break;
12076     }
12077   if ((src + dst + proto + tag1 + tag2 +
12078        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12079     return 0;
12080
12081   if (tag1 || ignore_tag1 || cos1)
12082     len = 18;
12083   if (tag2 || ignore_tag2 || cos2)
12084     len = 22;
12085
12086   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12087
12088   if (dst)
12089     clib_memcpy (match, dst_val, 6);
12090
12091   if (src)
12092     clib_memcpy (match + 6, src_val, 6);
12093
12094   if (tag2)
12095     {
12096       /* inner vlan tag */
12097       match[19] = tag2_val[1];
12098       match[18] = tag2_val[0];
12099       if (cos2)
12100         match[18] |= (cos2_val & 0x7) << 5;
12101       if (proto)
12102         {
12103           match[21] = proto_val & 0xff;
12104           match[20] = proto_val >> 8;
12105         }
12106       if (tag1)
12107         {
12108           match[15] = tag1_val[1];
12109           match[14] = tag1_val[0];
12110         }
12111       if (cos1)
12112         match[14] |= (cos1_val & 0x7) << 5;
12113       *matchp = match;
12114       return 1;
12115     }
12116   if (tag1)
12117     {
12118       match[15] = tag1_val[1];
12119       match[14] = tag1_val[0];
12120       if (proto)
12121         {
12122           match[17] = proto_val & 0xff;
12123           match[16] = proto_val >> 8;
12124         }
12125       if (cos1)
12126         match[14] |= (cos1_val & 0x7) << 5;
12127
12128       *matchp = match;
12129       return 1;
12130     }
12131   if (cos2)
12132     match[18] |= (cos2_val & 0x7) << 5;
12133   if (cos1)
12134     match[14] |= (cos1_val & 0x7) << 5;
12135   if (proto)
12136     {
12137       match[13] = proto_val & 0xff;
12138       match[12] = proto_val >> 8;
12139     }
12140
12141   *matchp = match;
12142   return 1;
12143 }
12144
12145 uword
12146 unformat_qos_source (unformat_input_t * input, va_list * args)
12147 {
12148   int *qs = va_arg (*args, int *);
12149
12150   if (unformat (input, "ip"))
12151     *qs = QOS_SOURCE_IP;
12152   else if (unformat (input, "mpls"))
12153     *qs = QOS_SOURCE_MPLS;
12154   else if (unformat (input, "ext"))
12155     *qs = QOS_SOURCE_EXT;
12156   else if (unformat (input, "vlan"))
12157     *qs = QOS_SOURCE_VLAN;
12158   else
12159     return 0;
12160
12161   return 1;
12162 }
12163 #endif
12164
12165 uword
12166 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12167 {
12168   u8 **matchp = va_arg (*args, u8 **);
12169   u32 skip_n_vectors = va_arg (*args, u32);
12170   u32 match_n_vectors = va_arg (*args, u32);
12171
12172   u8 *match = 0;
12173   u8 *l2 = 0;
12174   u8 *l3 = 0;
12175   u8 *l4 = 0;
12176
12177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12178     {
12179       if (unformat (input, "hex %U", unformat_hex_string, &match))
12180         ;
12181       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12182         ;
12183       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12184         ;
12185       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12186         ;
12187       else
12188         break;
12189     }
12190
12191   if (l4 && !l3)
12192     {
12193       vec_free (match);
12194       vec_free (l2);
12195       vec_free (l4);
12196       return 0;
12197     }
12198
12199   if (match || l2 || l3 || l4)
12200     {
12201       if (l2 || l3 || l4)
12202         {
12203           /* "Win a free Ethernet header in every packet" */
12204           if (l2 == 0)
12205             vec_validate_aligned (l2, 13, sizeof (u32x4));
12206           match = l2;
12207           if (vec_len (l3))
12208             {
12209               vec_append_aligned (match, l3, sizeof (u32x4));
12210               vec_free (l3);
12211             }
12212           if (vec_len (l4))
12213             {
12214               vec_append_aligned (match, l4, sizeof (u32x4));
12215               vec_free (l4);
12216             }
12217         }
12218
12219       /* Make sure the vector is big enough even if key is all 0's */
12220       vec_validate_aligned
12221         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12222          sizeof (u32x4));
12223
12224       /* Set size, include skipped vectors */
12225       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12226
12227       *matchp = match;
12228
12229       return 1;
12230     }
12231
12232   return 0;
12233 }
12234
12235 static int
12236 api_classify_add_del_session (vat_main_t * vam)
12237 {
12238   unformat_input_t *i = vam->input;
12239   vl_api_classify_add_del_session_t *mp;
12240   int is_add = 1;
12241   u32 table_index = ~0;
12242   u32 hit_next_index = ~0;
12243   u32 opaque_index = ~0;
12244   u8 *match = 0;
12245   i32 advance = 0;
12246   u32 skip_n_vectors = 0;
12247   u32 match_n_vectors = 0;
12248   u32 action = 0;
12249   u32 metadata = 0;
12250   int ret;
12251
12252   /*
12253    * Warning: you have to supply skip_n and match_n
12254    * because the API client cant simply look at the classify
12255    * table object.
12256    */
12257
12258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (i, "del"))
12261         is_add = 0;
12262       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12263                          &hit_next_index))
12264         ;
12265       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12266                          &hit_next_index))
12267         ;
12268       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12269                          &hit_next_index))
12270         ;
12271       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12272         ;
12273       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12274         ;
12275       else if (unformat (i, "opaque-index %d", &opaque_index))
12276         ;
12277       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12278         ;
12279       else if (unformat (i, "match_n %d", &match_n_vectors))
12280         ;
12281       else if (unformat (i, "match %U", api_unformat_classify_match,
12282                          &match, skip_n_vectors, match_n_vectors))
12283         ;
12284       else if (unformat (i, "advance %d", &advance))
12285         ;
12286       else if (unformat (i, "table-index %d", &table_index))
12287         ;
12288       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12289         action = 1;
12290       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12291         action = 2;
12292       else if (unformat (i, "action %d", &action))
12293         ;
12294       else if (unformat (i, "metadata %d", &metadata))
12295         ;
12296       else
12297         break;
12298     }
12299
12300   if (table_index == ~0)
12301     {
12302       errmsg ("Table index required");
12303       return -99;
12304     }
12305
12306   if (is_add && match == 0)
12307     {
12308       errmsg ("Match value required");
12309       return -99;
12310     }
12311
12312   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12313
12314   mp->is_add = is_add;
12315   mp->table_index = ntohl (table_index);
12316   mp->hit_next_index = ntohl (hit_next_index);
12317   mp->opaque_index = ntohl (opaque_index);
12318   mp->advance = ntohl (advance);
12319   mp->action = action;
12320   mp->metadata = ntohl (metadata);
12321   mp->match_len = ntohl (vec_len (match));
12322   clib_memcpy (mp->match, match, vec_len (match));
12323   vec_free (match);
12324
12325   S (mp);
12326   W (ret);
12327   return ret;
12328 }
12329
12330 static int
12331 api_classify_set_interface_ip_table (vat_main_t * vam)
12332 {
12333   unformat_input_t *i = vam->input;
12334   vl_api_classify_set_interface_ip_table_t *mp;
12335   u32 sw_if_index;
12336   int sw_if_index_set;
12337   u32 table_index = ~0;
12338   u8 is_ipv6 = 0;
12339   int ret;
12340
12341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12342     {
12343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12344         sw_if_index_set = 1;
12345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12346         sw_if_index_set = 1;
12347       else if (unformat (i, "table %d", &table_index))
12348         ;
12349       else
12350         {
12351           clib_warning ("parse error '%U'", format_unformat_error, i);
12352           return -99;
12353         }
12354     }
12355
12356   if (sw_if_index_set == 0)
12357     {
12358       errmsg ("missing interface name or sw_if_index");
12359       return -99;
12360     }
12361
12362
12363   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12364
12365   mp->sw_if_index = ntohl (sw_if_index);
12366   mp->table_index = ntohl (table_index);
12367   mp->is_ipv6 = is_ipv6;
12368
12369   S (mp);
12370   W (ret);
12371   return ret;
12372 }
12373
12374 static int
12375 api_classify_set_interface_l2_tables (vat_main_t * vam)
12376 {
12377   unformat_input_t *i = vam->input;
12378   vl_api_classify_set_interface_l2_tables_t *mp;
12379   u32 sw_if_index;
12380   int sw_if_index_set;
12381   u32 ip4_table_index = ~0;
12382   u32 ip6_table_index = ~0;
12383   u32 other_table_index = ~0;
12384   u32 is_input = 1;
12385   int ret;
12386
12387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12388     {
12389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12390         sw_if_index_set = 1;
12391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12392         sw_if_index_set = 1;
12393       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12394         ;
12395       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12396         ;
12397       else if (unformat (i, "other-table %d", &other_table_index))
12398         ;
12399       else if (unformat (i, "is-input %d", &is_input))
12400         ;
12401       else
12402         {
12403           clib_warning ("parse error '%U'", format_unformat_error, i);
12404           return -99;
12405         }
12406     }
12407
12408   if (sw_if_index_set == 0)
12409     {
12410       errmsg ("missing interface name or sw_if_index");
12411       return -99;
12412     }
12413
12414
12415   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12416
12417   mp->sw_if_index = ntohl (sw_if_index);
12418   mp->ip4_table_index = ntohl (ip4_table_index);
12419   mp->ip6_table_index = ntohl (ip6_table_index);
12420   mp->other_table_index = ntohl (other_table_index);
12421   mp->is_input = (u8) is_input;
12422
12423   S (mp);
12424   W (ret);
12425   return ret;
12426 }
12427
12428 static int
12429 api_set_ipfix_exporter (vat_main_t * vam)
12430 {
12431   unformat_input_t *i = vam->input;
12432   vl_api_set_ipfix_exporter_t *mp;
12433   ip4_address_t collector_address;
12434   u8 collector_address_set = 0;
12435   u32 collector_port = ~0;
12436   ip4_address_t src_address;
12437   u8 src_address_set = 0;
12438   u32 vrf_id = ~0;
12439   u32 path_mtu = ~0;
12440   u32 template_interval = ~0;
12441   u8 udp_checksum = 0;
12442   int ret;
12443
12444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12445     {
12446       if (unformat (i, "collector_address %U", unformat_ip4_address,
12447                     &collector_address))
12448         collector_address_set = 1;
12449       else if (unformat (i, "collector_port %d", &collector_port))
12450         ;
12451       else if (unformat (i, "src_address %U", unformat_ip4_address,
12452                          &src_address))
12453         src_address_set = 1;
12454       else if (unformat (i, "vrf_id %d", &vrf_id))
12455         ;
12456       else if (unformat (i, "path_mtu %d", &path_mtu))
12457         ;
12458       else if (unformat (i, "template_interval %d", &template_interval))
12459         ;
12460       else if (unformat (i, "udp_checksum"))
12461         udp_checksum = 1;
12462       else
12463         break;
12464     }
12465
12466   if (collector_address_set == 0)
12467     {
12468       errmsg ("collector_address required");
12469       return -99;
12470     }
12471
12472   if (src_address_set == 0)
12473     {
12474       errmsg ("src_address required");
12475       return -99;
12476     }
12477
12478   M (SET_IPFIX_EXPORTER, mp);
12479
12480   memcpy (mp->collector_address, collector_address.data,
12481           sizeof (collector_address.data));
12482   mp->collector_port = htons ((u16) collector_port);
12483   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12484   mp->vrf_id = htonl (vrf_id);
12485   mp->path_mtu = htonl (path_mtu);
12486   mp->template_interval = htonl (template_interval);
12487   mp->udp_checksum = udp_checksum;
12488
12489   S (mp);
12490   W (ret);
12491   return ret;
12492 }
12493
12494 static int
12495 api_set_ipfix_classify_stream (vat_main_t * vam)
12496 {
12497   unformat_input_t *i = vam->input;
12498   vl_api_set_ipfix_classify_stream_t *mp;
12499   u32 domain_id = 0;
12500   u32 src_port = UDP_DST_PORT_ipfix;
12501   int ret;
12502
12503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12504     {
12505       if (unformat (i, "domain %d", &domain_id))
12506         ;
12507       else if (unformat (i, "src_port %d", &src_port))
12508         ;
12509       else
12510         {
12511           errmsg ("unknown input `%U'", format_unformat_error, i);
12512           return -99;
12513         }
12514     }
12515
12516   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12517
12518   mp->domain_id = htonl (domain_id);
12519   mp->src_port = htons ((u16) src_port);
12520
12521   S (mp);
12522   W (ret);
12523   return ret;
12524 }
12525
12526 static int
12527 api_ipfix_classify_table_add_del (vat_main_t * vam)
12528 {
12529   unformat_input_t *i = vam->input;
12530   vl_api_ipfix_classify_table_add_del_t *mp;
12531   int is_add = -1;
12532   u32 classify_table_index = ~0;
12533   u8 ip_version = 0;
12534   u8 transport_protocol = 255;
12535   int ret;
12536
12537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12538     {
12539       if (unformat (i, "add"))
12540         is_add = 1;
12541       else if (unformat (i, "del"))
12542         is_add = 0;
12543       else if (unformat (i, "table %d", &classify_table_index))
12544         ;
12545       else if (unformat (i, "ip4"))
12546         ip_version = 4;
12547       else if (unformat (i, "ip6"))
12548         ip_version = 6;
12549       else if (unformat (i, "tcp"))
12550         transport_protocol = 6;
12551       else if (unformat (i, "udp"))
12552         transport_protocol = 17;
12553       else
12554         {
12555           errmsg ("unknown input `%U'", format_unformat_error, i);
12556           return -99;
12557         }
12558     }
12559
12560   if (is_add == -1)
12561     {
12562       errmsg ("expecting: add|del");
12563       return -99;
12564     }
12565   if (classify_table_index == ~0)
12566     {
12567       errmsg ("classifier table not specified");
12568       return -99;
12569     }
12570   if (ip_version == 0)
12571     {
12572       errmsg ("IP version not specified");
12573       return -99;
12574     }
12575
12576   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12577
12578   mp->is_add = is_add;
12579   mp->table_id = htonl (classify_table_index);
12580   mp->ip_version = ip_version;
12581   mp->transport_protocol = transport_protocol;
12582
12583   S (mp);
12584   W (ret);
12585   return ret;
12586 }
12587
12588 static int
12589 api_get_node_index (vat_main_t * vam)
12590 {
12591   unformat_input_t *i = vam->input;
12592   vl_api_get_node_index_t *mp;
12593   u8 *name = 0;
12594   int ret;
12595
12596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12597     {
12598       if (unformat (i, "node %s", &name))
12599         ;
12600       else
12601         break;
12602     }
12603   if (name == 0)
12604     {
12605       errmsg ("node name required");
12606       return -99;
12607     }
12608   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12609     {
12610       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12611       return -99;
12612     }
12613
12614   M (GET_NODE_INDEX, mp);
12615   clib_memcpy (mp->node_name, name, vec_len (name));
12616   vec_free (name);
12617
12618   S (mp);
12619   W (ret);
12620   return ret;
12621 }
12622
12623 static int
12624 api_get_next_index (vat_main_t * vam)
12625 {
12626   unformat_input_t *i = vam->input;
12627   vl_api_get_next_index_t *mp;
12628   u8 *node_name = 0, *next_node_name = 0;
12629   int ret;
12630
12631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12632     {
12633       if (unformat (i, "node-name %s", &node_name))
12634         ;
12635       else if (unformat (i, "next-node-name %s", &next_node_name))
12636         break;
12637     }
12638
12639   if (node_name == 0)
12640     {
12641       errmsg ("node name required");
12642       return -99;
12643     }
12644   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12645     {
12646       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12647       return -99;
12648     }
12649
12650   if (next_node_name == 0)
12651     {
12652       errmsg ("next node name required");
12653       return -99;
12654     }
12655   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12656     {
12657       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12658       return -99;
12659     }
12660
12661   M (GET_NEXT_INDEX, mp);
12662   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12663   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12664   vec_free (node_name);
12665   vec_free (next_node_name);
12666
12667   S (mp);
12668   W (ret);
12669   return ret;
12670 }
12671
12672 static int
12673 api_add_node_next (vat_main_t * vam)
12674 {
12675   unformat_input_t *i = vam->input;
12676   vl_api_add_node_next_t *mp;
12677   u8 *name = 0;
12678   u8 *next = 0;
12679   int ret;
12680
12681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12682     {
12683       if (unformat (i, "node %s", &name))
12684         ;
12685       else if (unformat (i, "next %s", &next))
12686         ;
12687       else
12688         break;
12689     }
12690   if (name == 0)
12691     {
12692       errmsg ("node name required");
12693       return -99;
12694     }
12695   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12696     {
12697       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12698       return -99;
12699     }
12700   if (next == 0)
12701     {
12702       errmsg ("next node required");
12703       return -99;
12704     }
12705   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12706     {
12707       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12708       return -99;
12709     }
12710
12711   M (ADD_NODE_NEXT, mp);
12712   clib_memcpy (mp->node_name, name, vec_len (name));
12713   clib_memcpy (mp->next_name, next, vec_len (next));
12714   vec_free (name);
12715   vec_free (next);
12716
12717   S (mp);
12718   W (ret);
12719   return ret;
12720 }
12721
12722 static int
12723 api_l2tpv3_create_tunnel (vat_main_t * vam)
12724 {
12725   unformat_input_t *i = vam->input;
12726   ip6_address_t client_address, our_address;
12727   int client_address_set = 0;
12728   int our_address_set = 0;
12729   u32 local_session_id = 0;
12730   u32 remote_session_id = 0;
12731   u64 local_cookie = 0;
12732   u64 remote_cookie = 0;
12733   u8 l2_sublayer_present = 0;
12734   vl_api_l2tpv3_create_tunnel_t *mp;
12735   int ret;
12736
12737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12738     {
12739       if (unformat (i, "client_address %U", unformat_ip6_address,
12740                     &client_address))
12741         client_address_set = 1;
12742       else if (unformat (i, "our_address %U", unformat_ip6_address,
12743                          &our_address))
12744         our_address_set = 1;
12745       else if (unformat (i, "local_session_id %d", &local_session_id))
12746         ;
12747       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12748         ;
12749       else if (unformat (i, "local_cookie %lld", &local_cookie))
12750         ;
12751       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12752         ;
12753       else if (unformat (i, "l2-sublayer-present"))
12754         l2_sublayer_present = 1;
12755       else
12756         break;
12757     }
12758
12759   if (client_address_set == 0)
12760     {
12761       errmsg ("client_address required");
12762       return -99;
12763     }
12764
12765   if (our_address_set == 0)
12766     {
12767       errmsg ("our_address required");
12768       return -99;
12769     }
12770
12771   M (L2TPV3_CREATE_TUNNEL, mp);
12772
12773   clib_memcpy (mp->client_address, client_address.as_u8,
12774                sizeof (mp->client_address));
12775
12776   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12777
12778   mp->local_session_id = ntohl (local_session_id);
12779   mp->remote_session_id = ntohl (remote_session_id);
12780   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12781   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12782   mp->l2_sublayer_present = l2_sublayer_present;
12783   mp->is_ipv6 = 1;
12784
12785   S (mp);
12786   W (ret);
12787   return ret;
12788 }
12789
12790 static int
12791 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12792 {
12793   unformat_input_t *i = vam->input;
12794   u32 sw_if_index;
12795   u8 sw_if_index_set = 0;
12796   u64 new_local_cookie = 0;
12797   u64 new_remote_cookie = 0;
12798   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12799   int ret;
12800
12801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12802     {
12803       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12804         sw_if_index_set = 1;
12805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12806         sw_if_index_set = 1;
12807       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12808         ;
12809       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12810         ;
12811       else
12812         break;
12813     }
12814
12815   if (sw_if_index_set == 0)
12816     {
12817       errmsg ("missing interface name or sw_if_index");
12818       return -99;
12819     }
12820
12821   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12822
12823   mp->sw_if_index = ntohl (sw_if_index);
12824   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12825   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12826
12827   S (mp);
12828   W (ret);
12829   return ret;
12830 }
12831
12832 static int
12833 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12834 {
12835   unformat_input_t *i = vam->input;
12836   vl_api_l2tpv3_interface_enable_disable_t *mp;
12837   u32 sw_if_index;
12838   u8 sw_if_index_set = 0;
12839   u8 enable_disable = 1;
12840   int ret;
12841
12842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12843     {
12844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12845         sw_if_index_set = 1;
12846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12847         sw_if_index_set = 1;
12848       else if (unformat (i, "enable"))
12849         enable_disable = 1;
12850       else if (unformat (i, "disable"))
12851         enable_disable = 0;
12852       else
12853         break;
12854     }
12855
12856   if (sw_if_index_set == 0)
12857     {
12858       errmsg ("missing interface name or sw_if_index");
12859       return -99;
12860     }
12861
12862   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12863
12864   mp->sw_if_index = ntohl (sw_if_index);
12865   mp->enable_disable = enable_disable;
12866
12867   S (mp);
12868   W (ret);
12869   return ret;
12870 }
12871
12872 static int
12873 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12874 {
12875   unformat_input_t *i = vam->input;
12876   vl_api_l2tpv3_set_lookup_key_t *mp;
12877   u8 key = ~0;
12878   int ret;
12879
12880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12881     {
12882       if (unformat (i, "lookup_v6_src"))
12883         key = L2T_LOOKUP_SRC_ADDRESS;
12884       else if (unformat (i, "lookup_v6_dst"))
12885         key = L2T_LOOKUP_DST_ADDRESS;
12886       else if (unformat (i, "lookup_session_id"))
12887         key = L2T_LOOKUP_SESSION_ID;
12888       else
12889         break;
12890     }
12891
12892   if (key == (u8) ~ 0)
12893     {
12894       errmsg ("l2tp session lookup key unset");
12895       return -99;
12896     }
12897
12898   M (L2TPV3_SET_LOOKUP_KEY, mp);
12899
12900   mp->key = key;
12901
12902   S (mp);
12903   W (ret);
12904   return ret;
12905 }
12906
12907 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12908   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12909 {
12910   vat_main_t *vam = &vat_main;
12911
12912   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12913          format_ip6_address, mp->our_address,
12914          format_ip6_address, mp->client_address,
12915          clib_net_to_host_u32 (mp->sw_if_index));
12916
12917   print (vam->ofp,
12918          "   local cookies %016llx %016llx remote cookie %016llx",
12919          clib_net_to_host_u64 (mp->local_cookie[0]),
12920          clib_net_to_host_u64 (mp->local_cookie[1]),
12921          clib_net_to_host_u64 (mp->remote_cookie));
12922
12923   print (vam->ofp, "   local session-id %d remote session-id %d",
12924          clib_net_to_host_u32 (mp->local_session_id),
12925          clib_net_to_host_u32 (mp->remote_session_id));
12926
12927   print (vam->ofp, "   l2 specific sublayer %s\n",
12928          mp->l2_sublayer_present ? "preset" : "absent");
12929
12930 }
12931
12932 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12933   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12934 {
12935   vat_main_t *vam = &vat_main;
12936   vat_json_node_t *node = NULL;
12937   struct in6_addr addr;
12938
12939   if (VAT_JSON_ARRAY != vam->json_tree.type)
12940     {
12941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12942       vat_json_init_array (&vam->json_tree);
12943     }
12944   node = vat_json_array_add (&vam->json_tree);
12945
12946   vat_json_init_object (node);
12947
12948   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12949   vat_json_object_add_ip6 (node, "our_address", addr);
12950   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12951   vat_json_object_add_ip6 (node, "client_address", addr);
12952
12953   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12954   vat_json_init_array (lc);
12955   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12956   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12957   vat_json_object_add_uint (node, "remote_cookie",
12958                             clib_net_to_host_u64 (mp->remote_cookie));
12959
12960   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12961   vat_json_object_add_uint (node, "local_session_id",
12962                             clib_net_to_host_u32 (mp->local_session_id));
12963   vat_json_object_add_uint (node, "remote_session_id",
12964                             clib_net_to_host_u32 (mp->remote_session_id));
12965   vat_json_object_add_string_copy (node, "l2_sublayer",
12966                                    mp->l2_sublayer_present ? (u8 *) "present"
12967                                    : (u8 *) "absent");
12968 }
12969
12970 static int
12971 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12972 {
12973   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12974   vl_api_control_ping_t *mp_ping;
12975   int ret;
12976
12977   /* Get list of l2tpv3-tunnel interfaces */
12978   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12979   S (mp);
12980
12981   /* Use a control ping for synchronization */
12982   MPING (CONTROL_PING, mp_ping);
12983   S (mp_ping);
12984
12985   W (ret);
12986   return ret;
12987 }
12988
12989
12990 static void vl_api_sw_interface_tap_details_t_handler
12991   (vl_api_sw_interface_tap_details_t * mp)
12992 {
12993   vat_main_t *vam = &vat_main;
12994
12995   print (vam->ofp, "%-16s %d",
12996          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12997 }
12998
12999 static void vl_api_sw_interface_tap_details_t_handler_json
13000   (vl_api_sw_interface_tap_details_t * mp)
13001 {
13002   vat_main_t *vam = &vat_main;
13003   vat_json_node_t *node = NULL;
13004
13005   if (VAT_JSON_ARRAY != vam->json_tree.type)
13006     {
13007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13008       vat_json_init_array (&vam->json_tree);
13009     }
13010   node = vat_json_array_add (&vam->json_tree);
13011
13012   vat_json_init_object (node);
13013   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13014   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13015 }
13016
13017 static int
13018 api_sw_interface_tap_dump (vat_main_t * vam)
13019 {
13020   vl_api_sw_interface_tap_dump_t *mp;
13021   vl_api_control_ping_t *mp_ping;
13022   int ret;
13023
13024   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13025   /* Get list of tap interfaces */
13026   M (SW_INTERFACE_TAP_DUMP, mp);
13027   S (mp);
13028
13029   /* Use a control ping for synchronization */
13030   MPING (CONTROL_PING, mp_ping);
13031   S (mp_ping);
13032
13033   W (ret);
13034   return ret;
13035 }
13036
13037 static void vl_api_sw_interface_tap_v2_details_t_handler
13038   (vl_api_sw_interface_tap_v2_details_t * mp)
13039 {
13040   vat_main_t *vam = &vat_main;
13041
13042   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13043                     mp->host_ip4_prefix_len);
13044   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13045                     mp->host_ip6_prefix_len);
13046
13047   print (vam->ofp,
13048          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13049          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13050          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13051          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13052          mp->host_bridge, ip4, ip6);
13053
13054   vec_free (ip4);
13055   vec_free (ip6);
13056 }
13057
13058 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13059   (vl_api_sw_interface_tap_v2_details_t * mp)
13060 {
13061   vat_main_t *vam = &vat_main;
13062   vat_json_node_t *node = NULL;
13063
13064   if (VAT_JSON_ARRAY != vam->json_tree.type)
13065     {
13066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13067       vat_json_init_array (&vam->json_tree);
13068     }
13069   node = vat_json_array_add (&vam->json_tree);
13070
13071   vat_json_init_object (node);
13072   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13073   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13074   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13075   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13076   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13077   vat_json_object_add_string_copy (node, "host_mac_addr",
13078                                    format (0, "%U", format_ethernet_address,
13079                                            &mp->host_mac_addr));
13080   vat_json_object_add_string_copy (node, "host_namespace",
13081                                    mp->host_namespace);
13082   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13083   vat_json_object_add_string_copy (node, "host_ip4_addr",
13084                                    format (0, "%U/%d", format_ip4_address,
13085                                            mp->host_ip4_addr,
13086                                            mp->host_ip4_prefix_len));
13087   vat_json_object_add_string_copy (node, "host_ip6_addr",
13088                                    format (0, "%U/%d", format_ip6_address,
13089                                            mp->host_ip6_addr,
13090                                            mp->host_ip6_prefix_len));
13091
13092 }
13093
13094 static int
13095 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13096 {
13097   vl_api_sw_interface_tap_v2_dump_t *mp;
13098   vl_api_control_ping_t *mp_ping;
13099   int ret;
13100
13101   print (vam->ofp,
13102          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13103          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13104          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13105          "host_ip6_addr");
13106
13107   /* Get list of tap interfaces */
13108   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13109   S (mp);
13110
13111   /* Use a control ping for synchronization */
13112   MPING (CONTROL_PING, mp_ping);
13113   S (mp_ping);
13114
13115   W (ret);
13116   return ret;
13117 }
13118
13119 static int
13120 api_vxlan_offload_rx (vat_main_t * vam)
13121 {
13122   unformat_input_t *line_input = vam->input;
13123   vl_api_vxlan_offload_rx_t *mp;
13124   u32 hw_if_index = ~0, rx_if_index = ~0;
13125   u8 is_add = 1;
13126   int ret;
13127
13128   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13129     {
13130       if (unformat (line_input, "del"))
13131         is_add = 0;
13132       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13133                          &hw_if_index))
13134         ;
13135       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13136         ;
13137       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13138                          &rx_if_index))
13139         ;
13140       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13141         ;
13142       else
13143         {
13144           errmsg ("parse error '%U'", format_unformat_error, line_input);
13145           return -99;
13146         }
13147     }
13148
13149   if (hw_if_index == ~0)
13150     {
13151       errmsg ("no hw interface");
13152       return -99;
13153     }
13154
13155   if (rx_if_index == ~0)
13156     {
13157       errmsg ("no rx tunnel");
13158       return -99;
13159     }
13160
13161   M (VXLAN_OFFLOAD_RX, mp);
13162
13163   mp->hw_if_index = ntohl (hw_if_index);
13164   mp->sw_if_index = ntohl (rx_if_index);
13165   mp->enable = is_add;
13166
13167   S (mp);
13168   W (ret);
13169   return ret;
13170 }
13171
13172 static uword unformat_vxlan_decap_next
13173   (unformat_input_t * input, va_list * args)
13174 {
13175   u32 *result = va_arg (*args, u32 *);
13176   u32 tmp;
13177
13178   if (unformat (input, "l2"))
13179     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13180   else if (unformat (input, "%d", &tmp))
13181     *result = tmp;
13182   else
13183     return 0;
13184   return 1;
13185 }
13186
13187 static int
13188 api_vxlan_add_del_tunnel (vat_main_t * vam)
13189 {
13190   unformat_input_t *line_input = vam->input;
13191   vl_api_vxlan_add_del_tunnel_t *mp;
13192   ip46_address_t src, dst;
13193   u8 is_add = 1;
13194   u8 ipv4_set = 0, ipv6_set = 0;
13195   u8 src_set = 0;
13196   u8 dst_set = 0;
13197   u8 grp_set = 0;
13198   u32 instance = ~0;
13199   u32 mcast_sw_if_index = ~0;
13200   u32 encap_vrf_id = 0;
13201   u32 decap_next_index = ~0;
13202   u32 vni = 0;
13203   int ret;
13204
13205   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13206   memset (&src, 0, sizeof src);
13207   memset (&dst, 0, sizeof dst);
13208
13209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13210     {
13211       if (unformat (line_input, "del"))
13212         is_add = 0;
13213       else if (unformat (line_input, "instance %d", &instance))
13214         ;
13215       else
13216         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13217         {
13218           ipv4_set = 1;
13219           src_set = 1;
13220         }
13221       else
13222         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13223         {
13224           ipv4_set = 1;
13225           dst_set = 1;
13226         }
13227       else
13228         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13229         {
13230           ipv6_set = 1;
13231           src_set = 1;
13232         }
13233       else
13234         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13235         {
13236           ipv6_set = 1;
13237           dst_set = 1;
13238         }
13239       else if (unformat (line_input, "group %U %U",
13240                          unformat_ip4_address, &dst.ip4,
13241                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13242         {
13243           grp_set = dst_set = 1;
13244           ipv4_set = 1;
13245         }
13246       else if (unformat (line_input, "group %U",
13247                          unformat_ip4_address, &dst.ip4))
13248         {
13249           grp_set = dst_set = 1;
13250           ipv4_set = 1;
13251         }
13252       else if (unformat (line_input, "group %U %U",
13253                          unformat_ip6_address, &dst.ip6,
13254                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13255         {
13256           grp_set = dst_set = 1;
13257           ipv6_set = 1;
13258         }
13259       else if (unformat (line_input, "group %U",
13260                          unformat_ip6_address, &dst.ip6))
13261         {
13262           grp_set = dst_set = 1;
13263           ipv6_set = 1;
13264         }
13265       else
13266         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13267         ;
13268       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13269         ;
13270       else if (unformat (line_input, "decap-next %U",
13271                          unformat_vxlan_decap_next, &decap_next_index))
13272         ;
13273       else if (unformat (line_input, "vni %d", &vni))
13274         ;
13275       else
13276         {
13277           errmsg ("parse error '%U'", format_unformat_error, line_input);
13278           return -99;
13279         }
13280     }
13281
13282   if (src_set == 0)
13283     {
13284       errmsg ("tunnel src address not specified");
13285       return -99;
13286     }
13287   if (dst_set == 0)
13288     {
13289       errmsg ("tunnel dst address not specified");
13290       return -99;
13291     }
13292
13293   if (grp_set && !ip46_address_is_multicast (&dst))
13294     {
13295       errmsg ("tunnel group address not multicast");
13296       return -99;
13297     }
13298   if (grp_set && mcast_sw_if_index == ~0)
13299     {
13300       errmsg ("tunnel nonexistent multicast device");
13301       return -99;
13302     }
13303   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13304     {
13305       errmsg ("tunnel dst address must be unicast");
13306       return -99;
13307     }
13308
13309
13310   if (ipv4_set && ipv6_set)
13311     {
13312       errmsg ("both IPv4 and IPv6 addresses specified");
13313       return -99;
13314     }
13315
13316   if ((vni == 0) || (vni >> 24))
13317     {
13318       errmsg ("vni not specified or out of range");
13319       return -99;
13320     }
13321
13322   M (VXLAN_ADD_DEL_TUNNEL, mp);
13323
13324   if (ipv6_set)
13325     {
13326       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13327       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13328     }
13329   else
13330     {
13331       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13332       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13333     }
13334
13335   mp->instance = htonl (instance);
13336   mp->encap_vrf_id = ntohl (encap_vrf_id);
13337   mp->decap_next_index = ntohl (decap_next_index);
13338   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13339   mp->vni = ntohl (vni);
13340   mp->is_add = is_add;
13341   mp->is_ipv6 = ipv6_set;
13342
13343   S (mp);
13344   W (ret);
13345   return ret;
13346 }
13347
13348 static void vl_api_vxlan_tunnel_details_t_handler
13349   (vl_api_vxlan_tunnel_details_t * mp)
13350 {
13351   vat_main_t *vam = &vat_main;
13352   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13353   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13354
13355   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13356          ntohl (mp->sw_if_index),
13357          ntohl (mp->instance),
13358          format_ip46_address, &src, IP46_TYPE_ANY,
13359          format_ip46_address, &dst, IP46_TYPE_ANY,
13360          ntohl (mp->encap_vrf_id),
13361          ntohl (mp->decap_next_index), ntohl (mp->vni),
13362          ntohl (mp->mcast_sw_if_index));
13363 }
13364
13365 static void vl_api_vxlan_tunnel_details_t_handler_json
13366   (vl_api_vxlan_tunnel_details_t * mp)
13367 {
13368   vat_main_t *vam = &vat_main;
13369   vat_json_node_t *node = NULL;
13370
13371   if (VAT_JSON_ARRAY != vam->json_tree.type)
13372     {
13373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13374       vat_json_init_array (&vam->json_tree);
13375     }
13376   node = vat_json_array_add (&vam->json_tree);
13377
13378   vat_json_init_object (node);
13379   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13380
13381   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13382
13383   if (mp->is_ipv6)
13384     {
13385       struct in6_addr ip6;
13386
13387       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13388       vat_json_object_add_ip6 (node, "src_address", ip6);
13389       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13390       vat_json_object_add_ip6 (node, "dst_address", ip6);
13391     }
13392   else
13393     {
13394       struct in_addr ip4;
13395
13396       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13397       vat_json_object_add_ip4 (node, "src_address", ip4);
13398       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13399       vat_json_object_add_ip4 (node, "dst_address", ip4);
13400     }
13401   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13402   vat_json_object_add_uint (node, "decap_next_index",
13403                             ntohl (mp->decap_next_index));
13404   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13405   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13406   vat_json_object_add_uint (node, "mcast_sw_if_index",
13407                             ntohl (mp->mcast_sw_if_index));
13408 }
13409
13410 static int
13411 api_vxlan_tunnel_dump (vat_main_t * vam)
13412 {
13413   unformat_input_t *i = vam->input;
13414   vl_api_vxlan_tunnel_dump_t *mp;
13415   vl_api_control_ping_t *mp_ping;
13416   u32 sw_if_index;
13417   u8 sw_if_index_set = 0;
13418   int ret;
13419
13420   /* Parse args required to build the message */
13421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13422     {
13423       if (unformat (i, "sw_if_index %d", &sw_if_index))
13424         sw_if_index_set = 1;
13425       else
13426         break;
13427     }
13428
13429   if (sw_if_index_set == 0)
13430     {
13431       sw_if_index = ~0;
13432     }
13433
13434   if (!vam->json_output)
13435     {
13436       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13437              "sw_if_index", "instance", "src_address", "dst_address",
13438              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13439     }
13440
13441   /* Get list of vxlan-tunnel interfaces */
13442   M (VXLAN_TUNNEL_DUMP, mp);
13443
13444   mp->sw_if_index = htonl (sw_if_index);
13445
13446   S (mp);
13447
13448   /* Use a control ping for synchronization */
13449   MPING (CONTROL_PING, mp_ping);
13450   S (mp_ping);
13451
13452   W (ret);
13453   return ret;
13454 }
13455
13456 static uword unformat_geneve_decap_next
13457   (unformat_input_t * input, va_list * args)
13458 {
13459   u32 *result = va_arg (*args, u32 *);
13460   u32 tmp;
13461
13462   if (unformat (input, "l2"))
13463     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13464   else if (unformat (input, "%d", &tmp))
13465     *result = tmp;
13466   else
13467     return 0;
13468   return 1;
13469 }
13470
13471 static int
13472 api_geneve_add_del_tunnel (vat_main_t * vam)
13473 {
13474   unformat_input_t *line_input = vam->input;
13475   vl_api_geneve_add_del_tunnel_t *mp;
13476   ip46_address_t src, dst;
13477   u8 is_add = 1;
13478   u8 ipv4_set = 0, ipv6_set = 0;
13479   u8 src_set = 0;
13480   u8 dst_set = 0;
13481   u8 grp_set = 0;
13482   u32 mcast_sw_if_index = ~0;
13483   u32 encap_vrf_id = 0;
13484   u32 decap_next_index = ~0;
13485   u32 vni = 0;
13486   int ret;
13487
13488   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13489   memset (&src, 0, sizeof src);
13490   memset (&dst, 0, sizeof dst);
13491
13492   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13493     {
13494       if (unformat (line_input, "del"))
13495         is_add = 0;
13496       else
13497         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13498         {
13499           ipv4_set = 1;
13500           src_set = 1;
13501         }
13502       else
13503         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13504         {
13505           ipv4_set = 1;
13506           dst_set = 1;
13507         }
13508       else
13509         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13510         {
13511           ipv6_set = 1;
13512           src_set = 1;
13513         }
13514       else
13515         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13516         {
13517           ipv6_set = 1;
13518           dst_set = 1;
13519         }
13520       else if (unformat (line_input, "group %U %U",
13521                          unformat_ip4_address, &dst.ip4,
13522                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13523         {
13524           grp_set = dst_set = 1;
13525           ipv4_set = 1;
13526         }
13527       else if (unformat (line_input, "group %U",
13528                          unformat_ip4_address, &dst.ip4))
13529         {
13530           grp_set = dst_set = 1;
13531           ipv4_set = 1;
13532         }
13533       else if (unformat (line_input, "group %U %U",
13534                          unformat_ip6_address, &dst.ip6,
13535                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13536         {
13537           grp_set = dst_set = 1;
13538           ipv6_set = 1;
13539         }
13540       else if (unformat (line_input, "group %U",
13541                          unformat_ip6_address, &dst.ip6))
13542         {
13543           grp_set = dst_set = 1;
13544           ipv6_set = 1;
13545         }
13546       else
13547         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13548         ;
13549       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13550         ;
13551       else if (unformat (line_input, "decap-next %U",
13552                          unformat_geneve_decap_next, &decap_next_index))
13553         ;
13554       else if (unformat (line_input, "vni %d", &vni))
13555         ;
13556       else
13557         {
13558           errmsg ("parse error '%U'", format_unformat_error, line_input);
13559           return -99;
13560         }
13561     }
13562
13563   if (src_set == 0)
13564     {
13565       errmsg ("tunnel src address not specified");
13566       return -99;
13567     }
13568   if (dst_set == 0)
13569     {
13570       errmsg ("tunnel dst address not specified");
13571       return -99;
13572     }
13573
13574   if (grp_set && !ip46_address_is_multicast (&dst))
13575     {
13576       errmsg ("tunnel group address not multicast");
13577       return -99;
13578     }
13579   if (grp_set && mcast_sw_if_index == ~0)
13580     {
13581       errmsg ("tunnel nonexistent multicast device");
13582       return -99;
13583     }
13584   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13585     {
13586       errmsg ("tunnel dst address must be unicast");
13587       return -99;
13588     }
13589
13590
13591   if (ipv4_set && ipv6_set)
13592     {
13593       errmsg ("both IPv4 and IPv6 addresses specified");
13594       return -99;
13595     }
13596
13597   if ((vni == 0) || (vni >> 24))
13598     {
13599       errmsg ("vni not specified or out of range");
13600       return -99;
13601     }
13602
13603   M (GENEVE_ADD_DEL_TUNNEL, mp);
13604
13605   if (ipv6_set)
13606     {
13607       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13608       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13609     }
13610   else
13611     {
13612       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13613       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13614     }
13615   mp->encap_vrf_id = ntohl (encap_vrf_id);
13616   mp->decap_next_index = ntohl (decap_next_index);
13617   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13618   mp->vni = ntohl (vni);
13619   mp->is_add = is_add;
13620   mp->is_ipv6 = ipv6_set;
13621
13622   S (mp);
13623   W (ret);
13624   return ret;
13625 }
13626
13627 static void vl_api_geneve_tunnel_details_t_handler
13628   (vl_api_geneve_tunnel_details_t * mp)
13629 {
13630   vat_main_t *vam = &vat_main;
13631   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13632   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13633
13634   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13635          ntohl (mp->sw_if_index),
13636          format_ip46_address, &src, IP46_TYPE_ANY,
13637          format_ip46_address, &dst, IP46_TYPE_ANY,
13638          ntohl (mp->encap_vrf_id),
13639          ntohl (mp->decap_next_index), ntohl (mp->vni),
13640          ntohl (mp->mcast_sw_if_index));
13641 }
13642
13643 static void vl_api_geneve_tunnel_details_t_handler_json
13644   (vl_api_geneve_tunnel_details_t * mp)
13645 {
13646   vat_main_t *vam = &vat_main;
13647   vat_json_node_t *node = NULL;
13648
13649   if (VAT_JSON_ARRAY != vam->json_tree.type)
13650     {
13651       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13652       vat_json_init_array (&vam->json_tree);
13653     }
13654   node = vat_json_array_add (&vam->json_tree);
13655
13656   vat_json_init_object (node);
13657   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13658   if (mp->is_ipv6)
13659     {
13660       struct in6_addr ip6;
13661
13662       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13663       vat_json_object_add_ip6 (node, "src_address", ip6);
13664       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13665       vat_json_object_add_ip6 (node, "dst_address", ip6);
13666     }
13667   else
13668     {
13669       struct in_addr ip4;
13670
13671       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13672       vat_json_object_add_ip4 (node, "src_address", ip4);
13673       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13674       vat_json_object_add_ip4 (node, "dst_address", ip4);
13675     }
13676   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13677   vat_json_object_add_uint (node, "decap_next_index",
13678                             ntohl (mp->decap_next_index));
13679   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13680   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13681   vat_json_object_add_uint (node, "mcast_sw_if_index",
13682                             ntohl (mp->mcast_sw_if_index));
13683 }
13684
13685 static int
13686 api_geneve_tunnel_dump (vat_main_t * vam)
13687 {
13688   unformat_input_t *i = vam->input;
13689   vl_api_geneve_tunnel_dump_t *mp;
13690   vl_api_control_ping_t *mp_ping;
13691   u32 sw_if_index;
13692   u8 sw_if_index_set = 0;
13693   int ret;
13694
13695   /* Parse args required to build the message */
13696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13697     {
13698       if (unformat (i, "sw_if_index %d", &sw_if_index))
13699         sw_if_index_set = 1;
13700       else
13701         break;
13702     }
13703
13704   if (sw_if_index_set == 0)
13705     {
13706       sw_if_index = ~0;
13707     }
13708
13709   if (!vam->json_output)
13710     {
13711       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13712              "sw_if_index", "local_address", "remote_address",
13713              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13714     }
13715
13716   /* Get list of geneve-tunnel interfaces */
13717   M (GENEVE_TUNNEL_DUMP, mp);
13718
13719   mp->sw_if_index = htonl (sw_if_index);
13720
13721   S (mp);
13722
13723   /* Use a control ping for synchronization */
13724   M (CONTROL_PING, mp_ping);
13725   S (mp_ping);
13726
13727   W (ret);
13728   return ret;
13729 }
13730
13731 static int
13732 api_gre_add_del_tunnel (vat_main_t * vam)
13733 {
13734   unformat_input_t *line_input = vam->input;
13735   vl_api_gre_add_del_tunnel_t *mp;
13736   ip4_address_t src4, dst4;
13737   ip6_address_t src6, dst6;
13738   u8 is_add = 1;
13739   u8 ipv4_set = 0;
13740   u8 ipv6_set = 0;
13741   u8 t_type = GRE_TUNNEL_TYPE_L3;
13742   u8 src_set = 0;
13743   u8 dst_set = 0;
13744   u32 outer_fib_id = 0;
13745   u32 session_id = 0;
13746   u32 instance = ~0;
13747   int ret;
13748
13749   memset (&src4, 0, sizeof src4);
13750   memset (&dst4, 0, sizeof dst4);
13751   memset (&src6, 0, sizeof src6);
13752   memset (&dst6, 0, sizeof dst6);
13753
13754   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13755     {
13756       if (unformat (line_input, "del"))
13757         is_add = 0;
13758       else if (unformat (line_input, "instance %d", &instance))
13759         ;
13760       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13761         {
13762           src_set = 1;
13763           ipv4_set = 1;
13764         }
13765       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13766         {
13767           dst_set = 1;
13768           ipv4_set = 1;
13769         }
13770       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13771         {
13772           src_set = 1;
13773           ipv6_set = 1;
13774         }
13775       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13776         {
13777           dst_set = 1;
13778           ipv6_set = 1;
13779         }
13780       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13781         ;
13782       else if (unformat (line_input, "teb"))
13783         t_type = GRE_TUNNEL_TYPE_TEB;
13784       else if (unformat (line_input, "erspan %d", &session_id))
13785         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13786       else
13787         {
13788           errmsg ("parse error '%U'", format_unformat_error, line_input);
13789           return -99;
13790         }
13791     }
13792
13793   if (src_set == 0)
13794     {
13795       errmsg ("tunnel src address not specified");
13796       return -99;
13797     }
13798   if (dst_set == 0)
13799     {
13800       errmsg ("tunnel dst address not specified");
13801       return -99;
13802     }
13803   if (ipv4_set && ipv6_set)
13804     {
13805       errmsg ("both IPv4 and IPv6 addresses specified");
13806       return -99;
13807     }
13808
13809
13810   M (GRE_ADD_DEL_TUNNEL, mp);
13811
13812   if (ipv4_set)
13813     {
13814       clib_memcpy (&mp->src_address, &src4, 4);
13815       clib_memcpy (&mp->dst_address, &dst4, 4);
13816     }
13817   else
13818     {
13819       clib_memcpy (&mp->src_address, &src6, 16);
13820       clib_memcpy (&mp->dst_address, &dst6, 16);
13821     }
13822   mp->instance = htonl (instance);
13823   mp->outer_fib_id = htonl (outer_fib_id);
13824   mp->is_add = is_add;
13825   mp->session_id = htons ((u16) session_id);
13826   mp->tunnel_type = t_type;
13827   mp->is_ipv6 = ipv6_set;
13828
13829   S (mp);
13830   W (ret);
13831   return ret;
13832 }
13833
13834 static void vl_api_gre_tunnel_details_t_handler
13835   (vl_api_gre_tunnel_details_t * mp)
13836 {
13837   vat_main_t *vam = &vat_main;
13838   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13839   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13840
13841   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13842          ntohl (mp->sw_if_index),
13843          ntohl (mp->instance),
13844          format_ip46_address, &src, IP46_TYPE_ANY,
13845          format_ip46_address, &dst, IP46_TYPE_ANY,
13846          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13847 }
13848
13849 static void vl_api_gre_tunnel_details_t_handler_json
13850   (vl_api_gre_tunnel_details_t * mp)
13851 {
13852   vat_main_t *vam = &vat_main;
13853   vat_json_node_t *node = NULL;
13854   struct in_addr ip4;
13855   struct in6_addr ip6;
13856
13857   if (VAT_JSON_ARRAY != vam->json_tree.type)
13858     {
13859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13860       vat_json_init_array (&vam->json_tree);
13861     }
13862   node = vat_json_array_add (&vam->json_tree);
13863
13864   vat_json_init_object (node);
13865   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13866   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13867   if (!mp->is_ipv6)
13868     {
13869       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13870       vat_json_object_add_ip4 (node, "src_address", ip4);
13871       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13872       vat_json_object_add_ip4 (node, "dst_address", ip4);
13873     }
13874   else
13875     {
13876       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13877       vat_json_object_add_ip6 (node, "src_address", ip6);
13878       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13879       vat_json_object_add_ip6 (node, "dst_address", ip6);
13880     }
13881   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13882   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13883   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13884   vat_json_object_add_uint (node, "session_id", mp->session_id);
13885 }
13886
13887 static int
13888 api_gre_tunnel_dump (vat_main_t * vam)
13889 {
13890   unformat_input_t *i = vam->input;
13891   vl_api_gre_tunnel_dump_t *mp;
13892   vl_api_control_ping_t *mp_ping;
13893   u32 sw_if_index;
13894   u8 sw_if_index_set = 0;
13895   int ret;
13896
13897   /* Parse args required to build the message */
13898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13899     {
13900       if (unformat (i, "sw_if_index %d", &sw_if_index))
13901         sw_if_index_set = 1;
13902       else
13903         break;
13904     }
13905
13906   if (sw_if_index_set == 0)
13907     {
13908       sw_if_index = ~0;
13909     }
13910
13911   if (!vam->json_output)
13912     {
13913       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13914              "sw_if_index", "instance", "src_address", "dst_address",
13915              "tunnel_type", "outer_fib_id", "session_id");
13916     }
13917
13918   /* Get list of gre-tunnel interfaces */
13919   M (GRE_TUNNEL_DUMP, mp);
13920
13921   mp->sw_if_index = htonl (sw_if_index);
13922
13923   S (mp);
13924
13925   /* Use a control ping for synchronization */
13926   MPING (CONTROL_PING, mp_ping);
13927   S (mp_ping);
13928
13929   W (ret);
13930   return ret;
13931 }
13932
13933 static int
13934 api_l2_fib_clear_table (vat_main_t * vam)
13935 {
13936 //  unformat_input_t * i = vam->input;
13937   vl_api_l2_fib_clear_table_t *mp;
13938   int ret;
13939
13940   M (L2_FIB_CLEAR_TABLE, mp);
13941
13942   S (mp);
13943   W (ret);
13944   return ret;
13945 }
13946
13947 static int
13948 api_l2_interface_efp_filter (vat_main_t * vam)
13949 {
13950   unformat_input_t *i = vam->input;
13951   vl_api_l2_interface_efp_filter_t *mp;
13952   u32 sw_if_index;
13953   u8 enable = 1;
13954   u8 sw_if_index_set = 0;
13955   int ret;
13956
13957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13958     {
13959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13960         sw_if_index_set = 1;
13961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13962         sw_if_index_set = 1;
13963       else if (unformat (i, "enable"))
13964         enable = 1;
13965       else if (unformat (i, "disable"))
13966         enable = 0;
13967       else
13968         {
13969           clib_warning ("parse error '%U'", format_unformat_error, i);
13970           return -99;
13971         }
13972     }
13973
13974   if (sw_if_index_set == 0)
13975     {
13976       errmsg ("missing sw_if_index");
13977       return -99;
13978     }
13979
13980   M (L2_INTERFACE_EFP_FILTER, mp);
13981
13982   mp->sw_if_index = ntohl (sw_if_index);
13983   mp->enable_disable = enable;
13984
13985   S (mp);
13986   W (ret);
13987   return ret;
13988 }
13989
13990 #define foreach_vtr_op                          \
13991 _("disable",  L2_VTR_DISABLED)                  \
13992 _("push-1",  L2_VTR_PUSH_1)                     \
13993 _("push-2",  L2_VTR_PUSH_2)                     \
13994 _("pop-1",  L2_VTR_POP_1)                       \
13995 _("pop-2",  L2_VTR_POP_2)                       \
13996 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13997 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13998 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13999 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14000
14001 static int
14002 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14003 {
14004   unformat_input_t *i = vam->input;
14005   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14006   u32 sw_if_index;
14007   u8 sw_if_index_set = 0;
14008   u8 vtr_op_set = 0;
14009   u32 vtr_op = 0;
14010   u32 push_dot1q = 1;
14011   u32 tag1 = ~0;
14012   u32 tag2 = ~0;
14013   int ret;
14014
14015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14016     {
14017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14018         sw_if_index_set = 1;
14019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14020         sw_if_index_set = 1;
14021       else if (unformat (i, "vtr_op %d", &vtr_op))
14022         vtr_op_set = 1;
14023 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14024       foreach_vtr_op
14025 #undef _
14026         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14027         ;
14028       else if (unformat (i, "tag1 %d", &tag1))
14029         ;
14030       else if (unformat (i, "tag2 %d", &tag2))
14031         ;
14032       else
14033         {
14034           clib_warning ("parse error '%U'", format_unformat_error, i);
14035           return -99;
14036         }
14037     }
14038
14039   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14040     {
14041       errmsg ("missing vtr operation or sw_if_index");
14042       return -99;
14043     }
14044
14045   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14046   mp->sw_if_index = ntohl (sw_if_index);
14047   mp->vtr_op = ntohl (vtr_op);
14048   mp->push_dot1q = ntohl (push_dot1q);
14049   mp->tag1 = ntohl (tag1);
14050   mp->tag2 = ntohl (tag2);
14051
14052   S (mp);
14053   W (ret);
14054   return ret;
14055 }
14056
14057 static int
14058 api_create_vhost_user_if (vat_main_t * vam)
14059 {
14060   unformat_input_t *i = vam->input;
14061   vl_api_create_vhost_user_if_t *mp;
14062   u8 *file_name;
14063   u8 is_server = 0;
14064   u8 file_name_set = 0;
14065   u32 custom_dev_instance = ~0;
14066   u8 hwaddr[6];
14067   u8 use_custom_mac = 0;
14068   u8 disable_mrg_rxbuf = 0;
14069   u8 disable_indirect_desc = 0;
14070   u8 *tag = 0;
14071   int ret;
14072
14073   /* Shut up coverity */
14074   memset (hwaddr, 0, sizeof (hwaddr));
14075
14076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14077     {
14078       if (unformat (i, "socket %s", &file_name))
14079         {
14080           file_name_set = 1;
14081         }
14082       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14083         ;
14084       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14085         use_custom_mac = 1;
14086       else if (unformat (i, "server"))
14087         is_server = 1;
14088       else if (unformat (i, "disable_mrg_rxbuf"))
14089         disable_mrg_rxbuf = 1;
14090       else if (unformat (i, "disable_indirect_desc"))
14091         disable_indirect_desc = 1;
14092       else if (unformat (i, "tag %s", &tag))
14093         ;
14094       else
14095         break;
14096     }
14097
14098   if (file_name_set == 0)
14099     {
14100       errmsg ("missing socket file name");
14101       return -99;
14102     }
14103
14104   if (vec_len (file_name) > 255)
14105     {
14106       errmsg ("socket file name too long");
14107       return -99;
14108     }
14109   vec_add1 (file_name, 0);
14110
14111   M (CREATE_VHOST_USER_IF, mp);
14112
14113   mp->is_server = is_server;
14114   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14115   mp->disable_indirect_desc = disable_indirect_desc;
14116   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14117   vec_free (file_name);
14118   if (custom_dev_instance != ~0)
14119     {
14120       mp->renumber = 1;
14121       mp->custom_dev_instance = ntohl (custom_dev_instance);
14122     }
14123
14124   mp->use_custom_mac = use_custom_mac;
14125   clib_memcpy (mp->mac_address, hwaddr, 6);
14126   if (tag)
14127     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14128   vec_free (tag);
14129
14130   S (mp);
14131   W (ret);
14132   return ret;
14133 }
14134
14135 static int
14136 api_modify_vhost_user_if (vat_main_t * vam)
14137 {
14138   unformat_input_t *i = vam->input;
14139   vl_api_modify_vhost_user_if_t *mp;
14140   u8 *file_name;
14141   u8 is_server = 0;
14142   u8 file_name_set = 0;
14143   u32 custom_dev_instance = ~0;
14144   u8 sw_if_index_set = 0;
14145   u32 sw_if_index = (u32) ~ 0;
14146   int ret;
14147
14148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14149     {
14150       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14151         sw_if_index_set = 1;
14152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14153         sw_if_index_set = 1;
14154       else if (unformat (i, "socket %s", &file_name))
14155         {
14156           file_name_set = 1;
14157         }
14158       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14159         ;
14160       else if (unformat (i, "server"))
14161         is_server = 1;
14162       else
14163         break;
14164     }
14165
14166   if (sw_if_index_set == 0)
14167     {
14168       errmsg ("missing sw_if_index or interface name");
14169       return -99;
14170     }
14171
14172   if (file_name_set == 0)
14173     {
14174       errmsg ("missing socket file name");
14175       return -99;
14176     }
14177
14178   if (vec_len (file_name) > 255)
14179     {
14180       errmsg ("socket file name too long");
14181       return -99;
14182     }
14183   vec_add1 (file_name, 0);
14184
14185   M (MODIFY_VHOST_USER_IF, mp);
14186
14187   mp->sw_if_index = ntohl (sw_if_index);
14188   mp->is_server = is_server;
14189   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14190   vec_free (file_name);
14191   if (custom_dev_instance != ~0)
14192     {
14193       mp->renumber = 1;
14194       mp->custom_dev_instance = ntohl (custom_dev_instance);
14195     }
14196
14197   S (mp);
14198   W (ret);
14199   return ret;
14200 }
14201
14202 static int
14203 api_delete_vhost_user_if (vat_main_t * vam)
14204 {
14205   unformat_input_t *i = vam->input;
14206   vl_api_delete_vhost_user_if_t *mp;
14207   u32 sw_if_index = ~0;
14208   u8 sw_if_index_set = 0;
14209   int ret;
14210
14211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14212     {
14213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14214         sw_if_index_set = 1;
14215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14216         sw_if_index_set = 1;
14217       else
14218         break;
14219     }
14220
14221   if (sw_if_index_set == 0)
14222     {
14223       errmsg ("missing sw_if_index or interface name");
14224       return -99;
14225     }
14226
14227
14228   M (DELETE_VHOST_USER_IF, mp);
14229
14230   mp->sw_if_index = ntohl (sw_if_index);
14231
14232   S (mp);
14233   W (ret);
14234   return ret;
14235 }
14236
14237 static void vl_api_sw_interface_vhost_user_details_t_handler
14238   (vl_api_sw_interface_vhost_user_details_t * mp)
14239 {
14240   vat_main_t *vam = &vat_main;
14241
14242   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14243          (char *) mp->interface_name,
14244          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14245          clib_net_to_host_u64 (mp->features), mp->is_server,
14246          ntohl (mp->num_regions), (char *) mp->sock_filename);
14247   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14248 }
14249
14250 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14251   (vl_api_sw_interface_vhost_user_details_t * mp)
14252 {
14253   vat_main_t *vam = &vat_main;
14254   vat_json_node_t *node = NULL;
14255
14256   if (VAT_JSON_ARRAY != vam->json_tree.type)
14257     {
14258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14259       vat_json_init_array (&vam->json_tree);
14260     }
14261   node = vat_json_array_add (&vam->json_tree);
14262
14263   vat_json_init_object (node);
14264   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14265   vat_json_object_add_string_copy (node, "interface_name",
14266                                    mp->interface_name);
14267   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14268                             ntohl (mp->virtio_net_hdr_sz));
14269   vat_json_object_add_uint (node, "features",
14270                             clib_net_to_host_u64 (mp->features));
14271   vat_json_object_add_uint (node, "is_server", mp->is_server);
14272   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14273   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14274   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14275 }
14276
14277 static int
14278 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14279 {
14280   vl_api_sw_interface_vhost_user_dump_t *mp;
14281   vl_api_control_ping_t *mp_ping;
14282   int ret;
14283   print (vam->ofp,
14284          "Interface name            idx hdr_sz features server regions filename");
14285
14286   /* Get list of vhost-user interfaces */
14287   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14288   S (mp);
14289
14290   /* Use a control ping for synchronization */
14291   MPING (CONTROL_PING, mp_ping);
14292   S (mp_ping);
14293
14294   W (ret);
14295   return ret;
14296 }
14297
14298 static int
14299 api_show_version (vat_main_t * vam)
14300 {
14301   vl_api_show_version_t *mp;
14302   int ret;
14303
14304   M (SHOW_VERSION, mp);
14305
14306   S (mp);
14307   W (ret);
14308   return ret;
14309 }
14310
14311
14312 static int
14313 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14314 {
14315   unformat_input_t *line_input = vam->input;
14316   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14317   ip4_address_t local4, remote4;
14318   ip6_address_t local6, remote6;
14319   u8 is_add = 1;
14320   u8 ipv4_set = 0, ipv6_set = 0;
14321   u8 local_set = 0;
14322   u8 remote_set = 0;
14323   u8 grp_set = 0;
14324   u32 mcast_sw_if_index = ~0;
14325   u32 encap_vrf_id = 0;
14326   u32 decap_vrf_id = 0;
14327   u8 protocol = ~0;
14328   u32 vni;
14329   u8 vni_set = 0;
14330   int ret;
14331
14332   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14333   memset (&local4, 0, sizeof local4);
14334   memset (&remote4, 0, sizeof remote4);
14335   memset (&local6, 0, sizeof local6);
14336   memset (&remote6, 0, sizeof remote6);
14337
14338   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14339     {
14340       if (unformat (line_input, "del"))
14341         is_add = 0;
14342       else if (unformat (line_input, "local %U",
14343                          unformat_ip4_address, &local4))
14344         {
14345           local_set = 1;
14346           ipv4_set = 1;
14347         }
14348       else if (unformat (line_input, "remote %U",
14349                          unformat_ip4_address, &remote4))
14350         {
14351           remote_set = 1;
14352           ipv4_set = 1;
14353         }
14354       else if (unformat (line_input, "local %U",
14355                          unformat_ip6_address, &local6))
14356         {
14357           local_set = 1;
14358           ipv6_set = 1;
14359         }
14360       else if (unformat (line_input, "remote %U",
14361                          unformat_ip6_address, &remote6))
14362         {
14363           remote_set = 1;
14364           ipv6_set = 1;
14365         }
14366       else if (unformat (line_input, "group %U %U",
14367                          unformat_ip4_address, &remote4,
14368                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14369         {
14370           grp_set = remote_set = 1;
14371           ipv4_set = 1;
14372         }
14373       else if (unformat (line_input, "group %U",
14374                          unformat_ip4_address, &remote4))
14375         {
14376           grp_set = remote_set = 1;
14377           ipv4_set = 1;
14378         }
14379       else if (unformat (line_input, "group %U %U",
14380                          unformat_ip6_address, &remote6,
14381                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14382         {
14383           grp_set = remote_set = 1;
14384           ipv6_set = 1;
14385         }
14386       else if (unformat (line_input, "group %U",
14387                          unformat_ip6_address, &remote6))
14388         {
14389           grp_set = remote_set = 1;
14390           ipv6_set = 1;
14391         }
14392       else
14393         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14394         ;
14395       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14396         ;
14397       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14398         ;
14399       else if (unformat (line_input, "vni %d", &vni))
14400         vni_set = 1;
14401       else if (unformat (line_input, "next-ip4"))
14402         protocol = 1;
14403       else if (unformat (line_input, "next-ip6"))
14404         protocol = 2;
14405       else if (unformat (line_input, "next-ethernet"))
14406         protocol = 3;
14407       else if (unformat (line_input, "next-nsh"))
14408         protocol = 4;
14409       else
14410         {
14411           errmsg ("parse error '%U'", format_unformat_error, line_input);
14412           return -99;
14413         }
14414     }
14415
14416   if (local_set == 0)
14417     {
14418       errmsg ("tunnel local address not specified");
14419       return -99;
14420     }
14421   if (remote_set == 0)
14422     {
14423       errmsg ("tunnel remote address not specified");
14424       return -99;
14425     }
14426   if (grp_set && mcast_sw_if_index == ~0)
14427     {
14428       errmsg ("tunnel nonexistent multicast device");
14429       return -99;
14430     }
14431   if (ipv4_set && ipv6_set)
14432     {
14433       errmsg ("both IPv4 and IPv6 addresses specified");
14434       return -99;
14435     }
14436
14437   if (vni_set == 0)
14438     {
14439       errmsg ("vni not specified");
14440       return -99;
14441     }
14442
14443   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14444
14445
14446   if (ipv6_set)
14447     {
14448       clib_memcpy (&mp->local, &local6, sizeof (local6));
14449       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14450     }
14451   else
14452     {
14453       clib_memcpy (&mp->local, &local4, sizeof (local4));
14454       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14455     }
14456
14457   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14458   mp->encap_vrf_id = ntohl (encap_vrf_id);
14459   mp->decap_vrf_id = ntohl (decap_vrf_id);
14460   mp->protocol = protocol;
14461   mp->vni = ntohl (vni);
14462   mp->is_add = is_add;
14463   mp->is_ipv6 = ipv6_set;
14464
14465   S (mp);
14466   W (ret);
14467   return ret;
14468 }
14469
14470 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14471   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14472 {
14473   vat_main_t *vam = &vat_main;
14474   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14475   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14476
14477   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14478          ntohl (mp->sw_if_index),
14479          format_ip46_address, &local, IP46_TYPE_ANY,
14480          format_ip46_address, &remote, IP46_TYPE_ANY,
14481          ntohl (mp->vni), mp->protocol,
14482          ntohl (mp->mcast_sw_if_index),
14483          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14484 }
14485
14486
14487 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14488   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14489 {
14490   vat_main_t *vam = &vat_main;
14491   vat_json_node_t *node = NULL;
14492   struct in_addr ip4;
14493   struct in6_addr ip6;
14494
14495   if (VAT_JSON_ARRAY != vam->json_tree.type)
14496     {
14497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14498       vat_json_init_array (&vam->json_tree);
14499     }
14500   node = vat_json_array_add (&vam->json_tree);
14501
14502   vat_json_init_object (node);
14503   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14504   if (mp->is_ipv6)
14505     {
14506       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14507       vat_json_object_add_ip6 (node, "local", ip6);
14508       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14509       vat_json_object_add_ip6 (node, "remote", ip6);
14510     }
14511   else
14512     {
14513       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14514       vat_json_object_add_ip4 (node, "local", ip4);
14515       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14516       vat_json_object_add_ip4 (node, "remote", ip4);
14517     }
14518   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14519   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14520   vat_json_object_add_uint (node, "mcast_sw_if_index",
14521                             ntohl (mp->mcast_sw_if_index));
14522   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14523   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14524   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14525 }
14526
14527 static int
14528 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14529 {
14530   unformat_input_t *i = vam->input;
14531   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14532   vl_api_control_ping_t *mp_ping;
14533   u32 sw_if_index;
14534   u8 sw_if_index_set = 0;
14535   int ret;
14536
14537   /* Parse args required to build the message */
14538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14539     {
14540       if (unformat (i, "sw_if_index %d", &sw_if_index))
14541         sw_if_index_set = 1;
14542       else
14543         break;
14544     }
14545
14546   if (sw_if_index_set == 0)
14547     {
14548       sw_if_index = ~0;
14549     }
14550
14551   if (!vam->json_output)
14552     {
14553       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14554              "sw_if_index", "local", "remote", "vni",
14555              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14556     }
14557
14558   /* Get list of vxlan-tunnel interfaces */
14559   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14560
14561   mp->sw_if_index = htonl (sw_if_index);
14562
14563   S (mp);
14564
14565   /* Use a control ping for synchronization */
14566   MPING (CONTROL_PING, mp_ping);
14567   S (mp_ping);
14568
14569   W (ret);
14570   return ret;
14571 }
14572
14573 static void vl_api_l2_fib_table_details_t_handler
14574   (vl_api_l2_fib_table_details_t * mp)
14575 {
14576   vat_main_t *vam = &vat_main;
14577
14578   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14579          "       %d       %d     %d",
14580          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14581          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14582          mp->bvi_mac);
14583 }
14584
14585 static void vl_api_l2_fib_table_details_t_handler_json
14586   (vl_api_l2_fib_table_details_t * mp)
14587 {
14588   vat_main_t *vam = &vat_main;
14589   vat_json_node_t *node = NULL;
14590
14591   if (VAT_JSON_ARRAY != vam->json_tree.type)
14592     {
14593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14594       vat_json_init_array (&vam->json_tree);
14595     }
14596   node = vat_json_array_add (&vam->json_tree);
14597
14598   vat_json_init_object (node);
14599   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14600   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14601   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14602   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14603   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14604   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14605 }
14606
14607 static int
14608 api_l2_fib_table_dump (vat_main_t * vam)
14609 {
14610   unformat_input_t *i = vam->input;
14611   vl_api_l2_fib_table_dump_t *mp;
14612   vl_api_control_ping_t *mp_ping;
14613   u32 bd_id;
14614   u8 bd_id_set = 0;
14615   int ret;
14616
14617   /* Parse args required to build the message */
14618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14619     {
14620       if (unformat (i, "bd_id %d", &bd_id))
14621         bd_id_set = 1;
14622       else
14623         break;
14624     }
14625
14626   if (bd_id_set == 0)
14627     {
14628       errmsg ("missing bridge domain");
14629       return -99;
14630     }
14631
14632   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14633
14634   /* Get list of l2 fib entries */
14635   M (L2_FIB_TABLE_DUMP, mp);
14636
14637   mp->bd_id = ntohl (bd_id);
14638   S (mp);
14639
14640   /* Use a control ping for synchronization */
14641   MPING (CONTROL_PING, mp_ping);
14642   S (mp_ping);
14643
14644   W (ret);
14645   return ret;
14646 }
14647
14648
14649 static int
14650 api_interface_name_renumber (vat_main_t * vam)
14651 {
14652   unformat_input_t *line_input = vam->input;
14653   vl_api_interface_name_renumber_t *mp;
14654   u32 sw_if_index = ~0;
14655   u32 new_show_dev_instance = ~0;
14656   int ret;
14657
14658   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14659     {
14660       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14661                     &sw_if_index))
14662         ;
14663       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14664         ;
14665       else if (unformat (line_input, "new_show_dev_instance %d",
14666                          &new_show_dev_instance))
14667         ;
14668       else
14669         break;
14670     }
14671
14672   if (sw_if_index == ~0)
14673     {
14674       errmsg ("missing interface name or sw_if_index");
14675       return -99;
14676     }
14677
14678   if (new_show_dev_instance == ~0)
14679     {
14680       errmsg ("missing new_show_dev_instance");
14681       return -99;
14682     }
14683
14684   M (INTERFACE_NAME_RENUMBER, mp);
14685
14686   mp->sw_if_index = ntohl (sw_if_index);
14687   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14688
14689   S (mp);
14690   W (ret);
14691   return ret;
14692 }
14693
14694 static int
14695 api_ip_probe_neighbor (vat_main_t * vam)
14696 {
14697   unformat_input_t *i = vam->input;
14698   vl_api_ip_probe_neighbor_t *mp;
14699   u8 int_set = 0;
14700   u8 adr_set = 0;
14701   u8 is_ipv6 = 0;
14702   u8 dst_adr[16];
14703   u32 sw_if_index;
14704   int ret;
14705
14706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14707     {
14708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14709         int_set = 1;
14710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14711         int_set = 1;
14712       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14713         adr_set = 1;
14714       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14715         {
14716           adr_set = 1;
14717           is_ipv6 = 1;
14718         }
14719       else
14720         break;
14721     }
14722
14723   if (int_set == 0)
14724     {
14725       errmsg ("missing interface");
14726       return -99;
14727     }
14728
14729   if (adr_set == 0)
14730     {
14731       errmsg ("missing addresses");
14732       return -99;
14733     }
14734
14735   M (IP_PROBE_NEIGHBOR, mp);
14736
14737   mp->sw_if_index = ntohl (sw_if_index);
14738   mp->is_ipv6 = is_ipv6;
14739   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14740
14741   S (mp);
14742   W (ret);
14743   return ret;
14744 }
14745
14746 static int
14747 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14748 {
14749   unformat_input_t *i = vam->input;
14750   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14751   u8 mode = IP_SCAN_V46_NEIGHBORS;
14752   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14753   int ret;
14754
14755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14756     {
14757       if (unformat (i, "ip4"))
14758         mode = IP_SCAN_V4_NEIGHBORS;
14759       else if (unformat (i, "ip6"))
14760         mode = IP_SCAN_V6_NEIGHBORS;
14761       if (unformat (i, "both"))
14762         mode = IP_SCAN_V46_NEIGHBORS;
14763       else if (unformat (i, "disable"))
14764         mode = IP_SCAN_DISABLED;
14765       else if (unformat (i, "interval %d", &interval))
14766         ;
14767       else if (unformat (i, "max-time %d", &time))
14768         ;
14769       else if (unformat (i, "max-update %d", &update))
14770         ;
14771       else if (unformat (i, "delay %d", &delay))
14772         ;
14773       else if (unformat (i, "stale %d", &stale))
14774         ;
14775       else
14776         break;
14777     }
14778
14779   if (interval > 255)
14780     {
14781       errmsg ("interval cannot exceed 255 minutes.");
14782       return -99;
14783     }
14784   if (time > 255)
14785     {
14786       errmsg ("max-time cannot exceed 255 usec.");
14787       return -99;
14788     }
14789   if (update > 255)
14790     {
14791       errmsg ("max-update cannot exceed 255.");
14792       return -99;
14793     }
14794   if (delay > 255)
14795     {
14796       errmsg ("delay cannot exceed 255 msec.");
14797       return -99;
14798     }
14799   if (stale > 255)
14800     {
14801       errmsg ("stale cannot exceed 255 minutes.");
14802       return -99;
14803     }
14804
14805   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14806   mp->mode = mode;
14807   mp->scan_interval = interval;
14808   mp->max_proc_time = time;
14809   mp->max_update = update;
14810   mp->scan_int_delay = delay;
14811   mp->stale_threshold = stale;
14812
14813   S (mp);
14814   W (ret);
14815   return ret;
14816 }
14817
14818 static int
14819 api_want_ip4_arp_events (vat_main_t * vam)
14820 {
14821   unformat_input_t *line_input = vam->input;
14822   vl_api_want_ip4_arp_events_t *mp;
14823   ip4_address_t address;
14824   int address_set = 0;
14825   u32 enable_disable = 1;
14826   int ret;
14827
14828   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14829     {
14830       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14831         address_set = 1;
14832       else if (unformat (line_input, "del"))
14833         enable_disable = 0;
14834       else
14835         break;
14836     }
14837
14838   if (address_set == 0)
14839     {
14840       errmsg ("missing addresses");
14841       return -99;
14842     }
14843
14844   M (WANT_IP4_ARP_EVENTS, mp);
14845   mp->enable_disable = enable_disable;
14846   mp->pid = htonl (getpid ());
14847   mp->address = address.as_u32;
14848
14849   S (mp);
14850   W (ret);
14851   return ret;
14852 }
14853
14854 static int
14855 api_want_ip6_nd_events (vat_main_t * vam)
14856 {
14857   unformat_input_t *line_input = vam->input;
14858   vl_api_want_ip6_nd_events_t *mp;
14859   ip6_address_t address;
14860   int address_set = 0;
14861   u32 enable_disable = 1;
14862   int ret;
14863
14864   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14865     {
14866       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14867         address_set = 1;
14868       else if (unformat (line_input, "del"))
14869         enable_disable = 0;
14870       else
14871         break;
14872     }
14873
14874   if (address_set == 0)
14875     {
14876       errmsg ("missing addresses");
14877       return -99;
14878     }
14879
14880   M (WANT_IP6_ND_EVENTS, mp);
14881   mp->enable_disable = enable_disable;
14882   mp->pid = htonl (getpid ());
14883   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14884
14885   S (mp);
14886   W (ret);
14887   return ret;
14888 }
14889
14890 static int
14891 api_want_l2_macs_events (vat_main_t * vam)
14892 {
14893   unformat_input_t *line_input = vam->input;
14894   vl_api_want_l2_macs_events_t *mp;
14895   u8 enable_disable = 1;
14896   u32 scan_delay = 0;
14897   u32 max_macs_in_event = 0;
14898   u32 learn_limit = 0;
14899   int ret;
14900
14901   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14902     {
14903       if (unformat (line_input, "learn-limit %d", &learn_limit))
14904         ;
14905       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14906         ;
14907       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14908         ;
14909       else if (unformat (line_input, "disable"))
14910         enable_disable = 0;
14911       else
14912         break;
14913     }
14914
14915   M (WANT_L2_MACS_EVENTS, mp);
14916   mp->enable_disable = enable_disable;
14917   mp->pid = htonl (getpid ());
14918   mp->learn_limit = htonl (learn_limit);
14919   mp->scan_delay = (u8) scan_delay;
14920   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14921   S (mp);
14922   W (ret);
14923   return ret;
14924 }
14925
14926 static int
14927 api_input_acl_set_interface (vat_main_t * vam)
14928 {
14929   unformat_input_t *i = vam->input;
14930   vl_api_input_acl_set_interface_t *mp;
14931   u32 sw_if_index;
14932   int sw_if_index_set;
14933   u32 ip4_table_index = ~0;
14934   u32 ip6_table_index = ~0;
14935   u32 l2_table_index = ~0;
14936   u8 is_add = 1;
14937   int ret;
14938
14939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14940     {
14941       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14942         sw_if_index_set = 1;
14943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14944         sw_if_index_set = 1;
14945       else if (unformat (i, "del"))
14946         is_add = 0;
14947       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14948         ;
14949       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14950         ;
14951       else if (unformat (i, "l2-table %d", &l2_table_index))
14952         ;
14953       else
14954         {
14955           clib_warning ("parse error '%U'", format_unformat_error, i);
14956           return -99;
14957         }
14958     }
14959
14960   if (sw_if_index_set == 0)
14961     {
14962       errmsg ("missing interface name or sw_if_index");
14963       return -99;
14964     }
14965
14966   M (INPUT_ACL_SET_INTERFACE, mp);
14967
14968   mp->sw_if_index = ntohl (sw_if_index);
14969   mp->ip4_table_index = ntohl (ip4_table_index);
14970   mp->ip6_table_index = ntohl (ip6_table_index);
14971   mp->l2_table_index = ntohl (l2_table_index);
14972   mp->is_add = is_add;
14973
14974   S (mp);
14975   W (ret);
14976   return ret;
14977 }
14978
14979 static int
14980 api_output_acl_set_interface (vat_main_t * vam)
14981 {
14982   unformat_input_t *i = vam->input;
14983   vl_api_output_acl_set_interface_t *mp;
14984   u32 sw_if_index;
14985   int sw_if_index_set;
14986   u32 ip4_table_index = ~0;
14987   u32 ip6_table_index = ~0;
14988   u32 l2_table_index = ~0;
14989   u8 is_add = 1;
14990   int ret;
14991
14992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14993     {
14994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14995         sw_if_index_set = 1;
14996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14997         sw_if_index_set = 1;
14998       else if (unformat (i, "del"))
14999         is_add = 0;
15000       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15001         ;
15002       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15003         ;
15004       else if (unformat (i, "l2-table %d", &l2_table_index))
15005         ;
15006       else
15007         {
15008           clib_warning ("parse error '%U'", format_unformat_error, i);
15009           return -99;
15010         }
15011     }
15012
15013   if (sw_if_index_set == 0)
15014     {
15015       errmsg ("missing interface name or sw_if_index");
15016       return -99;
15017     }
15018
15019   M (OUTPUT_ACL_SET_INTERFACE, mp);
15020
15021   mp->sw_if_index = ntohl (sw_if_index);
15022   mp->ip4_table_index = ntohl (ip4_table_index);
15023   mp->ip6_table_index = ntohl (ip6_table_index);
15024   mp->l2_table_index = ntohl (l2_table_index);
15025   mp->is_add = is_add;
15026
15027   S (mp);
15028   W (ret);
15029   return ret;
15030 }
15031
15032 static int
15033 api_ip_address_dump (vat_main_t * vam)
15034 {
15035   unformat_input_t *i = vam->input;
15036   vl_api_ip_address_dump_t *mp;
15037   vl_api_control_ping_t *mp_ping;
15038   u32 sw_if_index = ~0;
15039   u8 sw_if_index_set = 0;
15040   u8 ipv4_set = 0;
15041   u8 ipv6_set = 0;
15042   int ret;
15043
15044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15045     {
15046       if (unformat (i, "sw_if_index %d", &sw_if_index))
15047         sw_if_index_set = 1;
15048       else
15049         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15050         sw_if_index_set = 1;
15051       else if (unformat (i, "ipv4"))
15052         ipv4_set = 1;
15053       else if (unformat (i, "ipv6"))
15054         ipv6_set = 1;
15055       else
15056         break;
15057     }
15058
15059   if (ipv4_set && ipv6_set)
15060     {
15061       errmsg ("ipv4 and ipv6 flags cannot be both set");
15062       return -99;
15063     }
15064
15065   if ((!ipv4_set) && (!ipv6_set))
15066     {
15067       errmsg ("no ipv4 nor ipv6 flag set");
15068       return -99;
15069     }
15070
15071   if (sw_if_index_set == 0)
15072     {
15073       errmsg ("missing interface name or sw_if_index");
15074       return -99;
15075     }
15076
15077   vam->current_sw_if_index = sw_if_index;
15078   vam->is_ipv6 = ipv6_set;
15079
15080   M (IP_ADDRESS_DUMP, mp);
15081   mp->sw_if_index = ntohl (sw_if_index);
15082   mp->is_ipv6 = ipv6_set;
15083   S (mp);
15084
15085   /* Use a control ping for synchronization */
15086   MPING (CONTROL_PING, mp_ping);
15087   S (mp_ping);
15088
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_ip_dump (vat_main_t * vam)
15095 {
15096   vl_api_ip_dump_t *mp;
15097   vl_api_control_ping_t *mp_ping;
15098   unformat_input_t *in = vam->input;
15099   int ipv4_set = 0;
15100   int ipv6_set = 0;
15101   int is_ipv6;
15102   int i;
15103   int ret;
15104
15105   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15106     {
15107       if (unformat (in, "ipv4"))
15108         ipv4_set = 1;
15109       else if (unformat (in, "ipv6"))
15110         ipv6_set = 1;
15111       else
15112         break;
15113     }
15114
15115   if (ipv4_set && ipv6_set)
15116     {
15117       errmsg ("ipv4 and ipv6 flags cannot be both set");
15118       return -99;
15119     }
15120
15121   if ((!ipv4_set) && (!ipv6_set))
15122     {
15123       errmsg ("no ipv4 nor ipv6 flag set");
15124       return -99;
15125     }
15126
15127   is_ipv6 = ipv6_set;
15128   vam->is_ipv6 = is_ipv6;
15129
15130   /* free old data */
15131   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15132     {
15133       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15134     }
15135   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15136
15137   M (IP_DUMP, mp);
15138   mp->is_ipv6 = ipv6_set;
15139   S (mp);
15140
15141   /* Use a control ping for synchronization */
15142   MPING (CONTROL_PING, mp_ping);
15143   S (mp_ping);
15144
15145   W (ret);
15146   return ret;
15147 }
15148
15149 static int
15150 api_ipsec_spd_add_del (vat_main_t * vam)
15151 {
15152   unformat_input_t *i = vam->input;
15153   vl_api_ipsec_spd_add_del_t *mp;
15154   u32 spd_id = ~0;
15155   u8 is_add = 1;
15156   int ret;
15157
15158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15159     {
15160       if (unformat (i, "spd_id %d", &spd_id))
15161         ;
15162       else if (unformat (i, "del"))
15163         is_add = 0;
15164       else
15165         {
15166           clib_warning ("parse error '%U'", format_unformat_error, i);
15167           return -99;
15168         }
15169     }
15170   if (spd_id == ~0)
15171     {
15172       errmsg ("spd_id must be set");
15173       return -99;
15174     }
15175
15176   M (IPSEC_SPD_ADD_DEL, mp);
15177
15178   mp->spd_id = ntohl (spd_id);
15179   mp->is_add = is_add;
15180
15181   S (mp);
15182   W (ret);
15183   return ret;
15184 }
15185
15186 static int
15187 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15188 {
15189   unformat_input_t *i = vam->input;
15190   vl_api_ipsec_interface_add_del_spd_t *mp;
15191   u32 sw_if_index;
15192   u8 sw_if_index_set = 0;
15193   u32 spd_id = (u32) ~ 0;
15194   u8 is_add = 1;
15195   int ret;
15196
15197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15198     {
15199       if (unformat (i, "del"))
15200         is_add = 0;
15201       else if (unformat (i, "spd_id %d", &spd_id))
15202         ;
15203       else
15204         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15205         sw_if_index_set = 1;
15206       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15207         sw_if_index_set = 1;
15208       else
15209         {
15210           clib_warning ("parse error '%U'", format_unformat_error, i);
15211           return -99;
15212         }
15213
15214     }
15215
15216   if (spd_id == (u32) ~ 0)
15217     {
15218       errmsg ("spd_id must be set");
15219       return -99;
15220     }
15221
15222   if (sw_if_index_set == 0)
15223     {
15224       errmsg ("missing interface name or sw_if_index");
15225       return -99;
15226     }
15227
15228   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15229
15230   mp->spd_id = ntohl (spd_id);
15231   mp->sw_if_index = ntohl (sw_if_index);
15232   mp->is_add = is_add;
15233
15234   S (mp);
15235   W (ret);
15236   return ret;
15237 }
15238
15239 static int
15240 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15241 {
15242   unformat_input_t *i = vam->input;
15243   vl_api_ipsec_spd_add_del_entry_t *mp;
15244   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15245   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15246   i32 priority = 0;
15247   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15248   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15249   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15250   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15251   int ret;
15252
15253   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15254   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15255   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15256   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15257   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15258   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15259
15260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15261     {
15262       if (unformat (i, "del"))
15263         is_add = 0;
15264       if (unformat (i, "outbound"))
15265         is_outbound = 1;
15266       if (unformat (i, "inbound"))
15267         is_outbound = 0;
15268       else if (unformat (i, "spd_id %d", &spd_id))
15269         ;
15270       else if (unformat (i, "sa_id %d", &sa_id))
15271         ;
15272       else if (unformat (i, "priority %d", &priority))
15273         ;
15274       else if (unformat (i, "protocol %d", &protocol))
15275         ;
15276       else if (unformat (i, "lport_start %d", &lport_start))
15277         ;
15278       else if (unformat (i, "lport_stop %d", &lport_stop))
15279         ;
15280       else if (unformat (i, "rport_start %d", &rport_start))
15281         ;
15282       else if (unformat (i, "rport_stop %d", &rport_stop))
15283         ;
15284       else
15285         if (unformat
15286             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15287         {
15288           is_ipv6 = 0;
15289           is_ip_any = 0;
15290         }
15291       else
15292         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15293         {
15294           is_ipv6 = 0;
15295           is_ip_any = 0;
15296         }
15297       else
15298         if (unformat
15299             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15300         {
15301           is_ipv6 = 0;
15302           is_ip_any = 0;
15303         }
15304       else
15305         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15306         {
15307           is_ipv6 = 0;
15308           is_ip_any = 0;
15309         }
15310       else
15311         if (unformat
15312             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15313         {
15314           is_ipv6 = 1;
15315           is_ip_any = 0;
15316         }
15317       else
15318         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15319         {
15320           is_ipv6 = 1;
15321           is_ip_any = 0;
15322         }
15323       else
15324         if (unformat
15325             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15326         {
15327           is_ipv6 = 1;
15328           is_ip_any = 0;
15329         }
15330       else
15331         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15332         {
15333           is_ipv6 = 1;
15334           is_ip_any = 0;
15335         }
15336       else
15337         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15338         {
15339           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15340             {
15341               clib_warning ("unsupported action: 'resolve'");
15342               return -99;
15343             }
15344         }
15345       else
15346         {
15347           clib_warning ("parse error '%U'", format_unformat_error, i);
15348           return -99;
15349         }
15350
15351     }
15352
15353   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15354
15355   mp->spd_id = ntohl (spd_id);
15356   mp->priority = ntohl (priority);
15357   mp->is_outbound = is_outbound;
15358
15359   mp->is_ipv6 = is_ipv6;
15360   if (is_ipv6 || is_ip_any)
15361     {
15362       clib_memcpy (mp->remote_address_start, &raddr6_start,
15363                    sizeof (ip6_address_t));
15364       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15365                    sizeof (ip6_address_t));
15366       clib_memcpy (mp->local_address_start, &laddr6_start,
15367                    sizeof (ip6_address_t));
15368       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15369                    sizeof (ip6_address_t));
15370     }
15371   else
15372     {
15373       clib_memcpy (mp->remote_address_start, &raddr4_start,
15374                    sizeof (ip4_address_t));
15375       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15376                    sizeof (ip4_address_t));
15377       clib_memcpy (mp->local_address_start, &laddr4_start,
15378                    sizeof (ip4_address_t));
15379       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15380                    sizeof (ip4_address_t));
15381     }
15382   mp->protocol = (u8) protocol;
15383   mp->local_port_start = ntohs ((u16) lport_start);
15384   mp->local_port_stop = ntohs ((u16) lport_stop);
15385   mp->remote_port_start = ntohs ((u16) rport_start);
15386   mp->remote_port_stop = ntohs ((u16) rport_stop);
15387   mp->policy = (u8) policy;
15388   mp->sa_id = ntohl (sa_id);
15389   mp->is_add = is_add;
15390   mp->is_ip_any = is_ip_any;
15391   S (mp);
15392   W (ret);
15393   return ret;
15394 }
15395
15396 static int
15397 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15398 {
15399   unformat_input_t *i = vam->input;
15400   vl_api_ipsec_sad_add_del_entry_t *mp;
15401   u32 sad_id = 0, spi = 0;
15402   u8 *ck = 0, *ik = 0;
15403   u8 is_add = 1;
15404
15405   u8 protocol = IPSEC_PROTOCOL_AH;
15406   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15407   u32 crypto_alg = 0, integ_alg = 0;
15408   ip4_address_t tun_src4;
15409   ip4_address_t tun_dst4;
15410   ip6_address_t tun_src6;
15411   ip6_address_t tun_dst6;
15412   int ret;
15413
15414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15415     {
15416       if (unformat (i, "del"))
15417         is_add = 0;
15418       else if (unformat (i, "sad_id %d", &sad_id))
15419         ;
15420       else if (unformat (i, "spi %d", &spi))
15421         ;
15422       else if (unformat (i, "esp"))
15423         protocol = IPSEC_PROTOCOL_ESP;
15424       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15425         {
15426           is_tunnel = 1;
15427           is_tunnel_ipv6 = 0;
15428         }
15429       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15430         {
15431           is_tunnel = 1;
15432           is_tunnel_ipv6 = 0;
15433         }
15434       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15435         {
15436           is_tunnel = 1;
15437           is_tunnel_ipv6 = 1;
15438         }
15439       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15440         {
15441           is_tunnel = 1;
15442           is_tunnel_ipv6 = 1;
15443         }
15444       else
15445         if (unformat
15446             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15447         {
15448           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15449             {
15450               clib_warning ("unsupported crypto-alg: '%U'",
15451                             format_ipsec_crypto_alg, crypto_alg);
15452               return -99;
15453             }
15454         }
15455       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15456         ;
15457       else
15458         if (unformat
15459             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15460         {
15461           if (integ_alg >= IPSEC_INTEG_N_ALG)
15462             {
15463               clib_warning ("unsupported integ-alg: '%U'",
15464                             format_ipsec_integ_alg, integ_alg);
15465               return -99;
15466             }
15467         }
15468       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15469         ;
15470       else
15471         {
15472           clib_warning ("parse error '%U'", format_unformat_error, i);
15473           return -99;
15474         }
15475
15476     }
15477
15478   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15479
15480   mp->sad_id = ntohl (sad_id);
15481   mp->is_add = is_add;
15482   mp->protocol = protocol;
15483   mp->spi = ntohl (spi);
15484   mp->is_tunnel = is_tunnel;
15485   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15486   mp->crypto_algorithm = crypto_alg;
15487   mp->integrity_algorithm = integ_alg;
15488   mp->crypto_key_length = vec_len (ck);
15489   mp->integrity_key_length = vec_len (ik);
15490
15491   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15492     mp->crypto_key_length = sizeof (mp->crypto_key);
15493
15494   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15495     mp->integrity_key_length = sizeof (mp->integrity_key);
15496
15497   if (ck)
15498     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15499   if (ik)
15500     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15501
15502   if (is_tunnel)
15503     {
15504       if (is_tunnel_ipv6)
15505         {
15506           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15507                        sizeof (ip6_address_t));
15508           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15509                        sizeof (ip6_address_t));
15510         }
15511       else
15512         {
15513           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15514                        sizeof (ip4_address_t));
15515           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15516                        sizeof (ip4_address_t));
15517         }
15518     }
15519
15520   S (mp);
15521   W (ret);
15522   return ret;
15523 }
15524
15525 static int
15526 api_ipsec_sa_set_key (vat_main_t * vam)
15527 {
15528   unformat_input_t *i = vam->input;
15529   vl_api_ipsec_sa_set_key_t *mp;
15530   u32 sa_id;
15531   u8 *ck = 0, *ik = 0;
15532   int ret;
15533
15534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15535     {
15536       if (unformat (i, "sa_id %d", &sa_id))
15537         ;
15538       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15539         ;
15540       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15541         ;
15542       else
15543         {
15544           clib_warning ("parse error '%U'", format_unformat_error, i);
15545           return -99;
15546         }
15547     }
15548
15549   M (IPSEC_SA_SET_KEY, mp);
15550
15551   mp->sa_id = ntohl (sa_id);
15552   mp->crypto_key_length = vec_len (ck);
15553   mp->integrity_key_length = vec_len (ik);
15554
15555   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15556     mp->crypto_key_length = sizeof (mp->crypto_key);
15557
15558   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15559     mp->integrity_key_length = sizeof (mp->integrity_key);
15560
15561   if (ck)
15562     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15563   if (ik)
15564     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15565
15566   S (mp);
15567   W (ret);
15568   return ret;
15569 }
15570
15571 static int
15572 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15573 {
15574   unformat_input_t *i = vam->input;
15575   vl_api_ipsec_tunnel_if_add_del_t *mp;
15576   u32 local_spi = 0, remote_spi = 0;
15577   u32 crypto_alg = 0, integ_alg = 0;
15578   u8 *lck = NULL, *rck = NULL;
15579   u8 *lik = NULL, *rik = NULL;
15580   ip4_address_t local_ip = { {0} };
15581   ip4_address_t remote_ip = { {0} };
15582   u8 is_add = 1;
15583   u8 esn = 0;
15584   u8 anti_replay = 0;
15585   u8 renumber = 0;
15586   u32 instance = ~0;
15587   int ret;
15588
15589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15590     {
15591       if (unformat (i, "del"))
15592         is_add = 0;
15593       else if (unformat (i, "esn"))
15594         esn = 1;
15595       else if (unformat (i, "anti_replay"))
15596         anti_replay = 1;
15597       else if (unformat (i, "local_spi %d", &local_spi))
15598         ;
15599       else if (unformat (i, "remote_spi %d", &remote_spi))
15600         ;
15601       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15602         ;
15603       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15604         ;
15605       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15606         ;
15607       else
15608         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15609         ;
15610       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15611         ;
15612       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15613         ;
15614       else
15615         if (unformat
15616             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15617         {
15618           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15619             {
15620               errmsg ("unsupported crypto-alg: '%U'\n",
15621                       format_ipsec_crypto_alg, crypto_alg);
15622               return -99;
15623             }
15624         }
15625       else
15626         if (unformat
15627             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15628         {
15629           if (integ_alg >= IPSEC_INTEG_N_ALG)
15630             {
15631               errmsg ("unsupported integ-alg: '%U'\n",
15632                       format_ipsec_integ_alg, integ_alg);
15633               return -99;
15634             }
15635         }
15636       else if (unformat (i, "instance %u", &instance))
15637         renumber = 1;
15638       else
15639         {
15640           errmsg ("parse error '%U'\n", format_unformat_error, i);
15641           return -99;
15642         }
15643     }
15644
15645   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15646
15647   mp->is_add = is_add;
15648   mp->esn = esn;
15649   mp->anti_replay = anti_replay;
15650
15651   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15652   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15653
15654   mp->local_spi = htonl (local_spi);
15655   mp->remote_spi = htonl (remote_spi);
15656   mp->crypto_alg = (u8) crypto_alg;
15657
15658   mp->local_crypto_key_len = 0;
15659   if (lck)
15660     {
15661       mp->local_crypto_key_len = vec_len (lck);
15662       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15663         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15664       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15665     }
15666
15667   mp->remote_crypto_key_len = 0;
15668   if (rck)
15669     {
15670       mp->remote_crypto_key_len = vec_len (rck);
15671       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15672         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15673       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15674     }
15675
15676   mp->integ_alg = (u8) integ_alg;
15677
15678   mp->local_integ_key_len = 0;
15679   if (lik)
15680     {
15681       mp->local_integ_key_len = vec_len (lik);
15682       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15683         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15684       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15685     }
15686
15687   mp->remote_integ_key_len = 0;
15688   if (rik)
15689     {
15690       mp->remote_integ_key_len = vec_len (rik);
15691       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15692         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15693       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15694     }
15695
15696   if (renumber)
15697     {
15698       mp->renumber = renumber;
15699       mp->show_instance = ntohl (instance);
15700     }
15701
15702   S (mp);
15703   W (ret);
15704   return ret;
15705 }
15706
15707 static void
15708 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15709 {
15710   vat_main_t *vam = &vat_main;
15711
15712   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15713          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15714          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15715          "tunnel_src_addr %U tunnel_dst_addr %U "
15716          "salt %u seq_outbound %lu last_seq_inbound %lu "
15717          "replay_window %lu total_data_size %lu\n",
15718          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15719          mp->protocol,
15720          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15721          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15722          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15723          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15724          mp->tunnel_src_addr,
15725          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15726          mp->tunnel_dst_addr,
15727          ntohl (mp->salt),
15728          clib_net_to_host_u64 (mp->seq_outbound),
15729          clib_net_to_host_u64 (mp->last_seq_inbound),
15730          clib_net_to_host_u64 (mp->replay_window),
15731          clib_net_to_host_u64 (mp->total_data_size));
15732 }
15733
15734 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15735 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15736
15737 static void vl_api_ipsec_sa_details_t_handler_json
15738   (vl_api_ipsec_sa_details_t * mp)
15739 {
15740   vat_main_t *vam = &vat_main;
15741   vat_json_node_t *node = NULL;
15742   struct in_addr src_ip4, dst_ip4;
15743   struct in6_addr src_ip6, dst_ip6;
15744
15745   if (VAT_JSON_ARRAY != vam->json_tree.type)
15746     {
15747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15748       vat_json_init_array (&vam->json_tree);
15749     }
15750   node = vat_json_array_add (&vam->json_tree);
15751
15752   vat_json_init_object (node);
15753   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15754   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15755   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15756   vat_json_object_add_uint (node, "proto", mp->protocol);
15757   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15758   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15759   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15760   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15761   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15762   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15763   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15764                              mp->crypto_key_len);
15765   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15766                              mp->integ_key_len);
15767   if (mp->is_tunnel_ip6)
15768     {
15769       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15770       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15771       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15772       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15773     }
15774   else
15775     {
15776       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15777       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15778       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15779       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15780     }
15781   vat_json_object_add_uint (node, "replay_window",
15782                             clib_net_to_host_u64 (mp->replay_window));
15783   vat_json_object_add_uint (node, "total_data_size",
15784                             clib_net_to_host_u64 (mp->total_data_size));
15785
15786 }
15787
15788 static int
15789 api_ipsec_sa_dump (vat_main_t * vam)
15790 {
15791   unformat_input_t *i = vam->input;
15792   vl_api_ipsec_sa_dump_t *mp;
15793   vl_api_control_ping_t *mp_ping;
15794   u32 sa_id = ~0;
15795   int ret;
15796
15797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15798     {
15799       if (unformat (i, "sa_id %d", &sa_id))
15800         ;
15801       else
15802         {
15803           clib_warning ("parse error '%U'", format_unformat_error, i);
15804           return -99;
15805         }
15806     }
15807
15808   M (IPSEC_SA_DUMP, mp);
15809
15810   mp->sa_id = ntohl (sa_id);
15811
15812   S (mp);
15813
15814   /* Use a control ping for synchronization */
15815   M (CONTROL_PING, mp_ping);
15816   S (mp_ping);
15817
15818   W (ret);
15819   return ret;
15820 }
15821
15822 static int
15823 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15824 {
15825   unformat_input_t *i = vam->input;
15826   vl_api_ipsec_tunnel_if_set_key_t *mp;
15827   u32 sw_if_index = ~0;
15828   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15829   u8 *key = 0;
15830   u32 alg = ~0;
15831   int ret;
15832
15833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15834     {
15835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15836         ;
15837       else
15838         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15839         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15840       else
15841         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15842         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15843       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15844         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15845       else
15846         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15847         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15848       else if (unformat (i, "%U", unformat_hex_string, &key))
15849         ;
15850       else
15851         {
15852           clib_warning ("parse error '%U'", format_unformat_error, i);
15853           return -99;
15854         }
15855     }
15856
15857   if (sw_if_index == ~0)
15858     {
15859       errmsg ("interface must be specified");
15860       return -99;
15861     }
15862
15863   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15864     {
15865       errmsg ("key type must be specified");
15866       return -99;
15867     }
15868
15869   if (alg == ~0)
15870     {
15871       errmsg ("algorithm must be specified");
15872       return -99;
15873     }
15874
15875   if (vec_len (key) == 0)
15876     {
15877       errmsg ("key must be specified");
15878       return -99;
15879     }
15880
15881   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15882
15883   mp->sw_if_index = htonl (sw_if_index);
15884   mp->alg = alg;
15885   mp->key_type = key_type;
15886   mp->key_len = vec_len (key);
15887   clib_memcpy (mp->key, key, vec_len (key));
15888
15889   S (mp);
15890   W (ret);
15891
15892   return ret;
15893 }
15894
15895 static int
15896 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15897 {
15898   unformat_input_t *i = vam->input;
15899   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15900   u32 sw_if_index = ~0;
15901   u32 sa_id = ~0;
15902   u8 is_outbound = (u8) ~ 0;
15903   int ret;
15904
15905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15906     {
15907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15908         ;
15909       else if (unformat (i, "sa_id %d", &sa_id))
15910         ;
15911       else if (unformat (i, "outbound"))
15912         is_outbound = 1;
15913       else if (unformat (i, "inbound"))
15914         is_outbound = 0;
15915       else
15916         {
15917           clib_warning ("parse error '%U'", format_unformat_error, i);
15918           return -99;
15919         }
15920     }
15921
15922   if (sw_if_index == ~0)
15923     {
15924       errmsg ("interface must be specified");
15925       return -99;
15926     }
15927
15928   if (sa_id == ~0)
15929     {
15930       errmsg ("SA ID must be specified");
15931       return -99;
15932     }
15933
15934   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15935
15936   mp->sw_if_index = htonl (sw_if_index);
15937   mp->sa_id = htonl (sa_id);
15938   mp->is_outbound = is_outbound;
15939
15940   S (mp);
15941   W (ret);
15942
15943   return ret;
15944 }
15945
15946 static int
15947 api_ikev2_profile_add_del (vat_main_t * vam)
15948 {
15949   unformat_input_t *i = vam->input;
15950   vl_api_ikev2_profile_add_del_t *mp;
15951   u8 is_add = 1;
15952   u8 *name = 0;
15953   int ret;
15954
15955   const char *valid_chars = "a-zA-Z0-9_";
15956
15957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15958     {
15959       if (unformat (i, "del"))
15960         is_add = 0;
15961       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15962         vec_add1 (name, 0);
15963       else
15964         {
15965           errmsg ("parse error '%U'", format_unformat_error, i);
15966           return -99;
15967         }
15968     }
15969
15970   if (!vec_len (name))
15971     {
15972       errmsg ("profile name must be specified");
15973       return -99;
15974     }
15975
15976   if (vec_len (name) > 64)
15977     {
15978       errmsg ("profile name too long");
15979       return -99;
15980     }
15981
15982   M (IKEV2_PROFILE_ADD_DEL, mp);
15983
15984   clib_memcpy (mp->name, name, vec_len (name));
15985   mp->is_add = is_add;
15986   vec_free (name);
15987
15988   S (mp);
15989   W (ret);
15990   return ret;
15991 }
15992
15993 static int
15994 api_ikev2_profile_set_auth (vat_main_t * vam)
15995 {
15996   unformat_input_t *i = vam->input;
15997   vl_api_ikev2_profile_set_auth_t *mp;
15998   u8 *name = 0;
15999   u8 *data = 0;
16000   u32 auth_method = 0;
16001   u8 is_hex = 0;
16002   int ret;
16003
16004   const char *valid_chars = "a-zA-Z0-9_";
16005
16006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16007     {
16008       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16009         vec_add1 (name, 0);
16010       else if (unformat (i, "auth_method %U",
16011                          unformat_ikev2_auth_method, &auth_method))
16012         ;
16013       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16014         is_hex = 1;
16015       else if (unformat (i, "auth_data %v", &data))
16016         ;
16017       else
16018         {
16019           errmsg ("parse error '%U'", format_unformat_error, i);
16020           return -99;
16021         }
16022     }
16023
16024   if (!vec_len (name))
16025     {
16026       errmsg ("profile name must be specified");
16027       return -99;
16028     }
16029
16030   if (vec_len (name) > 64)
16031     {
16032       errmsg ("profile name too long");
16033       return -99;
16034     }
16035
16036   if (!vec_len (data))
16037     {
16038       errmsg ("auth_data must be specified");
16039       return -99;
16040     }
16041
16042   if (!auth_method)
16043     {
16044       errmsg ("auth_method must be specified");
16045       return -99;
16046     }
16047
16048   M (IKEV2_PROFILE_SET_AUTH, mp);
16049
16050   mp->is_hex = is_hex;
16051   mp->auth_method = (u8) auth_method;
16052   mp->data_len = vec_len (data);
16053   clib_memcpy (mp->name, name, vec_len (name));
16054   clib_memcpy (mp->data, data, vec_len (data));
16055   vec_free (name);
16056   vec_free (data);
16057
16058   S (mp);
16059   W (ret);
16060   return ret;
16061 }
16062
16063 static int
16064 api_ikev2_profile_set_id (vat_main_t * vam)
16065 {
16066   unformat_input_t *i = vam->input;
16067   vl_api_ikev2_profile_set_id_t *mp;
16068   u8 *name = 0;
16069   u8 *data = 0;
16070   u8 is_local = 0;
16071   u32 id_type = 0;
16072   ip4_address_t ip4;
16073   int ret;
16074
16075   const char *valid_chars = "a-zA-Z0-9_";
16076
16077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16078     {
16079       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16080         vec_add1 (name, 0);
16081       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16082         ;
16083       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16084         {
16085           data = vec_new (u8, 4);
16086           clib_memcpy (data, ip4.as_u8, 4);
16087         }
16088       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16089         ;
16090       else if (unformat (i, "id_data %v", &data))
16091         ;
16092       else if (unformat (i, "local"))
16093         is_local = 1;
16094       else if (unformat (i, "remote"))
16095         is_local = 0;
16096       else
16097         {
16098           errmsg ("parse error '%U'", format_unformat_error, i);
16099           return -99;
16100         }
16101     }
16102
16103   if (!vec_len (name))
16104     {
16105       errmsg ("profile name must be specified");
16106       return -99;
16107     }
16108
16109   if (vec_len (name) > 64)
16110     {
16111       errmsg ("profile name too long");
16112       return -99;
16113     }
16114
16115   if (!vec_len (data))
16116     {
16117       errmsg ("id_data must be specified");
16118       return -99;
16119     }
16120
16121   if (!id_type)
16122     {
16123       errmsg ("id_type must be specified");
16124       return -99;
16125     }
16126
16127   M (IKEV2_PROFILE_SET_ID, mp);
16128
16129   mp->is_local = is_local;
16130   mp->id_type = (u8) id_type;
16131   mp->data_len = vec_len (data);
16132   clib_memcpy (mp->name, name, vec_len (name));
16133   clib_memcpy (mp->data, data, vec_len (data));
16134   vec_free (name);
16135   vec_free (data);
16136
16137   S (mp);
16138   W (ret);
16139   return ret;
16140 }
16141
16142 static int
16143 api_ikev2_profile_set_ts (vat_main_t * vam)
16144 {
16145   unformat_input_t *i = vam->input;
16146   vl_api_ikev2_profile_set_ts_t *mp;
16147   u8 *name = 0;
16148   u8 is_local = 0;
16149   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16150   ip4_address_t start_addr, end_addr;
16151
16152   const char *valid_chars = "a-zA-Z0-9_";
16153   int ret;
16154
16155   start_addr.as_u32 = 0;
16156   end_addr.as_u32 = (u32) ~ 0;
16157
16158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16159     {
16160       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16161         vec_add1 (name, 0);
16162       else if (unformat (i, "protocol %d", &proto))
16163         ;
16164       else if (unformat (i, "start_port %d", &start_port))
16165         ;
16166       else if (unformat (i, "end_port %d", &end_port))
16167         ;
16168       else
16169         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16170         ;
16171       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16172         ;
16173       else if (unformat (i, "local"))
16174         is_local = 1;
16175       else if (unformat (i, "remote"))
16176         is_local = 0;
16177       else
16178         {
16179           errmsg ("parse error '%U'", format_unformat_error, i);
16180           return -99;
16181         }
16182     }
16183
16184   if (!vec_len (name))
16185     {
16186       errmsg ("profile name must be specified");
16187       return -99;
16188     }
16189
16190   if (vec_len (name) > 64)
16191     {
16192       errmsg ("profile name too long");
16193       return -99;
16194     }
16195
16196   M (IKEV2_PROFILE_SET_TS, mp);
16197
16198   mp->is_local = is_local;
16199   mp->proto = (u8) proto;
16200   mp->start_port = (u16) start_port;
16201   mp->end_port = (u16) end_port;
16202   mp->start_addr = start_addr.as_u32;
16203   mp->end_addr = end_addr.as_u32;
16204   clib_memcpy (mp->name, name, vec_len (name));
16205   vec_free (name);
16206
16207   S (mp);
16208   W (ret);
16209   return ret;
16210 }
16211
16212 static int
16213 api_ikev2_set_local_key (vat_main_t * vam)
16214 {
16215   unformat_input_t *i = vam->input;
16216   vl_api_ikev2_set_local_key_t *mp;
16217   u8 *file = 0;
16218   int ret;
16219
16220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16221     {
16222       if (unformat (i, "file %v", &file))
16223         vec_add1 (file, 0);
16224       else
16225         {
16226           errmsg ("parse error '%U'", format_unformat_error, i);
16227           return -99;
16228         }
16229     }
16230
16231   if (!vec_len (file))
16232     {
16233       errmsg ("RSA key file must be specified");
16234       return -99;
16235     }
16236
16237   if (vec_len (file) > 256)
16238     {
16239       errmsg ("file name too long");
16240       return -99;
16241     }
16242
16243   M (IKEV2_SET_LOCAL_KEY, mp);
16244
16245   clib_memcpy (mp->key_file, file, vec_len (file));
16246   vec_free (file);
16247
16248   S (mp);
16249   W (ret);
16250   return ret;
16251 }
16252
16253 static int
16254 api_ikev2_set_responder (vat_main_t * vam)
16255 {
16256   unformat_input_t *i = vam->input;
16257   vl_api_ikev2_set_responder_t *mp;
16258   int ret;
16259   u8 *name = 0;
16260   u32 sw_if_index = ~0;
16261   ip4_address_t address;
16262
16263   const char *valid_chars = "a-zA-Z0-9_";
16264
16265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16266     {
16267       if (unformat
16268           (i, "%U interface %d address %U", unformat_token, valid_chars,
16269            &name, &sw_if_index, unformat_ip4_address, &address))
16270         vec_add1 (name, 0);
16271       else
16272         {
16273           errmsg ("parse error '%U'", format_unformat_error, i);
16274           return -99;
16275         }
16276     }
16277
16278   if (!vec_len (name))
16279     {
16280       errmsg ("profile name must be specified");
16281       return -99;
16282     }
16283
16284   if (vec_len (name) > 64)
16285     {
16286       errmsg ("profile name too long");
16287       return -99;
16288     }
16289
16290   M (IKEV2_SET_RESPONDER, mp);
16291
16292   clib_memcpy (mp->name, name, vec_len (name));
16293   vec_free (name);
16294
16295   mp->sw_if_index = sw_if_index;
16296   clib_memcpy (mp->address, &address, sizeof (address));
16297
16298   S (mp);
16299   W (ret);
16300   return ret;
16301 }
16302
16303 static int
16304 api_ikev2_set_ike_transforms (vat_main_t * vam)
16305 {
16306   unformat_input_t *i = vam->input;
16307   vl_api_ikev2_set_ike_transforms_t *mp;
16308   int ret;
16309   u8 *name = 0;
16310   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16311
16312   const char *valid_chars = "a-zA-Z0-9_";
16313
16314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16315     {
16316       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16317                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16318         vec_add1 (name, 0);
16319       else
16320         {
16321           errmsg ("parse error '%U'", format_unformat_error, i);
16322           return -99;
16323         }
16324     }
16325
16326   if (!vec_len (name))
16327     {
16328       errmsg ("profile name must be specified");
16329       return -99;
16330     }
16331
16332   if (vec_len (name) > 64)
16333     {
16334       errmsg ("profile name too long");
16335       return -99;
16336     }
16337
16338   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16339
16340   clib_memcpy (mp->name, name, vec_len (name));
16341   vec_free (name);
16342   mp->crypto_alg = crypto_alg;
16343   mp->crypto_key_size = crypto_key_size;
16344   mp->integ_alg = integ_alg;
16345   mp->dh_group = dh_group;
16346
16347   S (mp);
16348   W (ret);
16349   return ret;
16350 }
16351
16352
16353 static int
16354 api_ikev2_set_esp_transforms (vat_main_t * vam)
16355 {
16356   unformat_input_t *i = vam->input;
16357   vl_api_ikev2_set_esp_transforms_t *mp;
16358   int ret;
16359   u8 *name = 0;
16360   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16361
16362   const char *valid_chars = "a-zA-Z0-9_";
16363
16364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16365     {
16366       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16367                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16368         vec_add1 (name, 0);
16369       else
16370         {
16371           errmsg ("parse error '%U'", format_unformat_error, i);
16372           return -99;
16373         }
16374     }
16375
16376   if (!vec_len (name))
16377     {
16378       errmsg ("profile name must be specified");
16379       return -99;
16380     }
16381
16382   if (vec_len (name) > 64)
16383     {
16384       errmsg ("profile name too long");
16385       return -99;
16386     }
16387
16388   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16389
16390   clib_memcpy (mp->name, name, vec_len (name));
16391   vec_free (name);
16392   mp->crypto_alg = crypto_alg;
16393   mp->crypto_key_size = crypto_key_size;
16394   mp->integ_alg = integ_alg;
16395   mp->dh_group = dh_group;
16396
16397   S (mp);
16398   W (ret);
16399   return ret;
16400 }
16401
16402 static int
16403 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16404 {
16405   unformat_input_t *i = vam->input;
16406   vl_api_ikev2_set_sa_lifetime_t *mp;
16407   int ret;
16408   u8 *name = 0;
16409   u64 lifetime, lifetime_maxdata;
16410   u32 lifetime_jitter, handover;
16411
16412   const char *valid_chars = "a-zA-Z0-9_";
16413
16414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16415     {
16416       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16417                     &lifetime, &lifetime_jitter, &handover,
16418                     &lifetime_maxdata))
16419         vec_add1 (name, 0);
16420       else
16421         {
16422           errmsg ("parse error '%U'", format_unformat_error, i);
16423           return -99;
16424         }
16425     }
16426
16427   if (!vec_len (name))
16428     {
16429       errmsg ("profile name must be specified");
16430       return -99;
16431     }
16432
16433   if (vec_len (name) > 64)
16434     {
16435       errmsg ("profile name too long");
16436       return -99;
16437     }
16438
16439   M (IKEV2_SET_SA_LIFETIME, mp);
16440
16441   clib_memcpy (mp->name, name, vec_len (name));
16442   vec_free (name);
16443   mp->lifetime = lifetime;
16444   mp->lifetime_jitter = lifetime_jitter;
16445   mp->handover = handover;
16446   mp->lifetime_maxdata = lifetime_maxdata;
16447
16448   S (mp);
16449   W (ret);
16450   return ret;
16451 }
16452
16453 static int
16454 api_ikev2_initiate_sa_init (vat_main_t * vam)
16455 {
16456   unformat_input_t *i = vam->input;
16457   vl_api_ikev2_initiate_sa_init_t *mp;
16458   int ret;
16459   u8 *name = 0;
16460
16461   const char *valid_chars = "a-zA-Z0-9_";
16462
16463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16464     {
16465       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16466         vec_add1 (name, 0);
16467       else
16468         {
16469           errmsg ("parse error '%U'", format_unformat_error, i);
16470           return -99;
16471         }
16472     }
16473
16474   if (!vec_len (name))
16475     {
16476       errmsg ("profile name must be specified");
16477       return -99;
16478     }
16479
16480   if (vec_len (name) > 64)
16481     {
16482       errmsg ("profile name too long");
16483       return -99;
16484     }
16485
16486   M (IKEV2_INITIATE_SA_INIT, mp);
16487
16488   clib_memcpy (mp->name, name, vec_len (name));
16489   vec_free (name);
16490
16491   S (mp);
16492   W (ret);
16493   return ret;
16494 }
16495
16496 static int
16497 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16498 {
16499   unformat_input_t *i = vam->input;
16500   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16501   int ret;
16502   u64 ispi;
16503
16504
16505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16506     {
16507       if (unformat (i, "%lx", &ispi))
16508         ;
16509       else
16510         {
16511           errmsg ("parse error '%U'", format_unformat_error, i);
16512           return -99;
16513         }
16514     }
16515
16516   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16517
16518   mp->ispi = ispi;
16519
16520   S (mp);
16521   W (ret);
16522   return ret;
16523 }
16524
16525 static int
16526 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16527 {
16528   unformat_input_t *i = vam->input;
16529   vl_api_ikev2_initiate_del_child_sa_t *mp;
16530   int ret;
16531   u32 ispi;
16532
16533
16534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16535     {
16536       if (unformat (i, "%x", &ispi))
16537         ;
16538       else
16539         {
16540           errmsg ("parse error '%U'", format_unformat_error, i);
16541           return -99;
16542         }
16543     }
16544
16545   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16546
16547   mp->ispi = ispi;
16548
16549   S (mp);
16550   W (ret);
16551   return ret;
16552 }
16553
16554 static int
16555 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16556 {
16557   unformat_input_t *i = vam->input;
16558   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16559   int ret;
16560   u32 ispi;
16561
16562
16563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16564     {
16565       if (unformat (i, "%x", &ispi))
16566         ;
16567       else
16568         {
16569           errmsg ("parse error '%U'", format_unformat_error, i);
16570           return -99;
16571         }
16572     }
16573
16574   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16575
16576   mp->ispi = ispi;
16577
16578   S (mp);
16579   W (ret);
16580   return ret;
16581 }
16582
16583 static int
16584 api_get_first_msg_id (vat_main_t * vam)
16585 {
16586   vl_api_get_first_msg_id_t *mp;
16587   unformat_input_t *i = vam->input;
16588   u8 *name;
16589   u8 name_set = 0;
16590   int ret;
16591
16592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16593     {
16594       if (unformat (i, "client %s", &name))
16595         name_set = 1;
16596       else
16597         break;
16598     }
16599
16600   if (name_set == 0)
16601     {
16602       errmsg ("missing client name");
16603       return -99;
16604     }
16605   vec_add1 (name, 0);
16606
16607   if (vec_len (name) > 63)
16608     {
16609       errmsg ("client name too long");
16610       return -99;
16611     }
16612
16613   M (GET_FIRST_MSG_ID, mp);
16614   clib_memcpy (mp->name, name, vec_len (name));
16615   S (mp);
16616   W (ret);
16617   return ret;
16618 }
16619
16620 static int
16621 api_cop_interface_enable_disable (vat_main_t * vam)
16622 {
16623   unformat_input_t *line_input = vam->input;
16624   vl_api_cop_interface_enable_disable_t *mp;
16625   u32 sw_if_index = ~0;
16626   u8 enable_disable = 1;
16627   int ret;
16628
16629   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16630     {
16631       if (unformat (line_input, "disable"))
16632         enable_disable = 0;
16633       if (unformat (line_input, "enable"))
16634         enable_disable = 1;
16635       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16636                          vam, &sw_if_index))
16637         ;
16638       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16639         ;
16640       else
16641         break;
16642     }
16643
16644   if (sw_if_index == ~0)
16645     {
16646       errmsg ("missing interface name or sw_if_index");
16647       return -99;
16648     }
16649
16650   /* Construct the API message */
16651   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16652   mp->sw_if_index = ntohl (sw_if_index);
16653   mp->enable_disable = enable_disable;
16654
16655   /* send it... */
16656   S (mp);
16657   /* Wait for the reply */
16658   W (ret);
16659   return ret;
16660 }
16661
16662 static int
16663 api_cop_whitelist_enable_disable (vat_main_t * vam)
16664 {
16665   unformat_input_t *line_input = vam->input;
16666   vl_api_cop_whitelist_enable_disable_t *mp;
16667   u32 sw_if_index = ~0;
16668   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16669   u32 fib_id = 0;
16670   int ret;
16671
16672   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16673     {
16674       if (unformat (line_input, "ip4"))
16675         ip4 = 1;
16676       else if (unformat (line_input, "ip6"))
16677         ip6 = 1;
16678       else if (unformat (line_input, "default"))
16679         default_cop = 1;
16680       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16681                          vam, &sw_if_index))
16682         ;
16683       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16684         ;
16685       else if (unformat (line_input, "fib-id %d", &fib_id))
16686         ;
16687       else
16688         break;
16689     }
16690
16691   if (sw_if_index == ~0)
16692     {
16693       errmsg ("missing interface name or sw_if_index");
16694       return -99;
16695     }
16696
16697   /* Construct the API message */
16698   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16699   mp->sw_if_index = ntohl (sw_if_index);
16700   mp->fib_id = ntohl (fib_id);
16701   mp->ip4 = ip4;
16702   mp->ip6 = ip6;
16703   mp->default_cop = default_cop;
16704
16705   /* send it... */
16706   S (mp);
16707   /* Wait for the reply */
16708   W (ret);
16709   return ret;
16710 }
16711
16712 static int
16713 api_get_node_graph (vat_main_t * vam)
16714 {
16715   vl_api_get_node_graph_t *mp;
16716   int ret;
16717
16718   M (GET_NODE_GRAPH, mp);
16719
16720   /* send it... */
16721   S (mp);
16722   /* Wait for the reply */
16723   W (ret);
16724   return ret;
16725 }
16726
16727 /* *INDENT-OFF* */
16728 /** Used for parsing LISP eids */
16729 typedef CLIB_PACKED(struct{
16730   u8 addr[16];   /**< eid address */
16731   u32 len;       /**< prefix length if IP */
16732   u8 type;      /**< type of eid */
16733 }) lisp_eid_vat_t;
16734 /* *INDENT-ON* */
16735
16736 static uword
16737 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16738 {
16739   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16740
16741   memset (a, 0, sizeof (a[0]));
16742
16743   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16744     {
16745       a->type = 0;              /* ipv4 type */
16746     }
16747   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16748     {
16749       a->type = 1;              /* ipv6 type */
16750     }
16751   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16752     {
16753       a->type = 2;              /* mac type */
16754     }
16755   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16756     {
16757       a->type = 3;              /* NSH type */
16758       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16759       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16760     }
16761   else
16762     {
16763       return 0;
16764     }
16765
16766   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16767     {
16768       return 0;
16769     }
16770
16771   return 1;
16772 }
16773
16774 static int
16775 lisp_eid_size_vat (u8 type)
16776 {
16777   switch (type)
16778     {
16779     case 0:
16780       return 4;
16781     case 1:
16782       return 16;
16783     case 2:
16784       return 6;
16785     case 3:
16786       return 5;
16787     }
16788   return 0;
16789 }
16790
16791 static void
16792 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16793 {
16794   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16795 }
16796
16797 static int
16798 api_one_add_del_locator_set (vat_main_t * vam)
16799 {
16800   unformat_input_t *input = vam->input;
16801   vl_api_one_add_del_locator_set_t *mp;
16802   u8 is_add = 1;
16803   u8 *locator_set_name = NULL;
16804   u8 locator_set_name_set = 0;
16805   vl_api_local_locator_t locator, *locators = 0;
16806   u32 sw_if_index, priority, weight;
16807   u32 data_len = 0;
16808
16809   int ret;
16810   /* Parse args required to build the message */
16811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16812     {
16813       if (unformat (input, "del"))
16814         {
16815           is_add = 0;
16816         }
16817       else if (unformat (input, "locator-set %s", &locator_set_name))
16818         {
16819           locator_set_name_set = 1;
16820         }
16821       else if (unformat (input, "sw_if_index %u p %u w %u",
16822                          &sw_if_index, &priority, &weight))
16823         {
16824           locator.sw_if_index = htonl (sw_if_index);
16825           locator.priority = priority;
16826           locator.weight = weight;
16827           vec_add1 (locators, locator);
16828         }
16829       else
16830         if (unformat
16831             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16832              &sw_if_index, &priority, &weight))
16833         {
16834           locator.sw_if_index = htonl (sw_if_index);
16835           locator.priority = priority;
16836           locator.weight = weight;
16837           vec_add1 (locators, locator);
16838         }
16839       else
16840         break;
16841     }
16842
16843   if (locator_set_name_set == 0)
16844     {
16845       errmsg ("missing locator-set name");
16846       vec_free (locators);
16847       return -99;
16848     }
16849
16850   if (vec_len (locator_set_name) > 64)
16851     {
16852       errmsg ("locator-set name too long");
16853       vec_free (locator_set_name);
16854       vec_free (locators);
16855       return -99;
16856     }
16857   vec_add1 (locator_set_name, 0);
16858
16859   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16860
16861   /* Construct the API message */
16862   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16863
16864   mp->is_add = is_add;
16865   clib_memcpy (mp->locator_set_name, locator_set_name,
16866                vec_len (locator_set_name));
16867   vec_free (locator_set_name);
16868
16869   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16870   if (locators)
16871     clib_memcpy (mp->locators, locators, data_len);
16872   vec_free (locators);
16873
16874   /* send it... */
16875   S (mp);
16876
16877   /* Wait for a reply... */
16878   W (ret);
16879   return ret;
16880 }
16881
16882 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16883
16884 static int
16885 api_one_add_del_locator (vat_main_t * vam)
16886 {
16887   unformat_input_t *input = vam->input;
16888   vl_api_one_add_del_locator_t *mp;
16889   u32 tmp_if_index = ~0;
16890   u32 sw_if_index = ~0;
16891   u8 sw_if_index_set = 0;
16892   u8 sw_if_index_if_name_set = 0;
16893   u32 priority = ~0;
16894   u8 priority_set = 0;
16895   u32 weight = ~0;
16896   u8 weight_set = 0;
16897   u8 is_add = 1;
16898   u8 *locator_set_name = NULL;
16899   u8 locator_set_name_set = 0;
16900   int ret;
16901
16902   /* Parse args required to build the message */
16903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16904     {
16905       if (unformat (input, "del"))
16906         {
16907           is_add = 0;
16908         }
16909       else if (unformat (input, "locator-set %s", &locator_set_name))
16910         {
16911           locator_set_name_set = 1;
16912         }
16913       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16914                          &tmp_if_index))
16915         {
16916           sw_if_index_if_name_set = 1;
16917           sw_if_index = tmp_if_index;
16918         }
16919       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16920         {
16921           sw_if_index_set = 1;
16922           sw_if_index = tmp_if_index;
16923         }
16924       else if (unformat (input, "p %d", &priority))
16925         {
16926           priority_set = 1;
16927         }
16928       else if (unformat (input, "w %d", &weight))
16929         {
16930           weight_set = 1;
16931         }
16932       else
16933         break;
16934     }
16935
16936   if (locator_set_name_set == 0)
16937     {
16938       errmsg ("missing locator-set name");
16939       return -99;
16940     }
16941
16942   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16943     {
16944       errmsg ("missing sw_if_index");
16945       vec_free (locator_set_name);
16946       return -99;
16947     }
16948
16949   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16950     {
16951       errmsg ("cannot use both params interface name and sw_if_index");
16952       vec_free (locator_set_name);
16953       return -99;
16954     }
16955
16956   if (priority_set == 0)
16957     {
16958       errmsg ("missing locator-set priority");
16959       vec_free (locator_set_name);
16960       return -99;
16961     }
16962
16963   if (weight_set == 0)
16964     {
16965       errmsg ("missing locator-set weight");
16966       vec_free (locator_set_name);
16967       return -99;
16968     }
16969
16970   if (vec_len (locator_set_name) > 64)
16971     {
16972       errmsg ("locator-set name too long");
16973       vec_free (locator_set_name);
16974       return -99;
16975     }
16976   vec_add1 (locator_set_name, 0);
16977
16978   /* Construct the API message */
16979   M (ONE_ADD_DEL_LOCATOR, mp);
16980
16981   mp->is_add = is_add;
16982   mp->sw_if_index = ntohl (sw_if_index);
16983   mp->priority = priority;
16984   mp->weight = weight;
16985   clib_memcpy (mp->locator_set_name, locator_set_name,
16986                vec_len (locator_set_name));
16987   vec_free (locator_set_name);
16988
16989   /* send it... */
16990   S (mp);
16991
16992   /* Wait for a reply... */
16993   W (ret);
16994   return ret;
16995 }
16996
16997 #define api_lisp_add_del_locator api_one_add_del_locator
16998
16999 uword
17000 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17001 {
17002   u32 *key_id = va_arg (*args, u32 *);
17003   u8 *s = 0;
17004
17005   if (unformat (input, "%s", &s))
17006     {
17007       if (!strcmp ((char *) s, "sha1"))
17008         key_id[0] = HMAC_SHA_1_96;
17009       else if (!strcmp ((char *) s, "sha256"))
17010         key_id[0] = HMAC_SHA_256_128;
17011       else
17012         {
17013           clib_warning ("invalid key_id: '%s'", s);
17014           key_id[0] = HMAC_NO_KEY;
17015         }
17016     }
17017   else
17018     return 0;
17019
17020   vec_free (s);
17021   return 1;
17022 }
17023
17024 static int
17025 api_one_add_del_local_eid (vat_main_t * vam)
17026 {
17027   unformat_input_t *input = vam->input;
17028   vl_api_one_add_del_local_eid_t *mp;
17029   u8 is_add = 1;
17030   u8 eid_set = 0;
17031   lisp_eid_vat_t _eid, *eid = &_eid;
17032   u8 *locator_set_name = 0;
17033   u8 locator_set_name_set = 0;
17034   u32 vni = 0;
17035   u16 key_id = 0;
17036   u8 *key = 0;
17037   int ret;
17038
17039   /* Parse args required to build the message */
17040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17041     {
17042       if (unformat (input, "del"))
17043         {
17044           is_add = 0;
17045         }
17046       else if (unformat (input, "vni %d", &vni))
17047         {
17048           ;
17049         }
17050       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17051         {
17052           eid_set = 1;
17053         }
17054       else if (unformat (input, "locator-set %s", &locator_set_name))
17055         {
17056           locator_set_name_set = 1;
17057         }
17058       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17059         ;
17060       else if (unformat (input, "secret-key %_%v%_", &key))
17061         ;
17062       else
17063         break;
17064     }
17065
17066   if (locator_set_name_set == 0)
17067     {
17068       errmsg ("missing locator-set name");
17069       return -99;
17070     }
17071
17072   if (0 == eid_set)
17073     {
17074       errmsg ("EID address not set!");
17075       vec_free (locator_set_name);
17076       return -99;
17077     }
17078
17079   if (key && (0 == key_id))
17080     {
17081       errmsg ("invalid key_id!");
17082       return -99;
17083     }
17084
17085   if (vec_len (key) > 64)
17086     {
17087       errmsg ("key too long");
17088       vec_free (key);
17089       return -99;
17090     }
17091
17092   if (vec_len (locator_set_name) > 64)
17093     {
17094       errmsg ("locator-set name too long");
17095       vec_free (locator_set_name);
17096       return -99;
17097     }
17098   vec_add1 (locator_set_name, 0);
17099
17100   /* Construct the API message */
17101   M (ONE_ADD_DEL_LOCAL_EID, mp);
17102
17103   mp->is_add = is_add;
17104   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17105   mp->eid_type = eid->type;
17106   mp->prefix_len = eid->len;
17107   mp->vni = clib_host_to_net_u32 (vni);
17108   mp->key_id = clib_host_to_net_u16 (key_id);
17109   clib_memcpy (mp->locator_set_name, locator_set_name,
17110                vec_len (locator_set_name));
17111   clib_memcpy (mp->key, key, vec_len (key));
17112
17113   vec_free (locator_set_name);
17114   vec_free (key);
17115
17116   /* send it... */
17117   S (mp);
17118
17119   /* Wait for a reply... */
17120   W (ret);
17121   return ret;
17122 }
17123
17124 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17125
17126 static int
17127 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17128 {
17129   u32 dp_table = 0, vni = 0;;
17130   unformat_input_t *input = vam->input;
17131   vl_api_gpe_add_del_fwd_entry_t *mp;
17132   u8 is_add = 1;
17133   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17134   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17135   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17136   u32 action = ~0, w;
17137   ip4_address_t rmt_rloc4, lcl_rloc4;
17138   ip6_address_t rmt_rloc6, lcl_rloc6;
17139   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17140   int ret;
17141
17142   memset (&rloc, 0, sizeof (rloc));
17143
17144   /* Parse args required to build the message */
17145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17146     {
17147       if (unformat (input, "del"))
17148         is_add = 0;
17149       else if (unformat (input, "add"))
17150         is_add = 1;
17151       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17152         {
17153           rmt_eid_set = 1;
17154         }
17155       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17156         {
17157           lcl_eid_set = 1;
17158         }
17159       else if (unformat (input, "vrf %d", &dp_table))
17160         ;
17161       else if (unformat (input, "bd %d", &dp_table))
17162         ;
17163       else if (unformat (input, "vni %d", &vni))
17164         ;
17165       else if (unformat (input, "w %d", &w))
17166         {
17167           if (!curr_rloc)
17168             {
17169               errmsg ("No RLOC configured for setting priority/weight!");
17170               return -99;
17171             }
17172           curr_rloc->weight = w;
17173         }
17174       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17175                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17176         {
17177           rloc.is_ip4 = 1;
17178
17179           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17180           rloc.weight = 0;
17181           vec_add1 (lcl_locs, rloc);
17182
17183           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17184           vec_add1 (rmt_locs, rloc);
17185           /* weight saved in rmt loc */
17186           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17187         }
17188       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17189                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17190         {
17191           rloc.is_ip4 = 0;
17192           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17193           rloc.weight = 0;
17194           vec_add1 (lcl_locs, rloc);
17195
17196           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17197           vec_add1 (rmt_locs, rloc);
17198           /* weight saved in rmt loc */
17199           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17200         }
17201       else if (unformat (input, "action %d", &action))
17202         {
17203           ;
17204         }
17205       else
17206         {
17207           clib_warning ("parse error '%U'", format_unformat_error, input);
17208           return -99;
17209         }
17210     }
17211
17212   if (!rmt_eid_set)
17213     {
17214       errmsg ("remote eid addresses not set");
17215       return -99;
17216     }
17217
17218   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17219     {
17220       errmsg ("eid types don't match");
17221       return -99;
17222     }
17223
17224   if (0 == rmt_locs && (u32) ~ 0 == action)
17225     {
17226       errmsg ("action not set for negative mapping");
17227       return -99;
17228     }
17229
17230   /* Construct the API message */
17231   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17232       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17233
17234   mp->is_add = is_add;
17235   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17236   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17237   mp->eid_type = rmt_eid->type;
17238   mp->dp_table = clib_host_to_net_u32 (dp_table);
17239   mp->vni = clib_host_to_net_u32 (vni);
17240   mp->rmt_len = rmt_eid->len;
17241   mp->lcl_len = lcl_eid->len;
17242   mp->action = action;
17243
17244   if (0 != rmt_locs && 0 != lcl_locs)
17245     {
17246       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17247       clib_memcpy (mp->locs, lcl_locs,
17248                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17249
17250       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17251       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17252                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17253     }
17254   vec_free (lcl_locs);
17255   vec_free (rmt_locs);
17256
17257   /* send it... */
17258   S (mp);
17259
17260   /* Wait for a reply... */
17261   W (ret);
17262   return ret;
17263 }
17264
17265 static int
17266 api_one_add_del_map_server (vat_main_t * vam)
17267 {
17268   unformat_input_t *input = vam->input;
17269   vl_api_one_add_del_map_server_t *mp;
17270   u8 is_add = 1;
17271   u8 ipv4_set = 0;
17272   u8 ipv6_set = 0;
17273   ip4_address_t ipv4;
17274   ip6_address_t ipv6;
17275   int ret;
17276
17277   /* Parse args required to build the message */
17278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17279     {
17280       if (unformat (input, "del"))
17281         {
17282           is_add = 0;
17283         }
17284       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17285         {
17286           ipv4_set = 1;
17287         }
17288       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17289         {
17290           ipv6_set = 1;
17291         }
17292       else
17293         break;
17294     }
17295
17296   if (ipv4_set && ipv6_set)
17297     {
17298       errmsg ("both eid v4 and v6 addresses set");
17299       return -99;
17300     }
17301
17302   if (!ipv4_set && !ipv6_set)
17303     {
17304       errmsg ("eid addresses not set");
17305       return -99;
17306     }
17307
17308   /* Construct the API message */
17309   M (ONE_ADD_DEL_MAP_SERVER, mp);
17310
17311   mp->is_add = is_add;
17312   if (ipv6_set)
17313     {
17314       mp->is_ipv6 = 1;
17315       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17316     }
17317   else
17318     {
17319       mp->is_ipv6 = 0;
17320       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17321     }
17322
17323   /* send it... */
17324   S (mp);
17325
17326   /* Wait for a reply... */
17327   W (ret);
17328   return ret;
17329 }
17330
17331 #define api_lisp_add_del_map_server api_one_add_del_map_server
17332
17333 static int
17334 api_one_add_del_map_resolver (vat_main_t * vam)
17335 {
17336   unformat_input_t *input = vam->input;
17337   vl_api_one_add_del_map_resolver_t *mp;
17338   u8 is_add = 1;
17339   u8 ipv4_set = 0;
17340   u8 ipv6_set = 0;
17341   ip4_address_t ipv4;
17342   ip6_address_t ipv6;
17343   int ret;
17344
17345   /* Parse args required to build the message */
17346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17347     {
17348       if (unformat (input, "del"))
17349         {
17350           is_add = 0;
17351         }
17352       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17353         {
17354           ipv4_set = 1;
17355         }
17356       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17357         {
17358           ipv6_set = 1;
17359         }
17360       else
17361         break;
17362     }
17363
17364   if (ipv4_set && ipv6_set)
17365     {
17366       errmsg ("both eid v4 and v6 addresses set");
17367       return -99;
17368     }
17369
17370   if (!ipv4_set && !ipv6_set)
17371     {
17372       errmsg ("eid addresses not set");
17373       return -99;
17374     }
17375
17376   /* Construct the API message */
17377   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17378
17379   mp->is_add = is_add;
17380   if (ipv6_set)
17381     {
17382       mp->is_ipv6 = 1;
17383       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17384     }
17385   else
17386     {
17387       mp->is_ipv6 = 0;
17388       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17389     }
17390
17391   /* send it... */
17392   S (mp);
17393
17394   /* Wait for a reply... */
17395   W (ret);
17396   return ret;
17397 }
17398
17399 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17400
17401 static int
17402 api_lisp_gpe_enable_disable (vat_main_t * vam)
17403 {
17404   unformat_input_t *input = vam->input;
17405   vl_api_gpe_enable_disable_t *mp;
17406   u8 is_set = 0;
17407   u8 is_en = 1;
17408   int ret;
17409
17410   /* Parse args required to build the message */
17411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17412     {
17413       if (unformat (input, "enable"))
17414         {
17415           is_set = 1;
17416           is_en = 1;
17417         }
17418       else if (unformat (input, "disable"))
17419         {
17420           is_set = 1;
17421           is_en = 0;
17422         }
17423       else
17424         break;
17425     }
17426
17427   if (is_set == 0)
17428     {
17429       errmsg ("Value not set");
17430       return -99;
17431     }
17432
17433   /* Construct the API message */
17434   M (GPE_ENABLE_DISABLE, mp);
17435
17436   mp->is_en = is_en;
17437
17438   /* send it... */
17439   S (mp);
17440
17441   /* Wait for a reply... */
17442   W (ret);
17443   return ret;
17444 }
17445
17446 static int
17447 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17448 {
17449   unformat_input_t *input = vam->input;
17450   vl_api_one_rloc_probe_enable_disable_t *mp;
17451   u8 is_set = 0;
17452   u8 is_en = 0;
17453   int ret;
17454
17455   /* Parse args required to build the message */
17456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17457     {
17458       if (unformat (input, "enable"))
17459         {
17460           is_set = 1;
17461           is_en = 1;
17462         }
17463       else if (unformat (input, "disable"))
17464         is_set = 1;
17465       else
17466         break;
17467     }
17468
17469   if (!is_set)
17470     {
17471       errmsg ("Value not set");
17472       return -99;
17473     }
17474
17475   /* Construct the API message */
17476   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17477
17478   mp->is_enabled = is_en;
17479
17480   /* send it... */
17481   S (mp);
17482
17483   /* Wait for a reply... */
17484   W (ret);
17485   return ret;
17486 }
17487
17488 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17489
17490 static int
17491 api_one_map_register_enable_disable (vat_main_t * vam)
17492 {
17493   unformat_input_t *input = vam->input;
17494   vl_api_one_map_register_enable_disable_t *mp;
17495   u8 is_set = 0;
17496   u8 is_en = 0;
17497   int ret;
17498
17499   /* Parse args required to build the message */
17500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17501     {
17502       if (unformat (input, "enable"))
17503         {
17504           is_set = 1;
17505           is_en = 1;
17506         }
17507       else if (unformat (input, "disable"))
17508         is_set = 1;
17509       else
17510         break;
17511     }
17512
17513   if (!is_set)
17514     {
17515       errmsg ("Value not set");
17516       return -99;
17517     }
17518
17519   /* Construct the API message */
17520   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17521
17522   mp->is_enabled = is_en;
17523
17524   /* send it... */
17525   S (mp);
17526
17527   /* Wait for a reply... */
17528   W (ret);
17529   return ret;
17530 }
17531
17532 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17533
17534 static int
17535 api_one_enable_disable (vat_main_t * vam)
17536 {
17537   unformat_input_t *input = vam->input;
17538   vl_api_one_enable_disable_t *mp;
17539   u8 is_set = 0;
17540   u8 is_en = 0;
17541   int ret;
17542
17543   /* Parse args required to build the message */
17544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17545     {
17546       if (unformat (input, "enable"))
17547         {
17548           is_set = 1;
17549           is_en = 1;
17550         }
17551       else if (unformat (input, "disable"))
17552         {
17553           is_set = 1;
17554         }
17555       else
17556         break;
17557     }
17558
17559   if (!is_set)
17560     {
17561       errmsg ("Value not set");
17562       return -99;
17563     }
17564
17565   /* Construct the API message */
17566   M (ONE_ENABLE_DISABLE, mp);
17567
17568   mp->is_en = is_en;
17569
17570   /* send it... */
17571   S (mp);
17572
17573   /* Wait for a reply... */
17574   W (ret);
17575   return ret;
17576 }
17577
17578 #define api_lisp_enable_disable api_one_enable_disable
17579
17580 static int
17581 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17582 {
17583   unformat_input_t *input = vam->input;
17584   vl_api_one_enable_disable_xtr_mode_t *mp;
17585   u8 is_set = 0;
17586   u8 is_en = 0;
17587   int ret;
17588
17589   /* Parse args required to build the message */
17590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17591     {
17592       if (unformat (input, "enable"))
17593         {
17594           is_set = 1;
17595           is_en = 1;
17596         }
17597       else if (unformat (input, "disable"))
17598         {
17599           is_set = 1;
17600         }
17601       else
17602         break;
17603     }
17604
17605   if (!is_set)
17606     {
17607       errmsg ("Value not set");
17608       return -99;
17609     }
17610
17611   /* Construct the API message */
17612   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17613
17614   mp->is_en = is_en;
17615
17616   /* send it... */
17617   S (mp);
17618
17619   /* Wait for a reply... */
17620   W (ret);
17621   return ret;
17622 }
17623
17624 static int
17625 api_one_show_xtr_mode (vat_main_t * vam)
17626 {
17627   vl_api_one_show_xtr_mode_t *mp;
17628   int ret;
17629
17630   /* Construct the API message */
17631   M (ONE_SHOW_XTR_MODE, mp);
17632
17633   /* send it... */
17634   S (mp);
17635
17636   /* Wait for a reply... */
17637   W (ret);
17638   return ret;
17639 }
17640
17641 static int
17642 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17643 {
17644   unformat_input_t *input = vam->input;
17645   vl_api_one_enable_disable_pitr_mode_t *mp;
17646   u8 is_set = 0;
17647   u8 is_en = 0;
17648   int ret;
17649
17650   /* Parse args required to build the message */
17651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17652     {
17653       if (unformat (input, "enable"))
17654         {
17655           is_set = 1;
17656           is_en = 1;
17657         }
17658       else if (unformat (input, "disable"))
17659         {
17660           is_set = 1;
17661         }
17662       else
17663         break;
17664     }
17665
17666   if (!is_set)
17667     {
17668       errmsg ("Value not set");
17669       return -99;
17670     }
17671
17672   /* Construct the API message */
17673   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17674
17675   mp->is_en = is_en;
17676
17677   /* send it... */
17678   S (mp);
17679
17680   /* Wait for a reply... */
17681   W (ret);
17682   return ret;
17683 }
17684
17685 static int
17686 api_one_show_pitr_mode (vat_main_t * vam)
17687 {
17688   vl_api_one_show_pitr_mode_t *mp;
17689   int ret;
17690
17691   /* Construct the API message */
17692   M (ONE_SHOW_PITR_MODE, mp);
17693
17694   /* send it... */
17695   S (mp);
17696
17697   /* Wait for a reply... */
17698   W (ret);
17699   return ret;
17700 }
17701
17702 static int
17703 api_one_enable_disable_petr_mode (vat_main_t * vam)
17704 {
17705   unformat_input_t *input = vam->input;
17706   vl_api_one_enable_disable_petr_mode_t *mp;
17707   u8 is_set = 0;
17708   u8 is_en = 0;
17709   int ret;
17710
17711   /* Parse args required to build the message */
17712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17713     {
17714       if (unformat (input, "enable"))
17715         {
17716           is_set = 1;
17717           is_en = 1;
17718         }
17719       else if (unformat (input, "disable"))
17720         {
17721           is_set = 1;
17722         }
17723       else
17724         break;
17725     }
17726
17727   if (!is_set)
17728     {
17729       errmsg ("Value not set");
17730       return -99;
17731     }
17732
17733   /* Construct the API message */
17734   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17735
17736   mp->is_en = is_en;
17737
17738   /* send it... */
17739   S (mp);
17740
17741   /* Wait for a reply... */
17742   W (ret);
17743   return ret;
17744 }
17745
17746 static int
17747 api_one_show_petr_mode (vat_main_t * vam)
17748 {
17749   vl_api_one_show_petr_mode_t *mp;
17750   int ret;
17751
17752   /* Construct the API message */
17753   M (ONE_SHOW_PETR_MODE, mp);
17754
17755   /* send it... */
17756   S (mp);
17757
17758   /* Wait for a reply... */
17759   W (ret);
17760   return ret;
17761 }
17762
17763 static int
17764 api_show_one_map_register_state (vat_main_t * vam)
17765 {
17766   vl_api_show_one_map_register_state_t *mp;
17767   int ret;
17768
17769   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17770
17771   /* send */
17772   S (mp);
17773
17774   /* wait for reply */
17775   W (ret);
17776   return ret;
17777 }
17778
17779 #define api_show_lisp_map_register_state api_show_one_map_register_state
17780
17781 static int
17782 api_show_one_rloc_probe_state (vat_main_t * vam)
17783 {
17784   vl_api_show_one_rloc_probe_state_t *mp;
17785   int ret;
17786
17787   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17788
17789   /* send */
17790   S (mp);
17791
17792   /* wait for reply */
17793   W (ret);
17794   return ret;
17795 }
17796
17797 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17798
17799 static int
17800 api_one_add_del_ndp_entry (vat_main_t * vam)
17801 {
17802   vl_api_one_add_del_ndp_entry_t *mp;
17803   unformat_input_t *input = vam->input;
17804   u8 is_add = 1;
17805   u8 mac_set = 0;
17806   u8 bd_set = 0;
17807   u8 ip_set = 0;
17808   u8 mac[6] = { 0, };
17809   u8 ip6[16] = { 0, };
17810   u32 bd = ~0;
17811   int ret;
17812
17813   /* Parse args required to build the message */
17814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17815     {
17816       if (unformat (input, "del"))
17817         is_add = 0;
17818       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17819         mac_set = 1;
17820       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17821         ip_set = 1;
17822       else if (unformat (input, "bd %d", &bd))
17823         bd_set = 1;
17824       else
17825         {
17826           errmsg ("parse error '%U'", format_unformat_error, input);
17827           return -99;
17828         }
17829     }
17830
17831   if (!bd_set || !ip_set || (!mac_set && is_add))
17832     {
17833       errmsg ("Missing BD, IP or MAC!");
17834       return -99;
17835     }
17836
17837   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17838   mp->is_add = is_add;
17839   clib_memcpy (mp->mac, mac, 6);
17840   mp->bd = clib_host_to_net_u32 (bd);
17841   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17842
17843   /* send */
17844   S (mp);
17845
17846   /* wait for reply */
17847   W (ret);
17848   return ret;
17849 }
17850
17851 static int
17852 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17853 {
17854   vl_api_one_add_del_l2_arp_entry_t *mp;
17855   unformat_input_t *input = vam->input;
17856   u8 is_add = 1;
17857   u8 mac_set = 0;
17858   u8 bd_set = 0;
17859   u8 ip_set = 0;
17860   u8 mac[6] = { 0, };
17861   u32 ip4 = 0, bd = ~0;
17862   int ret;
17863
17864   /* Parse args required to build the message */
17865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17866     {
17867       if (unformat (input, "del"))
17868         is_add = 0;
17869       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17870         mac_set = 1;
17871       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17872         ip_set = 1;
17873       else if (unformat (input, "bd %d", &bd))
17874         bd_set = 1;
17875       else
17876         {
17877           errmsg ("parse error '%U'", format_unformat_error, input);
17878           return -99;
17879         }
17880     }
17881
17882   if (!bd_set || !ip_set || (!mac_set && is_add))
17883     {
17884       errmsg ("Missing BD, IP or MAC!");
17885       return -99;
17886     }
17887
17888   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17889   mp->is_add = is_add;
17890   clib_memcpy (mp->mac, mac, 6);
17891   mp->bd = clib_host_to_net_u32 (bd);
17892   mp->ip4 = ip4;
17893
17894   /* send */
17895   S (mp);
17896
17897   /* wait for reply */
17898   W (ret);
17899   return ret;
17900 }
17901
17902 static int
17903 api_one_ndp_bd_get (vat_main_t * vam)
17904 {
17905   vl_api_one_ndp_bd_get_t *mp;
17906   int ret;
17907
17908   M (ONE_NDP_BD_GET, mp);
17909
17910   /* send */
17911   S (mp);
17912
17913   /* wait for reply */
17914   W (ret);
17915   return ret;
17916 }
17917
17918 static int
17919 api_one_ndp_entries_get (vat_main_t * vam)
17920 {
17921   vl_api_one_ndp_entries_get_t *mp;
17922   unformat_input_t *input = vam->input;
17923   u8 bd_set = 0;
17924   u32 bd = ~0;
17925   int ret;
17926
17927   /* Parse args required to build the message */
17928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17929     {
17930       if (unformat (input, "bd %d", &bd))
17931         bd_set = 1;
17932       else
17933         {
17934           errmsg ("parse error '%U'", format_unformat_error, input);
17935           return -99;
17936         }
17937     }
17938
17939   if (!bd_set)
17940     {
17941       errmsg ("Expected bridge domain!");
17942       return -99;
17943     }
17944
17945   M (ONE_NDP_ENTRIES_GET, mp);
17946   mp->bd = clib_host_to_net_u32 (bd);
17947
17948   /* send */
17949   S (mp);
17950
17951   /* wait for reply */
17952   W (ret);
17953   return ret;
17954 }
17955
17956 static int
17957 api_one_l2_arp_bd_get (vat_main_t * vam)
17958 {
17959   vl_api_one_l2_arp_bd_get_t *mp;
17960   int ret;
17961
17962   M (ONE_L2_ARP_BD_GET, mp);
17963
17964   /* send */
17965   S (mp);
17966
17967   /* wait for reply */
17968   W (ret);
17969   return ret;
17970 }
17971
17972 static int
17973 api_one_l2_arp_entries_get (vat_main_t * vam)
17974 {
17975   vl_api_one_l2_arp_entries_get_t *mp;
17976   unformat_input_t *input = vam->input;
17977   u8 bd_set = 0;
17978   u32 bd = ~0;
17979   int ret;
17980
17981   /* Parse args required to build the message */
17982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17983     {
17984       if (unformat (input, "bd %d", &bd))
17985         bd_set = 1;
17986       else
17987         {
17988           errmsg ("parse error '%U'", format_unformat_error, input);
17989           return -99;
17990         }
17991     }
17992
17993   if (!bd_set)
17994     {
17995       errmsg ("Expected bridge domain!");
17996       return -99;
17997     }
17998
17999   M (ONE_L2_ARP_ENTRIES_GET, mp);
18000   mp->bd = clib_host_to_net_u32 (bd);
18001
18002   /* send */
18003   S (mp);
18004
18005   /* wait for reply */
18006   W (ret);
18007   return ret;
18008 }
18009
18010 static int
18011 api_one_stats_enable_disable (vat_main_t * vam)
18012 {
18013   vl_api_one_stats_enable_disable_t *mp;
18014   unformat_input_t *input = vam->input;
18015   u8 is_set = 0;
18016   u8 is_en = 0;
18017   int ret;
18018
18019   /* Parse args required to build the message */
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "enable"))
18023         {
18024           is_set = 1;
18025           is_en = 1;
18026         }
18027       else if (unformat (input, "disable"))
18028         {
18029           is_set = 1;
18030         }
18031       else
18032         break;
18033     }
18034
18035   if (!is_set)
18036     {
18037       errmsg ("Value not set");
18038       return -99;
18039     }
18040
18041   M (ONE_STATS_ENABLE_DISABLE, mp);
18042   mp->is_en = is_en;
18043
18044   /* send */
18045   S (mp);
18046
18047   /* wait for reply */
18048   W (ret);
18049   return ret;
18050 }
18051
18052 static int
18053 api_show_one_stats_enable_disable (vat_main_t * vam)
18054 {
18055   vl_api_show_one_stats_enable_disable_t *mp;
18056   int ret;
18057
18058   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18059
18060   /* send */
18061   S (mp);
18062
18063   /* wait for reply */
18064   W (ret);
18065   return ret;
18066 }
18067
18068 static int
18069 api_show_one_map_request_mode (vat_main_t * vam)
18070 {
18071   vl_api_show_one_map_request_mode_t *mp;
18072   int ret;
18073
18074   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18075
18076   /* send */
18077   S (mp);
18078
18079   /* wait for reply */
18080   W (ret);
18081   return ret;
18082 }
18083
18084 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18085
18086 static int
18087 api_one_map_request_mode (vat_main_t * vam)
18088 {
18089   unformat_input_t *input = vam->input;
18090   vl_api_one_map_request_mode_t *mp;
18091   u8 mode = 0;
18092   int ret;
18093
18094   /* Parse args required to build the message */
18095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18096     {
18097       if (unformat (input, "dst-only"))
18098         mode = 0;
18099       else if (unformat (input, "src-dst"))
18100         mode = 1;
18101       else
18102         {
18103           errmsg ("parse error '%U'", format_unformat_error, input);
18104           return -99;
18105         }
18106     }
18107
18108   M (ONE_MAP_REQUEST_MODE, mp);
18109
18110   mp->mode = mode;
18111
18112   /* send */
18113   S (mp);
18114
18115   /* wait for reply */
18116   W (ret);
18117   return ret;
18118 }
18119
18120 #define api_lisp_map_request_mode api_one_map_request_mode
18121
18122 /**
18123  * Enable/disable ONE proxy ITR.
18124  *
18125  * @param vam vpp API test context
18126  * @return return code
18127  */
18128 static int
18129 api_one_pitr_set_locator_set (vat_main_t * vam)
18130 {
18131   u8 ls_name_set = 0;
18132   unformat_input_t *input = vam->input;
18133   vl_api_one_pitr_set_locator_set_t *mp;
18134   u8 is_add = 1;
18135   u8 *ls_name = 0;
18136   int ret;
18137
18138   /* Parse args required to build the message */
18139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18140     {
18141       if (unformat (input, "del"))
18142         is_add = 0;
18143       else if (unformat (input, "locator-set %s", &ls_name))
18144         ls_name_set = 1;
18145       else
18146         {
18147           errmsg ("parse error '%U'", format_unformat_error, input);
18148           return -99;
18149         }
18150     }
18151
18152   if (!ls_name_set)
18153     {
18154       errmsg ("locator-set name not set!");
18155       return -99;
18156     }
18157
18158   M (ONE_PITR_SET_LOCATOR_SET, mp);
18159
18160   mp->is_add = is_add;
18161   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18162   vec_free (ls_name);
18163
18164   /* send */
18165   S (mp);
18166
18167   /* wait for reply */
18168   W (ret);
18169   return ret;
18170 }
18171
18172 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18173
18174 static int
18175 api_one_nsh_set_locator_set (vat_main_t * vam)
18176 {
18177   u8 ls_name_set = 0;
18178   unformat_input_t *input = vam->input;
18179   vl_api_one_nsh_set_locator_set_t *mp;
18180   u8 is_add = 1;
18181   u8 *ls_name = 0;
18182   int ret;
18183
18184   /* Parse args required to build the message */
18185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18186     {
18187       if (unformat (input, "del"))
18188         is_add = 0;
18189       else if (unformat (input, "ls %s", &ls_name))
18190         ls_name_set = 1;
18191       else
18192         {
18193           errmsg ("parse error '%U'", format_unformat_error, input);
18194           return -99;
18195         }
18196     }
18197
18198   if (!ls_name_set && is_add)
18199     {
18200       errmsg ("locator-set name not set!");
18201       return -99;
18202     }
18203
18204   M (ONE_NSH_SET_LOCATOR_SET, mp);
18205
18206   mp->is_add = is_add;
18207   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18208   vec_free (ls_name);
18209
18210   /* send */
18211   S (mp);
18212
18213   /* wait for reply */
18214   W (ret);
18215   return ret;
18216 }
18217
18218 static int
18219 api_show_one_pitr (vat_main_t * vam)
18220 {
18221   vl_api_show_one_pitr_t *mp;
18222   int ret;
18223
18224   if (!vam->json_output)
18225     {
18226       print (vam->ofp, "%=20s", "lisp status:");
18227     }
18228
18229   M (SHOW_ONE_PITR, mp);
18230   /* send it... */
18231   S (mp);
18232
18233   /* Wait for a reply... */
18234   W (ret);
18235   return ret;
18236 }
18237
18238 #define api_show_lisp_pitr api_show_one_pitr
18239
18240 static int
18241 api_one_use_petr (vat_main_t * vam)
18242 {
18243   unformat_input_t *input = vam->input;
18244   vl_api_one_use_petr_t *mp;
18245   u8 is_add = 0;
18246   ip_address_t ip;
18247   int ret;
18248
18249   memset (&ip, 0, sizeof (ip));
18250
18251   /* Parse args required to build the message */
18252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18253     {
18254       if (unformat (input, "disable"))
18255         is_add = 0;
18256       else
18257         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18258         {
18259           is_add = 1;
18260           ip_addr_version (&ip) = IP4;
18261         }
18262       else
18263         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18264         {
18265           is_add = 1;
18266           ip_addr_version (&ip) = IP6;
18267         }
18268       else
18269         {
18270           errmsg ("parse error '%U'", format_unformat_error, input);
18271           return -99;
18272         }
18273     }
18274
18275   M (ONE_USE_PETR, mp);
18276
18277   mp->is_add = is_add;
18278   if (is_add)
18279     {
18280       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18281       if (mp->is_ip4)
18282         clib_memcpy (mp->address, &ip, 4);
18283       else
18284         clib_memcpy (mp->address, &ip, 16);
18285     }
18286
18287   /* send */
18288   S (mp);
18289
18290   /* wait for reply */
18291   W (ret);
18292   return ret;
18293 }
18294
18295 #define api_lisp_use_petr api_one_use_petr
18296
18297 static int
18298 api_show_one_nsh_mapping (vat_main_t * vam)
18299 {
18300   vl_api_show_one_use_petr_t *mp;
18301   int ret;
18302
18303   if (!vam->json_output)
18304     {
18305       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18306     }
18307
18308   M (SHOW_ONE_NSH_MAPPING, mp);
18309   /* send it... */
18310   S (mp);
18311
18312   /* Wait for a reply... */
18313   W (ret);
18314   return ret;
18315 }
18316
18317 static int
18318 api_show_one_use_petr (vat_main_t * vam)
18319 {
18320   vl_api_show_one_use_petr_t *mp;
18321   int ret;
18322
18323   if (!vam->json_output)
18324     {
18325       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18326     }
18327
18328   M (SHOW_ONE_USE_PETR, mp);
18329   /* send it... */
18330   S (mp);
18331
18332   /* Wait for a reply... */
18333   W (ret);
18334   return ret;
18335 }
18336
18337 #define api_show_lisp_use_petr api_show_one_use_petr
18338
18339 /**
18340  * Add/delete mapping between vni and vrf
18341  */
18342 static int
18343 api_one_eid_table_add_del_map (vat_main_t * vam)
18344 {
18345   unformat_input_t *input = vam->input;
18346   vl_api_one_eid_table_add_del_map_t *mp;
18347   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18348   u32 vni, vrf, bd_index;
18349   int ret;
18350
18351   /* Parse args required to build the message */
18352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18353     {
18354       if (unformat (input, "del"))
18355         is_add = 0;
18356       else if (unformat (input, "vrf %d", &vrf))
18357         vrf_set = 1;
18358       else if (unformat (input, "bd_index %d", &bd_index))
18359         bd_index_set = 1;
18360       else if (unformat (input, "vni %d", &vni))
18361         vni_set = 1;
18362       else
18363         break;
18364     }
18365
18366   if (!vni_set || (!vrf_set && !bd_index_set))
18367     {
18368       errmsg ("missing arguments!");
18369       return -99;
18370     }
18371
18372   if (vrf_set && bd_index_set)
18373     {
18374       errmsg ("error: both vrf and bd entered!");
18375       return -99;
18376     }
18377
18378   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18379
18380   mp->is_add = is_add;
18381   mp->vni = htonl (vni);
18382   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18383   mp->is_l2 = bd_index_set;
18384
18385   /* send */
18386   S (mp);
18387
18388   /* wait for reply */
18389   W (ret);
18390   return ret;
18391 }
18392
18393 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18394
18395 uword
18396 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18397 {
18398   u32 *action = va_arg (*args, u32 *);
18399   u8 *s = 0;
18400
18401   if (unformat (input, "%s", &s))
18402     {
18403       if (!strcmp ((char *) s, "no-action"))
18404         action[0] = 0;
18405       else if (!strcmp ((char *) s, "natively-forward"))
18406         action[0] = 1;
18407       else if (!strcmp ((char *) s, "send-map-request"))
18408         action[0] = 2;
18409       else if (!strcmp ((char *) s, "drop"))
18410         action[0] = 3;
18411       else
18412         {
18413           clib_warning ("invalid action: '%s'", s);
18414           action[0] = 3;
18415         }
18416     }
18417   else
18418     return 0;
18419
18420   vec_free (s);
18421   return 1;
18422 }
18423
18424 /**
18425  * Add/del remote mapping to/from ONE control plane
18426  *
18427  * @param vam vpp API test context
18428  * @return return code
18429  */
18430 static int
18431 api_one_add_del_remote_mapping (vat_main_t * vam)
18432 {
18433   unformat_input_t *input = vam->input;
18434   vl_api_one_add_del_remote_mapping_t *mp;
18435   u32 vni = 0;
18436   lisp_eid_vat_t _eid, *eid = &_eid;
18437   lisp_eid_vat_t _seid, *seid = &_seid;
18438   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18439   u32 action = ~0, p, w, data_len;
18440   ip4_address_t rloc4;
18441   ip6_address_t rloc6;
18442   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18443   int ret;
18444
18445   memset (&rloc, 0, sizeof (rloc));
18446
18447   /* Parse args required to build the message */
18448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18449     {
18450       if (unformat (input, "del-all"))
18451         {
18452           del_all = 1;
18453         }
18454       else if (unformat (input, "del"))
18455         {
18456           is_add = 0;
18457         }
18458       else if (unformat (input, "add"))
18459         {
18460           is_add = 1;
18461         }
18462       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18463         {
18464           eid_set = 1;
18465         }
18466       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18467         {
18468           seid_set = 1;
18469         }
18470       else if (unformat (input, "vni %d", &vni))
18471         {
18472           ;
18473         }
18474       else if (unformat (input, "p %d w %d", &p, &w))
18475         {
18476           if (!curr_rloc)
18477             {
18478               errmsg ("No RLOC configured for setting priority/weight!");
18479               return -99;
18480             }
18481           curr_rloc->priority = p;
18482           curr_rloc->weight = w;
18483         }
18484       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18485         {
18486           rloc.is_ip4 = 1;
18487           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18488           vec_add1 (rlocs, rloc);
18489           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18490         }
18491       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18492         {
18493           rloc.is_ip4 = 0;
18494           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18495           vec_add1 (rlocs, rloc);
18496           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18497         }
18498       else if (unformat (input, "action %U",
18499                          unformat_negative_mapping_action, &action))
18500         {
18501           ;
18502         }
18503       else
18504         {
18505           clib_warning ("parse error '%U'", format_unformat_error, input);
18506           return -99;
18507         }
18508     }
18509
18510   if (0 == eid_set)
18511     {
18512       errmsg ("missing params!");
18513       return -99;
18514     }
18515
18516   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18517     {
18518       errmsg ("no action set for negative map-reply!");
18519       return -99;
18520     }
18521
18522   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18523
18524   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18525   mp->is_add = is_add;
18526   mp->vni = htonl (vni);
18527   mp->action = (u8) action;
18528   mp->is_src_dst = seid_set;
18529   mp->eid_len = eid->len;
18530   mp->seid_len = seid->len;
18531   mp->del_all = del_all;
18532   mp->eid_type = eid->type;
18533   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18534   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18535
18536   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18537   clib_memcpy (mp->rlocs, rlocs, data_len);
18538   vec_free (rlocs);
18539
18540   /* send it... */
18541   S (mp);
18542
18543   /* Wait for a reply... */
18544   W (ret);
18545   return ret;
18546 }
18547
18548 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18549
18550 /**
18551  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18552  * forwarding entries in data-plane accordingly.
18553  *
18554  * @param vam vpp API test context
18555  * @return return code
18556  */
18557 static int
18558 api_one_add_del_adjacency (vat_main_t * vam)
18559 {
18560   unformat_input_t *input = vam->input;
18561   vl_api_one_add_del_adjacency_t *mp;
18562   u32 vni = 0;
18563   ip4_address_t leid4, reid4;
18564   ip6_address_t leid6, reid6;
18565   u8 reid_mac[6] = { 0 };
18566   u8 leid_mac[6] = { 0 };
18567   u8 reid_type, leid_type;
18568   u32 leid_len = 0, reid_len = 0, len;
18569   u8 is_add = 1;
18570   int ret;
18571
18572   leid_type = reid_type = (u8) ~ 0;
18573
18574   /* Parse args required to build the message */
18575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18576     {
18577       if (unformat (input, "del"))
18578         {
18579           is_add = 0;
18580         }
18581       else if (unformat (input, "add"))
18582         {
18583           is_add = 1;
18584         }
18585       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18586                          &reid4, &len))
18587         {
18588           reid_type = 0;        /* ipv4 */
18589           reid_len = len;
18590         }
18591       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18592                          &reid6, &len))
18593         {
18594           reid_type = 1;        /* ipv6 */
18595           reid_len = len;
18596         }
18597       else if (unformat (input, "reid %U", unformat_ethernet_address,
18598                          reid_mac))
18599         {
18600           reid_type = 2;        /* mac */
18601         }
18602       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18603                          &leid4, &len))
18604         {
18605           leid_type = 0;        /* ipv4 */
18606           leid_len = len;
18607         }
18608       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18609                          &leid6, &len))
18610         {
18611           leid_type = 1;        /* ipv6 */
18612           leid_len = len;
18613         }
18614       else if (unformat (input, "leid %U", unformat_ethernet_address,
18615                          leid_mac))
18616         {
18617           leid_type = 2;        /* mac */
18618         }
18619       else if (unformat (input, "vni %d", &vni))
18620         {
18621           ;
18622         }
18623       else
18624         {
18625           errmsg ("parse error '%U'", format_unformat_error, input);
18626           return -99;
18627         }
18628     }
18629
18630   if ((u8) ~ 0 == reid_type)
18631     {
18632       errmsg ("missing params!");
18633       return -99;
18634     }
18635
18636   if (leid_type != reid_type)
18637     {
18638       errmsg ("remote and local EIDs are of different types!");
18639       return -99;
18640     }
18641
18642   M (ONE_ADD_DEL_ADJACENCY, mp);
18643   mp->is_add = is_add;
18644   mp->vni = htonl (vni);
18645   mp->leid_len = leid_len;
18646   mp->reid_len = reid_len;
18647   mp->eid_type = reid_type;
18648
18649   switch (mp->eid_type)
18650     {
18651     case 0:
18652       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18653       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18654       break;
18655     case 1:
18656       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18657       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18658       break;
18659     case 2:
18660       clib_memcpy (mp->leid, leid_mac, 6);
18661       clib_memcpy (mp->reid, reid_mac, 6);
18662       break;
18663     default:
18664       errmsg ("unknown EID type %d!", mp->eid_type);
18665       return 0;
18666     }
18667
18668   /* send it... */
18669   S (mp);
18670
18671   /* Wait for a reply... */
18672   W (ret);
18673   return ret;
18674 }
18675
18676 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18677
18678 uword
18679 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18680 {
18681   u32 *mode = va_arg (*args, u32 *);
18682
18683   if (unformat (input, "lisp"))
18684     *mode = 0;
18685   else if (unformat (input, "vxlan"))
18686     *mode = 1;
18687   else
18688     return 0;
18689
18690   return 1;
18691 }
18692
18693 static int
18694 api_gpe_get_encap_mode (vat_main_t * vam)
18695 {
18696   vl_api_gpe_get_encap_mode_t *mp;
18697   int ret;
18698
18699   /* Construct the API message */
18700   M (GPE_GET_ENCAP_MODE, mp);
18701
18702   /* send it... */
18703   S (mp);
18704
18705   /* Wait for a reply... */
18706   W (ret);
18707   return ret;
18708 }
18709
18710 static int
18711 api_gpe_set_encap_mode (vat_main_t * vam)
18712 {
18713   unformat_input_t *input = vam->input;
18714   vl_api_gpe_set_encap_mode_t *mp;
18715   int ret;
18716   u32 mode = 0;
18717
18718   /* Parse args required to build the message */
18719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18720     {
18721       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18722         ;
18723       else
18724         break;
18725     }
18726
18727   /* Construct the API message */
18728   M (GPE_SET_ENCAP_MODE, mp);
18729
18730   mp->mode = mode;
18731
18732   /* send it... */
18733   S (mp);
18734
18735   /* Wait for a reply... */
18736   W (ret);
18737   return ret;
18738 }
18739
18740 static int
18741 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18742 {
18743   unformat_input_t *input = vam->input;
18744   vl_api_gpe_add_del_iface_t *mp;
18745   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18746   u32 dp_table = 0, vni = 0;
18747   int ret;
18748
18749   /* Parse args required to build the message */
18750   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (input, "up"))
18753         {
18754           action_set = 1;
18755           is_add = 1;
18756         }
18757       else if (unformat (input, "down"))
18758         {
18759           action_set = 1;
18760           is_add = 0;
18761         }
18762       else if (unformat (input, "table_id %d", &dp_table))
18763         {
18764           dp_table_set = 1;
18765         }
18766       else if (unformat (input, "bd_id %d", &dp_table))
18767         {
18768           dp_table_set = 1;
18769           is_l2 = 1;
18770         }
18771       else if (unformat (input, "vni %d", &vni))
18772         {
18773           vni_set = 1;
18774         }
18775       else
18776         break;
18777     }
18778
18779   if (action_set == 0)
18780     {
18781       errmsg ("Action not set");
18782       return -99;
18783     }
18784   if (dp_table_set == 0 || vni_set == 0)
18785     {
18786       errmsg ("vni and dp_table must be set");
18787       return -99;
18788     }
18789
18790   /* Construct the API message */
18791   M (GPE_ADD_DEL_IFACE, mp);
18792
18793   mp->is_add = is_add;
18794   mp->dp_table = clib_host_to_net_u32 (dp_table);
18795   mp->is_l2 = is_l2;
18796   mp->vni = clib_host_to_net_u32 (vni);
18797
18798   /* send it... */
18799   S (mp);
18800
18801   /* Wait for a reply... */
18802   W (ret);
18803   return ret;
18804 }
18805
18806 static int
18807 api_one_map_register_fallback_threshold (vat_main_t * vam)
18808 {
18809   unformat_input_t *input = vam->input;
18810   vl_api_one_map_register_fallback_threshold_t *mp;
18811   u32 value = 0;
18812   u8 is_set = 0;
18813   int ret;
18814
18815   /* Parse args required to build the message */
18816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18817     {
18818       if (unformat (input, "%u", &value))
18819         is_set = 1;
18820       else
18821         {
18822           clib_warning ("parse error '%U'", format_unformat_error, input);
18823           return -99;
18824         }
18825     }
18826
18827   if (!is_set)
18828     {
18829       errmsg ("fallback threshold value is missing!");
18830       return -99;
18831     }
18832
18833   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18834   mp->value = clib_host_to_net_u32 (value);
18835
18836   /* send it... */
18837   S (mp);
18838
18839   /* Wait for a reply... */
18840   W (ret);
18841   return ret;
18842 }
18843
18844 static int
18845 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18846 {
18847   vl_api_show_one_map_register_fallback_threshold_t *mp;
18848   int ret;
18849
18850   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18851
18852   /* send it... */
18853   S (mp);
18854
18855   /* Wait for a reply... */
18856   W (ret);
18857   return ret;
18858 }
18859
18860 uword
18861 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18862 {
18863   u32 *proto = va_arg (*args, u32 *);
18864
18865   if (unformat (input, "udp"))
18866     *proto = 1;
18867   else if (unformat (input, "api"))
18868     *proto = 2;
18869   else
18870     return 0;
18871
18872   return 1;
18873 }
18874
18875 static int
18876 api_one_set_transport_protocol (vat_main_t * vam)
18877 {
18878   unformat_input_t *input = vam->input;
18879   vl_api_one_set_transport_protocol_t *mp;
18880   u8 is_set = 0;
18881   u32 protocol = 0;
18882   int ret;
18883
18884   /* Parse args required to build the message */
18885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18886     {
18887       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18888         is_set = 1;
18889       else
18890         {
18891           clib_warning ("parse error '%U'", format_unformat_error, input);
18892           return -99;
18893         }
18894     }
18895
18896   if (!is_set)
18897     {
18898       errmsg ("Transport protocol missing!");
18899       return -99;
18900     }
18901
18902   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18903   mp->protocol = (u8) protocol;
18904
18905   /* send it... */
18906   S (mp);
18907
18908   /* Wait for a reply... */
18909   W (ret);
18910   return ret;
18911 }
18912
18913 static int
18914 api_one_get_transport_protocol (vat_main_t * vam)
18915 {
18916   vl_api_one_get_transport_protocol_t *mp;
18917   int ret;
18918
18919   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18920
18921   /* send it... */
18922   S (mp);
18923
18924   /* Wait for a reply... */
18925   W (ret);
18926   return ret;
18927 }
18928
18929 static int
18930 api_one_map_register_set_ttl (vat_main_t * vam)
18931 {
18932   unformat_input_t *input = vam->input;
18933   vl_api_one_map_register_set_ttl_t *mp;
18934   u32 ttl = 0;
18935   u8 is_set = 0;
18936   int ret;
18937
18938   /* Parse args required to build the message */
18939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18940     {
18941       if (unformat (input, "%u", &ttl))
18942         is_set = 1;
18943       else
18944         {
18945           clib_warning ("parse error '%U'", format_unformat_error, input);
18946           return -99;
18947         }
18948     }
18949
18950   if (!is_set)
18951     {
18952       errmsg ("TTL value missing!");
18953       return -99;
18954     }
18955
18956   M (ONE_MAP_REGISTER_SET_TTL, mp);
18957   mp->ttl = clib_host_to_net_u32 (ttl);
18958
18959   /* send it... */
18960   S (mp);
18961
18962   /* Wait for a reply... */
18963   W (ret);
18964   return ret;
18965 }
18966
18967 static int
18968 api_show_one_map_register_ttl (vat_main_t * vam)
18969 {
18970   vl_api_show_one_map_register_ttl_t *mp;
18971   int ret;
18972
18973   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18974
18975   /* send it... */
18976   S (mp);
18977
18978   /* Wait for a reply... */
18979   W (ret);
18980   return ret;
18981 }
18982
18983 /**
18984  * Add/del map request itr rlocs from ONE control plane and updates
18985  *
18986  * @param vam vpp API test context
18987  * @return return code
18988  */
18989 static int
18990 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18991 {
18992   unformat_input_t *input = vam->input;
18993   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18994   u8 *locator_set_name = 0;
18995   u8 locator_set_name_set = 0;
18996   u8 is_add = 1;
18997   int ret;
18998
18999   /* Parse args required to build the message */
19000   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19001     {
19002       if (unformat (input, "del"))
19003         {
19004           is_add = 0;
19005         }
19006       else if (unformat (input, "%_%v%_", &locator_set_name))
19007         {
19008           locator_set_name_set = 1;
19009         }
19010       else
19011         {
19012           clib_warning ("parse error '%U'", format_unformat_error, input);
19013           return -99;
19014         }
19015     }
19016
19017   if (is_add && !locator_set_name_set)
19018     {
19019       errmsg ("itr-rloc is not set!");
19020       return -99;
19021     }
19022
19023   if (is_add && vec_len (locator_set_name) > 64)
19024     {
19025       errmsg ("itr-rloc locator-set name too long");
19026       vec_free (locator_set_name);
19027       return -99;
19028     }
19029
19030   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19031   mp->is_add = is_add;
19032   if (is_add)
19033     {
19034       clib_memcpy (mp->locator_set_name, locator_set_name,
19035                    vec_len (locator_set_name));
19036     }
19037   else
19038     {
19039       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19040     }
19041   vec_free (locator_set_name);
19042
19043   /* send it... */
19044   S (mp);
19045
19046   /* Wait for a reply... */
19047   W (ret);
19048   return ret;
19049 }
19050
19051 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19052
19053 static int
19054 api_one_locator_dump (vat_main_t * vam)
19055 {
19056   unformat_input_t *input = vam->input;
19057   vl_api_one_locator_dump_t *mp;
19058   vl_api_control_ping_t *mp_ping;
19059   u8 is_index_set = 0, is_name_set = 0;
19060   u8 *ls_name = 0;
19061   u32 ls_index = ~0;
19062   int ret;
19063
19064   /* Parse args required to build the message */
19065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19066     {
19067       if (unformat (input, "ls_name %_%v%_", &ls_name))
19068         {
19069           is_name_set = 1;
19070         }
19071       else if (unformat (input, "ls_index %d", &ls_index))
19072         {
19073           is_index_set = 1;
19074         }
19075       else
19076         {
19077           errmsg ("parse error '%U'", format_unformat_error, input);
19078           return -99;
19079         }
19080     }
19081
19082   if (!is_index_set && !is_name_set)
19083     {
19084       errmsg ("error: expected one of index or name!");
19085       return -99;
19086     }
19087
19088   if (is_index_set && is_name_set)
19089     {
19090       errmsg ("error: only one param expected!");
19091       return -99;
19092     }
19093
19094   if (vec_len (ls_name) > 62)
19095     {
19096       errmsg ("error: locator set name too long!");
19097       return -99;
19098     }
19099
19100   if (!vam->json_output)
19101     {
19102       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19103     }
19104
19105   M (ONE_LOCATOR_DUMP, mp);
19106   mp->is_index_set = is_index_set;
19107
19108   if (is_index_set)
19109     mp->ls_index = clib_host_to_net_u32 (ls_index);
19110   else
19111     {
19112       vec_add1 (ls_name, 0);
19113       strncpy ((char *) mp->ls_name, (char *) ls_name,
19114                sizeof (mp->ls_name) - 1);
19115     }
19116
19117   /* send it... */
19118   S (mp);
19119
19120   /* Use a control ping for synchronization */
19121   MPING (CONTROL_PING, mp_ping);
19122   S (mp_ping);
19123
19124   /* Wait for a reply... */
19125   W (ret);
19126   return ret;
19127 }
19128
19129 #define api_lisp_locator_dump api_one_locator_dump
19130
19131 static int
19132 api_one_locator_set_dump (vat_main_t * vam)
19133 {
19134   vl_api_one_locator_set_dump_t *mp;
19135   vl_api_control_ping_t *mp_ping;
19136   unformat_input_t *input = vam->input;
19137   u8 filter = 0;
19138   int ret;
19139
19140   /* Parse args required to build the message */
19141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19142     {
19143       if (unformat (input, "local"))
19144         {
19145           filter = 1;
19146         }
19147       else if (unformat (input, "remote"))
19148         {
19149           filter = 2;
19150         }
19151       else
19152         {
19153           errmsg ("parse error '%U'", format_unformat_error, input);
19154           return -99;
19155         }
19156     }
19157
19158   if (!vam->json_output)
19159     {
19160       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19161     }
19162
19163   M (ONE_LOCATOR_SET_DUMP, mp);
19164
19165   mp->filter = filter;
19166
19167   /* send it... */
19168   S (mp);
19169
19170   /* Use a control ping for synchronization */
19171   MPING (CONTROL_PING, mp_ping);
19172   S (mp_ping);
19173
19174   /* Wait for a reply... */
19175   W (ret);
19176   return ret;
19177 }
19178
19179 #define api_lisp_locator_set_dump api_one_locator_set_dump
19180
19181 static int
19182 api_one_eid_table_map_dump (vat_main_t * vam)
19183 {
19184   u8 is_l2 = 0;
19185   u8 mode_set = 0;
19186   unformat_input_t *input = vam->input;
19187   vl_api_one_eid_table_map_dump_t *mp;
19188   vl_api_control_ping_t *mp_ping;
19189   int ret;
19190
19191   /* Parse args required to build the message */
19192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19193     {
19194       if (unformat (input, "l2"))
19195         {
19196           is_l2 = 1;
19197           mode_set = 1;
19198         }
19199       else if (unformat (input, "l3"))
19200         {
19201           is_l2 = 0;
19202           mode_set = 1;
19203         }
19204       else
19205         {
19206           errmsg ("parse error '%U'", format_unformat_error, input);
19207           return -99;
19208         }
19209     }
19210
19211   if (!mode_set)
19212     {
19213       errmsg ("expected one of 'l2' or 'l3' parameter!");
19214       return -99;
19215     }
19216
19217   if (!vam->json_output)
19218     {
19219       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19220     }
19221
19222   M (ONE_EID_TABLE_MAP_DUMP, mp);
19223   mp->is_l2 = is_l2;
19224
19225   /* send it... */
19226   S (mp);
19227
19228   /* Use a control ping for synchronization */
19229   MPING (CONTROL_PING, mp_ping);
19230   S (mp_ping);
19231
19232   /* Wait for a reply... */
19233   W (ret);
19234   return ret;
19235 }
19236
19237 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19238
19239 static int
19240 api_one_eid_table_vni_dump (vat_main_t * vam)
19241 {
19242   vl_api_one_eid_table_vni_dump_t *mp;
19243   vl_api_control_ping_t *mp_ping;
19244   int ret;
19245
19246   if (!vam->json_output)
19247     {
19248       print (vam->ofp, "VNI");
19249     }
19250
19251   M (ONE_EID_TABLE_VNI_DUMP, mp);
19252
19253   /* send it... */
19254   S (mp);
19255
19256   /* Use a control ping for synchronization */
19257   MPING (CONTROL_PING, mp_ping);
19258   S (mp_ping);
19259
19260   /* Wait for a reply... */
19261   W (ret);
19262   return ret;
19263 }
19264
19265 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19266
19267 static int
19268 api_one_eid_table_dump (vat_main_t * vam)
19269 {
19270   unformat_input_t *i = vam->input;
19271   vl_api_one_eid_table_dump_t *mp;
19272   vl_api_control_ping_t *mp_ping;
19273   struct in_addr ip4;
19274   struct in6_addr ip6;
19275   u8 mac[6];
19276   u8 eid_type = ~0, eid_set = 0;
19277   u32 prefix_length = ~0, t, vni = 0;
19278   u8 filter = 0;
19279   int ret;
19280   lisp_nsh_api_t nsh;
19281
19282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19283     {
19284       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19285         {
19286           eid_set = 1;
19287           eid_type = 0;
19288           prefix_length = t;
19289         }
19290       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19291         {
19292           eid_set = 1;
19293           eid_type = 1;
19294           prefix_length = t;
19295         }
19296       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19297         {
19298           eid_set = 1;
19299           eid_type = 2;
19300         }
19301       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19302         {
19303           eid_set = 1;
19304           eid_type = 3;
19305         }
19306       else if (unformat (i, "vni %d", &t))
19307         {
19308           vni = t;
19309         }
19310       else if (unformat (i, "local"))
19311         {
19312           filter = 1;
19313         }
19314       else if (unformat (i, "remote"))
19315         {
19316           filter = 2;
19317         }
19318       else
19319         {
19320           errmsg ("parse error '%U'", format_unformat_error, i);
19321           return -99;
19322         }
19323     }
19324
19325   if (!vam->json_output)
19326     {
19327       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19328              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19329     }
19330
19331   M (ONE_EID_TABLE_DUMP, mp);
19332
19333   mp->filter = filter;
19334   if (eid_set)
19335     {
19336       mp->eid_set = 1;
19337       mp->vni = htonl (vni);
19338       mp->eid_type = eid_type;
19339       switch (eid_type)
19340         {
19341         case 0:
19342           mp->prefix_length = prefix_length;
19343           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19344           break;
19345         case 1:
19346           mp->prefix_length = prefix_length;
19347           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19348           break;
19349         case 2:
19350           clib_memcpy (mp->eid, mac, sizeof (mac));
19351           break;
19352         case 3:
19353           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19354           break;
19355         default:
19356           errmsg ("unknown EID type %d!", eid_type);
19357           return -99;
19358         }
19359     }
19360
19361   /* send it... */
19362   S (mp);
19363
19364   /* Use a control ping for synchronization */
19365   MPING (CONTROL_PING, mp_ping);
19366   S (mp_ping);
19367
19368   /* Wait for a reply... */
19369   W (ret);
19370   return ret;
19371 }
19372
19373 #define api_lisp_eid_table_dump api_one_eid_table_dump
19374
19375 static int
19376 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19377 {
19378   unformat_input_t *i = vam->input;
19379   vl_api_gpe_fwd_entries_get_t *mp;
19380   u8 vni_set = 0;
19381   u32 vni = ~0;
19382   int ret;
19383
19384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19385     {
19386       if (unformat (i, "vni %d", &vni))
19387         {
19388           vni_set = 1;
19389         }
19390       else
19391         {
19392           errmsg ("parse error '%U'", format_unformat_error, i);
19393           return -99;
19394         }
19395     }
19396
19397   if (!vni_set)
19398     {
19399       errmsg ("vni not set!");
19400       return -99;
19401     }
19402
19403   if (!vam->json_output)
19404     {
19405       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19406              "leid", "reid");
19407     }
19408
19409   M (GPE_FWD_ENTRIES_GET, mp);
19410   mp->vni = clib_host_to_net_u32 (vni);
19411
19412   /* send it... */
19413   S (mp);
19414
19415   /* Wait for a reply... */
19416   W (ret);
19417   return ret;
19418 }
19419
19420 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19421 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19422 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19423 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19424 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19425 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19426 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19427 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19428
19429 static int
19430 api_one_adjacencies_get (vat_main_t * vam)
19431 {
19432   unformat_input_t *i = vam->input;
19433   vl_api_one_adjacencies_get_t *mp;
19434   u8 vni_set = 0;
19435   u32 vni = ~0;
19436   int ret;
19437
19438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19439     {
19440       if (unformat (i, "vni %d", &vni))
19441         {
19442           vni_set = 1;
19443         }
19444       else
19445         {
19446           errmsg ("parse error '%U'", format_unformat_error, i);
19447           return -99;
19448         }
19449     }
19450
19451   if (!vni_set)
19452     {
19453       errmsg ("vni not set!");
19454       return -99;
19455     }
19456
19457   if (!vam->json_output)
19458     {
19459       print (vam->ofp, "%s %40s", "leid", "reid");
19460     }
19461
19462   M (ONE_ADJACENCIES_GET, mp);
19463   mp->vni = clib_host_to_net_u32 (vni);
19464
19465   /* send it... */
19466   S (mp);
19467
19468   /* Wait for a reply... */
19469   W (ret);
19470   return ret;
19471 }
19472
19473 #define api_lisp_adjacencies_get api_one_adjacencies_get
19474
19475 static int
19476 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19477 {
19478   unformat_input_t *i = vam->input;
19479   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19480   int ret;
19481   u8 ip_family_set = 0, is_ip4 = 1;
19482
19483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19484     {
19485       if (unformat (i, "ip4"))
19486         {
19487           ip_family_set = 1;
19488           is_ip4 = 1;
19489         }
19490       else if (unformat (i, "ip6"))
19491         {
19492           ip_family_set = 1;
19493           is_ip4 = 0;
19494         }
19495       else
19496         {
19497           errmsg ("parse error '%U'", format_unformat_error, i);
19498           return -99;
19499         }
19500     }
19501
19502   if (!ip_family_set)
19503     {
19504       errmsg ("ip family not set!");
19505       return -99;
19506     }
19507
19508   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19509   mp->is_ip4 = is_ip4;
19510
19511   /* send it... */
19512   S (mp);
19513
19514   /* Wait for a reply... */
19515   W (ret);
19516   return ret;
19517 }
19518
19519 static int
19520 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19521 {
19522   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19523   int ret;
19524
19525   if (!vam->json_output)
19526     {
19527       print (vam->ofp, "VNIs");
19528     }
19529
19530   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19531
19532   /* send it... */
19533   S (mp);
19534
19535   /* Wait for a reply... */
19536   W (ret);
19537   return ret;
19538 }
19539
19540 static int
19541 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19542 {
19543   unformat_input_t *i = vam->input;
19544   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19545   int ret = 0;
19546   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19547   struct in_addr ip4;
19548   struct in6_addr ip6;
19549   u32 table_id = 0, nh_sw_if_index = ~0;
19550
19551   memset (&ip4, 0, sizeof (ip4));
19552   memset (&ip6, 0, sizeof (ip6));
19553
19554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19555     {
19556       if (unformat (i, "del"))
19557         is_add = 0;
19558       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19559                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19560         {
19561           ip_set = 1;
19562           is_ip4 = 1;
19563         }
19564       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19565                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19566         {
19567           ip_set = 1;
19568           is_ip4 = 0;
19569         }
19570       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19571         {
19572           ip_set = 1;
19573           is_ip4 = 1;
19574           nh_sw_if_index = ~0;
19575         }
19576       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19577         {
19578           ip_set = 1;
19579           is_ip4 = 0;
19580           nh_sw_if_index = ~0;
19581         }
19582       else if (unformat (i, "table %d", &table_id))
19583         ;
19584       else
19585         {
19586           errmsg ("parse error '%U'", format_unformat_error, i);
19587           return -99;
19588         }
19589     }
19590
19591   if (!ip_set)
19592     {
19593       errmsg ("nh addr not set!");
19594       return -99;
19595     }
19596
19597   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19598   mp->is_add = is_add;
19599   mp->table_id = clib_host_to_net_u32 (table_id);
19600   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19601   mp->is_ip4 = is_ip4;
19602   if (is_ip4)
19603     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19604   else
19605     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19606
19607   /* send it... */
19608   S (mp);
19609
19610   /* Wait for a reply... */
19611   W (ret);
19612   return ret;
19613 }
19614
19615 static int
19616 api_one_map_server_dump (vat_main_t * vam)
19617 {
19618   vl_api_one_map_server_dump_t *mp;
19619   vl_api_control_ping_t *mp_ping;
19620   int ret;
19621
19622   if (!vam->json_output)
19623     {
19624       print (vam->ofp, "%=20s", "Map server");
19625     }
19626
19627   M (ONE_MAP_SERVER_DUMP, mp);
19628   /* send it... */
19629   S (mp);
19630
19631   /* Use a control ping for synchronization */
19632   MPING (CONTROL_PING, mp_ping);
19633   S (mp_ping);
19634
19635   /* Wait for a reply... */
19636   W (ret);
19637   return ret;
19638 }
19639
19640 #define api_lisp_map_server_dump api_one_map_server_dump
19641
19642 static int
19643 api_one_map_resolver_dump (vat_main_t * vam)
19644 {
19645   vl_api_one_map_resolver_dump_t *mp;
19646   vl_api_control_ping_t *mp_ping;
19647   int ret;
19648
19649   if (!vam->json_output)
19650     {
19651       print (vam->ofp, "%=20s", "Map resolver");
19652     }
19653
19654   M (ONE_MAP_RESOLVER_DUMP, mp);
19655   /* send it... */
19656   S (mp);
19657
19658   /* Use a control ping for synchronization */
19659   MPING (CONTROL_PING, mp_ping);
19660   S (mp_ping);
19661
19662   /* Wait for a reply... */
19663   W (ret);
19664   return ret;
19665 }
19666
19667 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19668
19669 static int
19670 api_one_stats_flush (vat_main_t * vam)
19671 {
19672   vl_api_one_stats_flush_t *mp;
19673   int ret = 0;
19674
19675   M (ONE_STATS_FLUSH, mp);
19676   S (mp);
19677   W (ret);
19678   return ret;
19679 }
19680
19681 static int
19682 api_one_stats_dump (vat_main_t * vam)
19683 {
19684   vl_api_one_stats_dump_t *mp;
19685   vl_api_control_ping_t *mp_ping;
19686   int ret;
19687
19688   M (ONE_STATS_DUMP, mp);
19689   /* send it... */
19690   S (mp);
19691
19692   /* Use a control ping for synchronization */
19693   MPING (CONTROL_PING, mp_ping);
19694   S (mp_ping);
19695
19696   /* Wait for a reply... */
19697   W (ret);
19698   return ret;
19699 }
19700
19701 static int
19702 api_show_one_status (vat_main_t * vam)
19703 {
19704   vl_api_show_one_status_t *mp;
19705   int ret;
19706
19707   if (!vam->json_output)
19708     {
19709       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19710     }
19711
19712   M (SHOW_ONE_STATUS, mp);
19713   /* send it... */
19714   S (mp);
19715   /* Wait for a reply... */
19716   W (ret);
19717   return ret;
19718 }
19719
19720 #define api_show_lisp_status api_show_one_status
19721
19722 static int
19723 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19724 {
19725   vl_api_gpe_fwd_entry_path_dump_t *mp;
19726   vl_api_control_ping_t *mp_ping;
19727   unformat_input_t *i = vam->input;
19728   u32 fwd_entry_index = ~0;
19729   int ret;
19730
19731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19732     {
19733       if (unformat (i, "index %d", &fwd_entry_index))
19734         ;
19735       else
19736         break;
19737     }
19738
19739   if (~0 == fwd_entry_index)
19740     {
19741       errmsg ("no index specified!");
19742       return -99;
19743     }
19744
19745   if (!vam->json_output)
19746     {
19747       print (vam->ofp, "first line");
19748     }
19749
19750   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19751
19752   /* send it... */
19753   S (mp);
19754   /* Use a control ping for synchronization */
19755   MPING (CONTROL_PING, mp_ping);
19756   S (mp_ping);
19757
19758   /* Wait for a reply... */
19759   W (ret);
19760   return ret;
19761 }
19762
19763 static int
19764 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19765 {
19766   vl_api_one_get_map_request_itr_rlocs_t *mp;
19767   int ret;
19768
19769   if (!vam->json_output)
19770     {
19771       print (vam->ofp, "%=20s", "itr-rlocs:");
19772     }
19773
19774   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19775   /* send it... */
19776   S (mp);
19777   /* Wait for a reply... */
19778   W (ret);
19779   return ret;
19780 }
19781
19782 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19783
19784 static int
19785 api_af_packet_create (vat_main_t * vam)
19786 {
19787   unformat_input_t *i = vam->input;
19788   vl_api_af_packet_create_t *mp;
19789   u8 *host_if_name = 0;
19790   u8 hw_addr[6];
19791   u8 random_hw_addr = 1;
19792   int ret;
19793
19794   memset (hw_addr, 0, sizeof (hw_addr));
19795
19796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19797     {
19798       if (unformat (i, "name %s", &host_if_name))
19799         vec_add1 (host_if_name, 0);
19800       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19801         random_hw_addr = 0;
19802       else
19803         break;
19804     }
19805
19806   if (!vec_len (host_if_name))
19807     {
19808       errmsg ("host-interface name must be specified");
19809       return -99;
19810     }
19811
19812   if (vec_len (host_if_name) > 64)
19813     {
19814       errmsg ("host-interface name too long");
19815       return -99;
19816     }
19817
19818   M (AF_PACKET_CREATE, mp);
19819
19820   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19821   clib_memcpy (mp->hw_addr, hw_addr, 6);
19822   mp->use_random_hw_addr = random_hw_addr;
19823   vec_free (host_if_name);
19824
19825   S (mp);
19826
19827   /* *INDENT-OFF* */
19828   W2 (ret,
19829       ({
19830         if (ret == 0)
19831           fprintf (vam->ofp ? vam->ofp : stderr,
19832                    " new sw_if_index = %d\n", vam->sw_if_index);
19833       }));
19834   /* *INDENT-ON* */
19835   return ret;
19836 }
19837
19838 static int
19839 api_af_packet_delete (vat_main_t * vam)
19840 {
19841   unformat_input_t *i = vam->input;
19842   vl_api_af_packet_delete_t *mp;
19843   u8 *host_if_name = 0;
19844   int ret;
19845
19846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19847     {
19848       if (unformat (i, "name %s", &host_if_name))
19849         vec_add1 (host_if_name, 0);
19850       else
19851         break;
19852     }
19853
19854   if (!vec_len (host_if_name))
19855     {
19856       errmsg ("host-interface name must be specified");
19857       return -99;
19858     }
19859
19860   if (vec_len (host_if_name) > 64)
19861     {
19862       errmsg ("host-interface name too long");
19863       return -99;
19864     }
19865
19866   M (AF_PACKET_DELETE, mp);
19867
19868   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19869   vec_free (host_if_name);
19870
19871   S (mp);
19872   W (ret);
19873   return ret;
19874 }
19875
19876 static void vl_api_af_packet_details_t_handler
19877   (vl_api_af_packet_details_t * mp)
19878 {
19879   vat_main_t *vam = &vat_main;
19880
19881   print (vam->ofp, "%-16s %d",
19882          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19883 }
19884
19885 static void vl_api_af_packet_details_t_handler_json
19886   (vl_api_af_packet_details_t * mp)
19887 {
19888   vat_main_t *vam = &vat_main;
19889   vat_json_node_t *node = NULL;
19890
19891   if (VAT_JSON_ARRAY != vam->json_tree.type)
19892     {
19893       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19894       vat_json_init_array (&vam->json_tree);
19895     }
19896   node = vat_json_array_add (&vam->json_tree);
19897
19898   vat_json_init_object (node);
19899   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19900   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19901 }
19902
19903 static int
19904 api_af_packet_dump (vat_main_t * vam)
19905 {
19906   vl_api_af_packet_dump_t *mp;
19907   vl_api_control_ping_t *mp_ping;
19908   int ret;
19909
19910   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19911   /* Get list of tap interfaces */
19912   M (AF_PACKET_DUMP, mp);
19913   S (mp);
19914
19915   /* Use a control ping for synchronization */
19916   MPING (CONTROL_PING, mp_ping);
19917   S (mp_ping);
19918
19919   W (ret);
19920   return ret;
19921 }
19922
19923 static int
19924 api_policer_add_del (vat_main_t * vam)
19925 {
19926   unformat_input_t *i = vam->input;
19927   vl_api_policer_add_del_t *mp;
19928   u8 is_add = 1;
19929   u8 *name = 0;
19930   u32 cir = 0;
19931   u32 eir = 0;
19932   u64 cb = 0;
19933   u64 eb = 0;
19934   u8 rate_type = 0;
19935   u8 round_type = 0;
19936   u8 type = 0;
19937   u8 color_aware = 0;
19938   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19939   int ret;
19940
19941   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19942   conform_action.dscp = 0;
19943   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19944   exceed_action.dscp = 0;
19945   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19946   violate_action.dscp = 0;
19947
19948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19949     {
19950       if (unformat (i, "del"))
19951         is_add = 0;
19952       else if (unformat (i, "name %s", &name))
19953         vec_add1 (name, 0);
19954       else if (unformat (i, "cir %u", &cir))
19955         ;
19956       else if (unformat (i, "eir %u", &eir))
19957         ;
19958       else if (unformat (i, "cb %u", &cb))
19959         ;
19960       else if (unformat (i, "eb %u", &eb))
19961         ;
19962       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19963                          &rate_type))
19964         ;
19965       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19966                          &round_type))
19967         ;
19968       else if (unformat (i, "type %U", unformat_policer_type, &type))
19969         ;
19970       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19971                          &conform_action))
19972         ;
19973       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19974                          &exceed_action))
19975         ;
19976       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19977                          &violate_action))
19978         ;
19979       else if (unformat (i, "color-aware"))
19980         color_aware = 1;
19981       else
19982         break;
19983     }
19984
19985   if (!vec_len (name))
19986     {
19987       errmsg ("policer name must be specified");
19988       return -99;
19989     }
19990
19991   if (vec_len (name) > 64)
19992     {
19993       errmsg ("policer name too long");
19994       return -99;
19995     }
19996
19997   M (POLICER_ADD_DEL, mp);
19998
19999   clib_memcpy (mp->name, name, vec_len (name));
20000   vec_free (name);
20001   mp->is_add = is_add;
20002   mp->cir = ntohl (cir);
20003   mp->eir = ntohl (eir);
20004   mp->cb = clib_net_to_host_u64 (cb);
20005   mp->eb = clib_net_to_host_u64 (eb);
20006   mp->rate_type = rate_type;
20007   mp->round_type = round_type;
20008   mp->type = type;
20009   mp->conform_action_type = conform_action.action_type;
20010   mp->conform_dscp = conform_action.dscp;
20011   mp->exceed_action_type = exceed_action.action_type;
20012   mp->exceed_dscp = exceed_action.dscp;
20013   mp->violate_action_type = violate_action.action_type;
20014   mp->violate_dscp = violate_action.dscp;
20015   mp->color_aware = color_aware;
20016
20017   S (mp);
20018   W (ret);
20019   return ret;
20020 }
20021
20022 static int
20023 api_policer_dump (vat_main_t * vam)
20024 {
20025   unformat_input_t *i = vam->input;
20026   vl_api_policer_dump_t *mp;
20027   vl_api_control_ping_t *mp_ping;
20028   u8 *match_name = 0;
20029   u8 match_name_valid = 0;
20030   int ret;
20031
20032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20033     {
20034       if (unformat (i, "name %s", &match_name))
20035         {
20036           vec_add1 (match_name, 0);
20037           match_name_valid = 1;
20038         }
20039       else
20040         break;
20041     }
20042
20043   M (POLICER_DUMP, mp);
20044   mp->match_name_valid = match_name_valid;
20045   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20046   vec_free (match_name);
20047   /* send it... */
20048   S (mp);
20049
20050   /* Use a control ping for synchronization */
20051   MPING (CONTROL_PING, mp_ping);
20052   S (mp_ping);
20053
20054   /* Wait for a reply... */
20055   W (ret);
20056   return ret;
20057 }
20058
20059 static int
20060 api_policer_classify_set_interface (vat_main_t * vam)
20061 {
20062   unformat_input_t *i = vam->input;
20063   vl_api_policer_classify_set_interface_t *mp;
20064   u32 sw_if_index;
20065   int sw_if_index_set;
20066   u32 ip4_table_index = ~0;
20067   u32 ip6_table_index = ~0;
20068   u32 l2_table_index = ~0;
20069   u8 is_add = 1;
20070   int ret;
20071
20072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20073     {
20074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20075         sw_if_index_set = 1;
20076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20077         sw_if_index_set = 1;
20078       else if (unformat (i, "del"))
20079         is_add = 0;
20080       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20081         ;
20082       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20083         ;
20084       else if (unformat (i, "l2-table %d", &l2_table_index))
20085         ;
20086       else
20087         {
20088           clib_warning ("parse error '%U'", format_unformat_error, i);
20089           return -99;
20090         }
20091     }
20092
20093   if (sw_if_index_set == 0)
20094     {
20095       errmsg ("missing interface name or sw_if_index");
20096       return -99;
20097     }
20098
20099   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20100
20101   mp->sw_if_index = ntohl (sw_if_index);
20102   mp->ip4_table_index = ntohl (ip4_table_index);
20103   mp->ip6_table_index = ntohl (ip6_table_index);
20104   mp->l2_table_index = ntohl (l2_table_index);
20105   mp->is_add = is_add;
20106
20107   S (mp);
20108   W (ret);
20109   return ret;
20110 }
20111
20112 static int
20113 api_policer_classify_dump (vat_main_t * vam)
20114 {
20115   unformat_input_t *i = vam->input;
20116   vl_api_policer_classify_dump_t *mp;
20117   vl_api_control_ping_t *mp_ping;
20118   u8 type = POLICER_CLASSIFY_N_TABLES;
20119   int ret;
20120
20121   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20122     ;
20123   else
20124     {
20125       errmsg ("classify table type must be specified");
20126       return -99;
20127     }
20128
20129   if (!vam->json_output)
20130     {
20131       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20132     }
20133
20134   M (POLICER_CLASSIFY_DUMP, mp);
20135   mp->type = type;
20136   /* send it... */
20137   S (mp);
20138
20139   /* Use a control ping for synchronization */
20140   MPING (CONTROL_PING, mp_ping);
20141   S (mp_ping);
20142
20143   /* Wait for a reply... */
20144   W (ret);
20145   return ret;
20146 }
20147
20148 static int
20149 api_netmap_create (vat_main_t * vam)
20150 {
20151   unformat_input_t *i = vam->input;
20152   vl_api_netmap_create_t *mp;
20153   u8 *if_name = 0;
20154   u8 hw_addr[6];
20155   u8 random_hw_addr = 1;
20156   u8 is_pipe = 0;
20157   u8 is_master = 0;
20158   int ret;
20159
20160   memset (hw_addr, 0, sizeof (hw_addr));
20161
20162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20163     {
20164       if (unformat (i, "name %s", &if_name))
20165         vec_add1 (if_name, 0);
20166       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20167         random_hw_addr = 0;
20168       else if (unformat (i, "pipe"))
20169         is_pipe = 1;
20170       else if (unformat (i, "master"))
20171         is_master = 1;
20172       else if (unformat (i, "slave"))
20173         is_master = 0;
20174       else
20175         break;
20176     }
20177
20178   if (!vec_len (if_name))
20179     {
20180       errmsg ("interface name must be specified");
20181       return -99;
20182     }
20183
20184   if (vec_len (if_name) > 64)
20185     {
20186       errmsg ("interface name too long");
20187       return -99;
20188     }
20189
20190   M (NETMAP_CREATE, mp);
20191
20192   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20193   clib_memcpy (mp->hw_addr, hw_addr, 6);
20194   mp->use_random_hw_addr = random_hw_addr;
20195   mp->is_pipe = is_pipe;
20196   mp->is_master = is_master;
20197   vec_free (if_name);
20198
20199   S (mp);
20200   W (ret);
20201   return ret;
20202 }
20203
20204 static int
20205 api_netmap_delete (vat_main_t * vam)
20206 {
20207   unformat_input_t *i = vam->input;
20208   vl_api_netmap_delete_t *mp;
20209   u8 *if_name = 0;
20210   int ret;
20211
20212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20213     {
20214       if (unformat (i, "name %s", &if_name))
20215         vec_add1 (if_name, 0);
20216       else
20217         break;
20218     }
20219
20220   if (!vec_len (if_name))
20221     {
20222       errmsg ("interface name must be specified");
20223       return -99;
20224     }
20225
20226   if (vec_len (if_name) > 64)
20227     {
20228       errmsg ("interface name too long");
20229       return -99;
20230     }
20231
20232   M (NETMAP_DELETE, mp);
20233
20234   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20235   vec_free (if_name);
20236
20237   S (mp);
20238   W (ret);
20239   return ret;
20240 }
20241
20242 static void
20243 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20244 {
20245   if (fp->afi == IP46_TYPE_IP6)
20246     print (vam->ofp,
20247            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20248            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20249            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20250            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20251            format_ip6_address, fp->next_hop);
20252   else if (fp->afi == IP46_TYPE_IP4)
20253     print (vam->ofp,
20254            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20255            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20256            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20257            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20258            format_ip4_address, fp->next_hop);
20259 }
20260
20261 static void
20262 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20263                                  vl_api_fib_path_t * fp)
20264 {
20265   struct in_addr ip4;
20266   struct in6_addr ip6;
20267
20268   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20269   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20270   vat_json_object_add_uint (node, "is_local", fp->is_local);
20271   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20272   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20273   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20274   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20275   if (fp->afi == IP46_TYPE_IP4)
20276     {
20277       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20278       vat_json_object_add_ip4 (node, "next_hop", ip4);
20279     }
20280   else if (fp->afi == IP46_TYPE_IP6)
20281     {
20282       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20283       vat_json_object_add_ip6 (node, "next_hop", ip6);
20284     }
20285 }
20286
20287 static void
20288 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20289 {
20290   vat_main_t *vam = &vat_main;
20291   int count = ntohl (mp->mt_count);
20292   vl_api_fib_path_t *fp;
20293   i32 i;
20294
20295   print (vam->ofp, "[%d]: sw_if_index %d via:",
20296          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20297   fp = mp->mt_paths;
20298   for (i = 0; i < count; i++)
20299     {
20300       vl_api_mpls_fib_path_print (vam, fp);
20301       fp++;
20302     }
20303
20304   print (vam->ofp, "");
20305 }
20306
20307 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20308 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20309
20310 static void
20311 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20312 {
20313   vat_main_t *vam = &vat_main;
20314   vat_json_node_t *node = NULL;
20315   int count = ntohl (mp->mt_count);
20316   vl_api_fib_path_t *fp;
20317   i32 i;
20318
20319   if (VAT_JSON_ARRAY != vam->json_tree.type)
20320     {
20321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20322       vat_json_init_array (&vam->json_tree);
20323     }
20324   node = vat_json_array_add (&vam->json_tree);
20325
20326   vat_json_init_object (node);
20327   vat_json_object_add_uint (node, "tunnel_index",
20328                             ntohl (mp->mt_tunnel_index));
20329   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20330
20331   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20332
20333   fp = mp->mt_paths;
20334   for (i = 0; i < count; i++)
20335     {
20336       vl_api_mpls_fib_path_json_print (node, fp);
20337       fp++;
20338     }
20339 }
20340
20341 static int
20342 api_mpls_tunnel_dump (vat_main_t * vam)
20343 {
20344   vl_api_mpls_tunnel_dump_t *mp;
20345   vl_api_control_ping_t *mp_ping;
20346   i32 index = -1;
20347   int ret;
20348
20349   /* Parse args required to build the message */
20350   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20351     {
20352       if (!unformat (vam->input, "tunnel_index %d", &index))
20353         {
20354           index = -1;
20355           break;
20356         }
20357     }
20358
20359   print (vam->ofp, "  tunnel_index %d", index);
20360
20361   M (MPLS_TUNNEL_DUMP, mp);
20362   mp->tunnel_index = htonl (index);
20363   S (mp);
20364
20365   /* Use a control ping for synchronization */
20366   MPING (CONTROL_PING, mp_ping);
20367   S (mp_ping);
20368
20369   W (ret);
20370   return ret;
20371 }
20372
20373 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20374 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20375
20376
20377 static void
20378 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20379 {
20380   vat_main_t *vam = &vat_main;
20381   int count = ntohl (mp->count);
20382   vl_api_fib_path_t *fp;
20383   int i;
20384
20385   print (vam->ofp,
20386          "table-id %d, label %u, ess_bit %u",
20387          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20388   fp = mp->path;
20389   for (i = 0; i < count; i++)
20390     {
20391       vl_api_mpls_fib_path_print (vam, fp);
20392       fp++;
20393     }
20394 }
20395
20396 static void vl_api_mpls_fib_details_t_handler_json
20397   (vl_api_mpls_fib_details_t * mp)
20398 {
20399   vat_main_t *vam = &vat_main;
20400   int count = ntohl (mp->count);
20401   vat_json_node_t *node = NULL;
20402   vl_api_fib_path_t *fp;
20403   int i;
20404
20405   if (VAT_JSON_ARRAY != vam->json_tree.type)
20406     {
20407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20408       vat_json_init_array (&vam->json_tree);
20409     }
20410   node = vat_json_array_add (&vam->json_tree);
20411
20412   vat_json_init_object (node);
20413   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20414   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20415   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20416   vat_json_object_add_uint (node, "path_count", count);
20417   fp = mp->path;
20418   for (i = 0; i < count; i++)
20419     {
20420       vl_api_mpls_fib_path_json_print (node, fp);
20421       fp++;
20422     }
20423 }
20424
20425 static int
20426 api_mpls_fib_dump (vat_main_t * vam)
20427 {
20428   vl_api_mpls_fib_dump_t *mp;
20429   vl_api_control_ping_t *mp_ping;
20430   int ret;
20431
20432   M (MPLS_FIB_DUMP, mp);
20433   S (mp);
20434
20435   /* Use a control ping for synchronization */
20436   MPING (CONTROL_PING, mp_ping);
20437   S (mp_ping);
20438
20439   W (ret);
20440   return ret;
20441 }
20442
20443 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20444 #define vl_api_ip_fib_details_t_print vl_noop_handler
20445
20446 static void
20447 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20448 {
20449   vat_main_t *vam = &vat_main;
20450   int count = ntohl (mp->count);
20451   vl_api_fib_path_t *fp;
20452   int i;
20453
20454   print (vam->ofp,
20455          "table-id %d, prefix %U/%d stats-index %d",
20456          ntohl (mp->table_id), format_ip4_address, mp->address,
20457          mp->address_length, ntohl (mp->stats_index));
20458   fp = mp->path;
20459   for (i = 0; i < count; i++)
20460     {
20461       if (fp->afi == IP46_TYPE_IP6)
20462         print (vam->ofp,
20463                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20464                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20465                "next_hop_table %d",
20466                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20467                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20468                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20469       else if (fp->afi == IP46_TYPE_IP4)
20470         print (vam->ofp,
20471                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20472                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20473                "next_hop_table %d",
20474                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20475                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20476                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20477       fp++;
20478     }
20479 }
20480
20481 static void vl_api_ip_fib_details_t_handler_json
20482   (vl_api_ip_fib_details_t * mp)
20483 {
20484   vat_main_t *vam = &vat_main;
20485   int count = ntohl (mp->count);
20486   vat_json_node_t *node = NULL;
20487   struct in_addr ip4;
20488   struct in6_addr ip6;
20489   vl_api_fib_path_t *fp;
20490   int i;
20491
20492   if (VAT_JSON_ARRAY != vam->json_tree.type)
20493     {
20494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20495       vat_json_init_array (&vam->json_tree);
20496     }
20497   node = vat_json_array_add (&vam->json_tree);
20498
20499   vat_json_init_object (node);
20500   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20501   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20502   vat_json_object_add_ip4 (node, "prefix", ip4);
20503   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20504   vat_json_object_add_uint (node, "path_count", count);
20505   fp = mp->path;
20506   for (i = 0; i < count; i++)
20507     {
20508       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20509       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20510       vat_json_object_add_uint (node, "is_local", fp->is_local);
20511       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20512       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20513       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20514       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20515       if (fp->afi == IP46_TYPE_IP4)
20516         {
20517           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20518           vat_json_object_add_ip4 (node, "next_hop", ip4);
20519         }
20520       else if (fp->afi == IP46_TYPE_IP6)
20521         {
20522           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20523           vat_json_object_add_ip6 (node, "next_hop", ip6);
20524         }
20525     }
20526 }
20527
20528 static int
20529 api_ip_fib_dump (vat_main_t * vam)
20530 {
20531   vl_api_ip_fib_dump_t *mp;
20532   vl_api_control_ping_t *mp_ping;
20533   int ret;
20534
20535   M (IP_FIB_DUMP, mp);
20536   S (mp);
20537
20538   /* Use a control ping for synchronization */
20539   MPING (CONTROL_PING, mp_ping);
20540   S (mp_ping);
20541
20542   W (ret);
20543   return ret;
20544 }
20545
20546 static int
20547 api_ip_mfib_dump (vat_main_t * vam)
20548 {
20549   vl_api_ip_mfib_dump_t *mp;
20550   vl_api_control_ping_t *mp_ping;
20551   int ret;
20552
20553   M (IP_MFIB_DUMP, mp);
20554   S (mp);
20555
20556   /* Use a control ping for synchronization */
20557   MPING (CONTROL_PING, mp_ping);
20558   S (mp_ping);
20559
20560   W (ret);
20561   return ret;
20562 }
20563
20564 static void vl_api_ip_neighbor_details_t_handler
20565   (vl_api_ip_neighbor_details_t * mp)
20566 {
20567   vat_main_t *vam = &vat_main;
20568
20569   print (vam->ofp, "%c %U %U",
20570          (mp->is_static) ? 'S' : 'D',
20571          format_ethernet_address, &mp->mac_address,
20572          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20573          &mp->ip_address);
20574 }
20575
20576 static void vl_api_ip_neighbor_details_t_handler_json
20577   (vl_api_ip_neighbor_details_t * mp)
20578 {
20579
20580   vat_main_t *vam = &vat_main;
20581   vat_json_node_t *node;
20582   struct in_addr ip4;
20583   struct in6_addr ip6;
20584
20585   if (VAT_JSON_ARRAY != vam->json_tree.type)
20586     {
20587       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20588       vat_json_init_array (&vam->json_tree);
20589     }
20590   node = vat_json_array_add (&vam->json_tree);
20591
20592   vat_json_init_object (node);
20593   vat_json_object_add_string_copy (node, "flag",
20594                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20595                                    "dynamic");
20596
20597   vat_json_object_add_string_copy (node, "link_layer",
20598                                    format (0, "%U", format_ethernet_address,
20599                                            &mp->mac_address));
20600
20601   if (mp->is_ipv6)
20602     {
20603       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20604       vat_json_object_add_ip6 (node, "ip_address", ip6);
20605     }
20606   else
20607     {
20608       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20609       vat_json_object_add_ip4 (node, "ip_address", ip4);
20610     }
20611 }
20612
20613 static int
20614 api_ip_neighbor_dump (vat_main_t * vam)
20615 {
20616   unformat_input_t *i = vam->input;
20617   vl_api_ip_neighbor_dump_t *mp;
20618   vl_api_control_ping_t *mp_ping;
20619   u8 is_ipv6 = 0;
20620   u32 sw_if_index = ~0;
20621   int ret;
20622
20623   /* Parse args required to build the message */
20624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20625     {
20626       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20627         ;
20628       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20629         ;
20630       else if (unformat (i, "ip6"))
20631         is_ipv6 = 1;
20632       else
20633         break;
20634     }
20635
20636   if (sw_if_index == ~0)
20637     {
20638       errmsg ("missing interface name or sw_if_index");
20639       return -99;
20640     }
20641
20642   M (IP_NEIGHBOR_DUMP, mp);
20643   mp->is_ipv6 = (u8) is_ipv6;
20644   mp->sw_if_index = ntohl (sw_if_index);
20645   S (mp);
20646
20647   /* Use a control ping for synchronization */
20648   MPING (CONTROL_PING, mp_ping);
20649   S (mp_ping);
20650
20651   W (ret);
20652   return ret;
20653 }
20654
20655 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20656 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20657
20658 static void
20659 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20660 {
20661   vat_main_t *vam = &vat_main;
20662   int count = ntohl (mp->count);
20663   vl_api_fib_path_t *fp;
20664   int i;
20665
20666   print (vam->ofp,
20667          "table-id %d, prefix %U/%d stats-index %d",
20668          ntohl (mp->table_id), format_ip6_address, mp->address,
20669          mp->address_length, ntohl (mp->stats_index));
20670   fp = mp->path;
20671   for (i = 0; i < count; i++)
20672     {
20673       if (fp->afi == IP46_TYPE_IP6)
20674         print (vam->ofp,
20675                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20676                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20677                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20678                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20679                format_ip6_address, fp->next_hop);
20680       else if (fp->afi == IP46_TYPE_IP4)
20681         print (vam->ofp,
20682                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20683                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20684                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20685                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20686                format_ip4_address, fp->next_hop);
20687       fp++;
20688     }
20689 }
20690
20691 static void vl_api_ip6_fib_details_t_handler_json
20692   (vl_api_ip6_fib_details_t * mp)
20693 {
20694   vat_main_t *vam = &vat_main;
20695   int count = ntohl (mp->count);
20696   vat_json_node_t *node = NULL;
20697   struct in_addr ip4;
20698   struct in6_addr ip6;
20699   vl_api_fib_path_t *fp;
20700   int i;
20701
20702   if (VAT_JSON_ARRAY != vam->json_tree.type)
20703     {
20704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20705       vat_json_init_array (&vam->json_tree);
20706     }
20707   node = vat_json_array_add (&vam->json_tree);
20708
20709   vat_json_init_object (node);
20710   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20711   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20712   vat_json_object_add_ip6 (node, "prefix", ip6);
20713   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20714   vat_json_object_add_uint (node, "path_count", count);
20715   fp = mp->path;
20716   for (i = 0; i < count; i++)
20717     {
20718       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20719       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20720       vat_json_object_add_uint (node, "is_local", fp->is_local);
20721       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20722       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20723       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20724       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20725       if (fp->afi == IP46_TYPE_IP4)
20726         {
20727           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20728           vat_json_object_add_ip4 (node, "next_hop", ip4);
20729         }
20730       else if (fp->afi == IP46_TYPE_IP6)
20731         {
20732           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20733           vat_json_object_add_ip6 (node, "next_hop", ip6);
20734         }
20735     }
20736 }
20737
20738 static int
20739 api_ip6_fib_dump (vat_main_t * vam)
20740 {
20741   vl_api_ip6_fib_dump_t *mp;
20742   vl_api_control_ping_t *mp_ping;
20743   int ret;
20744
20745   M (IP6_FIB_DUMP, mp);
20746   S (mp);
20747
20748   /* Use a control ping for synchronization */
20749   MPING (CONTROL_PING, mp_ping);
20750   S (mp_ping);
20751
20752   W (ret);
20753   return ret;
20754 }
20755
20756 static int
20757 api_ip6_mfib_dump (vat_main_t * vam)
20758 {
20759   vl_api_ip6_mfib_dump_t *mp;
20760   vl_api_control_ping_t *mp_ping;
20761   int ret;
20762
20763   M (IP6_MFIB_DUMP, mp);
20764   S (mp);
20765
20766   /* Use a control ping for synchronization */
20767   MPING (CONTROL_PING, mp_ping);
20768   S (mp_ping);
20769
20770   W (ret);
20771   return ret;
20772 }
20773
20774 int
20775 api_classify_table_ids (vat_main_t * vam)
20776 {
20777   vl_api_classify_table_ids_t *mp;
20778   int ret;
20779
20780   /* Construct the API message */
20781   M (CLASSIFY_TABLE_IDS, mp);
20782   mp->context = 0;
20783
20784   S (mp);
20785   W (ret);
20786   return ret;
20787 }
20788
20789 int
20790 api_classify_table_by_interface (vat_main_t * vam)
20791 {
20792   unformat_input_t *input = vam->input;
20793   vl_api_classify_table_by_interface_t *mp;
20794
20795   u32 sw_if_index = ~0;
20796   int ret;
20797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20798     {
20799       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20800         ;
20801       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20802         ;
20803       else
20804         break;
20805     }
20806   if (sw_if_index == ~0)
20807     {
20808       errmsg ("missing interface name or sw_if_index");
20809       return -99;
20810     }
20811
20812   /* Construct the API message */
20813   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20814   mp->context = 0;
20815   mp->sw_if_index = ntohl (sw_if_index);
20816
20817   S (mp);
20818   W (ret);
20819   return ret;
20820 }
20821
20822 int
20823 api_classify_table_info (vat_main_t * vam)
20824 {
20825   unformat_input_t *input = vam->input;
20826   vl_api_classify_table_info_t *mp;
20827
20828   u32 table_id = ~0;
20829   int ret;
20830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20831     {
20832       if (unformat (input, "table_id %d", &table_id))
20833         ;
20834       else
20835         break;
20836     }
20837   if (table_id == ~0)
20838     {
20839       errmsg ("missing table id");
20840       return -99;
20841     }
20842
20843   /* Construct the API message */
20844   M (CLASSIFY_TABLE_INFO, mp);
20845   mp->context = 0;
20846   mp->table_id = ntohl (table_id);
20847
20848   S (mp);
20849   W (ret);
20850   return ret;
20851 }
20852
20853 int
20854 api_classify_session_dump (vat_main_t * vam)
20855 {
20856   unformat_input_t *input = vam->input;
20857   vl_api_classify_session_dump_t *mp;
20858   vl_api_control_ping_t *mp_ping;
20859
20860   u32 table_id = ~0;
20861   int ret;
20862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20863     {
20864       if (unformat (input, "table_id %d", &table_id))
20865         ;
20866       else
20867         break;
20868     }
20869   if (table_id == ~0)
20870     {
20871       errmsg ("missing table id");
20872       return -99;
20873     }
20874
20875   /* Construct the API message */
20876   M (CLASSIFY_SESSION_DUMP, mp);
20877   mp->context = 0;
20878   mp->table_id = ntohl (table_id);
20879   S (mp);
20880
20881   /* Use a control ping for synchronization */
20882   MPING (CONTROL_PING, mp_ping);
20883   S (mp_ping);
20884
20885   W (ret);
20886   return ret;
20887 }
20888
20889 static void
20890 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20891 {
20892   vat_main_t *vam = &vat_main;
20893
20894   print (vam->ofp, "collector_address %U, collector_port %d, "
20895          "src_address %U, vrf_id %d, path_mtu %u, "
20896          "template_interval %u, udp_checksum %d",
20897          format_ip4_address, mp->collector_address,
20898          ntohs (mp->collector_port),
20899          format_ip4_address, mp->src_address,
20900          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20901          ntohl (mp->template_interval), mp->udp_checksum);
20902
20903   vam->retval = 0;
20904   vam->result_ready = 1;
20905 }
20906
20907 static void
20908   vl_api_ipfix_exporter_details_t_handler_json
20909   (vl_api_ipfix_exporter_details_t * mp)
20910 {
20911   vat_main_t *vam = &vat_main;
20912   vat_json_node_t node;
20913   struct in_addr collector_address;
20914   struct in_addr src_address;
20915
20916   vat_json_init_object (&node);
20917   clib_memcpy (&collector_address, &mp->collector_address,
20918                sizeof (collector_address));
20919   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20920   vat_json_object_add_uint (&node, "collector_port",
20921                             ntohs (mp->collector_port));
20922   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20923   vat_json_object_add_ip4 (&node, "src_address", src_address);
20924   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20925   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20926   vat_json_object_add_uint (&node, "template_interval",
20927                             ntohl (mp->template_interval));
20928   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20929
20930   vat_json_print (vam->ofp, &node);
20931   vat_json_free (&node);
20932   vam->retval = 0;
20933   vam->result_ready = 1;
20934 }
20935
20936 int
20937 api_ipfix_exporter_dump (vat_main_t * vam)
20938 {
20939   vl_api_ipfix_exporter_dump_t *mp;
20940   int ret;
20941
20942   /* Construct the API message */
20943   M (IPFIX_EXPORTER_DUMP, mp);
20944   mp->context = 0;
20945
20946   S (mp);
20947   W (ret);
20948   return ret;
20949 }
20950
20951 static int
20952 api_ipfix_classify_stream_dump (vat_main_t * vam)
20953 {
20954   vl_api_ipfix_classify_stream_dump_t *mp;
20955   int ret;
20956
20957   /* Construct the API message */
20958   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20959   mp->context = 0;
20960
20961   S (mp);
20962   W (ret);
20963   return ret;
20964   /* NOTREACHED */
20965   return 0;
20966 }
20967
20968 static void
20969   vl_api_ipfix_classify_stream_details_t_handler
20970   (vl_api_ipfix_classify_stream_details_t * mp)
20971 {
20972   vat_main_t *vam = &vat_main;
20973   print (vam->ofp, "domain_id %d, src_port %d",
20974          ntohl (mp->domain_id), ntohs (mp->src_port));
20975   vam->retval = 0;
20976   vam->result_ready = 1;
20977 }
20978
20979 static void
20980   vl_api_ipfix_classify_stream_details_t_handler_json
20981   (vl_api_ipfix_classify_stream_details_t * mp)
20982 {
20983   vat_main_t *vam = &vat_main;
20984   vat_json_node_t node;
20985
20986   vat_json_init_object (&node);
20987   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20988   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20989
20990   vat_json_print (vam->ofp, &node);
20991   vat_json_free (&node);
20992   vam->retval = 0;
20993   vam->result_ready = 1;
20994 }
20995
20996 static int
20997 api_ipfix_classify_table_dump (vat_main_t * vam)
20998 {
20999   vl_api_ipfix_classify_table_dump_t *mp;
21000   vl_api_control_ping_t *mp_ping;
21001   int ret;
21002
21003   if (!vam->json_output)
21004     {
21005       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21006              "transport_protocol");
21007     }
21008
21009   /* Construct the API message */
21010   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21011
21012   /* send it... */
21013   S (mp);
21014
21015   /* Use a control ping for synchronization */
21016   MPING (CONTROL_PING, mp_ping);
21017   S (mp_ping);
21018
21019   W (ret);
21020   return ret;
21021 }
21022
21023 static void
21024   vl_api_ipfix_classify_table_details_t_handler
21025   (vl_api_ipfix_classify_table_details_t * mp)
21026 {
21027   vat_main_t *vam = &vat_main;
21028   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21029          mp->transport_protocol);
21030 }
21031
21032 static void
21033   vl_api_ipfix_classify_table_details_t_handler_json
21034   (vl_api_ipfix_classify_table_details_t * mp)
21035 {
21036   vat_json_node_t *node = NULL;
21037   vat_main_t *vam = &vat_main;
21038
21039   if (VAT_JSON_ARRAY != vam->json_tree.type)
21040     {
21041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21042       vat_json_init_array (&vam->json_tree);
21043     }
21044
21045   node = vat_json_array_add (&vam->json_tree);
21046   vat_json_init_object (node);
21047
21048   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21049   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21050   vat_json_object_add_uint (node, "transport_protocol",
21051                             mp->transport_protocol);
21052 }
21053
21054 static int
21055 api_sw_interface_span_enable_disable (vat_main_t * vam)
21056 {
21057   unformat_input_t *i = vam->input;
21058   vl_api_sw_interface_span_enable_disable_t *mp;
21059   u32 src_sw_if_index = ~0;
21060   u32 dst_sw_if_index = ~0;
21061   u8 state = 3;
21062   int ret;
21063   u8 is_l2 = 0;
21064
21065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21066     {
21067       if (unformat
21068           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21069         ;
21070       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21071         ;
21072       else
21073         if (unformat
21074             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21075         ;
21076       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21077         ;
21078       else if (unformat (i, "disable"))
21079         state = 0;
21080       else if (unformat (i, "rx"))
21081         state = 1;
21082       else if (unformat (i, "tx"))
21083         state = 2;
21084       else if (unformat (i, "both"))
21085         state = 3;
21086       else if (unformat (i, "l2"))
21087         is_l2 = 1;
21088       else
21089         break;
21090     }
21091
21092   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21093
21094   mp->sw_if_index_from = htonl (src_sw_if_index);
21095   mp->sw_if_index_to = htonl (dst_sw_if_index);
21096   mp->state = state;
21097   mp->is_l2 = is_l2;
21098
21099   S (mp);
21100   W (ret);
21101   return ret;
21102 }
21103
21104 static void
21105 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21106                                             * mp)
21107 {
21108   vat_main_t *vam = &vat_main;
21109   u8 *sw_if_from_name = 0;
21110   u8 *sw_if_to_name = 0;
21111   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21112   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21113   char *states[] = { "none", "rx", "tx", "both" };
21114   hash_pair_t *p;
21115
21116   /* *INDENT-OFF* */
21117   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21118   ({
21119     if ((u32) p->value[0] == sw_if_index_from)
21120       {
21121         sw_if_from_name = (u8 *)(p->key);
21122         if (sw_if_to_name)
21123           break;
21124       }
21125     if ((u32) p->value[0] == sw_if_index_to)
21126       {
21127         sw_if_to_name = (u8 *)(p->key);
21128         if (sw_if_from_name)
21129           break;
21130       }
21131   }));
21132   /* *INDENT-ON* */
21133   print (vam->ofp, "%20s => %20s (%s) %s",
21134          sw_if_from_name, sw_if_to_name, states[mp->state],
21135          mp->is_l2 ? "l2" : "device");
21136 }
21137
21138 static void
21139   vl_api_sw_interface_span_details_t_handler_json
21140   (vl_api_sw_interface_span_details_t * mp)
21141 {
21142   vat_main_t *vam = &vat_main;
21143   vat_json_node_t *node = NULL;
21144   u8 *sw_if_from_name = 0;
21145   u8 *sw_if_to_name = 0;
21146   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21147   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21148   hash_pair_t *p;
21149
21150   /* *INDENT-OFF* */
21151   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21152   ({
21153     if ((u32) p->value[0] == sw_if_index_from)
21154       {
21155         sw_if_from_name = (u8 *)(p->key);
21156         if (sw_if_to_name)
21157           break;
21158       }
21159     if ((u32) p->value[0] == sw_if_index_to)
21160       {
21161         sw_if_to_name = (u8 *)(p->key);
21162         if (sw_if_from_name)
21163           break;
21164       }
21165   }));
21166   /* *INDENT-ON* */
21167
21168   if (VAT_JSON_ARRAY != vam->json_tree.type)
21169     {
21170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21171       vat_json_init_array (&vam->json_tree);
21172     }
21173   node = vat_json_array_add (&vam->json_tree);
21174
21175   vat_json_init_object (node);
21176   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21177   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21178   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21179   if (0 != sw_if_to_name)
21180     {
21181       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21182     }
21183   vat_json_object_add_uint (node, "state", mp->state);
21184   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21185 }
21186
21187 static int
21188 api_sw_interface_span_dump (vat_main_t * vam)
21189 {
21190   unformat_input_t *input = vam->input;
21191   vl_api_sw_interface_span_dump_t *mp;
21192   vl_api_control_ping_t *mp_ping;
21193   u8 is_l2 = 0;
21194   int ret;
21195
21196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21197     {
21198       if (unformat (input, "l2"))
21199         is_l2 = 1;
21200       else
21201         break;
21202     }
21203
21204   M (SW_INTERFACE_SPAN_DUMP, mp);
21205   mp->is_l2 = is_l2;
21206   S (mp);
21207
21208   /* Use a control ping for synchronization */
21209   MPING (CONTROL_PING, mp_ping);
21210   S (mp_ping);
21211
21212   W (ret);
21213   return ret;
21214 }
21215
21216 int
21217 api_pg_create_interface (vat_main_t * vam)
21218 {
21219   unformat_input_t *input = vam->input;
21220   vl_api_pg_create_interface_t *mp;
21221
21222   u32 if_id = ~0;
21223   int ret;
21224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21225     {
21226       if (unformat (input, "if_id %d", &if_id))
21227         ;
21228       else
21229         break;
21230     }
21231   if (if_id == ~0)
21232     {
21233       errmsg ("missing pg interface index");
21234       return -99;
21235     }
21236
21237   /* Construct the API message */
21238   M (PG_CREATE_INTERFACE, mp);
21239   mp->context = 0;
21240   mp->interface_id = ntohl (if_id);
21241
21242   S (mp);
21243   W (ret);
21244   return ret;
21245 }
21246
21247 int
21248 api_pg_capture (vat_main_t * vam)
21249 {
21250   unformat_input_t *input = vam->input;
21251   vl_api_pg_capture_t *mp;
21252
21253   u32 if_id = ~0;
21254   u8 enable = 1;
21255   u32 count = 1;
21256   u8 pcap_file_set = 0;
21257   u8 *pcap_file = 0;
21258   int ret;
21259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21260     {
21261       if (unformat (input, "if_id %d", &if_id))
21262         ;
21263       else if (unformat (input, "pcap %s", &pcap_file))
21264         pcap_file_set = 1;
21265       else if (unformat (input, "count %d", &count))
21266         ;
21267       else if (unformat (input, "disable"))
21268         enable = 0;
21269       else
21270         break;
21271     }
21272   if (if_id == ~0)
21273     {
21274       errmsg ("missing pg interface index");
21275       return -99;
21276     }
21277   if (pcap_file_set > 0)
21278     {
21279       if (vec_len (pcap_file) > 255)
21280         {
21281           errmsg ("pcap file name is too long");
21282           return -99;
21283         }
21284     }
21285
21286   u32 name_len = vec_len (pcap_file);
21287   /* Construct the API message */
21288   M (PG_CAPTURE, mp);
21289   mp->context = 0;
21290   mp->interface_id = ntohl (if_id);
21291   mp->is_enabled = enable;
21292   mp->count = ntohl (count);
21293   mp->pcap_name_length = ntohl (name_len);
21294   if (pcap_file_set != 0)
21295     {
21296       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21297     }
21298   vec_free (pcap_file);
21299
21300   S (mp);
21301   W (ret);
21302   return ret;
21303 }
21304
21305 int
21306 api_pg_enable_disable (vat_main_t * vam)
21307 {
21308   unformat_input_t *input = vam->input;
21309   vl_api_pg_enable_disable_t *mp;
21310
21311   u8 enable = 1;
21312   u8 stream_name_set = 0;
21313   u8 *stream_name = 0;
21314   int ret;
21315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21316     {
21317       if (unformat (input, "stream %s", &stream_name))
21318         stream_name_set = 1;
21319       else if (unformat (input, "disable"))
21320         enable = 0;
21321       else
21322         break;
21323     }
21324
21325   if (stream_name_set > 0)
21326     {
21327       if (vec_len (stream_name) > 255)
21328         {
21329           errmsg ("stream name too long");
21330           return -99;
21331         }
21332     }
21333
21334   u32 name_len = vec_len (stream_name);
21335   /* Construct the API message */
21336   M (PG_ENABLE_DISABLE, mp);
21337   mp->context = 0;
21338   mp->is_enabled = enable;
21339   if (stream_name_set != 0)
21340     {
21341       mp->stream_name_length = ntohl (name_len);
21342       clib_memcpy (mp->stream_name, stream_name, name_len);
21343     }
21344   vec_free (stream_name);
21345
21346   S (mp);
21347   W (ret);
21348   return ret;
21349 }
21350
21351 int
21352 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21353 {
21354   unformat_input_t *input = vam->input;
21355   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21356
21357   u16 *low_ports = 0;
21358   u16 *high_ports = 0;
21359   u16 this_low;
21360   u16 this_hi;
21361   ip4_address_t ip4_addr;
21362   ip6_address_t ip6_addr;
21363   u32 length;
21364   u32 tmp, tmp2;
21365   u8 prefix_set = 0;
21366   u32 vrf_id = ~0;
21367   u8 is_add = 1;
21368   u8 is_ipv6 = 0;
21369   int ret;
21370
21371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21372     {
21373       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21374         {
21375           prefix_set = 1;
21376         }
21377       else
21378         if (unformat
21379             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21380         {
21381           prefix_set = 1;
21382           is_ipv6 = 1;
21383         }
21384       else if (unformat (input, "vrf %d", &vrf_id))
21385         ;
21386       else if (unformat (input, "del"))
21387         is_add = 0;
21388       else if (unformat (input, "port %d", &tmp))
21389         {
21390           if (tmp == 0 || tmp > 65535)
21391             {
21392               errmsg ("port %d out of range", tmp);
21393               return -99;
21394             }
21395           this_low = tmp;
21396           this_hi = this_low + 1;
21397           vec_add1 (low_ports, this_low);
21398           vec_add1 (high_ports, this_hi);
21399         }
21400       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21401         {
21402           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21403             {
21404               errmsg ("incorrect range parameters");
21405               return -99;
21406             }
21407           this_low = tmp;
21408           /* Note: in debug CLI +1 is added to high before
21409              passing to real fn that does "the work"
21410              (ip_source_and_port_range_check_add_del).
21411              This fn is a wrapper around the binary API fn a
21412              control plane will call, which expects this increment
21413              to have occurred. Hence letting the binary API control
21414              plane fn do the increment for consistency between VAT
21415              and other control planes.
21416            */
21417           this_hi = tmp2;
21418           vec_add1 (low_ports, this_low);
21419           vec_add1 (high_ports, this_hi);
21420         }
21421       else
21422         break;
21423     }
21424
21425   if (prefix_set == 0)
21426     {
21427       errmsg ("<address>/<mask> not specified");
21428       return -99;
21429     }
21430
21431   if (vrf_id == ~0)
21432     {
21433       errmsg ("VRF ID required, not specified");
21434       return -99;
21435     }
21436
21437   if (vrf_id == 0)
21438     {
21439       errmsg
21440         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21441       return -99;
21442     }
21443
21444   if (vec_len (low_ports) == 0)
21445     {
21446       errmsg ("At least one port or port range required");
21447       return -99;
21448     }
21449
21450   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21451
21452   mp->is_add = is_add;
21453
21454   if (is_ipv6)
21455     {
21456       mp->is_ipv6 = 1;
21457       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21458     }
21459   else
21460     {
21461       mp->is_ipv6 = 0;
21462       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21463     }
21464
21465   mp->mask_length = length;
21466   mp->number_of_ranges = vec_len (low_ports);
21467
21468   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21469   vec_free (low_ports);
21470
21471   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21472   vec_free (high_ports);
21473
21474   mp->vrf_id = ntohl (vrf_id);
21475
21476   S (mp);
21477   W (ret);
21478   return ret;
21479 }
21480
21481 int
21482 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21483 {
21484   unformat_input_t *input = vam->input;
21485   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21486   u32 sw_if_index = ~0;
21487   int vrf_set = 0;
21488   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21489   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21490   u8 is_add = 1;
21491   int ret;
21492
21493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21494     {
21495       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21496         ;
21497       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21498         ;
21499       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21500         vrf_set = 1;
21501       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21502         vrf_set = 1;
21503       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21504         vrf_set = 1;
21505       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21506         vrf_set = 1;
21507       else if (unformat (input, "del"))
21508         is_add = 0;
21509       else
21510         break;
21511     }
21512
21513   if (sw_if_index == ~0)
21514     {
21515       errmsg ("Interface required but not specified");
21516       return -99;
21517     }
21518
21519   if (vrf_set == 0)
21520     {
21521       errmsg ("VRF ID required but not specified");
21522       return -99;
21523     }
21524
21525   if (tcp_out_vrf_id == 0
21526       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21527     {
21528       errmsg
21529         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21530       return -99;
21531     }
21532
21533   /* Construct the API message */
21534   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21535
21536   mp->sw_if_index = ntohl (sw_if_index);
21537   mp->is_add = is_add;
21538   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21539   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21540   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21541   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21542
21543   /* send it... */
21544   S (mp);
21545
21546   /* Wait for a reply... */
21547   W (ret);
21548   return ret;
21549 }
21550
21551 static int
21552 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21553 {
21554   unformat_input_t *i = vam->input;
21555   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21556   u32 local_sa_id = 0;
21557   u32 remote_sa_id = 0;
21558   ip4_address_t src_address;
21559   ip4_address_t dst_address;
21560   u8 is_add = 1;
21561   int ret;
21562
21563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21564     {
21565       if (unformat (i, "local_sa %d", &local_sa_id))
21566         ;
21567       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21568         ;
21569       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21570         ;
21571       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21572         ;
21573       else if (unformat (i, "del"))
21574         is_add = 0;
21575       else
21576         {
21577           clib_warning ("parse error '%U'", format_unformat_error, i);
21578           return -99;
21579         }
21580     }
21581
21582   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21583
21584   mp->local_sa_id = ntohl (local_sa_id);
21585   mp->remote_sa_id = ntohl (remote_sa_id);
21586   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21587   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21588   mp->is_add = is_add;
21589
21590   S (mp);
21591   W (ret);
21592   return ret;
21593 }
21594
21595 static int
21596 api_punt (vat_main_t * vam)
21597 {
21598   unformat_input_t *i = vam->input;
21599   vl_api_punt_t *mp;
21600   u32 ipv = ~0;
21601   u32 protocol = ~0;
21602   u32 port = ~0;
21603   int is_add = 1;
21604   int ret;
21605
21606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21607     {
21608       if (unformat (i, "ip %d", &ipv))
21609         ;
21610       else if (unformat (i, "protocol %d", &protocol))
21611         ;
21612       else if (unformat (i, "port %d", &port))
21613         ;
21614       else if (unformat (i, "del"))
21615         is_add = 0;
21616       else
21617         {
21618           clib_warning ("parse error '%U'", format_unformat_error, i);
21619           return -99;
21620         }
21621     }
21622
21623   M (PUNT, mp);
21624
21625   mp->is_add = (u8) is_add;
21626   mp->ipv = (u8) ipv;
21627   mp->l4_protocol = (u8) protocol;
21628   mp->l4_port = htons ((u16) port);
21629
21630   S (mp);
21631   W (ret);
21632   return ret;
21633 }
21634
21635 static void vl_api_ipsec_gre_tunnel_details_t_handler
21636   (vl_api_ipsec_gre_tunnel_details_t * mp)
21637 {
21638   vat_main_t *vam = &vat_main;
21639
21640   print (vam->ofp, "%11d%15U%15U%14d%14d",
21641          ntohl (mp->sw_if_index),
21642          format_ip4_address, &mp->src_address,
21643          format_ip4_address, &mp->dst_address,
21644          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21645 }
21646
21647 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21648   (vl_api_ipsec_gre_tunnel_details_t * mp)
21649 {
21650   vat_main_t *vam = &vat_main;
21651   vat_json_node_t *node = NULL;
21652   struct in_addr ip4;
21653
21654   if (VAT_JSON_ARRAY != vam->json_tree.type)
21655     {
21656       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21657       vat_json_init_array (&vam->json_tree);
21658     }
21659   node = vat_json_array_add (&vam->json_tree);
21660
21661   vat_json_init_object (node);
21662   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21663   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21664   vat_json_object_add_ip4 (node, "src_address", ip4);
21665   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21666   vat_json_object_add_ip4 (node, "dst_address", ip4);
21667   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21668   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21669 }
21670
21671 static int
21672 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21673 {
21674   unformat_input_t *i = vam->input;
21675   vl_api_ipsec_gre_tunnel_dump_t *mp;
21676   vl_api_control_ping_t *mp_ping;
21677   u32 sw_if_index;
21678   u8 sw_if_index_set = 0;
21679   int ret;
21680
21681   /* Parse args required to build the message */
21682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21683     {
21684       if (unformat (i, "sw_if_index %d", &sw_if_index))
21685         sw_if_index_set = 1;
21686       else
21687         break;
21688     }
21689
21690   if (sw_if_index_set == 0)
21691     {
21692       sw_if_index = ~0;
21693     }
21694
21695   if (!vam->json_output)
21696     {
21697       print (vam->ofp, "%11s%15s%15s%14s%14s",
21698              "sw_if_index", "src_address", "dst_address",
21699              "local_sa_id", "remote_sa_id");
21700     }
21701
21702   /* Get list of gre-tunnel interfaces */
21703   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21704
21705   mp->sw_if_index = htonl (sw_if_index);
21706
21707   S (mp);
21708
21709   /* Use a control ping for synchronization */
21710   MPING (CONTROL_PING, mp_ping);
21711   S (mp_ping);
21712
21713   W (ret);
21714   return ret;
21715 }
21716
21717 static int
21718 api_delete_subif (vat_main_t * vam)
21719 {
21720   unformat_input_t *i = vam->input;
21721   vl_api_delete_subif_t *mp;
21722   u32 sw_if_index = ~0;
21723   int ret;
21724
21725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21726     {
21727       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21728         ;
21729       if (unformat (i, "sw_if_index %d", &sw_if_index))
21730         ;
21731       else
21732         break;
21733     }
21734
21735   if (sw_if_index == ~0)
21736     {
21737       errmsg ("missing sw_if_index");
21738       return -99;
21739     }
21740
21741   /* Construct the API message */
21742   M (DELETE_SUBIF, mp);
21743   mp->sw_if_index = ntohl (sw_if_index);
21744
21745   S (mp);
21746   W (ret);
21747   return ret;
21748 }
21749
21750 #define foreach_pbb_vtr_op      \
21751 _("disable",  L2_VTR_DISABLED)  \
21752 _("pop",  L2_VTR_POP_2)         \
21753 _("push",  L2_VTR_PUSH_2)
21754
21755 static int
21756 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21757 {
21758   unformat_input_t *i = vam->input;
21759   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21760   u32 sw_if_index = ~0, vtr_op = ~0;
21761   u16 outer_tag = ~0;
21762   u8 dmac[6], smac[6];
21763   u8 dmac_set = 0, smac_set = 0;
21764   u16 vlanid = 0;
21765   u32 sid = ~0;
21766   u32 tmp;
21767   int ret;
21768
21769   /* Shut up coverity */
21770   memset (dmac, 0, sizeof (dmac));
21771   memset (smac, 0, sizeof (smac));
21772
21773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21774     {
21775       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21776         ;
21777       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21778         ;
21779       else if (unformat (i, "vtr_op %d", &vtr_op))
21780         ;
21781 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21782       foreach_pbb_vtr_op
21783 #undef _
21784         else if (unformat (i, "translate_pbb_stag"))
21785         {
21786           if (unformat (i, "%d", &tmp))
21787             {
21788               vtr_op = L2_VTR_TRANSLATE_2_1;
21789               outer_tag = tmp;
21790             }
21791           else
21792             {
21793               errmsg
21794                 ("translate_pbb_stag operation requires outer tag definition");
21795               return -99;
21796             }
21797         }
21798       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21799         dmac_set++;
21800       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21801         smac_set++;
21802       else if (unformat (i, "sid %d", &sid))
21803         ;
21804       else if (unformat (i, "vlanid %d", &tmp))
21805         vlanid = tmp;
21806       else
21807         {
21808           clib_warning ("parse error '%U'", format_unformat_error, i);
21809           return -99;
21810         }
21811     }
21812
21813   if ((sw_if_index == ~0) || (vtr_op == ~0))
21814     {
21815       errmsg ("missing sw_if_index or vtr operation");
21816       return -99;
21817     }
21818   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21819       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21820     {
21821       errmsg
21822         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21823       return -99;
21824     }
21825
21826   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21827   mp->sw_if_index = ntohl (sw_if_index);
21828   mp->vtr_op = ntohl (vtr_op);
21829   mp->outer_tag = ntohs (outer_tag);
21830   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21831   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21832   mp->b_vlanid = ntohs (vlanid);
21833   mp->i_sid = ntohl (sid);
21834
21835   S (mp);
21836   W (ret);
21837   return ret;
21838 }
21839
21840 static int
21841 api_flow_classify_set_interface (vat_main_t * vam)
21842 {
21843   unformat_input_t *i = vam->input;
21844   vl_api_flow_classify_set_interface_t *mp;
21845   u32 sw_if_index;
21846   int sw_if_index_set;
21847   u32 ip4_table_index = ~0;
21848   u32 ip6_table_index = ~0;
21849   u8 is_add = 1;
21850   int ret;
21851
21852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21853     {
21854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21855         sw_if_index_set = 1;
21856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21857         sw_if_index_set = 1;
21858       else if (unformat (i, "del"))
21859         is_add = 0;
21860       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21861         ;
21862       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21863         ;
21864       else
21865         {
21866           clib_warning ("parse error '%U'", format_unformat_error, i);
21867           return -99;
21868         }
21869     }
21870
21871   if (sw_if_index_set == 0)
21872     {
21873       errmsg ("missing interface name or sw_if_index");
21874       return -99;
21875     }
21876
21877   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21878
21879   mp->sw_if_index = ntohl (sw_if_index);
21880   mp->ip4_table_index = ntohl (ip4_table_index);
21881   mp->ip6_table_index = ntohl (ip6_table_index);
21882   mp->is_add = is_add;
21883
21884   S (mp);
21885   W (ret);
21886   return ret;
21887 }
21888
21889 static int
21890 api_flow_classify_dump (vat_main_t * vam)
21891 {
21892   unformat_input_t *i = vam->input;
21893   vl_api_flow_classify_dump_t *mp;
21894   vl_api_control_ping_t *mp_ping;
21895   u8 type = FLOW_CLASSIFY_N_TABLES;
21896   int ret;
21897
21898   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21899     ;
21900   else
21901     {
21902       errmsg ("classify table type must be specified");
21903       return -99;
21904     }
21905
21906   if (!vam->json_output)
21907     {
21908       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21909     }
21910
21911   M (FLOW_CLASSIFY_DUMP, mp);
21912   mp->type = type;
21913   /* send it... */
21914   S (mp);
21915
21916   /* Use a control ping for synchronization */
21917   MPING (CONTROL_PING, mp_ping);
21918   S (mp_ping);
21919
21920   /* Wait for a reply... */
21921   W (ret);
21922   return ret;
21923 }
21924
21925 static int
21926 api_feature_enable_disable (vat_main_t * vam)
21927 {
21928   unformat_input_t *i = vam->input;
21929   vl_api_feature_enable_disable_t *mp;
21930   u8 *arc_name = 0;
21931   u8 *feature_name = 0;
21932   u32 sw_if_index = ~0;
21933   u8 enable = 1;
21934   int ret;
21935
21936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21937     {
21938       if (unformat (i, "arc_name %s", &arc_name))
21939         ;
21940       else if (unformat (i, "feature_name %s", &feature_name))
21941         ;
21942       else
21943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21944         ;
21945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21946         ;
21947       else if (unformat (i, "disable"))
21948         enable = 0;
21949       else
21950         break;
21951     }
21952
21953   if (arc_name == 0)
21954     {
21955       errmsg ("missing arc name");
21956       return -99;
21957     }
21958   if (vec_len (arc_name) > 63)
21959     {
21960       errmsg ("arc name too long");
21961     }
21962
21963   if (feature_name == 0)
21964     {
21965       errmsg ("missing feature name");
21966       return -99;
21967     }
21968   if (vec_len (feature_name) > 63)
21969     {
21970       errmsg ("feature name too long");
21971     }
21972
21973   if (sw_if_index == ~0)
21974     {
21975       errmsg ("missing interface name or sw_if_index");
21976       return -99;
21977     }
21978
21979   /* Construct the API message */
21980   M (FEATURE_ENABLE_DISABLE, mp);
21981   mp->sw_if_index = ntohl (sw_if_index);
21982   mp->enable = enable;
21983   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21984   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21985   vec_free (arc_name);
21986   vec_free (feature_name);
21987
21988   S (mp);
21989   W (ret);
21990   return ret;
21991 }
21992
21993 static int
21994 api_sw_interface_tag_add_del (vat_main_t * vam)
21995 {
21996   unformat_input_t *i = vam->input;
21997   vl_api_sw_interface_tag_add_del_t *mp;
21998   u32 sw_if_index = ~0;
21999   u8 *tag = 0;
22000   u8 enable = 1;
22001   int ret;
22002
22003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22004     {
22005       if (unformat (i, "tag %s", &tag))
22006         ;
22007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22008         ;
22009       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22010         ;
22011       else if (unformat (i, "del"))
22012         enable = 0;
22013       else
22014         break;
22015     }
22016
22017   if (sw_if_index == ~0)
22018     {
22019       errmsg ("missing interface name or sw_if_index");
22020       return -99;
22021     }
22022
22023   if (enable && (tag == 0))
22024     {
22025       errmsg ("no tag specified");
22026       return -99;
22027     }
22028
22029   /* Construct the API message */
22030   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22031   mp->sw_if_index = ntohl (sw_if_index);
22032   mp->is_add = enable;
22033   if (enable)
22034     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22035   vec_free (tag);
22036
22037   S (mp);
22038   W (ret);
22039   return ret;
22040 }
22041
22042 static void vl_api_l2_xconnect_details_t_handler
22043   (vl_api_l2_xconnect_details_t * mp)
22044 {
22045   vat_main_t *vam = &vat_main;
22046
22047   print (vam->ofp, "%15d%15d",
22048          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22049 }
22050
22051 static void vl_api_l2_xconnect_details_t_handler_json
22052   (vl_api_l2_xconnect_details_t * mp)
22053 {
22054   vat_main_t *vam = &vat_main;
22055   vat_json_node_t *node = NULL;
22056
22057   if (VAT_JSON_ARRAY != vam->json_tree.type)
22058     {
22059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22060       vat_json_init_array (&vam->json_tree);
22061     }
22062   node = vat_json_array_add (&vam->json_tree);
22063
22064   vat_json_init_object (node);
22065   vat_json_object_add_uint (node, "rx_sw_if_index",
22066                             ntohl (mp->rx_sw_if_index));
22067   vat_json_object_add_uint (node, "tx_sw_if_index",
22068                             ntohl (mp->tx_sw_if_index));
22069 }
22070
22071 static int
22072 api_l2_xconnect_dump (vat_main_t * vam)
22073 {
22074   vl_api_l2_xconnect_dump_t *mp;
22075   vl_api_control_ping_t *mp_ping;
22076   int ret;
22077
22078   if (!vam->json_output)
22079     {
22080       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22081     }
22082
22083   M (L2_XCONNECT_DUMP, mp);
22084
22085   S (mp);
22086
22087   /* Use a control ping for synchronization */
22088   MPING (CONTROL_PING, mp_ping);
22089   S (mp_ping);
22090
22091   W (ret);
22092   return ret;
22093 }
22094
22095 static int
22096 api_hw_interface_set_mtu (vat_main_t * vam)
22097 {
22098   unformat_input_t *i = vam->input;
22099   vl_api_hw_interface_set_mtu_t *mp;
22100   u32 sw_if_index = ~0;
22101   u32 mtu = 0;
22102   int ret;
22103
22104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22105     {
22106       if (unformat (i, "mtu %d", &mtu))
22107         ;
22108       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22109         ;
22110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22111         ;
22112       else
22113         break;
22114     }
22115
22116   if (sw_if_index == ~0)
22117     {
22118       errmsg ("missing interface name or sw_if_index");
22119       return -99;
22120     }
22121
22122   if (mtu == 0)
22123     {
22124       errmsg ("no mtu specified");
22125       return -99;
22126     }
22127
22128   /* Construct the API message */
22129   M (HW_INTERFACE_SET_MTU, mp);
22130   mp->sw_if_index = ntohl (sw_if_index);
22131   mp->mtu = ntohs ((u16) mtu);
22132
22133   S (mp);
22134   W (ret);
22135   return ret;
22136 }
22137
22138 static int
22139 api_p2p_ethernet_add (vat_main_t * vam)
22140 {
22141   unformat_input_t *i = vam->input;
22142   vl_api_p2p_ethernet_add_t *mp;
22143   u32 parent_if_index = ~0;
22144   u32 sub_id = ~0;
22145   u8 remote_mac[6];
22146   u8 mac_set = 0;
22147   int ret;
22148
22149   memset (remote_mac, 0, sizeof (remote_mac));
22150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22151     {
22152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22153         ;
22154       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22155         ;
22156       else
22157         if (unformat
22158             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22159         mac_set++;
22160       else if (unformat (i, "sub_id %d", &sub_id))
22161         ;
22162       else
22163         {
22164           clib_warning ("parse error '%U'", format_unformat_error, i);
22165           return -99;
22166         }
22167     }
22168
22169   if (parent_if_index == ~0)
22170     {
22171       errmsg ("missing interface name or sw_if_index");
22172       return -99;
22173     }
22174   if (mac_set == 0)
22175     {
22176       errmsg ("missing remote mac address");
22177       return -99;
22178     }
22179   if (sub_id == ~0)
22180     {
22181       errmsg ("missing sub-interface id");
22182       return -99;
22183     }
22184
22185   M (P2P_ETHERNET_ADD, mp);
22186   mp->parent_if_index = ntohl (parent_if_index);
22187   mp->subif_id = ntohl (sub_id);
22188   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22189
22190   S (mp);
22191   W (ret);
22192   return ret;
22193 }
22194
22195 static int
22196 api_p2p_ethernet_del (vat_main_t * vam)
22197 {
22198   unformat_input_t *i = vam->input;
22199   vl_api_p2p_ethernet_del_t *mp;
22200   u32 parent_if_index = ~0;
22201   u8 remote_mac[6];
22202   u8 mac_set = 0;
22203   int ret;
22204
22205   memset (remote_mac, 0, sizeof (remote_mac));
22206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22207     {
22208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22209         ;
22210       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22211         ;
22212       else
22213         if (unformat
22214             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22215         mac_set++;
22216       else
22217         {
22218           clib_warning ("parse error '%U'", format_unformat_error, i);
22219           return -99;
22220         }
22221     }
22222
22223   if (parent_if_index == ~0)
22224     {
22225       errmsg ("missing interface name or sw_if_index");
22226       return -99;
22227     }
22228   if (mac_set == 0)
22229     {
22230       errmsg ("missing remote mac address");
22231       return -99;
22232     }
22233
22234   M (P2P_ETHERNET_DEL, mp);
22235   mp->parent_if_index = ntohl (parent_if_index);
22236   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22237
22238   S (mp);
22239   W (ret);
22240   return ret;
22241 }
22242
22243 static int
22244 api_lldp_config (vat_main_t * vam)
22245 {
22246   unformat_input_t *i = vam->input;
22247   vl_api_lldp_config_t *mp;
22248   int tx_hold = 0;
22249   int tx_interval = 0;
22250   u8 *sys_name = NULL;
22251   int ret;
22252
22253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22254     {
22255       if (unformat (i, "system-name %s", &sys_name))
22256         ;
22257       else if (unformat (i, "tx-hold %d", &tx_hold))
22258         ;
22259       else if (unformat (i, "tx-interval %d", &tx_interval))
22260         ;
22261       else
22262         {
22263           clib_warning ("parse error '%U'", format_unformat_error, i);
22264           return -99;
22265         }
22266     }
22267
22268   vec_add1 (sys_name, 0);
22269
22270   M (LLDP_CONFIG, mp);
22271   mp->tx_hold = htonl (tx_hold);
22272   mp->tx_interval = htonl (tx_interval);
22273   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22274   vec_free (sys_name);
22275
22276   S (mp);
22277   W (ret);
22278   return ret;
22279 }
22280
22281 static int
22282 api_sw_interface_set_lldp (vat_main_t * vam)
22283 {
22284   unformat_input_t *i = vam->input;
22285   vl_api_sw_interface_set_lldp_t *mp;
22286   u32 sw_if_index = ~0;
22287   u32 enable = 1;
22288   u8 *port_desc = NULL, *mgmt_oid = NULL;
22289   ip4_address_t ip4_addr;
22290   ip6_address_t ip6_addr;
22291   int ret;
22292
22293   memset (&ip4_addr, 0, sizeof (ip4_addr));
22294   memset (&ip6_addr, 0, sizeof (ip6_addr));
22295
22296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22297     {
22298       if (unformat (i, "disable"))
22299         enable = 0;
22300       else
22301         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22302         ;
22303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22304         ;
22305       else if (unformat (i, "port-desc %s", &port_desc))
22306         ;
22307       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22308         ;
22309       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22310         ;
22311       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22312         ;
22313       else
22314         break;
22315     }
22316
22317   if (sw_if_index == ~0)
22318     {
22319       errmsg ("missing interface name or sw_if_index");
22320       return -99;
22321     }
22322
22323   /* Construct the API message */
22324   vec_add1 (port_desc, 0);
22325   vec_add1 (mgmt_oid, 0);
22326   M (SW_INTERFACE_SET_LLDP, mp);
22327   mp->sw_if_index = ntohl (sw_if_index);
22328   mp->enable = enable;
22329   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22330   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22331   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22332   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22333   vec_free (port_desc);
22334   vec_free (mgmt_oid);
22335
22336   S (mp);
22337   W (ret);
22338   return ret;
22339 }
22340
22341 static int
22342 api_tcp_configure_src_addresses (vat_main_t * vam)
22343 {
22344   vl_api_tcp_configure_src_addresses_t *mp;
22345   unformat_input_t *i = vam->input;
22346   ip4_address_t v4first, v4last;
22347   ip6_address_t v6first, v6last;
22348   u8 range_set = 0;
22349   u32 vrf_id = 0;
22350   int ret;
22351
22352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22353     {
22354       if (unformat (i, "%U - %U",
22355                     unformat_ip4_address, &v4first,
22356                     unformat_ip4_address, &v4last))
22357         {
22358           if (range_set)
22359             {
22360               errmsg ("one range per message (range already set)");
22361               return -99;
22362             }
22363           range_set = 1;
22364         }
22365       else if (unformat (i, "%U - %U",
22366                          unformat_ip6_address, &v6first,
22367                          unformat_ip6_address, &v6last))
22368         {
22369           if (range_set)
22370             {
22371               errmsg ("one range per message (range already set)");
22372               return -99;
22373             }
22374           range_set = 2;
22375         }
22376       else if (unformat (i, "vrf %d", &vrf_id))
22377         ;
22378       else
22379         break;
22380     }
22381
22382   if (range_set == 0)
22383     {
22384       errmsg ("address range not set");
22385       return -99;
22386     }
22387
22388   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22389   mp->vrf_id = ntohl (vrf_id);
22390   /* ipv6? */
22391   if (range_set == 2)
22392     {
22393       mp->is_ipv6 = 1;
22394       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22395       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22396     }
22397   else
22398     {
22399       mp->is_ipv6 = 0;
22400       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22401       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22402     }
22403   S (mp);
22404   W (ret);
22405   return ret;
22406 }
22407
22408 static void vl_api_app_namespace_add_del_reply_t_handler
22409   (vl_api_app_namespace_add_del_reply_t * mp)
22410 {
22411   vat_main_t *vam = &vat_main;
22412   i32 retval = ntohl (mp->retval);
22413   if (vam->async_mode)
22414     {
22415       vam->async_errors += (retval < 0);
22416     }
22417   else
22418     {
22419       vam->retval = retval;
22420       if (retval == 0)
22421         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22422       vam->result_ready = 1;
22423     }
22424 }
22425
22426 static void vl_api_app_namespace_add_del_reply_t_handler_json
22427   (vl_api_app_namespace_add_del_reply_t * mp)
22428 {
22429   vat_main_t *vam = &vat_main;
22430   vat_json_node_t node;
22431
22432   vat_json_init_object (&node);
22433   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22434   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22435
22436   vat_json_print (vam->ofp, &node);
22437   vat_json_free (&node);
22438
22439   vam->retval = ntohl (mp->retval);
22440   vam->result_ready = 1;
22441 }
22442
22443 static int
22444 api_app_namespace_add_del (vat_main_t * vam)
22445 {
22446   vl_api_app_namespace_add_del_t *mp;
22447   unformat_input_t *i = vam->input;
22448   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22449   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22450   u64 secret;
22451   int ret;
22452
22453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22454     {
22455       if (unformat (i, "id %_%v%_", &ns_id))
22456         ;
22457       else if (unformat (i, "secret %lu", &secret))
22458         secret_set = 1;
22459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22460         sw_if_index_set = 1;
22461       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22462         ;
22463       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22464         ;
22465       else
22466         break;
22467     }
22468   if (!ns_id || !secret_set || !sw_if_index_set)
22469     {
22470       errmsg ("namespace id, secret and sw_if_index must be set");
22471       return -99;
22472     }
22473   if (vec_len (ns_id) > 64)
22474     {
22475       errmsg ("namespace id too long");
22476       return -99;
22477     }
22478   M (APP_NAMESPACE_ADD_DEL, mp);
22479
22480   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22481   mp->namespace_id_len = vec_len (ns_id);
22482   mp->secret = clib_host_to_net_u64 (secret);
22483   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22484   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22485   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22486   vec_free (ns_id);
22487   S (mp);
22488   W (ret);
22489   return ret;
22490 }
22491
22492 static int
22493 api_sock_init_shm (vat_main_t * vam)
22494 {
22495 #if VPP_API_TEST_BUILTIN == 0
22496   unformat_input_t *i = vam->input;
22497   vl_api_shm_elem_config_t *config = 0;
22498   u64 size = 64 << 20;
22499   int rv;
22500
22501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22502     {
22503       if (unformat (i, "size %U", unformat_memory_size, &size))
22504         ;
22505       else
22506         break;
22507     }
22508
22509   /*
22510    * Canned custom ring allocator config.
22511    * Should probably parse all of this
22512    */
22513   vec_validate (config, 6);
22514   config[0].type = VL_API_VLIB_RING;
22515   config[0].size = 256;
22516   config[0].count = 32;
22517
22518   config[1].type = VL_API_VLIB_RING;
22519   config[1].size = 1024;
22520   config[1].count = 16;
22521
22522   config[2].type = VL_API_VLIB_RING;
22523   config[2].size = 4096;
22524   config[2].count = 2;
22525
22526   config[3].type = VL_API_CLIENT_RING;
22527   config[3].size = 256;
22528   config[3].count = 32;
22529
22530   config[4].type = VL_API_CLIENT_RING;
22531   config[4].size = 1024;
22532   config[4].count = 16;
22533
22534   config[5].type = VL_API_CLIENT_RING;
22535   config[5].size = 4096;
22536   config[5].count = 2;
22537
22538   config[6].type = VL_API_QUEUE;
22539   config[6].count = 128;
22540   config[6].size = sizeof (uword);
22541
22542   rv = vl_socket_client_init_shm (config);
22543   if (!rv)
22544     vam->client_index_invalid = 1;
22545   return rv;
22546 #else
22547   return -99;
22548 #endif
22549 }
22550
22551 static int
22552 api_dns_enable_disable (vat_main_t * vam)
22553 {
22554   unformat_input_t *line_input = vam->input;
22555   vl_api_dns_enable_disable_t *mp;
22556   u8 enable_disable = 1;
22557   int ret;
22558
22559   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22560     {
22561       if (unformat (line_input, "disable"))
22562         enable_disable = 0;
22563       if (unformat (line_input, "enable"))
22564         enable_disable = 1;
22565       else
22566         break;
22567     }
22568
22569   /* Construct the API message */
22570   M (DNS_ENABLE_DISABLE, mp);
22571   mp->enable = enable_disable;
22572
22573   /* send it... */
22574   S (mp);
22575   /* Wait for the reply */
22576   W (ret);
22577   return ret;
22578 }
22579
22580 static int
22581 api_dns_resolve_name (vat_main_t * vam)
22582 {
22583   unformat_input_t *line_input = vam->input;
22584   vl_api_dns_resolve_name_t *mp;
22585   u8 *name = 0;
22586   int ret;
22587
22588   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22589     {
22590       if (unformat (line_input, "%s", &name))
22591         ;
22592       else
22593         break;
22594     }
22595
22596   if (vec_len (name) > 127)
22597     {
22598       errmsg ("name too long");
22599       return -99;
22600     }
22601
22602   /* Construct the API message */
22603   M (DNS_RESOLVE_NAME, mp);
22604   memcpy (mp->name, name, vec_len (name));
22605   vec_free (name);
22606
22607   /* send it... */
22608   S (mp);
22609   /* Wait for the reply */
22610   W (ret);
22611   return ret;
22612 }
22613
22614 static int
22615 api_dns_resolve_ip (vat_main_t * vam)
22616 {
22617   unformat_input_t *line_input = vam->input;
22618   vl_api_dns_resolve_ip_t *mp;
22619   int is_ip6 = -1;
22620   ip4_address_t addr4;
22621   ip6_address_t addr6;
22622   int ret;
22623
22624   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22625     {
22626       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22627         is_ip6 = 1;
22628       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22629         is_ip6 = 0;
22630       else
22631         break;
22632     }
22633
22634   if (is_ip6 == -1)
22635     {
22636       errmsg ("missing address");
22637       return -99;
22638     }
22639
22640   /* Construct the API message */
22641   M (DNS_RESOLVE_IP, mp);
22642   mp->is_ip6 = is_ip6;
22643   if (is_ip6)
22644     memcpy (mp->address, &addr6, sizeof (addr6));
22645   else
22646     memcpy (mp->address, &addr4, sizeof (addr4));
22647
22648   /* send it... */
22649   S (mp);
22650   /* Wait for the reply */
22651   W (ret);
22652   return ret;
22653 }
22654
22655 static int
22656 api_dns_name_server_add_del (vat_main_t * vam)
22657 {
22658   unformat_input_t *i = vam->input;
22659   vl_api_dns_name_server_add_del_t *mp;
22660   u8 is_add = 1;
22661   ip6_address_t ip6_server;
22662   ip4_address_t ip4_server;
22663   int ip6_set = 0;
22664   int ip4_set = 0;
22665   int ret = 0;
22666
22667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22668     {
22669       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22670         ip6_set = 1;
22671       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22672         ip4_set = 1;
22673       else if (unformat (i, "del"))
22674         is_add = 0;
22675       else
22676         {
22677           clib_warning ("parse error '%U'", format_unformat_error, i);
22678           return -99;
22679         }
22680     }
22681
22682   if (ip4_set && ip6_set)
22683     {
22684       errmsg ("Only one server address allowed per message");
22685       return -99;
22686     }
22687   if ((ip4_set + ip6_set) == 0)
22688     {
22689       errmsg ("Server address required");
22690       return -99;
22691     }
22692
22693   /* Construct the API message */
22694   M (DNS_NAME_SERVER_ADD_DEL, mp);
22695
22696   if (ip6_set)
22697     {
22698       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22699       mp->is_ip6 = 1;
22700     }
22701   else
22702     {
22703       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22704       mp->is_ip6 = 0;
22705     }
22706
22707   mp->is_add = is_add;
22708
22709   /* send it... */
22710   S (mp);
22711
22712   /* Wait for a reply, return good/bad news  */
22713   W (ret);
22714   return ret;
22715 }
22716
22717 static void
22718 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22719 {
22720   vat_main_t *vam = &vat_main;
22721
22722   if (mp->is_ip4)
22723     {
22724       print (vam->ofp,
22725              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22726              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22727              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22728              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22729              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22730              clib_net_to_host_u32 (mp->action_index), mp->tag);
22731     }
22732   else
22733     {
22734       print (vam->ofp,
22735              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22736              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22737              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22738              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22739              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22740              clib_net_to_host_u32 (mp->action_index), mp->tag);
22741     }
22742 }
22743
22744 static void
22745 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22746                                              mp)
22747 {
22748   vat_main_t *vam = &vat_main;
22749   vat_json_node_t *node = NULL;
22750   struct in6_addr ip6;
22751   struct in_addr ip4;
22752
22753   if (VAT_JSON_ARRAY != vam->json_tree.type)
22754     {
22755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22756       vat_json_init_array (&vam->json_tree);
22757     }
22758   node = vat_json_array_add (&vam->json_tree);
22759   vat_json_init_object (node);
22760
22761   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22762   vat_json_object_add_uint (node, "appns_index",
22763                             clib_net_to_host_u32 (mp->appns_index));
22764   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22765   vat_json_object_add_uint (node, "scope", mp->scope);
22766   vat_json_object_add_uint (node, "action_index",
22767                             clib_net_to_host_u32 (mp->action_index));
22768   vat_json_object_add_uint (node, "lcl_port",
22769                             clib_net_to_host_u16 (mp->lcl_port));
22770   vat_json_object_add_uint (node, "rmt_port",
22771                             clib_net_to_host_u16 (mp->rmt_port));
22772   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22773   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22774   vat_json_object_add_string_copy (node, "tag", mp->tag);
22775   if (mp->is_ip4)
22776     {
22777       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22778       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22779       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22780       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22781     }
22782   else
22783     {
22784       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22785       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22786       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22787       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22788     }
22789 }
22790
22791 static int
22792 api_session_rule_add_del (vat_main_t * vam)
22793 {
22794   vl_api_session_rule_add_del_t *mp;
22795   unformat_input_t *i = vam->input;
22796   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22797   u32 appns_index = 0, scope = 0;
22798   ip4_address_t lcl_ip4, rmt_ip4;
22799   ip6_address_t lcl_ip6, rmt_ip6;
22800   u8 is_ip4 = 1, conn_set = 0;
22801   u8 is_add = 1, *tag = 0;
22802   int ret;
22803
22804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22805     {
22806       if (unformat (i, "del"))
22807         is_add = 0;
22808       else if (unformat (i, "add"))
22809         ;
22810       else if (unformat (i, "proto tcp"))
22811         proto = 0;
22812       else if (unformat (i, "proto udp"))
22813         proto = 1;
22814       else if (unformat (i, "appns %d", &appns_index))
22815         ;
22816       else if (unformat (i, "scope %d", &scope))
22817         ;
22818       else if (unformat (i, "tag %_%v%_", &tag))
22819         ;
22820       else
22821         if (unformat
22822             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22823              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22824              &rmt_port))
22825         {
22826           is_ip4 = 1;
22827           conn_set = 1;
22828         }
22829       else
22830         if (unformat
22831             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22832              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22833              &rmt_port))
22834         {
22835           is_ip4 = 0;
22836           conn_set = 1;
22837         }
22838       else if (unformat (i, "action %d", &action))
22839         ;
22840       else
22841         break;
22842     }
22843   if (proto == ~0 || !conn_set || action == ~0)
22844     {
22845       errmsg ("transport proto, connection and action must be set");
22846       return -99;
22847     }
22848
22849   if (scope > 3)
22850     {
22851       errmsg ("scope should be 0-3");
22852       return -99;
22853     }
22854
22855   M (SESSION_RULE_ADD_DEL, mp);
22856
22857   mp->is_ip4 = is_ip4;
22858   mp->transport_proto = proto;
22859   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22860   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22861   mp->lcl_plen = lcl_plen;
22862   mp->rmt_plen = rmt_plen;
22863   mp->action_index = clib_host_to_net_u32 (action);
22864   mp->appns_index = clib_host_to_net_u32 (appns_index);
22865   mp->scope = scope;
22866   mp->is_add = is_add;
22867   if (is_ip4)
22868     {
22869       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22870       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22871     }
22872   else
22873     {
22874       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22875       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22876     }
22877   if (tag)
22878     {
22879       clib_memcpy (mp->tag, tag, vec_len (tag));
22880       vec_free (tag);
22881     }
22882
22883   S (mp);
22884   W (ret);
22885   return ret;
22886 }
22887
22888 static int
22889 api_session_rules_dump (vat_main_t * vam)
22890 {
22891   vl_api_session_rules_dump_t *mp;
22892   vl_api_control_ping_t *mp_ping;
22893   int ret;
22894
22895   if (!vam->json_output)
22896     {
22897       print (vam->ofp, "%=20s", "Session Rules");
22898     }
22899
22900   M (SESSION_RULES_DUMP, mp);
22901   /* send it... */
22902   S (mp);
22903
22904   /* Use a control ping for synchronization */
22905   MPING (CONTROL_PING, mp_ping);
22906   S (mp_ping);
22907
22908   /* Wait for a reply... */
22909   W (ret);
22910   return ret;
22911 }
22912
22913 static int
22914 api_ip_container_proxy_add_del (vat_main_t * vam)
22915 {
22916   vl_api_ip_container_proxy_add_del_t *mp;
22917   unformat_input_t *i = vam->input;
22918   u32 plen = ~0, sw_if_index = ~0;
22919   ip4_address_t ip4;
22920   ip6_address_t ip6;
22921   u8 is_ip4 = 1;
22922   u8 is_add = 1;
22923   int ret;
22924
22925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22926     {
22927       if (unformat (i, "del"))
22928         is_add = 0;
22929       else if (unformat (i, "add"))
22930         ;
22931       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22932         {
22933           is_ip4 = 1;
22934           plen = 32;
22935         }
22936       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22937         {
22938           is_ip4 = 0;
22939           plen = 128;
22940         }
22941       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22942         ;
22943       else
22944         break;
22945     }
22946   if (sw_if_index == ~0 || plen == ~0)
22947     {
22948       errmsg ("address and sw_if_index must be set");
22949       return -99;
22950     }
22951
22952   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22953
22954   mp->is_ip4 = is_ip4;
22955   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22956   mp->plen = plen;
22957   mp->is_add = is_add;
22958   if (is_ip4)
22959     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22960   else
22961     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22962
22963   S (mp);
22964   W (ret);
22965   return ret;
22966 }
22967
22968 static int
22969 api_qos_record_enable_disable (vat_main_t * vam)
22970 {
22971   unformat_input_t *i = vam->input;
22972   vl_api_qos_record_enable_disable_t *mp;
22973   u32 sw_if_index, qs = 0xff;
22974   u8 sw_if_index_set = 0;
22975   u8 enable = 1;
22976   int ret;
22977
22978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22979     {
22980       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22981         sw_if_index_set = 1;
22982       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22983         sw_if_index_set = 1;
22984       else if (unformat (i, "%U", unformat_qos_source, &qs))
22985         ;
22986       else if (unformat (i, "disable"))
22987         enable = 0;
22988       else
22989         {
22990           clib_warning ("parse error '%U'", format_unformat_error, i);
22991           return -99;
22992         }
22993     }
22994
22995   if (sw_if_index_set == 0)
22996     {
22997       errmsg ("missing interface name or sw_if_index");
22998       return -99;
22999     }
23000   if (qs == 0xff)
23001     {
23002       errmsg ("input location must be specified");
23003       return -99;
23004     }
23005
23006   M (QOS_RECORD_ENABLE_DISABLE, mp);
23007
23008   mp->sw_if_index = ntohl (sw_if_index);
23009   mp->input_source = qs;
23010   mp->enable = enable;
23011
23012   S (mp);
23013   W (ret);
23014   return ret;
23015 }
23016
23017
23018 static int
23019 q_or_quit (vat_main_t * vam)
23020 {
23021 #if VPP_API_TEST_BUILTIN == 0
23022   longjmp (vam->jump_buf, 1);
23023 #endif
23024   return 0;                     /* not so much */
23025 }
23026
23027 static int
23028 q (vat_main_t * vam)
23029 {
23030   return q_or_quit (vam);
23031 }
23032
23033 static int
23034 quit (vat_main_t * vam)
23035 {
23036   return q_or_quit (vam);
23037 }
23038
23039 static int
23040 comment (vat_main_t * vam)
23041 {
23042   return 0;
23043 }
23044
23045 static int
23046 statseg (vat_main_t * vam)
23047 {
23048   ssvm_private_t *ssvmp = &vam->stat_segment;
23049   ssvm_shared_header_t *shared_header = ssvmp->sh;
23050   vlib_counter_t **counters;
23051   u64 thread0_index1_packets;
23052   u64 thread0_index1_bytes;
23053   f64 vector_rate, input_rate;
23054   uword *p;
23055
23056   uword *counter_vector_by_name;
23057   if (vam->stat_segment_lockp == 0)
23058     {
23059       errmsg ("Stat segment not mapped...");
23060       return -99;
23061     }
23062
23063   /* look up "/if/rx for sw_if_index 1 as a test */
23064
23065   clib_spinlock_lock (vam->stat_segment_lockp);
23066
23067   counter_vector_by_name = (uword *) shared_header->opaque[1];
23068
23069   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23070   if (p == 0)
23071     {
23072       clib_spinlock_unlock (vam->stat_segment_lockp);
23073       errmsg ("/if/tx not found?");
23074       return -99;
23075     }
23076
23077   /* Fish per-thread vector of combined counters from shared memory */
23078   counters = (vlib_counter_t **) p[0];
23079
23080   if (vec_len (counters[0]) < 2)
23081     {
23082       clib_spinlock_unlock (vam->stat_segment_lockp);
23083       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23084       return -99;
23085     }
23086
23087   /* Read thread 0 sw_if_index 1 counter */
23088   thread0_index1_packets = counters[0][1].packets;
23089   thread0_index1_bytes = counters[0][1].bytes;
23090
23091   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23092   if (p == 0)
23093     {
23094       clib_spinlock_unlock (vam->stat_segment_lockp);
23095       errmsg ("vector_rate not found?");
23096       return -99;
23097     }
23098
23099   vector_rate = *(f64 *) (p[0]);
23100   p = hash_get_mem (counter_vector_by_name, "input_rate");
23101   if (p == 0)
23102     {
23103       clib_spinlock_unlock (vam->stat_segment_lockp);
23104       errmsg ("input_rate not found?");
23105       return -99;
23106     }
23107   input_rate = *(f64 *) (p[0]);
23108
23109   clib_spinlock_unlock (vam->stat_segment_lockp);
23110
23111   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23112          vector_rate, input_rate);
23113   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23114          thread0_index1_packets, thread0_index1_bytes);
23115
23116   return 0;
23117 }
23118
23119 static int
23120 cmd_cmp (void *a1, void *a2)
23121 {
23122   u8 **c1 = a1;
23123   u8 **c2 = a2;
23124
23125   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23126 }
23127
23128 static int
23129 help (vat_main_t * vam)
23130 {
23131   u8 **cmds = 0;
23132   u8 *name = 0;
23133   hash_pair_t *p;
23134   unformat_input_t *i = vam->input;
23135   int j;
23136
23137   if (unformat (i, "%s", &name))
23138     {
23139       uword *hs;
23140
23141       vec_add1 (name, 0);
23142
23143       hs = hash_get_mem (vam->help_by_name, name);
23144       if (hs)
23145         print (vam->ofp, "usage: %s %s", name, hs[0]);
23146       else
23147         print (vam->ofp, "No such msg / command '%s'", name);
23148       vec_free (name);
23149       return 0;
23150     }
23151
23152   print (vam->ofp, "Help is available for the following:");
23153
23154     /* *INDENT-OFF* */
23155     hash_foreach_pair (p, vam->function_by_name,
23156     ({
23157       vec_add1 (cmds, (u8 *)(p->key));
23158     }));
23159     /* *INDENT-ON* */
23160
23161   vec_sort_with_function (cmds, cmd_cmp);
23162
23163   for (j = 0; j < vec_len (cmds); j++)
23164     print (vam->ofp, "%s", cmds[j]);
23165
23166   vec_free (cmds);
23167   return 0;
23168 }
23169
23170 static int
23171 set (vat_main_t * vam)
23172 {
23173   u8 *name = 0, *value = 0;
23174   unformat_input_t *i = vam->input;
23175
23176   if (unformat (i, "%s", &name))
23177     {
23178       /* The input buffer is a vector, not a string. */
23179       value = vec_dup (i->buffer);
23180       vec_delete (value, i->index, 0);
23181       /* Almost certainly has a trailing newline */
23182       if (value[vec_len (value) - 1] == '\n')
23183         value[vec_len (value) - 1] = 0;
23184       /* Make sure it's a proper string, one way or the other */
23185       vec_add1 (value, 0);
23186       (void) clib_macro_set_value (&vam->macro_main,
23187                                    (char *) name, (char *) value);
23188     }
23189   else
23190     errmsg ("usage: set <name> <value>");
23191
23192   vec_free (name);
23193   vec_free (value);
23194   return 0;
23195 }
23196
23197 static int
23198 unset (vat_main_t * vam)
23199 {
23200   u8 *name = 0;
23201
23202   if (unformat (vam->input, "%s", &name))
23203     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23204       errmsg ("unset: %s wasn't set", name);
23205   vec_free (name);
23206   return 0;
23207 }
23208
23209 typedef struct
23210 {
23211   u8 *name;
23212   u8 *value;
23213 } macro_sort_t;
23214
23215
23216 static int
23217 macro_sort_cmp (void *a1, void *a2)
23218 {
23219   macro_sort_t *s1 = a1;
23220   macro_sort_t *s2 = a2;
23221
23222   return strcmp ((char *) (s1->name), (char *) (s2->name));
23223 }
23224
23225 static int
23226 dump_macro_table (vat_main_t * vam)
23227 {
23228   macro_sort_t *sort_me = 0, *sm;
23229   int i;
23230   hash_pair_t *p;
23231
23232     /* *INDENT-OFF* */
23233     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23234     ({
23235       vec_add2 (sort_me, sm, 1);
23236       sm->name = (u8 *)(p->key);
23237       sm->value = (u8 *) (p->value[0]);
23238     }));
23239     /* *INDENT-ON* */
23240
23241   vec_sort_with_function (sort_me, macro_sort_cmp);
23242
23243   if (vec_len (sort_me))
23244     print (vam->ofp, "%-15s%s", "Name", "Value");
23245   else
23246     print (vam->ofp, "The macro table is empty...");
23247
23248   for (i = 0; i < vec_len (sort_me); i++)
23249     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23250   return 0;
23251 }
23252
23253 static int
23254 dump_node_table (vat_main_t * vam)
23255 {
23256   int i, j;
23257   vlib_node_t *node, *next_node;
23258
23259   if (vec_len (vam->graph_nodes) == 0)
23260     {
23261       print (vam->ofp, "Node table empty, issue get_node_graph...");
23262       return 0;
23263     }
23264
23265   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23266     {
23267       node = vam->graph_nodes[0][i];
23268       print (vam->ofp, "[%d] %s", i, node->name);
23269       for (j = 0; j < vec_len (node->next_nodes); j++)
23270         {
23271           if (node->next_nodes[j] != ~0)
23272             {
23273               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23274               print (vam->ofp, "  [%d] %s", j, next_node->name);
23275             }
23276         }
23277     }
23278   return 0;
23279 }
23280
23281 static int
23282 value_sort_cmp (void *a1, void *a2)
23283 {
23284   name_sort_t *n1 = a1;
23285   name_sort_t *n2 = a2;
23286
23287   if (n1->value < n2->value)
23288     return -1;
23289   if (n1->value > n2->value)
23290     return 1;
23291   return 0;
23292 }
23293
23294
23295 static int
23296 dump_msg_api_table (vat_main_t * vam)
23297 {
23298   api_main_t *am = &api_main;
23299   name_sort_t *nses = 0, *ns;
23300   hash_pair_t *hp;
23301   int i;
23302
23303   /* *INDENT-OFF* */
23304   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23305   ({
23306     vec_add2 (nses, ns, 1);
23307     ns->name = (u8 *)(hp->key);
23308     ns->value = (u32) hp->value[0];
23309   }));
23310   /* *INDENT-ON* */
23311
23312   vec_sort_with_function (nses, value_sort_cmp);
23313
23314   for (i = 0; i < vec_len (nses); i++)
23315     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23316   vec_free (nses);
23317   return 0;
23318 }
23319
23320 static int
23321 get_msg_id (vat_main_t * vam)
23322 {
23323   u8 *name_and_crc;
23324   u32 message_index;
23325
23326   if (unformat (vam->input, "%s", &name_and_crc))
23327     {
23328       message_index = vl_msg_api_get_msg_index (name_and_crc);
23329       if (message_index == ~0)
23330         {
23331           print (vam->ofp, " '%s' not found", name_and_crc);
23332           return 0;
23333         }
23334       print (vam->ofp, " '%s' has message index %d",
23335              name_and_crc, message_index);
23336       return 0;
23337     }
23338   errmsg ("name_and_crc required...");
23339   return 0;
23340 }
23341
23342 static int
23343 search_node_table (vat_main_t * vam)
23344 {
23345   unformat_input_t *line_input = vam->input;
23346   u8 *node_to_find;
23347   int j;
23348   vlib_node_t *node, *next_node;
23349   uword *p;
23350
23351   if (vam->graph_node_index_by_name == 0)
23352     {
23353       print (vam->ofp, "Node table empty, issue get_node_graph...");
23354       return 0;
23355     }
23356
23357   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23358     {
23359       if (unformat (line_input, "%s", &node_to_find))
23360         {
23361           vec_add1 (node_to_find, 0);
23362           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23363           if (p == 0)
23364             {
23365               print (vam->ofp, "%s not found...", node_to_find);
23366               goto out;
23367             }
23368           node = vam->graph_nodes[0][p[0]];
23369           print (vam->ofp, "[%d] %s", p[0], node->name);
23370           for (j = 0; j < vec_len (node->next_nodes); j++)
23371             {
23372               if (node->next_nodes[j] != ~0)
23373                 {
23374                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23375                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23376                 }
23377             }
23378         }
23379
23380       else
23381         {
23382           clib_warning ("parse error '%U'", format_unformat_error,
23383                         line_input);
23384           return -99;
23385         }
23386
23387     out:
23388       vec_free (node_to_find);
23389
23390     }
23391
23392   return 0;
23393 }
23394
23395
23396 static int
23397 script (vat_main_t * vam)
23398 {
23399 #if (VPP_API_TEST_BUILTIN==0)
23400   u8 *s = 0;
23401   char *save_current_file;
23402   unformat_input_t save_input;
23403   jmp_buf save_jump_buf;
23404   u32 save_line_number;
23405
23406   FILE *new_fp, *save_ifp;
23407
23408   if (unformat (vam->input, "%s", &s))
23409     {
23410       new_fp = fopen ((char *) s, "r");
23411       if (new_fp == 0)
23412         {
23413           errmsg ("Couldn't open script file %s", s);
23414           vec_free (s);
23415           return -99;
23416         }
23417     }
23418   else
23419     {
23420       errmsg ("Missing script name");
23421       return -99;
23422     }
23423
23424   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23425   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23426   save_ifp = vam->ifp;
23427   save_line_number = vam->input_line_number;
23428   save_current_file = (char *) vam->current_file;
23429
23430   vam->input_line_number = 0;
23431   vam->ifp = new_fp;
23432   vam->current_file = s;
23433   do_one_file (vam);
23434
23435   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23436   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23437   vam->ifp = save_ifp;
23438   vam->input_line_number = save_line_number;
23439   vam->current_file = (u8 *) save_current_file;
23440   vec_free (s);
23441
23442   return 0;
23443 #else
23444   clib_warning ("use the exec command...");
23445   return -99;
23446 #endif
23447 }
23448
23449 static int
23450 echo (vat_main_t * vam)
23451 {
23452   print (vam->ofp, "%v", vam->input->buffer);
23453   return 0;
23454 }
23455
23456 /* List of API message constructors, CLI names map to api_xxx */
23457 #define foreach_vpe_api_msg                                             \
23458 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23459 _(sw_interface_dump,"")                                                 \
23460 _(sw_interface_set_flags,                                               \
23461   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23462 _(sw_interface_add_del_address,                                         \
23463   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23464 _(sw_interface_set_rx_mode,                                             \
23465   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23466 _(sw_interface_set_rx_placement,                                        \
23467   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23468 _(sw_interface_set_table,                                               \
23469   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23470 _(sw_interface_set_mpls_enable,                                         \
23471   "<intfc> | sw_if_index [disable | dis]")                              \
23472 _(sw_interface_set_vpath,                                               \
23473   "<intfc> | sw_if_index <id> enable | disable")                        \
23474 _(sw_interface_set_vxlan_bypass,                                        \
23475   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23476 _(sw_interface_set_geneve_bypass,                                       \
23477   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23478 _(sw_interface_set_l2_xconnect,                                         \
23479   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23480   "enable | disable")                                                   \
23481 _(sw_interface_set_l2_bridge,                                           \
23482   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23483   "[shg <split-horizon-group>] [bvi]\n"                                 \
23484   "enable | disable")                                                   \
23485 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23486 _(bridge_domain_add_del,                                                \
23487   "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") \
23488 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23489 _(l2fib_add_del,                                                        \
23490   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23491 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23492 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23493 _(l2_flags,                                                             \
23494   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23495 _(bridge_flags,                                                         \
23496   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23497 _(tap_connect,                                                          \
23498   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23499 _(tap_modify,                                                           \
23500   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23501 _(tap_delete,                                                           \
23502   "<vpp-if-name> | sw_if_index <id>")                                   \
23503 _(sw_interface_tap_dump, "")                                            \
23504 _(tap_create_v2,                                                        \
23505   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23506 _(tap_delete_v2,                                                        \
23507   "<vpp-if-name> | sw_if_index <id>")                                   \
23508 _(sw_interface_tap_v2_dump, "")                                         \
23509 _(bond_create,                                                          \
23510   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23511   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23512 _(bond_delete,                                                          \
23513   "<vpp-if-name> | sw_if_index <id>")                                   \
23514 _(bond_enslave,                                                         \
23515   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23516 _(bond_detach_slave,                                                    \
23517   "sw_if_index <n>")                                                    \
23518 _(sw_interface_bond_dump, "")                                           \
23519 _(sw_interface_slave_dump,                                              \
23520   "<vpp-if-name> | sw_if_index <id>")                                   \
23521 _(ip_table_add_del,                                                     \
23522   "table <n> [ipv6] [add | del]\n")                                     \
23523 _(ip_add_del_route,                                                     \
23524   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23525   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23526   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23527   "[multipath] [count <n>]")                                            \
23528 _(ip_mroute_add_del,                                                    \
23529   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23530   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23531 _(mpls_table_add_del,                                                   \
23532   "table <n> [add | del]\n")                                            \
23533 _(mpls_route_add_del,                                                   \
23534   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23535   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23536   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23537   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23538   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23539 _(mpls_ip_bind_unbind,                                                  \
23540   "<label> <addr/len>")                                                 \
23541 _(mpls_tunnel_add_del,                                                  \
23542   " via <addr> [table-id <n>]\n"                                        \
23543   "sw_if_index <id>] [l2]  [del]")                                      \
23544 _(sr_mpls_policy_add,                                                   \
23545   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23546 _(sr_mpls_policy_del,                                                   \
23547   "bsid <id>")                                                          \
23548 _(bier_table_add_del,                                                   \
23549   "<label> <sub-domain> <set> <bsl> [del]")                             \
23550 _(bier_route_add_del,                                                   \
23551   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23552   "[<intfc> | sw_if_index <id>]"                                        \
23553   "[weight <n>] [del] [multipath]")                                     \
23554 _(proxy_arp_add_del,                                                    \
23555   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23556 _(proxy_arp_intfc_enable_disable,                                       \
23557   "<intfc> | sw_if_index <id> enable | disable")                        \
23558 _(sw_interface_set_unnumbered,                                          \
23559   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23560 _(ip_neighbor_add_del,                                                  \
23561   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23562   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23563 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23564 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23565   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23566   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23567   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23568 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23569 _(reset_fib, "vrf <n> [ipv6]")                                          \
23570 _(dhcp_proxy_config,                                                    \
23571   "svr <v46-address> src <v46-address>\n"                               \
23572    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23573 _(dhcp_proxy_set_vss,                                                   \
23574   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23575 _(dhcp_proxy_dump, "ip6")                                               \
23576 _(dhcp_client_config,                                                   \
23577   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23578 _(set_ip_flow_hash,                                                     \
23579   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23580 _(sw_interface_ip6_enable_disable,                                      \
23581   "<intfc> | sw_if_index <id> enable | disable")                        \
23582 _(sw_interface_ip6_set_link_local_address,                              \
23583   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23584 _(ip6nd_proxy_add_del,                                                  \
23585   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23586 _(ip6nd_proxy_dump, "")                                                 \
23587 _(sw_interface_ip6nd_ra_prefix,                                         \
23588   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23589   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23590   "[nolink] [isno]")                                                    \
23591 _(sw_interface_ip6nd_ra_config,                                         \
23592   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23593   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23594   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23595 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23596 _(l2_patch_add_del,                                                     \
23597   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23598   "enable | disable")                                                   \
23599 _(sr_localsid_add_del,                                                  \
23600   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23601   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23602 _(classify_add_del_table,                                               \
23603   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23604   " [del] [del-chain] mask <mask-value>\n"                              \
23605   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23606   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23607 _(classify_add_del_session,                                             \
23608   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23609   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23610   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23611   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23612 _(classify_set_interface_ip_table,                                      \
23613   "<intfc> | sw_if_index <nn> table <nn>")                              \
23614 _(classify_set_interface_l2_tables,                                     \
23615   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23616   "  [other-table <nn>]")                                               \
23617 _(get_node_index, "node <node-name")                                    \
23618 _(add_node_next, "node <node-name> next <next-node-name>")              \
23619 _(l2tpv3_create_tunnel,                                                 \
23620   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23621   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23622   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23623 _(l2tpv3_set_tunnel_cookies,                                            \
23624   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23625   "[new_remote_cookie <nn>]\n")                                         \
23626 _(l2tpv3_interface_enable_disable,                                      \
23627   "<intfc> | sw_if_index <nn> enable | disable")                        \
23628 _(l2tpv3_set_lookup_key,                                                \
23629   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23630 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23631 _(vxlan_offload_rx,                                                     \
23632   "hw { <interface name> | hw_if_index <nn>} "                          \
23633   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23634 _(vxlan_add_del_tunnel,                                                 \
23635   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23636   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23637   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23638 _(geneve_add_del_tunnel,                                                \
23639   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23640   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23641   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23642 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23643 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23644 _(gre_add_del_tunnel,                                                   \
23645   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23646   "[teb | erspan <session-id>] [del]")                                  \
23647 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23648 _(l2_fib_clear_table, "")                                               \
23649 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23650 _(l2_interface_vlan_tag_rewrite,                                        \
23651   "<intfc> | sw_if_index <nn> \n"                                       \
23652   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23653   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23654 _(create_vhost_user_if,                                                 \
23655         "socket <filename> [server] [renumber <dev_instance>] "         \
23656         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23657         "[mac <mac_address>]")                                          \
23658 _(modify_vhost_user_if,                                                 \
23659         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23660         "[server] [renumber <dev_instance>]")                           \
23661 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23662 _(sw_interface_vhost_user_dump, "")                                     \
23663 _(show_version, "")                                                     \
23664 _(vxlan_gpe_add_del_tunnel,                                             \
23665   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23666   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23667   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23668   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23669 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23670 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23671 _(interface_name_renumber,                                              \
23672   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23673 _(input_acl_set_interface,                                              \
23674   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23675   "  [l2-table <nn>] [del]")                                            \
23676 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23677 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23678   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23679 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23680 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23681 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23682 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23683 _(ip_dump, "ipv4 | ipv6")                                               \
23684 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23685 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23686   "  spid_id <n> ")                                                     \
23687 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23688   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23689   "  integ_alg <alg> integ_key <hex>")                                  \
23690 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23691   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23692   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23693   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23694 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23695 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23696   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23697   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23698   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23699   "  [instance <n>]")     \
23700 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23701 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23702   "  <alg> <hex>\n")                                                    \
23703 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23704 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23705 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23706   "(auth_data 0x<data> | auth_data <data>)")                            \
23707 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23708   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23709 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23710   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23711   "(local|remote)")                                                     \
23712 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23713 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23714 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23715 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23716 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23717 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23718 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23719 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23720 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23721 _(delete_loopback,"sw_if_index <nn>")                                   \
23722 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23723 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23724 _(want_interface_events,  "enable|disable")                             \
23725 _(want_stats,"enable|disable")                                          \
23726 _(get_first_msg_id, "client <name>")                                    \
23727 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23728 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23729   "fib-id <nn> [ip4][ip6][default]")                                    \
23730 _(get_node_graph, " ")                                                  \
23731 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23732 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23733 _(ioam_disable, "")                                                     \
23734 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23735                             " sw_if_index <sw_if_index> p <priority> "  \
23736                             "w <weight>] [del]")                        \
23737 _(one_add_del_locator, "locator-set <locator_name> "                    \
23738                         "iface <intf> | sw_if_index <sw_if_index> "     \
23739                         "p <priority> w <weight> [del]")                \
23740 _(one_add_del_local_eid,"vni <vni> eid "                                \
23741                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23742                          "locator-set <locator_name> [del]"             \
23743                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23744 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23745 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23746 _(one_enable_disable, "enable|disable")                                 \
23747 _(one_map_register_enable_disable, "enable|disable")                    \
23748 _(one_map_register_fallback_threshold, "<value>")                       \
23749 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23750 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23751                                "[seid <seid>] "                         \
23752                                "rloc <locator> p <prio> "               \
23753                                "w <weight> [rloc <loc> ... ] "          \
23754                                "action <action> [del-all]")             \
23755 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23756                           "<local-eid>")                                \
23757 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23758 _(one_use_petr, "ip-address> | disable")                                \
23759 _(one_map_request_mode, "src-dst|dst-only")                             \
23760 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23761 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23762 _(one_locator_set_dump, "[local | remote]")                             \
23763 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23764 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23765                        "[local] | [remote]")                            \
23766 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23767 _(one_ndp_bd_get, "")                                                   \
23768 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23769 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23770 _(one_l2_arp_bd_get, "")                                                \
23771 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23772 _(one_stats_enable_disable, "enable|disalbe")                           \
23773 _(show_one_stats_enable_disable, "")                                    \
23774 _(one_eid_table_vni_dump, "")                                           \
23775 _(one_eid_table_map_dump, "l2|l3")                                      \
23776 _(one_map_resolver_dump, "")                                            \
23777 _(one_map_server_dump, "")                                              \
23778 _(one_adjacencies_get, "vni <vni>")                                     \
23779 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23780 _(show_one_rloc_probe_state, "")                                        \
23781 _(show_one_map_register_state, "")                                      \
23782 _(show_one_status, "")                                                  \
23783 _(one_stats_dump, "")                                                   \
23784 _(one_stats_flush, "")                                                  \
23785 _(one_get_map_request_itr_rlocs, "")                                    \
23786 _(one_map_register_set_ttl, "<ttl>")                                    \
23787 _(one_set_transport_protocol, "udp|api")                                \
23788 _(one_get_transport_protocol, "")                                       \
23789 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23790 _(one_show_xtr_mode, "")                                                \
23791 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23792 _(one_show_pitr_mode, "")                                               \
23793 _(one_enable_disable_petr_mode, "enable|disable")                       \
23794 _(one_show_petr_mode, "")                                               \
23795 _(show_one_nsh_mapping, "")                                             \
23796 _(show_one_pitr, "")                                                    \
23797 _(show_one_use_petr, "")                                                \
23798 _(show_one_map_request_mode, "")                                        \
23799 _(show_one_map_register_ttl, "")                                        \
23800 _(show_one_map_register_fallback_threshold, "")                         \
23801 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23802                             " sw_if_index <sw_if_index> p <priority> "  \
23803                             "w <weight>] [del]")                        \
23804 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23805                         "iface <intf> | sw_if_index <sw_if_index> "     \
23806                         "p <priority> w <weight> [del]")                \
23807 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23808                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23809                          "locator-set <locator_name> [del]"             \
23810                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23811 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23812 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23813 _(lisp_enable_disable, "enable|disable")                                \
23814 _(lisp_map_register_enable_disable, "enable|disable")                   \
23815 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23816 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23817                                "[seid <seid>] "                         \
23818                                "rloc <locator> p <prio> "               \
23819                                "w <weight> [rloc <loc> ... ] "          \
23820                                "action <action> [del-all]")             \
23821 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23822                           "<local-eid>")                                \
23823 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23824 _(lisp_use_petr, "<ip-address> | disable")                              \
23825 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23826 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23827 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23828 _(lisp_locator_set_dump, "[local | remote]")                            \
23829 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23830 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23831                        "[local] | [remote]")                            \
23832 _(lisp_eid_table_vni_dump, "")                                          \
23833 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23834 _(lisp_map_resolver_dump, "")                                           \
23835 _(lisp_map_server_dump, "")                                             \
23836 _(lisp_adjacencies_get, "vni <vni>")                                    \
23837 _(gpe_fwd_entry_vnis_get, "")                                           \
23838 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23839 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23840                                 "[table <table-id>]")                   \
23841 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23842 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23843 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23844 _(gpe_get_encap_mode, "")                                               \
23845 _(lisp_gpe_add_del_iface, "up|down")                                    \
23846 _(lisp_gpe_enable_disable, "enable|disable")                            \
23847 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23848   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23849 _(show_lisp_rloc_probe_state, "")                                       \
23850 _(show_lisp_map_register_state, "")                                     \
23851 _(show_lisp_status, "")                                                 \
23852 _(lisp_get_map_request_itr_rlocs, "")                                   \
23853 _(show_lisp_pitr, "")                                                   \
23854 _(show_lisp_use_petr, "")                                               \
23855 _(show_lisp_map_request_mode, "")                                       \
23856 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23857 _(af_packet_delete, "name <host interface name>")                       \
23858 _(af_packet_dump, "")                                                   \
23859 _(policer_add_del, "name <policer name> <params> [del]")                \
23860 _(policer_dump, "[name <policer name>]")                                \
23861 _(policer_classify_set_interface,                                       \
23862   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23863   "  [l2-table <nn>] [del]")                                            \
23864 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23865 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23866     "[master|slave]")                                                   \
23867 _(netmap_delete, "name <interface name>")                               \
23868 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23869 _(mpls_fib_dump, "")                                                    \
23870 _(classify_table_ids, "")                                               \
23871 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23872 _(classify_table_info, "table_id <nn>")                                 \
23873 _(classify_session_dump, "table_id <nn>")                               \
23874 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23875     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23876     "[template_interval <nn>] [udp_checksum]")                          \
23877 _(ipfix_exporter_dump, "")                                              \
23878 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23879 _(ipfix_classify_stream_dump, "")                                       \
23880 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23881 _(ipfix_classify_table_dump, "")                                        \
23882 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23883 _(sw_interface_span_dump, "[l2]")                                           \
23884 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23885 _(pg_create_interface, "if_id <nn>")                                    \
23886 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23887 _(pg_enable_disable, "[stream <id>] disable")                           \
23888 _(ip_source_and_port_range_check_add_del,                               \
23889   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23890 _(ip_source_and_port_range_check_interface_add_del,                     \
23891   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23892   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23893 _(ipsec_gre_add_del_tunnel,                                             \
23894   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23895 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23896 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23897 _(l2_interface_pbb_tag_rewrite,                                         \
23898   "<intfc> | sw_if_index <nn> \n"                                       \
23899   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23900   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23901 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23902 _(flow_classify_set_interface,                                          \
23903   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23904 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23905 _(ip_fib_dump, "")                                                      \
23906 _(ip_mfib_dump, "")                                                     \
23907 _(ip6_fib_dump, "")                                                     \
23908 _(ip6_mfib_dump, "")                                                    \
23909 _(feature_enable_disable, "arc_name <arc_name> "                        \
23910   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23911 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23912 "[disable]")                                                            \
23913 _(l2_xconnect_dump, "")                                                 \
23914 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23915 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23916 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23917 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23918 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23919 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23920 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23921   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23922 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23923 _(sock_init_shm, "size <nnn>")                                          \
23924 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23925 _(dns_enable_disable, "[enable][disable]")                              \
23926 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23927 _(dns_resolve_name, "<hostname>")                                       \
23928 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23929 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23930 _(dns_resolve_name, "<hostname>")                                       \
23931 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23932   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23933 _(session_rules_dump, "")                                               \
23934 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23935 _(output_acl_set_interface,                                             \
23936   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23937   "  [l2-table <nn>] [del]")                                            \
23938 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23939
23940 /* List of command functions, CLI names map directly to functions */
23941 #define foreach_cli_function                                    \
23942 _(comment, "usage: comment <ignore-rest-of-line>")              \
23943 _(dump_interface_table, "usage: dump_interface_table")          \
23944 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23945 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23946 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23947 _(dump_stats_table, "usage: dump_stats_table")                  \
23948 _(dump_macro_table, "usage: dump_macro_table ")                 \
23949 _(dump_node_table, "usage: dump_node_table")                    \
23950 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23951 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23952 _(echo, "usage: echo <message>")                                \
23953 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23954 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23955 _(help, "usage: help")                                          \
23956 _(q, "usage: quit")                                             \
23957 _(quit, "usage: quit")                                          \
23958 _(search_node_table, "usage: search_node_table <name>...")      \
23959 _(set, "usage: set <variable-name> <value>")                    \
23960 _(script, "usage: script <file-name>")                          \
23961 _(statseg, "usage: statseg");                                   \
23962 _(unset, "usage: unset <variable-name>")
23963
23964 #define _(N,n)                                  \
23965     static void vl_api_##n##_t_handler_uni      \
23966     (vl_api_##n##_t * mp)                       \
23967     {                                           \
23968         vat_main_t * vam = &vat_main;           \
23969         if (vam->json_output) {                 \
23970             vl_api_##n##_t_handler_json(mp);    \
23971         } else {                                \
23972             vl_api_##n##_t_handler(mp);         \
23973         }                                       \
23974     }
23975 foreach_vpe_api_reply_msg;
23976 #if VPP_API_TEST_BUILTIN == 0
23977 foreach_standalone_reply_msg;
23978 #endif
23979 #undef _
23980
23981 void
23982 vat_api_hookup (vat_main_t * vam)
23983 {
23984 #define _(N,n)                                                  \
23985     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23986                            vl_api_##n##_t_handler_uni,          \
23987                            vl_noop_handler,                     \
23988                            vl_api_##n##_t_endian,               \
23989                            vl_api_##n##_t_print,                \
23990                            sizeof(vl_api_##n##_t), 1);
23991   foreach_vpe_api_reply_msg;
23992 #if VPP_API_TEST_BUILTIN == 0
23993   foreach_standalone_reply_msg;
23994 #endif
23995 #undef _
23996
23997 #if (VPP_API_TEST_BUILTIN==0)
23998   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23999
24000   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24001
24002   vam->function_by_name = hash_create_string (0, sizeof (uword));
24003
24004   vam->help_by_name = hash_create_string (0, sizeof (uword));
24005 #endif
24006
24007   /* API messages we can send */
24008 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24009   foreach_vpe_api_msg;
24010 #undef _
24011
24012   /* Help strings */
24013 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24014   foreach_vpe_api_msg;
24015 #undef _
24016
24017   /* CLI functions */
24018 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24019   foreach_cli_function;
24020 #undef _
24021
24022   /* Help strings */
24023 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24024   foreach_cli_function;
24025 #undef _
24026 }
24027
24028 #if VPP_API_TEST_BUILTIN
24029 static clib_error_t *
24030 vat_api_hookup_shim (vlib_main_t * vm)
24031 {
24032   vat_api_hookup (&vat_main);
24033   return 0;
24034 }
24035
24036 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24037 #endif
24038
24039 /*
24040  * fd.io coding-style-patch-verification: ON
24041  *
24042  * Local Variables:
24043  * eval: (c-set-style "gnu")
24044  * End:
24045  */