Ehnance and fix vpp_api_test and custom_dump to support SR-MPLS
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 static uword
180 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
181 {
182   return 0;
183 }
184
185 /* Parse an IP4 address %d.%d.%d.%d. */
186 uword
187 unformat_ip4_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   unsigned a[4];
191
192   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
193     return 0;
194
195   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
196     return 0;
197
198   result[0] = a[0];
199   result[1] = a[1];
200   result[2] = a[2];
201   result[3] = a[3];
202
203   return 1;
204 }
205
206 uword
207 unformat_ethernet_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   u32 i, a[6];
211
212   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
213                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
214     return 0;
215
216   /* Check range. */
217   for (i = 0; i < 6; i++)
218     if (a[i] >= (1 << 8))
219       return 0;
220
221   for (i = 0; i < 6; i++)
222     result[i] = a[i];
223
224   return 1;
225 }
226
227 /* Returns ethernet type as an int in host byte order. */
228 uword
229 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
230                                         va_list * args)
231 {
232   u16 *result = va_arg (*args, u16 *);
233   int type;
234
235   /* Numeric type. */
236   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
237     {
238       if (type >= (1 << 16))
239         return 0;
240       *result = type;
241       return 1;
242     }
243   return 0;
244 }
245
246 /* Parse an IP6 address. */
247 uword
248 unformat_ip6_address (unformat_input_t * input, va_list * args)
249 {
250   ip6_address_t *result = va_arg (*args, ip6_address_t *);
251   u16 hex_quads[8];
252   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
253   uword c, n_colon, double_colon_index;
254
255   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
256   double_colon_index = ARRAY_LEN (hex_quads);
257   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
258     {
259       hex_digit = 16;
260       if (c >= '0' && c <= '9')
261         hex_digit = c - '0';
262       else if (c >= 'a' && c <= 'f')
263         hex_digit = c + 10 - 'a';
264       else if (c >= 'A' && c <= 'F')
265         hex_digit = c + 10 - 'A';
266       else if (c == ':' && n_colon < 2)
267         n_colon++;
268       else
269         {
270           unformat_put_input (input);
271           break;
272         }
273
274       /* Too many hex quads. */
275       if (n_hex_quads >= ARRAY_LEN (hex_quads))
276         return 0;
277
278       if (hex_digit < 16)
279         {
280           hex_quad = (hex_quad << 4) | hex_digit;
281
282           /* Hex quad must fit in 16 bits. */
283           if (n_hex_digits >= 4)
284             return 0;
285
286           n_colon = 0;
287           n_hex_digits++;
288         }
289
290       /* Save position of :: */
291       if (n_colon == 2)
292         {
293           /* More than one :: ? */
294           if (double_colon_index < ARRAY_LEN (hex_quads))
295             return 0;
296           double_colon_index = n_hex_quads;
297         }
298
299       if (n_colon > 0 && n_hex_digits > 0)
300         {
301           hex_quads[n_hex_quads++] = hex_quad;
302           hex_quad = 0;
303           n_hex_digits = 0;
304         }
305     }
306
307   if (n_hex_digits > 0)
308     hex_quads[n_hex_quads++] = hex_quad;
309
310   {
311     word i;
312
313     /* Expand :: to appropriate number of zero hex quads. */
314     if (double_colon_index < ARRAY_LEN (hex_quads))
315       {
316         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
317
318         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
319           hex_quads[n_zero + i] = hex_quads[i];
320
321         for (i = 0; i < n_zero; i++)
322           hex_quads[double_colon_index + i] = 0;
323
324         n_hex_quads = ARRAY_LEN (hex_quads);
325       }
326
327     /* Too few hex quads given. */
328     if (n_hex_quads < ARRAY_LEN (hex_quads))
329       return 0;
330
331     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
332       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
333
334     return 1;
335   }
336 }
337
338 uword
339 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
340 {
341   u32 *r = va_arg (*args, u32 *);
342
343   if (0);
344 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
345   foreach_ipsec_policy_action
346 #undef _
347     else
348     return 0;
349   return 1;
350 }
351
352 uword
353 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
354 {
355   u32 *r = va_arg (*args, u32 *);
356
357   if (0);
358 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
359   foreach_ipsec_crypto_alg
360 #undef _
361     else
362     return 0;
363   return 1;
364 }
365
366 u8 *
367 format_ipsec_crypto_alg (u8 * s, va_list * args)
368 {
369   u32 i = va_arg (*args, u32);
370   u8 *t = 0;
371
372   switch (i)
373     {
374 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
375       foreach_ipsec_crypto_alg
376 #undef _
377     default:
378       return format (s, "unknown");
379     }
380   return format (s, "%s", t);
381 }
382
383 uword
384 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
385 {
386   u32 *r = va_arg (*args, u32 *);
387
388   if (0);
389 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
390   foreach_ipsec_integ_alg
391 #undef _
392     else
393     return 0;
394   return 1;
395 }
396
397 u8 *
398 format_ipsec_integ_alg (u8 * s, va_list * args)
399 {
400   u32 i = va_arg (*args, u32);
401   u8 *t = 0;
402
403   switch (i)
404     {
405 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
406       foreach_ipsec_integ_alg
407 #undef _
408     default:
409       return format (s, "unknown");
410     }
411   return format (s, "%s", t);
412 }
413
414 uword
415 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
416 {
417   u32 *r = va_arg (*args, u32 *);
418
419   if (0);
420 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
421   foreach_ikev2_auth_method
422 #undef _
423     else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
435   foreach_ikev2_id_type
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441 #else /* VPP_API_TEST_BUILTIN == 1 */
442 static uword
443 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
444 {
445   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
446   vnet_main_t *vnm = vnet_get_main ();
447   u32 *result = va_arg (*args, u32 *);
448
449   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
450 }
451
452 static uword
453 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
454 {
455   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
456   vnet_main_t *vnm = vnet_get_main ();
457   u32 *result = va_arg (*args, u32 *);
458
459   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
460 }
461
462 #endif /* VPP_API_TEST_BUILTIN */
463
464 static uword
465 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
466 {
467   u8 *r = va_arg (*args, u8 *);
468
469   if (unformat (input, "kbps"))
470     *r = SSE2_QOS_RATE_KBPS;
471   else if (unformat (input, "pps"))
472     *r = SSE2_QOS_RATE_PPS;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_round_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "closest"))
484     *r = SSE2_QOS_ROUND_TO_CLOSEST;
485   else if (unformat (input, "up"))
486     *r = SSE2_QOS_ROUND_TO_UP;
487   else if (unformat (input, "down"))
488     *r = SSE2_QOS_ROUND_TO_DOWN;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "1r2c"))
500     *r = SSE2_QOS_POLICER_TYPE_1R2C;
501   else if (unformat (input, "1r3c"))
502     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
503   else if (unformat (input, "2r3c-2698"))
504     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
505   else if (unformat (input, "2r3c-4115"))
506     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
507   else if (unformat (input, "2r3c-mef5cf1"))
508     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
509   else
510     return 0;
511   return 1;
512 }
513
514 static uword
515 unformat_dscp (unformat_input_t * input, va_list * va)
516 {
517   u8 *r = va_arg (*va, u8 *);
518
519   if (0);
520 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
521   foreach_vnet_dscp
522 #undef _
523     else
524     return 0;
525   return 1;
526 }
527
528 static uword
529 unformat_policer_action_type (unformat_input_t * input, va_list * va)
530 {
531   sse2_qos_pol_action_params_st *a
532     = va_arg (*va, sse2_qos_pol_action_params_st *);
533
534   if (unformat (input, "drop"))
535     a->action_type = SSE2_QOS_ACTION_DROP;
536   else if (unformat (input, "transmit"))
537     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
538   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
539     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
540   else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
547 {
548   u32 *r = va_arg (*va, u32 *);
549   u32 tid;
550
551   if (unformat (input, "ip4"))
552     tid = POLICER_CLASSIFY_TABLE_IP4;
553   else if (unformat (input, "ip6"))
554     tid = POLICER_CLASSIFY_TABLE_IP6;
555   else if (unformat (input, "l2"))
556     tid = POLICER_CLASSIFY_TABLE_L2;
557   else
558     return 0;
559
560   *r = tid;
561   return 1;
562 }
563
564 static uword
565 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
566 {
567   u32 *r = va_arg (*va, u32 *);
568   u32 tid;
569
570   if (unformat (input, "ip4"))
571     tid = FLOW_CLASSIFY_TABLE_IP4;
572   else if (unformat (input, "ip6"))
573     tid = FLOW_CLASSIFY_TABLE_IP6;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
582 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
583 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
584 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
585
586 #if (VPP_API_TEST_BUILTIN==0)
587 uword
588 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
589 {
590   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
591   mfib_itf_attribute_t attr;
592
593   old = *iflags;
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_long_names[attr]))
597       *iflags |= (1 << attr);
598   }
599   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_itf_flag_names[attr]))
602       *iflags |= (1 << attr);
603   }
604
605   return (old == *iflags ? 0 : 1);
606 }
607
608 uword
609 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
610 {
611   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
612   mfib_entry_attribute_t attr;
613
614   old = *eflags;
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_long_names[attr]))
618       *eflags |= (1 << attr);
619   }
620   FOR_EACH_MFIB_ATTRIBUTE (attr)
621   {
622     if (unformat (input, mfib_flag_names[attr]))
623       *eflags |= (1 << attr);
624   }
625
626   return (old == *eflags ? 0 : 1);
627 }
628
629 u8 *
630 format_ip4_address (u8 * s, va_list * args)
631 {
632   u8 *a = va_arg (*args, u8 *);
633   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
634 }
635
636 u8 *
637 format_ip6_address (u8 * s, va_list * args)
638 {
639   ip6_address_t *a = va_arg (*args, ip6_address_t *);
640   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
641
642   i_max_n_zero = ARRAY_LEN (a->as_u16);
643   max_n_zeros = 0;
644   i_first_zero = i_max_n_zero;
645   n_zeros = 0;
646   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
647     {
648       u32 is_zero = a->as_u16[i] == 0;
649       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
650         {
651           i_first_zero = i;
652           n_zeros = 0;
653         }
654       n_zeros += is_zero;
655       if ((!is_zero && n_zeros > max_n_zeros)
656           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
657         {
658           i_max_n_zero = i_first_zero;
659           max_n_zeros = n_zeros;
660           i_first_zero = ARRAY_LEN (a->as_u16);
661           n_zeros = 0;
662         }
663     }
664
665   last_double_colon = 0;
666   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
667     {
668       if (i == i_max_n_zero && max_n_zeros > 1)
669         {
670           s = format (s, "::");
671           i += max_n_zeros - 1;
672           last_double_colon = 1;
673         }
674       else
675         {
676           s = format (s, "%s%x",
677                       (last_double_colon || i == 0) ? "" : ":",
678                       clib_net_to_host_u16 (a->as_u16[i]));
679           last_double_colon = 0;
680         }
681     }
682
683   return s;
684 }
685
686 /* Format an IP46 address. */
687 u8 *
688 format_ip46_address (u8 * s, va_list * args)
689 {
690   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
691   ip46_type_t type = va_arg (*args, ip46_type_t);
692   int is_ip4 = 1;
693
694   switch (type)
695     {
696     case IP46_TYPE_ANY:
697       is_ip4 = ip46_address_is_ip4 (ip46);
698       break;
699     case IP46_TYPE_IP4:
700       is_ip4 = 1;
701       break;
702     case IP46_TYPE_IP6:
703       is_ip4 = 0;
704       break;
705     }
706
707   return is_ip4 ?
708     format (s, "%U", format_ip4_address, &ip46->ip4) :
709     format (s, "%U", format_ip6_address, &ip46->ip6);
710 }
711
712 u8 *
713 format_ethernet_address (u8 * s, va_list * args)
714 {
715   u8 *a = va_arg (*args, u8 *);
716
717   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
718                  a[0], a[1], a[2], a[3], a[4], a[5]);
719 }
720 #endif
721
722 static void
723 increment_v4_address (ip4_address_t * a)
724 {
725   u32 v;
726
727   v = ntohl (a->as_u32) + 1;
728   a->as_u32 = ntohl (v);
729 }
730
731 static void
732 increment_v6_address (ip6_address_t * a)
733 {
734   u64 v0, v1;
735
736   v0 = clib_net_to_host_u64 (a->as_u64[0]);
737   v1 = clib_net_to_host_u64 (a->as_u64[1]);
738
739   v1 += 1;
740   if (v1 == 0)
741     v0 += 1;
742   a->as_u64[0] = clib_net_to_host_u64 (v0);
743   a->as_u64[1] = clib_net_to_host_u64 (v1);
744 }
745
746 static void
747 increment_mac_address (u8 * mac)
748 {
749   u64 tmp = *((u64 *) mac);
750   tmp = clib_net_to_host_u64 (tmp);
751   tmp += 1 << 16;               /* skip unused (least significant) octets */
752   tmp = clib_host_to_net_u64 (tmp);
753
754   clib_memcpy (mac, &tmp, 6);
755 }
756
757 static void vl_api_create_loopback_reply_t_handler
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_loopback_reply_t_handler_json
770   (vl_api_create_loopback_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781   vam->retval = ntohl (mp->retval);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   i32 retval = ntohl (mp->retval);
790
791   vam->retval = retval;
792   vam->regenerate_interface_table = 1;
793   vam->sw_if_index = ntohl (mp->sw_if_index);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_loopback_instance_reply_t_handler_json
798   (vl_api_create_loopback_instance_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   vat_json_node_t node;
802
803   vat_json_init_object (&node);
804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
806
807   vat_json_print (vam->ofp, &node);
808   vat_json_free (&node);
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_af_packet_create_reply_t_handler_json
826   (vl_api_af_packet_create_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->sw_if_index = ntohl (mp->sw_if_index);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_vlan_subif_reply_t_handler_json
855   (vl_api_create_vlan_subif_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   vat_json_node_t node;
859
860   vat_json_init_object (&node);
861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
863
864   vat_json_print (vam->ofp, &node);
865   vat_json_free (&node);
866
867   vam->retval = ntohl (mp->retval);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   i32 retval = ntohl (mp->retval);
876
877   vam->retval = retval;
878   vam->regenerate_interface_table = 1;
879   vam->sw_if_index = ntohl (mp->sw_if_index);
880   vam->result_ready = 1;
881 }
882
883 static void vl_api_create_subif_reply_t_handler_json
884   (vl_api_create_subif_reply_t * mp)
885 {
886   vat_main_t *vam = &vat_main;
887   vat_json_node_t node;
888
889   vat_json_init_object (&node);
890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
892
893   vat_json_print (vam->ofp, &node);
894   vat_json_free (&node);
895
896   vam->retval = ntohl (mp->retval);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   i32 retval = ntohl (mp->retval);
905
906   vam->retval = retval;
907   vam->regenerate_interface_table = 1;
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler_json
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   vat_json_node_t node;
916
917   vat_json_init_object (&node);
918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
919
920   vat_json_print (vam->ofp, &node);
921   vat_json_free (&node);
922
923   vam->retval = ntohl (mp->retval);
924   vam->result_ready = 1;
925 }
926
927 /*
928  * Special-case: build the interface table, maintain
929  * the next loopback sw_if_index vbl.
930  */
931 static void vl_api_sw_interface_details_t_handler
932   (vl_api_sw_interface_details_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   u8 *s = format (0, "%s%c", mp->interface_name, 0);
936
937   hash_set_mem (vam->sw_if_index_by_interface_name, s,
938                 ntohl (mp->sw_if_index));
939
940   /* In sub interface case, fill the sub interface table entry */
941   if (mp->sw_if_index != mp->sup_sw_if_index)
942     {
943       sw_interface_subif_t *sub = NULL;
944
945       vec_add2 (vam->sw_if_subif_table, sub, 1);
946
947       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
948       strncpy ((char *) sub->interface_name, (char *) s,
949                vec_len (sub->interface_name));
950       sub->sw_if_index = ntohl (mp->sw_if_index);
951       sub->sub_id = ntohl (mp->sub_id);
952
953       sub->sub_dot1ad = mp->sub_dot1ad;
954       sub->sub_number_of_tags = mp->sub_number_of_tags;
955       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
956       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
957       sub->sub_exact_match = mp->sub_exact_match;
958       sub->sub_default = mp->sub_default;
959       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
960       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
961
962       /* vlan tag rewrite */
963       sub->vtr_op = ntohl (mp->vtr_op);
964       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
965       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
966       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
967     }
968 }
969
970 static void vl_api_sw_interface_details_t_handler_json
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t *node = NULL;
975
976   if (VAT_JSON_ARRAY != vam->json_tree.type)
977     {
978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
979       vat_json_init_array (&vam->json_tree);
980     }
981   node = vat_json_array_add (&vam->json_tree);
982
983   vat_json_init_object (node);
984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
985   vat_json_object_add_uint (node, "sup_sw_if_index",
986                             ntohl (mp->sup_sw_if_index));
987   vat_json_object_add_uint (node, "l2_address_length",
988                             ntohl (mp->l2_address_length));
989   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
990                              sizeof (mp->l2_address));
991   vat_json_object_add_string_copy (node, "interface_name",
992                                    mp->interface_name);
993   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
994   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
995   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
996   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
997   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
998   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
999   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1000   vat_json_object_add_uint (node, "sub_number_of_tags",
1001                             mp->sub_number_of_tags);
1002   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1003                             ntohs (mp->sub_outer_vlan_id));
1004   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1005                             ntohs (mp->sub_inner_vlan_id));
1006   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1007   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1008   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1009                             mp->sub_outer_vlan_id_any);
1010   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1011                             mp->sub_inner_vlan_id_any);
1012   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1013   vat_json_object_add_uint (node, "vtr_push_dot1q",
1014                             ntohl (mp->vtr_push_dot1q));
1015   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1016   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1017   if (mp->sub_dot1ah)
1018     {
1019       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1020                                        format (0, "%U",
1021                                                format_ethernet_address,
1022                                                &mp->b_dmac));
1023       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1024                                        format (0, "%U",
1025                                                format_ethernet_address,
1026                                                &mp->b_smac));
1027       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1028       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1029     }
1030 }
1031
1032 #if VPP_API_TEST_BUILTIN == 0
1033 static void vl_api_sw_interface_event_t_handler
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   if (vam->interface_event_display)
1038     errmsg ("interface flags: sw_if_index %d %s %s",
1039             ntohl (mp->sw_if_index),
1040             mp->admin_up_down ? "admin-up" : "admin-down",
1041             mp->link_up_down ? "link-up" : "link-down");
1042 }
1043 #endif
1044
1045 static void vl_api_sw_interface_event_t_handler_json
1046   (vl_api_sw_interface_event_t * mp)
1047 {
1048   /* JSON output not supported */
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   i32 retval = ntohl (mp->retval);
1056
1057   vam->retval = retval;
1058   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   vat_json_node_t node;
1067   api_main_t *am = &api_main;
1068   void *oldheap;
1069   u8 *reply;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "reply_in_shmem",
1074                             ntohl (mp->reply_in_shmem));
1075   /* Toss the shared-memory original... */
1076   pthread_mutex_lock (&am->vlib_rp->mutex);
1077   oldheap = svm_push_data_heap (am->vlib_rp);
1078
1079   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1080   vec_free (reply);
1081
1082   svm_pop_heap (oldheap);
1083   pthread_mutex_unlock (&am->vlib_rp->mutex);
1084
1085   vat_json_print (vam->ofp, &node);
1086   vat_json_free (&node);
1087
1088   vam->retval = ntohl (mp->retval);
1089   vam->result_ready = 1;
1090 }
1091
1092 static void
1093 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1094 {
1095   vat_main_t *vam = &vat_main;
1096   i32 retval = ntohl (mp->retval);
1097   u32 length = ntohl (mp->length);
1098
1099   vec_reset_length (vam->cmd_reply);
1100
1101   vam->retval = retval;
1102   if (retval == 0)
1103     {
1104       vec_validate (vam->cmd_reply, length);
1105       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1106       vam->cmd_reply[length] = 0;
1107     }
1108   vam->result_ready = 1;
1109 }
1110
1111 static void
1112 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vec_reset_length (vam->cmd_reply);
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1122
1123   vat_json_print (vam->ofp, &node);
1124   vat_json_free (&node);
1125
1126   vam->retval = ntohl (mp->retval);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void vl_api_classify_add_del_table_reply_t_handler
1131   (vl_api_classify_add_del_table_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135   if (vam->async_mode)
1136     {
1137       vam->async_errors += (retval < 0);
1138     }
1139   else
1140     {
1141       vam->retval = retval;
1142       if (retval == 0 &&
1143           ((mp->new_table_index != 0xFFFFFFFF) ||
1144            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1145            (mp->match_n_vectors != 0xFFFFFFFF)))
1146         /*
1147          * Note: this is just barely thread-safe, depends on
1148          * the main thread spinning waiting for an answer...
1149          */
1150         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1151                 ntohl (mp->new_table_index),
1152                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1153       vam->result_ready = 1;
1154     }
1155 }
1156
1157 static void vl_api_classify_add_del_table_reply_t_handler_json
1158   (vl_api_classify_add_del_table_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   vat_json_node_t node;
1162
1163   vat_json_init_object (&node);
1164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1165   vat_json_object_add_uint (&node, "new_table_index",
1166                             ntohl (mp->new_table_index));
1167   vat_json_object_add_uint (&node, "skip_n_vectors",
1168                             ntohl (mp->skip_n_vectors));
1169   vat_json_object_add_uint (&node, "match_n_vectors",
1170                             ntohl (mp->match_n_vectors));
1171
1172   vat_json_print (vam->ofp, &node);
1173   vat_json_free (&node);
1174
1175   vam->retval = ntohl (mp->retval);
1176   vam->result_ready = 1;
1177 }
1178
1179 static void vl_api_get_node_index_reply_t_handler
1180   (vl_api_get_node_index_reply_t * mp)
1181 {
1182   vat_main_t *vam = &vat_main;
1183   i32 retval = ntohl (mp->retval);
1184   if (vam->async_mode)
1185     {
1186       vam->async_errors += (retval < 0);
1187     }
1188   else
1189     {
1190       vam->retval = retval;
1191       if (retval == 0)
1192         errmsg ("node index %d", ntohl (mp->node_index));
1193       vam->result_ready = 1;
1194     }
1195 }
1196
1197 static void vl_api_get_node_index_reply_t_handler_json
1198   (vl_api_get_node_index_reply_t * mp)
1199 {
1200   vat_main_t *vam = &vat_main;
1201   vat_json_node_t node;
1202
1203   vat_json_init_object (&node);
1204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1205   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_next_index_reply_t_handler
1215   (vl_api_get_next_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("next node index %d", ntohl (mp->next_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_next_index_reply_t_handler_json
1233   (vl_api_get_next_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_add_node_next_reply_t_handler
1250   (vl_api_add_node_next_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_add_node_next_reply_t_handler_json
1268   (vl_api_add_node_next_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_show_version_reply_t_handler
1285   (vl_api_show_version_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289
1290   if (retval >= 0)
1291     {
1292       errmsg ("        program: %s", mp->program);
1293       errmsg ("        version: %s", mp->version);
1294       errmsg ("     build date: %s", mp->build_date);
1295       errmsg ("build directory: %s", mp->build_directory);
1296     }
1297   vam->retval = retval;
1298   vam->result_ready = 1;
1299 }
1300
1301 static void vl_api_show_version_reply_t_handler_json
1302   (vl_api_show_version_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_string_copy (&node, "program", mp->program);
1310   vat_json_object_add_string_copy (&node, "version", mp->version);
1311   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1312   vat_json_object_add_string_copy (&node, "build_directory",
1313                                    mp->build_directory);
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void
1323 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1324 {
1325   u32 sw_if_index = ntohl (mp->sw_if_index);
1326   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1327           mp->mac_ip ? "mac/ip binding" : "address resolution",
1328           ntohl (mp->pid), format_ip4_address, &mp->address,
1329           format_ethernet_address, mp->new_mac, sw_if_index);
1330 }
1331
1332 static void
1333 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1334 {
1335   /* JSON output not supported */
1336 }
1337
1338 static void
1339 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1340 {
1341   u32 sw_if_index = ntohl (mp->sw_if_index);
1342   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1343           mp->mac_ip ? "mac/ip binding" : "address resolution",
1344           ntohl (mp->pid), format_ip6_address, mp->address,
1345           format_ethernet_address, mp->new_mac, sw_if_index);
1346 }
1347
1348 static void
1349 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1350 {
1351   /* JSON output not supported */
1352 }
1353
1354 static void
1355 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1356 {
1357   u32 n_macs = ntohl (mp->n_macs);
1358   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1359           ntohl (mp->pid), mp->client_index, n_macs);
1360   int i;
1361   for (i = 0; i < n_macs; i++)
1362     {
1363       vl_api_mac_entry_t *mac = &mp->mac[i];
1364       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1365               i + 1, ntohl (mac->sw_if_index),
1366               format_ethernet_address, mac->mac_addr, mac->action);
1367       if (i == 1000)
1368         break;
1369     }
1370 }
1371
1372 static void
1373 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1374 {
1375   /* JSON output not supported */
1376 }
1377
1378 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1379 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1380
1381 /*
1382  * Special-case: build the bridge domain table, maintain
1383  * the next bd id vbl.
1384  */
1385 static void vl_api_bridge_domain_details_t_handler
1386   (vl_api_bridge_domain_details_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1390   int i;
1391
1392   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1393          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1394
1395   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1396          ntohl (mp->bd_id), mp->learn, mp->forward,
1397          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1398
1399   if (n_sw_ifs)
1400     {
1401       vl_api_bridge_domain_sw_if_t *sw_ifs;
1402       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1403              "Interface Name");
1404
1405       sw_ifs = mp->sw_if_details;
1406       for (i = 0; i < n_sw_ifs; i++)
1407         {
1408           u8 *sw_if_name = 0;
1409           u32 sw_if_index;
1410           hash_pair_t *p;
1411
1412           sw_if_index = ntohl (sw_ifs->sw_if_index);
1413
1414           /* *INDENT-OFF* */
1415           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1416                              ({
1417                                if ((u32) p->value[0] == sw_if_index)
1418                                  {
1419                                    sw_if_name = (u8 *)(p->key);
1420                                    break;
1421                                  }
1422                              }));
1423           /* *INDENT-ON* */
1424           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1425                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1426                  "sw_if_index not found!");
1427
1428           sw_ifs++;
1429         }
1430     }
1431 }
1432
1433 static void vl_api_bridge_domain_details_t_handler_json
1434   (vl_api_bridge_domain_details_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   vat_json_node_t *node, *array = NULL;
1438   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1439
1440   if (VAT_JSON_ARRAY != vam->json_tree.type)
1441     {
1442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1443       vat_json_init_array (&vam->json_tree);
1444     }
1445   node = vat_json_array_add (&vam->json_tree);
1446
1447   vat_json_init_object (node);
1448   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1449   vat_json_object_add_uint (node, "flood", mp->flood);
1450   vat_json_object_add_uint (node, "forward", mp->forward);
1451   vat_json_object_add_uint (node, "learn", mp->learn);
1452   vat_json_object_add_uint (node, "bvi_sw_if_index",
1453                             ntohl (mp->bvi_sw_if_index));
1454   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1455   array = vat_json_object_add (node, "sw_if");
1456   vat_json_init_array (array);
1457
1458
1459
1460   if (n_sw_ifs)
1461     {
1462       vl_api_bridge_domain_sw_if_t *sw_ifs;
1463       int i;
1464
1465       sw_ifs = mp->sw_if_details;
1466       for (i = 0; i < n_sw_ifs; i++)
1467         {
1468           node = vat_json_array_add (array);
1469           vat_json_init_object (node);
1470           vat_json_object_add_uint (node, "sw_if_index",
1471                                     ntohl (sw_ifs->sw_if_index));
1472           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1473           sw_ifs++;
1474         }
1475     }
1476 }
1477
1478 static void vl_api_control_ping_reply_t_handler
1479   (vl_api_control_ping_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   i32 retval = ntohl (mp->retval);
1483   if (vam->async_mode)
1484     {
1485       vam->async_errors += (retval < 0);
1486     }
1487   else
1488     {
1489       vam->retval = retval;
1490       vam->result_ready = 1;
1491     }
1492   if (vam->socket_client_main)
1493     vam->socket_client_main->control_pings_outstanding--;
1494 }
1495
1496 static void vl_api_control_ping_reply_t_handler_json
1497   (vl_api_control_ping_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   i32 retval = ntohl (mp->retval);
1501
1502   if (VAT_JSON_NONE != vam->json_tree.type)
1503     {
1504       vat_json_print (vam->ofp, &vam->json_tree);
1505       vat_json_free (&vam->json_tree);
1506       vam->json_tree.type = VAT_JSON_NONE;
1507     }
1508   else
1509     {
1510       /* just print [] */
1511       vat_json_init_array (&vam->json_tree);
1512       vat_json_print (vam->ofp, &vam->json_tree);
1513       vam->json_tree.type = VAT_JSON_NONE;
1514     }
1515
1516   vam->retval = retval;
1517   vam->result_ready = 1;
1518 }
1519
1520 static void
1521   vl_api_bridge_domain_set_mac_age_reply_t_handler
1522   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   i32 retval = ntohl (mp->retval);
1526   if (vam->async_mode)
1527     {
1528       vam->async_errors += (retval < 0);
1529     }
1530   else
1531     {
1532       vam->retval = retval;
1533       vam->result_ready = 1;
1534     }
1535 }
1536
1537 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1538   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1539 {
1540   vat_main_t *vam = &vat_main;
1541   vat_json_node_t node;
1542
1543   vat_json_init_object (&node);
1544   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1545
1546   vat_json_print (vam->ofp, &node);
1547   vat_json_free (&node);
1548
1549   vam->retval = ntohl (mp->retval);
1550   vam->result_ready = 1;
1551 }
1552
1553 static void
1554 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1555 {
1556   vat_main_t *vam = &vat_main;
1557   i32 retval = ntohl (mp->retval);
1558   if (vam->async_mode)
1559     {
1560       vam->async_errors += (retval < 0);
1561     }
1562   else
1563     {
1564       vam->retval = retval;
1565       vam->result_ready = 1;
1566     }
1567 }
1568
1569 static void vl_api_l2_flags_reply_t_handler_json
1570   (vl_api_l2_flags_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1578                             ntohl (mp->resulting_feature_bitmap));
1579
1580   vat_json_print (vam->ofp, &node);
1581   vat_json_free (&node);
1582
1583   vam->retval = ntohl (mp->retval);
1584   vam->result_ready = 1;
1585 }
1586
1587 static void vl_api_bridge_flags_reply_t_handler
1588   (vl_api_bridge_flags_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->result_ready = 1;
1600     }
1601 }
1602
1603 static void vl_api_bridge_flags_reply_t_handler_json
1604   (vl_api_bridge_flags_reply_t * mp)
1605 {
1606   vat_main_t *vam = &vat_main;
1607   vat_json_node_t node;
1608
1609   vat_json_init_object (&node);
1610   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1611   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1612                             ntohl (mp->resulting_feature_bitmap));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void vl_api_tap_connect_reply_t_handler
1622   (vl_api_tap_connect_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->sw_if_index = ntohl (mp->sw_if_index);
1634       vam->result_ready = 1;
1635     }
1636
1637 }
1638
1639 static void vl_api_tap_connect_reply_t_handler_json
1640   (vl_api_tap_connect_reply_t * mp)
1641 {
1642   vat_main_t *vam = &vat_main;
1643   vat_json_node_t node;
1644
1645   vat_json_init_object (&node);
1646   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1647   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654
1655 }
1656
1657 static void
1658 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1659 {
1660   vat_main_t *vam = &vat_main;
1661   i32 retval = ntohl (mp->retval);
1662   if (vam->async_mode)
1663     {
1664       vam->async_errors += (retval < 0);
1665     }
1666   else
1667     {
1668       vam->retval = retval;
1669       vam->sw_if_index = ntohl (mp->sw_if_index);
1670       vam->result_ready = 1;
1671     }
1672 }
1673
1674 static void vl_api_tap_modify_reply_t_handler_json
1675   (vl_api_tap_modify_reply_t * mp)
1676 {
1677   vat_main_t *vam = &vat_main;
1678   vat_json_node_t node;
1679
1680   vat_json_init_object (&node);
1681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1682   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1683
1684   vat_json_print (vam->ofp, &node);
1685   vat_json_free (&node);
1686
1687   vam->retval = ntohl (mp->retval);
1688   vam->result_ready = 1;
1689 }
1690
1691 static void
1692 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1693 {
1694   vat_main_t *vam = &vat_main;
1695   i32 retval = ntohl (mp->retval);
1696   if (vam->async_mode)
1697     {
1698       vam->async_errors += (retval < 0);
1699     }
1700   else
1701     {
1702       vam->retval = retval;
1703       vam->result_ready = 1;
1704     }
1705 }
1706
1707 static void vl_api_tap_delete_reply_t_handler_json
1708   (vl_api_tap_delete_reply_t * mp)
1709 {
1710   vat_main_t *vam = &vat_main;
1711   vat_json_node_t node;
1712
1713   vat_json_init_object (&node);
1714   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1715
1716   vat_json_print (vam->ofp, &node);
1717   vat_json_free (&node);
1718
1719   vam->retval = ntohl (mp->retval);
1720   vam->result_ready = 1;
1721 }
1722
1723 static void
1724 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1725 {
1726   vat_main_t *vam = &vat_main;
1727   i32 retval = ntohl (mp->retval);
1728   if (vam->async_mode)
1729     {
1730       vam->async_errors += (retval < 0);
1731     }
1732   else
1733     {
1734       vam->retval = retval;
1735       vam->sw_if_index = ntohl (mp->sw_if_index);
1736       vam->result_ready = 1;
1737     }
1738
1739 }
1740
1741 static void vl_api_tap_create_v2_reply_t_handler_json
1742   (vl_api_tap_create_v2_reply_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745   vat_json_node_t node;
1746
1747   vat_json_init_object (&node);
1748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1749   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1750
1751   vat_json_print (vam->ofp, &node);
1752   vat_json_free (&node);
1753
1754   vam->retval = ntohl (mp->retval);
1755   vam->result_ready = 1;
1756
1757 }
1758
1759 static void
1760 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1761 {
1762   vat_main_t *vam = &vat_main;
1763   i32 retval = ntohl (mp->retval);
1764   if (vam->async_mode)
1765     {
1766       vam->async_errors += (retval < 0);
1767     }
1768   else
1769     {
1770       vam->retval = retval;
1771       vam->result_ready = 1;
1772     }
1773 }
1774
1775 static void vl_api_tap_delete_v2_reply_t_handler_json
1776   (vl_api_tap_delete_v2_reply_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779   vat_json_node_t node;
1780
1781   vat_json_init_object (&node);
1782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1783
1784   vat_json_print (vam->ofp, &node);
1785   vat_json_free (&node);
1786
1787   vam->retval = ntohl (mp->retval);
1788   vam->result_ready = 1;
1789 }
1790
1791 static void
1792 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796
1797   if (vam->async_mode)
1798     {
1799       vam->async_errors += (retval < 0);
1800     }
1801   else
1802     {
1803       vam->retval = retval;
1804       vam->sw_if_index = ntohl (mp->sw_if_index);
1805       vam->result_ready = 1;
1806     }
1807 }
1808
1809 static void vl_api_bond_create_reply_t_handler_json
1810   (vl_api_bond_create_reply_t * mp)
1811 {
1812   vat_main_t *vam = &vat_main;
1813   vat_json_node_t node;
1814
1815   vat_json_init_object (&node);
1816   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1817   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1818
1819   vat_json_print (vam->ofp, &node);
1820   vat_json_free (&node);
1821
1822   vam->retval = ntohl (mp->retval);
1823   vam->result_ready = 1;
1824 }
1825
1826 static void
1827 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1828 {
1829   vat_main_t *vam = &vat_main;
1830   i32 retval = ntohl (mp->retval);
1831
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->result_ready = 1;
1840     }
1841 }
1842
1843 static void vl_api_bond_delete_reply_t_handler_json
1844   (vl_api_bond_delete_reply_t * mp)
1845 {
1846   vat_main_t *vam = &vat_main;
1847   vat_json_node_t node;
1848
1849   vat_json_init_object (&node);
1850   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1861 {
1862   vat_main_t *vam = &vat_main;
1863   i32 retval = ntohl (mp->retval);
1864
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_bond_enslave_reply_t_handler_json
1877   (vl_api_bond_enslave_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1894                                           mp)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   i32 retval = ntohl (mp->retval);
1898
1899   if (vam->async_mode)
1900     {
1901       vam->async_errors += (retval < 0);
1902     }
1903   else
1904     {
1905       vam->retval = retval;
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_detach_slave_reply_t_handler_json
1911   (vl_api_bond_detach_slave_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918
1919   vat_json_print (vam->ofp, &node);
1920   vat_json_free (&node);
1921
1922   vam->retval = ntohl (mp->retval);
1923   vam->result_ready = 1;
1924 }
1925
1926 static void vl_api_sw_interface_bond_details_t_handler
1927   (vl_api_sw_interface_bond_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   print (vam->ofp,
1932          "%-16s %-12d %-12U %-13U %-14u %-14u",
1933          mp->interface_name, ntohl (mp->sw_if_index),
1934          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
1935          ntohl (mp->active_slaves), ntohl (mp->slaves));
1936 }
1937
1938 static void vl_api_sw_interface_bond_details_t_handler_json
1939   (vl_api_sw_interface_bond_details_t * mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   vat_json_node_t *node = NULL;
1943
1944   if (VAT_JSON_ARRAY != vam->json_tree.type)
1945     {
1946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1947       vat_json_init_array (&vam->json_tree);
1948     }
1949   node = vat_json_array_add (&vam->json_tree);
1950
1951   vat_json_init_object (node);
1952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1953   vat_json_object_add_string_copy (node, "interface_name",
1954                                    mp->interface_name);
1955   vat_json_object_add_uint (node, "mode", mp->mode);
1956   vat_json_object_add_uint (node, "load_balance", mp->lb);
1957   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
1958   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
1959 }
1960
1961 static int
1962 api_sw_interface_bond_dump (vat_main_t * vam)
1963 {
1964   vl_api_sw_interface_bond_dump_t *mp;
1965   vl_api_control_ping_t *mp_ping;
1966   int ret;
1967
1968   print (vam->ofp,
1969          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
1970          "interface name", "sw_if_index", "mode", "load balance",
1971          "active slaves", "slaves");
1972
1973   /* Get list of bond interfaces */
1974   M (SW_INTERFACE_BOND_DUMP, mp);
1975   S (mp);
1976
1977   /* Use a control ping for synchronization */
1978   MPING (CONTROL_PING, mp_ping);
1979   S (mp_ping);
1980
1981   W (ret);
1982   return ret;
1983 }
1984
1985 static void vl_api_sw_interface_slave_details_t_handler
1986   (vl_api_sw_interface_slave_details_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989
1990   print (vam->ofp,
1991          "%-25s %-12d %-12d %d", mp->interface_name,
1992          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
1993 }
1994
1995 static void vl_api_sw_interface_slave_details_t_handler_json
1996   (vl_api_sw_interface_slave_details_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   vat_json_node_t *node = NULL;
2000
2001   if (VAT_JSON_ARRAY != vam->json_tree.type)
2002     {
2003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2004       vat_json_init_array (&vam->json_tree);
2005     }
2006   node = vat_json_array_add (&vam->json_tree);
2007
2008   vat_json_init_object (node);
2009   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2010   vat_json_object_add_string_copy (node, "interface_name",
2011                                    mp->interface_name);
2012   vat_json_object_add_uint (node, "passive", mp->is_passive);
2013   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2014 }
2015
2016 static int
2017 api_sw_interface_slave_dump (vat_main_t * vam)
2018 {
2019   unformat_input_t *i = vam->input;
2020   vl_api_sw_interface_slave_dump_t *mp;
2021   vl_api_control_ping_t *mp_ping;
2022   u32 sw_if_index = ~0;
2023   u8 sw_if_index_set = 0;
2024   int ret;
2025
2026   /* Parse args required to build the message */
2027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2028     {
2029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2030         sw_if_index_set = 1;
2031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2032         sw_if_index_set = 1;
2033       else
2034         break;
2035     }
2036
2037   if (sw_if_index_set == 0)
2038     {
2039       errmsg ("missing vpp interface name. ");
2040       return -99;
2041     }
2042
2043   print (vam->ofp,
2044          "\n%-25s %-12s %-12s %s",
2045          "slave interface name", "sw_if_index", "passive", "long_timeout");
2046
2047   /* Get list of bond interfaces */
2048   M (SW_INTERFACE_SLAVE_DUMP, mp);
2049   mp->sw_if_index = ntohl (sw_if_index);
2050   S (mp);
2051
2052   /* Use a control ping for synchronization */
2053   MPING (CONTROL_PING, mp_ping);
2054   S (mp_ping);
2055
2056   W (ret);
2057   return ret;
2058 }
2059
2060 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2061   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064   i32 retval = ntohl (mp->retval);
2065   if (vam->async_mode)
2066     {
2067       vam->async_errors += (retval < 0);
2068     }
2069   else
2070     {
2071       vam->retval = retval;
2072       vam->result_ready = 1;
2073     }
2074 }
2075
2076 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2077   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   vat_json_node_t node;
2081
2082   vat_json_init_object (&node);
2083   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2084   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2085                             ntohl (mp->sw_if_index));
2086
2087   vat_json_print (vam->ofp, &node);
2088   vat_json_free (&node);
2089
2090   vam->retval = ntohl (mp->retval);
2091   vam->result_ready = 1;
2092 }
2093
2094 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2095   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2096 {
2097   vat_main_t *vam = &vat_main;
2098   i32 retval = ntohl (mp->retval);
2099   if (vam->async_mode)
2100     {
2101       vam->async_errors += (retval < 0);
2102     }
2103   else
2104     {
2105       vam->retval = retval;
2106       vam->sw_if_index = ntohl (mp->sw_if_index);
2107       vam->result_ready = 1;
2108     }
2109 }
2110
2111 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2112   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2113 {
2114   vat_main_t *vam = &vat_main;
2115   vat_json_node_t node;
2116
2117   vat_json_init_object (&node);
2118   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2119   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2120
2121   vat_json_print (vam->ofp, &node);
2122   vat_json_free (&node);
2123
2124   vam->retval = ntohl (mp->retval);
2125   vam->result_ready = 1;
2126 }
2127
2128 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2129   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2130 {
2131   vat_main_t *vam = &vat_main;
2132   i32 retval = ntohl (mp->retval);
2133   if (vam->async_mode)
2134     {
2135       vam->async_errors += (retval < 0);
2136     }
2137   else
2138     {
2139       vam->retval = retval;
2140       vam->result_ready = 1;
2141     }
2142 }
2143
2144 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2145   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   vat_json_node_t node;
2149
2150   vat_json_init_object (&node);
2151   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2152   vat_json_object_add_uint (&node, "fwd_entry_index",
2153                             clib_net_to_host_u32 (mp->fwd_entry_index));
2154
2155   vat_json_print (vam->ofp, &node);
2156   vat_json_free (&node);
2157
2158   vam->retval = ntohl (mp->retval);
2159   vam->result_ready = 1;
2160 }
2161
2162 u8 *
2163 format_lisp_transport_protocol (u8 * s, va_list * args)
2164 {
2165   u32 proto = va_arg (*args, u32);
2166
2167   switch (proto)
2168     {
2169     case 1:
2170       return format (s, "udp");
2171     case 2:
2172       return format (s, "api");
2173     default:
2174       return 0;
2175     }
2176   return 0;
2177 }
2178
2179 static void vl_api_one_get_transport_protocol_reply_t_handler
2180   (vl_api_one_get_transport_protocol_reply_t * mp)
2181 {
2182   vat_main_t *vam = &vat_main;
2183   i32 retval = ntohl (mp->retval);
2184   if (vam->async_mode)
2185     {
2186       vam->async_errors += (retval < 0);
2187     }
2188   else
2189     {
2190       u32 proto = mp->protocol;
2191       print (vam->ofp, "Transport protocol: %U",
2192              format_lisp_transport_protocol, proto);
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195     }
2196 }
2197
2198 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2199   (vl_api_one_get_transport_protocol_reply_t * mp)
2200 {
2201   vat_main_t *vam = &vat_main;
2202   vat_json_node_t node;
2203   u8 *s;
2204
2205   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2206   vec_add1 (s, 0);
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2211
2212   vec_free (s);
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_one_add_del_locator_set_reply_t_handler
2221   (vl_api_one_add_del_locator_set_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->result_ready = 1;
2233     }
2234 }
2235
2236 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2237   (vl_api_one_add_del_locator_set_reply_t * mp)
2238 {
2239   vat_main_t *vam = &vat_main;
2240   vat_json_node_t node;
2241
2242   vat_json_init_object (&node);
2243   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2244   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2245
2246   vat_json_print (vam->ofp, &node);
2247   vat_json_free (&node);
2248
2249   vam->retval = ntohl (mp->retval);
2250   vam->result_ready = 1;
2251 }
2252
2253 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2254   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   i32 retval = ntohl (mp->retval);
2258   if (vam->async_mode)
2259     {
2260       vam->async_errors += (retval < 0);
2261     }
2262   else
2263     {
2264       vam->retval = retval;
2265       vam->sw_if_index = ntohl (mp->sw_if_index);
2266       vam->result_ready = 1;
2267     }
2268   vam->regenerate_interface_table = 1;
2269 }
2270
2271 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2272   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 static void vl_api_vxlan_offload_rx_reply_t_handler
2289   (vl_api_vxlan_offload_rx_reply_t * mp)
2290 {
2291   vat_main_t *vam = &vat_main;
2292   i32 retval = ntohl (mp->retval);
2293   if (vam->async_mode)
2294     {
2295       vam->async_errors += (retval < 0);
2296     }
2297   else
2298     {
2299       vam->retval = retval;
2300       vam->result_ready = 1;
2301     }
2302 }
2303
2304 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2305   (vl_api_vxlan_offload_rx_reply_t * mp)
2306 {
2307   vat_main_t *vam = &vat_main;
2308   vat_json_node_t node;
2309
2310   vat_json_init_object (&node);
2311   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2312
2313   vat_json_print (vam->ofp, &node);
2314   vat_json_free (&node);
2315
2316   vam->retval = ntohl (mp->retval);
2317   vam->result_ready = 1;
2318 }
2319
2320 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2321   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325   if (vam->async_mode)
2326     {
2327       vam->async_errors += (retval < 0);
2328     }
2329   else
2330     {
2331       vam->retval = retval;
2332       vam->sw_if_index = ntohl (mp->sw_if_index);
2333       vam->result_ready = 1;
2334     }
2335 }
2336
2337 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2338   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2339 {
2340   vat_main_t *vam = &vat_main;
2341   vat_json_node_t node;
2342
2343   vat_json_init_object (&node);
2344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2345   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2346
2347   vat_json_print (vam->ofp, &node);
2348   vat_json_free (&node);
2349
2350   vam->retval = ntohl (mp->retval);
2351   vam->result_ready = 1;
2352 }
2353
2354 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2355   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2356 {
2357   vat_main_t *vam = &vat_main;
2358   i32 retval = ntohl (mp->retval);
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->sw_if_index = ntohl (mp->sw_if_index);
2367       vam->result_ready = 1;
2368     }
2369   vam->regenerate_interface_table = 1;
2370 }
2371
2372 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2373   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   vat_json_node_t node;
2377
2378   vat_json_init_object (&node);
2379   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2380   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2381
2382   vat_json_print (vam->ofp, &node);
2383   vat_json_free (&node);
2384
2385   vam->retval = ntohl (mp->retval);
2386   vam->result_ready = 1;
2387 }
2388
2389 static void vl_api_gre_add_del_tunnel_reply_t_handler
2390   (vl_api_gre_add_del_tunnel_reply_t * mp)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   i32 retval = ntohl (mp->retval);
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->sw_if_index = ntohl (mp->sw_if_index);
2402       vam->result_ready = 1;
2403     }
2404 }
2405
2406 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2407   (vl_api_gre_add_del_tunnel_reply_t * mp)
2408 {
2409   vat_main_t *vam = &vat_main;
2410   vat_json_node_t node;
2411
2412   vat_json_init_object (&node);
2413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2415
2416   vat_json_print (vam->ofp, &node);
2417   vat_json_free (&node);
2418
2419   vam->retval = ntohl (mp->retval);
2420   vam->result_ready = 1;
2421 }
2422
2423 static void vl_api_create_vhost_user_if_reply_t_handler
2424   (vl_api_create_vhost_user_if_reply_t * mp)
2425 {
2426   vat_main_t *vam = &vat_main;
2427   i32 retval = ntohl (mp->retval);
2428   if (vam->async_mode)
2429     {
2430       vam->async_errors += (retval < 0);
2431     }
2432   else
2433     {
2434       vam->retval = retval;
2435       vam->sw_if_index = ntohl (mp->sw_if_index);
2436       vam->result_ready = 1;
2437     }
2438   vam->regenerate_interface_table = 1;
2439 }
2440
2441 static void vl_api_create_vhost_user_if_reply_t_handler_json
2442   (vl_api_create_vhost_user_if_reply_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t node;
2446
2447   vat_json_init_object (&node);
2448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2450
2451   vat_json_print (vam->ofp, &node);
2452   vat_json_free (&node);
2453
2454   vam->retval = ntohl (mp->retval);
2455   vam->result_ready = 1;
2456 }
2457
2458 static void vl_api_dns_resolve_name_reply_t_handler
2459   (vl_api_dns_resolve_name_reply_t * mp)
2460 {
2461   vat_main_t *vam = &vat_main;
2462   i32 retval = ntohl (mp->retval);
2463   if (vam->async_mode)
2464     {
2465       vam->async_errors += (retval < 0);
2466     }
2467   else
2468     {
2469       vam->retval = retval;
2470       vam->result_ready = 1;
2471
2472       if (retval == 0)
2473         {
2474           if (mp->ip4_set)
2475             clib_warning ("ip4 address %U", format_ip4_address,
2476                           (ip4_address_t *) mp->ip4_address);
2477           if (mp->ip6_set)
2478             clib_warning ("ip6 address %U", format_ip6_address,
2479                           (ip6_address_t *) mp->ip6_address);
2480         }
2481       else
2482         clib_warning ("retval %d", retval);
2483     }
2484 }
2485
2486 static void vl_api_dns_resolve_name_reply_t_handler_json
2487   (vl_api_dns_resolve_name_reply_t * mp)
2488 {
2489   clib_warning ("not implemented");
2490 }
2491
2492 static void vl_api_dns_resolve_ip_reply_t_handler
2493   (vl_api_dns_resolve_ip_reply_t * mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   i32 retval = ntohl (mp->retval);
2497   if (vam->async_mode)
2498     {
2499       vam->async_errors += (retval < 0);
2500     }
2501   else
2502     {
2503       vam->retval = retval;
2504       vam->result_ready = 1;
2505
2506       if (retval == 0)
2507         {
2508           clib_warning ("canonical name %s", mp->name);
2509         }
2510       else
2511         clib_warning ("retval %d", retval);
2512     }
2513 }
2514
2515 static void vl_api_dns_resolve_ip_reply_t_handler_json
2516   (vl_api_dns_resolve_ip_reply_t * mp)
2517 {
2518   clib_warning ("not implemented");
2519 }
2520
2521
2522 static void vl_api_ip_address_details_t_handler
2523   (vl_api_ip_address_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   static ip_address_details_t empty_ip_address_details = { {0} };
2527   ip_address_details_t *address = NULL;
2528   ip_details_t *current_ip_details = NULL;
2529   ip_details_t *details = NULL;
2530
2531   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2532
2533   if (!details || vam->current_sw_if_index >= vec_len (details)
2534       || !details[vam->current_sw_if_index].present)
2535     {
2536       errmsg ("ip address details arrived but not stored");
2537       errmsg ("ip_dump should be called first");
2538       return;
2539     }
2540
2541   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2542
2543 #define addresses (current_ip_details->addr)
2544
2545   vec_validate_init_empty (addresses, vec_len (addresses),
2546                            empty_ip_address_details);
2547
2548   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2549
2550   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2551   address->prefix_length = mp->prefix_length;
2552 #undef addresses
2553 }
2554
2555 static void vl_api_ip_address_details_t_handler_json
2556   (vl_api_ip_address_details_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t *node = NULL;
2560   struct in6_addr ip6;
2561   struct in_addr ip4;
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   if (vam->is_ipv6)
2572     {
2573       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2574       vat_json_object_add_ip6 (node, "ip", ip6);
2575     }
2576   else
2577     {
2578       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2579       vat_json_object_add_ip4 (node, "ip", ip4);
2580     }
2581   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2582 }
2583
2584 static void
2585 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_details_t empty_ip_details = { 0 };
2589   ip_details_t *ip = NULL;
2590   u32 sw_if_index = ~0;
2591
2592   sw_if_index = ntohl (mp->sw_if_index);
2593
2594   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2595                            sw_if_index, empty_ip_details);
2596
2597   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2598                          sw_if_index);
2599
2600   ip->present = 1;
2601 }
2602
2603 static void
2604 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607
2608   if (VAT_JSON_ARRAY != vam->json_tree.type)
2609     {
2610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2611       vat_json_init_array (&vam->json_tree);
2612     }
2613   vat_json_array_add_uint (&vam->json_tree,
2614                            clib_net_to_host_u32 (mp->sw_if_index));
2615 }
2616
2617 static void
2618 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2619 {
2620   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2621           "router_addr %U host_mac %U",
2622           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2623           mp->lease.hostname,
2624           format_ip4_address, &mp->lease.host_address,
2625           format_ip4_address, &mp->lease.router_address,
2626           format_ethernet_address, mp->lease.host_mac);
2627 }
2628
2629 static void vl_api_dhcp_compl_event_t_handler_json
2630   (vl_api_dhcp_compl_event_t * mp)
2631 {
2632   /* JSON output not supported */
2633 }
2634
2635 static void
2636 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2637                               u32 counter)
2638 {
2639   vat_main_t *vam = &vat_main;
2640   static u64 default_counter = 0;
2641
2642   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2643                            NULL);
2644   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2645                            sw_if_index, default_counter);
2646   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2647 }
2648
2649 static void
2650 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2651                                 interface_counter_t counter)
2652 {
2653   vat_main_t *vam = &vat_main;
2654   static interface_counter_t default_counter = { 0, };
2655
2656   vec_validate_init_empty (vam->combined_interface_counters,
2657                            vnet_counter_type, NULL);
2658   vec_validate_init_empty (vam->combined_interface_counters
2659                            [vnet_counter_type], sw_if_index, default_counter);
2660   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2661 }
2662
2663 static void vl_api_vnet_interface_simple_counters_t_handler
2664   (vl_api_vnet_interface_simple_counters_t * mp)
2665 {
2666   /* not supported */
2667 }
2668
2669 static void vl_api_vnet_interface_combined_counters_t_handler
2670   (vl_api_vnet_interface_combined_counters_t * mp)
2671 {
2672   /* not supported */
2673 }
2674
2675 static void vl_api_vnet_interface_simple_counters_t_handler_json
2676   (vl_api_vnet_interface_simple_counters_t * mp)
2677 {
2678   u64 *v_packets;
2679   u64 packets;
2680   u32 count;
2681   u32 first_sw_if_index;
2682   int i;
2683
2684   count = ntohl (mp->count);
2685   first_sw_if_index = ntohl (mp->first_sw_if_index);
2686
2687   v_packets = (u64 *) & mp->data;
2688   for (i = 0; i < count; i++)
2689     {
2690       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2691       set_simple_interface_counter (mp->vnet_counter_type,
2692                                     first_sw_if_index + i, packets);
2693       v_packets++;
2694     }
2695 }
2696
2697 static void vl_api_vnet_interface_combined_counters_t_handler_json
2698   (vl_api_vnet_interface_combined_counters_t * mp)
2699 {
2700   interface_counter_t counter;
2701   vlib_counter_t *v;
2702   u32 first_sw_if_index;
2703   int i;
2704   u32 count;
2705
2706   count = ntohl (mp->count);
2707   first_sw_if_index = ntohl (mp->first_sw_if_index);
2708
2709   v = (vlib_counter_t *) & mp->data;
2710   for (i = 0; i < count; i++)
2711     {
2712       counter.packets =
2713         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2714       counter.bytes =
2715         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2716       set_combined_interface_counter (mp->vnet_counter_type,
2717                                       first_sw_if_index + i, counter);
2718       v++;
2719     }
2720 }
2721
2722 static u32
2723 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2724 {
2725   vat_main_t *vam = &vat_main;
2726   u32 i;
2727
2728   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2729     {
2730       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2731         {
2732           return i;
2733         }
2734     }
2735   return ~0;
2736 }
2737
2738 static u32
2739 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2740 {
2741   vat_main_t *vam = &vat_main;
2742   u32 i;
2743
2744   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2745     {
2746       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2747         {
2748           return i;
2749         }
2750     }
2751   return ~0;
2752 }
2753
2754 static void vl_api_vnet_ip4_fib_counters_t_handler
2755   (vl_api_vnet_ip4_fib_counters_t * mp)
2756 {
2757   /* not supported */
2758 }
2759
2760 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2761   (vl_api_vnet_ip4_fib_counters_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   vl_api_ip4_fib_counter_t *v;
2765   ip4_fib_counter_t *counter;
2766   struct in_addr ip4;
2767   u32 vrf_id;
2768   u32 vrf_index;
2769   u32 count;
2770   int i;
2771
2772   vrf_id = ntohl (mp->vrf_id);
2773   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2774   if (~0 == vrf_index)
2775     {
2776       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2777       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2778       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2779       vec_validate (vam->ip4_fib_counters, vrf_index);
2780       vam->ip4_fib_counters[vrf_index] = NULL;
2781     }
2782
2783   vec_free (vam->ip4_fib_counters[vrf_index]);
2784   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2785   count = ntohl (mp->count);
2786   for (i = 0; i < count; i++)
2787     {
2788       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2789       counter = &vam->ip4_fib_counters[vrf_index][i];
2790       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2791       counter->address = ip4;
2792       counter->address_length = v->address_length;
2793       counter->packets = clib_net_to_host_u64 (v->packets);
2794       counter->bytes = clib_net_to_host_u64 (v->bytes);
2795       v++;
2796     }
2797 }
2798
2799 static void vl_api_vnet_ip4_nbr_counters_t_handler
2800   (vl_api_vnet_ip4_nbr_counters_t * mp)
2801 {
2802   /* not supported */
2803 }
2804
2805 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2806   (vl_api_vnet_ip4_nbr_counters_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vl_api_ip4_nbr_counter_t *v;
2810   ip4_nbr_counter_t *counter;
2811   u32 sw_if_index;
2812   u32 count;
2813   int i;
2814
2815   sw_if_index = ntohl (mp->sw_if_index);
2816   count = ntohl (mp->count);
2817   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2818
2819   if (mp->begin)
2820     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2821
2822   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2823   for (i = 0; i < count; i++)
2824     {
2825       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2826       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2827       counter->address.s_addr = v->address;
2828       counter->packets = clib_net_to_host_u64 (v->packets);
2829       counter->bytes = clib_net_to_host_u64 (v->bytes);
2830       counter->linkt = v->link_type;
2831       v++;
2832     }
2833 }
2834
2835 static void vl_api_vnet_ip6_fib_counters_t_handler
2836   (vl_api_vnet_ip6_fib_counters_t * mp)
2837 {
2838   /* not supported */
2839 }
2840
2841 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2842   (vl_api_vnet_ip6_fib_counters_t * mp)
2843 {
2844   vat_main_t *vam = &vat_main;
2845   vl_api_ip6_fib_counter_t *v;
2846   ip6_fib_counter_t *counter;
2847   struct in6_addr ip6;
2848   u32 vrf_id;
2849   u32 vrf_index;
2850   u32 count;
2851   int i;
2852
2853   vrf_id = ntohl (mp->vrf_id);
2854   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2855   if (~0 == vrf_index)
2856     {
2857       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2858       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2859       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2860       vec_validate (vam->ip6_fib_counters, vrf_index);
2861       vam->ip6_fib_counters[vrf_index] = NULL;
2862     }
2863
2864   vec_free (vam->ip6_fib_counters[vrf_index]);
2865   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2866   count = ntohl (mp->count);
2867   for (i = 0; i < count; i++)
2868     {
2869       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2870       counter = &vam->ip6_fib_counters[vrf_index][i];
2871       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2872       counter->address = ip6;
2873       counter->address_length = v->address_length;
2874       counter->packets = clib_net_to_host_u64 (v->packets);
2875       counter->bytes = clib_net_to_host_u64 (v->bytes);
2876       v++;
2877     }
2878 }
2879
2880 static void vl_api_vnet_ip6_nbr_counters_t_handler
2881   (vl_api_vnet_ip6_nbr_counters_t * mp)
2882 {
2883   /* not supported */
2884 }
2885
2886 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2887   (vl_api_vnet_ip6_nbr_counters_t * mp)
2888 {
2889   vat_main_t *vam = &vat_main;
2890   vl_api_ip6_nbr_counter_t *v;
2891   ip6_nbr_counter_t *counter;
2892   struct in6_addr ip6;
2893   u32 sw_if_index;
2894   u32 count;
2895   int i;
2896
2897   sw_if_index = ntohl (mp->sw_if_index);
2898   count = ntohl (mp->count);
2899   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2900
2901   if (mp->begin)
2902     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2903
2904   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2905   for (i = 0; i < count; i++)
2906     {
2907       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2908       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2909       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2910       counter->address = ip6;
2911       counter->packets = clib_net_to_host_u64 (v->packets);
2912       counter->bytes = clib_net_to_host_u64 (v->bytes);
2913       v++;
2914     }
2915 }
2916
2917 static void vl_api_get_first_msg_id_reply_t_handler
2918   (vl_api_get_first_msg_id_reply_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   i32 retval = ntohl (mp->retval);
2922
2923   if (vam->async_mode)
2924     {
2925       vam->async_errors += (retval < 0);
2926     }
2927   else
2928     {
2929       vam->retval = retval;
2930       vam->result_ready = 1;
2931     }
2932   if (retval >= 0)
2933     {
2934       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2935     }
2936 }
2937
2938 static void vl_api_get_first_msg_id_reply_t_handler_json
2939   (vl_api_get_first_msg_id_reply_t * mp)
2940 {
2941   vat_main_t *vam = &vat_main;
2942   vat_json_node_t node;
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2946   vat_json_object_add_uint (&node, "first_msg_id",
2947                             (uint) ntohs (mp->first_msg_id));
2948
2949   vat_json_print (vam->ofp, &node);
2950   vat_json_free (&node);
2951
2952   vam->retval = ntohl (mp->retval);
2953   vam->result_ready = 1;
2954 }
2955
2956 static void vl_api_get_node_graph_reply_t_handler
2957   (vl_api_get_node_graph_reply_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   api_main_t *am = &api_main;
2961   i32 retval = ntohl (mp->retval);
2962   u8 *pvt_copy, *reply;
2963   void *oldheap;
2964   vlib_node_t *node;
2965   int i;
2966
2967   if (vam->async_mode)
2968     {
2969       vam->async_errors += (retval < 0);
2970     }
2971   else
2972     {
2973       vam->retval = retval;
2974       vam->result_ready = 1;
2975     }
2976
2977   /* "Should never happen..." */
2978   if (retval != 0)
2979     return;
2980
2981   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2982   pvt_copy = vec_dup (reply);
2983
2984   /* Toss the shared-memory original... */
2985   pthread_mutex_lock (&am->vlib_rp->mutex);
2986   oldheap = svm_push_data_heap (am->vlib_rp);
2987
2988   vec_free (reply);
2989
2990   svm_pop_heap (oldheap);
2991   pthread_mutex_unlock (&am->vlib_rp->mutex);
2992
2993   if (vam->graph_nodes)
2994     {
2995       hash_free (vam->graph_node_index_by_name);
2996
2997       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2998         {
2999           node = vam->graph_nodes[0][i];
3000           vec_free (node->name);
3001           vec_free (node->next_nodes);
3002           vec_free (node);
3003         }
3004       vec_free (vam->graph_nodes[0]);
3005       vec_free (vam->graph_nodes);
3006     }
3007
3008   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3009   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3010   vec_free (pvt_copy);
3011
3012   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3013     {
3014       node = vam->graph_nodes[0][i];
3015       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3016     }
3017 }
3018
3019 static void vl_api_get_node_graph_reply_t_handler_json
3020   (vl_api_get_node_graph_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   api_main_t *am = &api_main;
3024   void *oldheap;
3025   vat_json_node_t node;
3026   u8 *reply;
3027
3028   /* $$$$ make this real? */
3029   vat_json_init_object (&node);
3030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3031   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3032
3033   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3034
3035   /* Toss the shared-memory original... */
3036   pthread_mutex_lock (&am->vlib_rp->mutex);
3037   oldheap = svm_push_data_heap (am->vlib_rp);
3038
3039   vec_free (reply);
3040
3041   svm_pop_heap (oldheap);
3042   pthread_mutex_unlock (&am->vlib_rp->mutex);
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void
3052 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   u8 *s = 0;
3056
3057   if (mp->local)
3058     {
3059       s = format (s, "%=16d%=16d%=16d",
3060                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3061     }
3062   else
3063     {
3064       s = format (s, "%=16U%=16d%=16d",
3065                   mp->is_ipv6 ? format_ip6_address :
3066                   format_ip4_address,
3067                   mp->ip_address, mp->priority, mp->weight);
3068     }
3069
3070   print (vam->ofp, "%v", s);
3071   vec_free (s);
3072 }
3073
3074 static void
3075 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3076 {
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = NULL;
3079   struct in6_addr ip6;
3080   struct in_addr ip4;
3081
3082   if (VAT_JSON_ARRAY != vam->json_tree.type)
3083     {
3084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3085       vat_json_init_array (&vam->json_tree);
3086     }
3087   node = vat_json_array_add (&vam->json_tree);
3088   vat_json_init_object (node);
3089
3090   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3091   vat_json_object_add_uint (node, "priority", mp->priority);
3092   vat_json_object_add_uint (node, "weight", mp->weight);
3093
3094   if (mp->local)
3095     vat_json_object_add_uint (node, "sw_if_index",
3096                               clib_net_to_host_u32 (mp->sw_if_index));
3097   else
3098     {
3099       if (mp->is_ipv6)
3100         {
3101           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3102           vat_json_object_add_ip6 (node, "address", ip6);
3103         }
3104       else
3105         {
3106           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3107           vat_json_object_add_ip4 (node, "address", ip4);
3108         }
3109     }
3110 }
3111
3112 static void
3113 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3114                                           mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   u8 *ls_name = 0;
3118
3119   ls_name = format (0, "%s", mp->ls_name);
3120
3121   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3122          ls_name);
3123   vec_free (ls_name);
3124 }
3125
3126 static void
3127   vl_api_one_locator_set_details_t_handler_json
3128   (vl_api_one_locator_set_details_t * mp)
3129 {
3130   vat_main_t *vam = &vat_main;
3131   vat_json_node_t *node = 0;
3132   u8 *ls_name = 0;
3133
3134   ls_name = format (0, "%s", mp->ls_name);
3135   vec_add1 (ls_name, 0);
3136
3137   if (VAT_JSON_ARRAY != vam->json_tree.type)
3138     {
3139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3140       vat_json_init_array (&vam->json_tree);
3141     }
3142   node = vat_json_array_add (&vam->json_tree);
3143
3144   vat_json_init_object (node);
3145   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3146   vat_json_object_add_uint (node, "ls_index",
3147                             clib_net_to_host_u32 (mp->ls_index));
3148   vec_free (ls_name);
3149 }
3150
3151 typedef struct
3152 {
3153   u32 spi;
3154   u8 si;
3155 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3156
3157 uword
3158 unformat_nsh_address (unformat_input_t * input, va_list * args)
3159 {
3160   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3161   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3162 }
3163
3164 u8 *
3165 format_nsh_address_vat (u8 * s, va_list * args)
3166 {
3167   nsh_t *a = va_arg (*args, nsh_t *);
3168   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3169 }
3170
3171 static u8 *
3172 format_lisp_flat_eid (u8 * s, va_list * args)
3173 {
3174   u32 type = va_arg (*args, u32);
3175   u8 *eid = va_arg (*args, u8 *);
3176   u32 eid_len = va_arg (*args, u32);
3177
3178   switch (type)
3179     {
3180     case 0:
3181       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3182     case 1:
3183       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3184     case 2:
3185       return format (s, "%U", format_ethernet_address, eid);
3186     case 3:
3187       return format (s, "%U", format_nsh_address_vat, eid);
3188     }
3189   return 0;
3190 }
3191
3192 static u8 *
3193 format_lisp_eid_vat (u8 * s, va_list * args)
3194 {
3195   u32 type = va_arg (*args, u32);
3196   u8 *eid = va_arg (*args, u8 *);
3197   u32 eid_len = va_arg (*args, u32);
3198   u8 *seid = va_arg (*args, u8 *);
3199   u32 seid_len = va_arg (*args, u32);
3200   u32 is_src_dst = va_arg (*args, u32);
3201
3202   if (is_src_dst)
3203     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3204
3205   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3206
3207   return s;
3208 }
3209
3210 static void
3211 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3212 {
3213   vat_main_t *vam = &vat_main;
3214   u8 *s = 0, *eid = 0;
3215
3216   if (~0 == mp->locator_set_index)
3217     s = format (0, "action: %d", mp->action);
3218   else
3219     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3220
3221   eid = format (0, "%U", format_lisp_eid_vat,
3222                 mp->eid_type,
3223                 mp->eid,
3224                 mp->eid_prefix_len,
3225                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3226   vec_add1 (eid, 0);
3227
3228   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3229          clib_net_to_host_u32 (mp->vni),
3230          eid,
3231          mp->is_local ? "local" : "remote",
3232          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3233          clib_net_to_host_u16 (mp->key_id), mp->key);
3234
3235   vec_free (s);
3236   vec_free (eid);
3237 }
3238
3239 static void
3240 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3241                                              * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t *node = 0;
3245   u8 *eid = 0;
3246
3247   if (VAT_JSON_ARRAY != vam->json_tree.type)
3248     {
3249       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3250       vat_json_init_array (&vam->json_tree);
3251     }
3252   node = vat_json_array_add (&vam->json_tree);
3253
3254   vat_json_init_object (node);
3255   if (~0 == mp->locator_set_index)
3256     vat_json_object_add_uint (node, "action", mp->action);
3257   else
3258     vat_json_object_add_uint (node, "locator_set_index",
3259                               clib_net_to_host_u32 (mp->locator_set_index));
3260
3261   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3262   if (mp->eid_type == 3)
3263     {
3264       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3265       vat_json_init_object (nsh_json);
3266       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3267       vat_json_object_add_uint (nsh_json, "spi",
3268                                 clib_net_to_host_u32 (nsh->spi));
3269       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3270     }
3271   else
3272     {
3273       eid = format (0, "%U", format_lisp_eid_vat,
3274                     mp->eid_type,
3275                     mp->eid,
3276                     mp->eid_prefix_len,
3277                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3278       vec_add1 (eid, 0);
3279       vat_json_object_add_string_copy (node, "eid", eid);
3280       vec_free (eid);
3281     }
3282   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3283   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3284   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3285
3286   if (mp->key_id)
3287     {
3288       vat_json_object_add_uint (node, "key_id",
3289                                 clib_net_to_host_u16 (mp->key_id));
3290       vat_json_object_add_string_copy (node, "key", mp->key);
3291     }
3292 }
3293
3294 static void
3295 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3296 {
3297   vat_main_t *vam = &vat_main;
3298   u8 *seid = 0, *deid = 0;
3299   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3300
3301   deid = format (0, "%U", format_lisp_eid_vat,
3302                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3303
3304   seid = format (0, "%U", format_lisp_eid_vat,
3305                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3306
3307   vec_add1 (deid, 0);
3308   vec_add1 (seid, 0);
3309
3310   if (mp->is_ip4)
3311     format_ip_address_fcn = format_ip4_address;
3312   else
3313     format_ip_address_fcn = format_ip6_address;
3314
3315
3316   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3317          clib_net_to_host_u32 (mp->vni),
3318          seid, deid,
3319          format_ip_address_fcn, mp->lloc,
3320          format_ip_address_fcn, mp->rloc,
3321          clib_net_to_host_u32 (mp->pkt_count),
3322          clib_net_to_host_u32 (mp->bytes));
3323
3324   vec_free (deid);
3325   vec_free (seid);
3326 }
3327
3328 static void
3329 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3330 {
3331   struct in6_addr ip6;
3332   struct in_addr ip4;
3333   vat_main_t *vam = &vat_main;
3334   vat_json_node_t *node = 0;
3335   u8 *deid = 0, *seid = 0;
3336
3337   if (VAT_JSON_ARRAY != vam->json_tree.type)
3338     {
3339       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3340       vat_json_init_array (&vam->json_tree);
3341     }
3342   node = vat_json_array_add (&vam->json_tree);
3343
3344   vat_json_init_object (node);
3345   deid = format (0, "%U", format_lisp_eid_vat,
3346                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3347
3348   seid = format (0, "%U", format_lisp_eid_vat,
3349                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3350
3351   vec_add1 (deid, 0);
3352   vec_add1 (seid, 0);
3353
3354   vat_json_object_add_string_copy (node, "seid", seid);
3355   vat_json_object_add_string_copy (node, "deid", deid);
3356   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3357
3358   if (mp->is_ip4)
3359     {
3360       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3361       vat_json_object_add_ip4 (node, "lloc", ip4);
3362       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3363       vat_json_object_add_ip4 (node, "rloc", ip4);
3364     }
3365   else
3366     {
3367       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3368       vat_json_object_add_ip6 (node, "lloc", ip6);
3369       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3370       vat_json_object_add_ip6 (node, "rloc", ip6);
3371     }
3372   vat_json_object_add_uint (node, "pkt_count",
3373                             clib_net_to_host_u32 (mp->pkt_count));
3374   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3375
3376   vec_free (deid);
3377   vec_free (seid);
3378 }
3379
3380 static void
3381   vl_api_one_eid_table_map_details_t_handler
3382   (vl_api_one_eid_table_map_details_t * mp)
3383 {
3384   vat_main_t *vam = &vat_main;
3385
3386   u8 *line = format (0, "%=10d%=10d",
3387                      clib_net_to_host_u32 (mp->vni),
3388                      clib_net_to_host_u32 (mp->dp_table));
3389   print (vam->ofp, "%v", line);
3390   vec_free (line);
3391 }
3392
3393 static void
3394   vl_api_one_eid_table_map_details_t_handler_json
3395   (vl_api_one_eid_table_map_details_t * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398   vat_json_node_t *node = NULL;
3399
3400   if (VAT_JSON_ARRAY != vam->json_tree.type)
3401     {
3402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3403       vat_json_init_array (&vam->json_tree);
3404     }
3405   node = vat_json_array_add (&vam->json_tree);
3406   vat_json_init_object (node);
3407   vat_json_object_add_uint (node, "dp_table",
3408                             clib_net_to_host_u32 (mp->dp_table));
3409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3410 }
3411
3412 static void
3413   vl_api_one_eid_table_vni_details_t_handler
3414   (vl_api_one_eid_table_vni_details_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417
3418   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3419   print (vam->ofp, "%v", line);
3420   vec_free (line);
3421 }
3422
3423 static void
3424   vl_api_one_eid_table_vni_details_t_handler_json
3425   (vl_api_one_eid_table_vni_details_t * mp)
3426 {
3427   vat_main_t *vam = &vat_main;
3428   vat_json_node_t *node = NULL;
3429
3430   if (VAT_JSON_ARRAY != vam->json_tree.type)
3431     {
3432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3433       vat_json_init_array (&vam->json_tree);
3434     }
3435   node = vat_json_array_add (&vam->json_tree);
3436   vat_json_init_object (node);
3437   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3438 }
3439
3440 static void
3441   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3442   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   int retval = clib_net_to_host_u32 (mp->retval);
3446
3447   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3448   print (vam->ofp, "fallback threshold value: %d", mp->value);
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3456   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t _node, *node = &_node;
3460   int retval = clib_net_to_host_u32 (mp->retval);
3461
3462   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3463   vat_json_init_object (node);
3464   vat_json_object_add_uint (node, "value", mp->value);
3465
3466   vat_json_print (vam->ofp, node);
3467   vat_json_free (node);
3468
3469   vam->retval = retval;
3470   vam->result_ready = 1;
3471 }
3472
3473 static void
3474   vl_api_show_one_map_register_state_reply_t_handler
3475   (vl_api_show_one_map_register_state_reply_t * mp)
3476 {
3477   vat_main_t *vam = &vat_main;
3478   int retval = clib_net_to_host_u32 (mp->retval);
3479
3480   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3481
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_show_one_map_register_state_reply_t_handler_json
3488   (vl_api_show_one_map_register_state_reply_t * mp)
3489 {
3490   vat_main_t *vam = &vat_main;
3491   vat_json_node_t _node, *node = &_node;
3492   int retval = clib_net_to_host_u32 (mp->retval);
3493
3494   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3495
3496   vat_json_init_object (node);
3497   vat_json_object_add_string_copy (node, "state", s);
3498
3499   vat_json_print (vam->ofp, node);
3500   vat_json_free (node);
3501
3502   vam->retval = retval;
3503   vam->result_ready = 1;
3504   vec_free (s);
3505 }
3506
3507 static void
3508   vl_api_show_one_rloc_probe_state_reply_t_handler
3509   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3510 {
3511   vat_main_t *vam = &vat_main;
3512   int retval = clib_net_to_host_u32 (mp->retval);
3513
3514   if (retval)
3515     goto end;
3516
3517   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3518 end:
3519   vam->retval = retval;
3520   vam->result_ready = 1;
3521 }
3522
3523 static void
3524   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3525   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3526 {
3527   vat_main_t *vam = &vat_main;
3528   vat_json_node_t _node, *node = &_node;
3529   int retval = clib_net_to_host_u32 (mp->retval);
3530
3531   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3532   vat_json_init_object (node);
3533   vat_json_object_add_string_copy (node, "state", s);
3534
3535   vat_json_print (vam->ofp, node);
3536   vat_json_free (node);
3537
3538   vam->retval = retval;
3539   vam->result_ready = 1;
3540   vec_free (s);
3541 }
3542
3543 static void
3544   vl_api_show_one_stats_enable_disable_reply_t_handler
3545   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3546 {
3547   vat_main_t *vam = &vat_main;
3548   int retval = clib_net_to_host_u32 (mp->retval);
3549
3550   if (retval)
3551     goto end;
3552
3553   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3554 end:
3555   vam->retval = retval;
3556   vam->result_ready = 1;
3557 }
3558
3559 static void
3560   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3561   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3562 {
3563   vat_main_t *vam = &vat_main;
3564   vat_json_node_t _node, *node = &_node;
3565   int retval = clib_net_to_host_u32 (mp->retval);
3566
3567   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3568   vat_json_init_object (node);
3569   vat_json_object_add_string_copy (node, "state", s);
3570
3571   vat_json_print (vam->ofp, node);
3572   vat_json_free (node);
3573
3574   vam->retval = retval;
3575   vam->result_ready = 1;
3576   vec_free (s);
3577 }
3578
3579 static void
3580 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3581 {
3582   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3583   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3584   e->vni = clib_net_to_host_u32 (e->vni);
3585 }
3586
3587 static void
3588   gpe_fwd_entries_get_reply_t_net_to_host
3589   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3590 {
3591   u32 i;
3592
3593   mp->count = clib_net_to_host_u32 (mp->count);
3594   for (i = 0; i < mp->count; i++)
3595     {
3596       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3597     }
3598 }
3599
3600 static u8 *
3601 format_gpe_encap_mode (u8 * s, va_list * args)
3602 {
3603   u32 mode = va_arg (*args, u32);
3604
3605   switch (mode)
3606     {
3607     case 0:
3608       return format (s, "lisp");
3609     case 1:
3610       return format (s, "vxlan");
3611     }
3612   return 0;
3613 }
3614
3615 static void
3616   vl_api_gpe_get_encap_mode_reply_t_handler
3617   (vl_api_gpe_get_encap_mode_reply_t * mp)
3618 {
3619   vat_main_t *vam = &vat_main;
3620
3621   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3622   vam->retval = ntohl (mp->retval);
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_get_encap_mode_reply_t_handler_json
3628   (vl_api_gpe_get_encap_mode_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t node;
3632
3633   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3634   vec_add1 (encap_mode, 0);
3635
3636   vat_json_init_object (&node);
3637   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3638
3639   vec_free (encap_mode);
3640   vat_json_print (vam->ofp, &node);
3641   vat_json_free (&node);
3642
3643   vam->retval = ntohl (mp->retval);
3644   vam->result_ready = 1;
3645 }
3646
3647 static void
3648   vl_api_gpe_fwd_entry_path_details_t_handler
3649   (vl_api_gpe_fwd_entry_path_details_t * mp)
3650 {
3651   vat_main_t *vam = &vat_main;
3652   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3653
3654   if (mp->lcl_loc.is_ip4)
3655     format_ip_address_fcn = format_ip4_address;
3656   else
3657     format_ip_address_fcn = format_ip6_address;
3658
3659   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3660          format_ip_address_fcn, &mp->lcl_loc,
3661          format_ip_address_fcn, &mp->rmt_loc);
3662 }
3663
3664 static void
3665 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3666 {
3667   struct in6_addr ip6;
3668   struct in_addr ip4;
3669
3670   if (loc->is_ip4)
3671     {
3672       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3673       vat_json_object_add_ip4 (n, "address", ip4);
3674     }
3675   else
3676     {
3677       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3678       vat_json_object_add_ip6 (n, "address", ip6);
3679     }
3680   vat_json_object_add_uint (n, "weight", loc->weight);
3681 }
3682
3683 static void
3684   vl_api_gpe_fwd_entry_path_details_t_handler_json
3685   (vl_api_gpe_fwd_entry_path_details_t * mp)
3686 {
3687   vat_main_t *vam = &vat_main;
3688   vat_json_node_t *node = NULL;
3689   vat_json_node_t *loc_node;
3690
3691   if (VAT_JSON_ARRAY != vam->json_tree.type)
3692     {
3693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3694       vat_json_init_array (&vam->json_tree);
3695     }
3696   node = vat_json_array_add (&vam->json_tree);
3697   vat_json_init_object (node);
3698
3699   loc_node = vat_json_object_add (node, "local_locator");
3700   vat_json_init_object (loc_node);
3701   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3702
3703   loc_node = vat_json_object_add (node, "remote_locator");
3704   vat_json_init_object (loc_node);
3705   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3706 }
3707
3708 static void
3709   vl_api_gpe_fwd_entries_get_reply_t_handler
3710   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   u32 i;
3714   int retval = clib_net_to_host_u32 (mp->retval);
3715   vl_api_gpe_fwd_entry_t *e;
3716
3717   if (retval)
3718     goto end;
3719
3720   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3721
3722   for (i = 0; i < mp->count; i++)
3723     {
3724       e = &mp->entries[i];
3725       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3726              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3727              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3728     }
3729
3730 end:
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3737   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3738 {
3739   u8 *s = 0;
3740   vat_main_t *vam = &vat_main;
3741   vat_json_node_t *e = 0, root;
3742   u32 i;
3743   int retval = clib_net_to_host_u32 (mp->retval);
3744   vl_api_gpe_fwd_entry_t *fwd;
3745
3746   if (retval)
3747     goto end;
3748
3749   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3750   vat_json_init_array (&root);
3751
3752   for (i = 0; i < mp->count; i++)
3753     {
3754       e = vat_json_array_add (&root);
3755       fwd = &mp->entries[i];
3756
3757       vat_json_init_object (e);
3758       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3759       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3760       vat_json_object_add_int (e, "vni", fwd->vni);
3761       vat_json_object_add_int (e, "action", fwd->action);
3762
3763       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3764                   fwd->leid_prefix_len);
3765       vec_add1 (s, 0);
3766       vat_json_object_add_string_copy (e, "leid", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3770                   fwd->reid_prefix_len);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "reid", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3786   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791   vl_api_gpe_native_fwd_rpath_t *r;
3792
3793   if (retval)
3794     goto end;
3795
3796   n = clib_net_to_host_u32 (mp->count);
3797
3798   for (i = 0; i < n; i++)
3799     {
3800       r = &mp->entries[i];
3801       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3802              clib_net_to_host_u32 (r->fib_index),
3803              clib_net_to_host_u32 (r->nh_sw_if_index),
3804              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3805     }
3806
3807 end:
3808   vam->retval = retval;
3809   vam->result_ready = 1;
3810 }
3811
3812 static void
3813   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3814   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3815 {
3816   vat_main_t *vam = &vat_main;
3817   vat_json_node_t root, *e;
3818   u32 i, n;
3819   int retval = clib_net_to_host_u32 (mp->retval);
3820   vl_api_gpe_native_fwd_rpath_t *r;
3821   u8 *s;
3822
3823   if (retval)
3824     goto end;
3825
3826   n = clib_net_to_host_u32 (mp->count);
3827   vat_json_init_array (&root);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       e = vat_json_array_add (&root);
3832       vat_json_init_object (e);
3833       r = &mp->entries[i];
3834       s =
3835         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3836                 r->nh_addr);
3837       vec_add1 (s, 0);
3838       vat_json_object_add_string_copy (e, "ip4", s);
3839       vec_free (s);
3840
3841       vat_json_object_add_uint (e, "fib_index",
3842                                 clib_net_to_host_u32 (r->fib_index));
3843       vat_json_object_add_uint (e, "nh_sw_if_index",
3844                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3845     }
3846
3847   vat_json_print (vam->ofp, &root);
3848   vat_json_free (&root);
3849
3850 end:
3851   vam->retval = retval;
3852   vam->result_ready = 1;
3853 }
3854
3855 static void
3856   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3857   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3858 {
3859   vat_main_t *vam = &vat_main;
3860   u32 i, n;
3861   int retval = clib_net_to_host_u32 (mp->retval);
3862
3863   if (retval)
3864     goto end;
3865
3866   n = clib_net_to_host_u32 (mp->count);
3867
3868   for (i = 0; i < n; i++)
3869     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3870
3871 end:
3872   vam->retval = retval;
3873   vam->result_ready = 1;
3874 }
3875
3876 static void
3877   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3878   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3879 {
3880   vat_main_t *vam = &vat_main;
3881   vat_json_node_t root;
3882   u32 i, n;
3883   int retval = clib_net_to_host_u32 (mp->retval);
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3893
3894   vat_json_print (vam->ofp, &root);
3895   vat_json_free (&root);
3896
3897 end:
3898   vam->retval = retval;
3899   vam->result_ready = 1;
3900 }
3901
3902 static void
3903   vl_api_one_ndp_entries_get_reply_t_handler
3904   (vl_api_one_ndp_entries_get_reply_t * mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   u32 i, n;
3908   int retval = clib_net_to_host_u32 (mp->retval);
3909
3910   if (retval)
3911     goto end;
3912
3913   n = clib_net_to_host_u32 (mp->count);
3914
3915   for (i = 0; i < n; i++)
3916     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3917            format_ethernet_address, mp->entries[i].mac);
3918
3919 end:
3920   vam->retval = retval;
3921   vam->result_ready = 1;
3922 }
3923
3924 static void
3925   vl_api_one_ndp_entries_get_reply_t_handler_json
3926   (vl_api_one_ndp_entries_get_reply_t * mp)
3927 {
3928   u8 *s = 0;
3929   vat_main_t *vam = &vat_main;
3930   vat_json_node_t *e = 0, root;
3931   u32 i, n;
3932   int retval = clib_net_to_host_u32 (mp->retval);
3933   vl_api_one_ndp_entry_t *arp_entry;
3934
3935   if (retval)
3936     goto end;
3937
3938   n = clib_net_to_host_u32 (mp->count);
3939   vat_json_init_array (&root);
3940
3941   for (i = 0; i < n; i++)
3942     {
3943       e = vat_json_array_add (&root);
3944       arp_entry = &mp->entries[i];
3945
3946       vat_json_init_object (e);
3947       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3948       vec_add1 (s, 0);
3949
3950       vat_json_object_add_string_copy (e, "mac", s);
3951       vec_free (s);
3952
3953       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3954       vec_add1 (s, 0);
3955       vat_json_object_add_string_copy (e, "ip6", s);
3956       vec_free (s);
3957     }
3958
3959   vat_json_print (vam->ofp, &root);
3960   vat_json_free (&root);
3961
3962 end:
3963   vam->retval = retval;
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968   vl_api_one_l2_arp_entries_get_reply_t_handler
3969   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   u32 i, n;
3973   int retval = clib_net_to_host_u32 (mp->retval);
3974
3975   if (retval)
3976     goto end;
3977
3978   n = clib_net_to_host_u32 (mp->count);
3979
3980   for (i = 0; i < n; i++)
3981     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3982            format_ethernet_address, mp->entries[i].mac);
3983
3984 end:
3985   vam->retval = retval;
3986   vam->result_ready = 1;
3987 }
3988
3989 static void
3990   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3991   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3992 {
3993   u8 *s = 0;
3994   vat_main_t *vam = &vat_main;
3995   vat_json_node_t *e = 0, root;
3996   u32 i, n;
3997   int retval = clib_net_to_host_u32 (mp->retval);
3998   vl_api_one_l2_arp_entry_t *arp_entry;
3999
4000   if (retval)
4001     goto end;
4002
4003   n = clib_net_to_host_u32 (mp->count);
4004   vat_json_init_array (&root);
4005
4006   for (i = 0; i < n; i++)
4007     {
4008       e = vat_json_array_add (&root);
4009       arp_entry = &mp->entries[i];
4010
4011       vat_json_init_object (e);
4012       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4013       vec_add1 (s, 0);
4014
4015       vat_json_object_add_string_copy (e, "mac", s);
4016       vec_free (s);
4017
4018       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4019       vec_add1 (s, 0);
4020       vat_json_object_add_string_copy (e, "ip4", s);
4021       vec_free (s);
4022     }
4023
4024   vat_json_print (vam->ofp, &root);
4025   vat_json_free (&root);
4026
4027 end:
4028   vam->retval = retval;
4029   vam->result_ready = 1;
4030 }
4031
4032 static void
4033 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4034 {
4035   vat_main_t *vam = &vat_main;
4036   u32 i, n;
4037   int retval = clib_net_to_host_u32 (mp->retval);
4038
4039   if (retval)
4040     goto end;
4041
4042   n = clib_net_to_host_u32 (mp->count);
4043
4044   for (i = 0; i < n; i++)
4045     {
4046       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4047     }
4048
4049 end:
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_one_ndp_bd_get_reply_t_handler_json
4056   (vl_api_one_ndp_bd_get_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t root;
4060   u32 i, n;
4061   int retval = clib_net_to_host_u32 (mp->retval);
4062
4063   if (retval)
4064     goto end;
4065
4066   n = clib_net_to_host_u32 (mp->count);
4067   vat_json_init_array (&root);
4068
4069   for (i = 0; i < n; i++)
4070     {
4071       vat_json_array_add_uint (&root,
4072                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4073     }
4074
4075   vat_json_print (vam->ofp, &root);
4076   vat_json_free (&root);
4077
4078 end:
4079   vam->retval = retval;
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_l2_arp_bd_get_reply_t_handler
4085   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   u32 i, n;
4089   int retval = clib_net_to_host_u32 (mp->retval);
4090
4091   if (retval)
4092     goto end;
4093
4094   n = clib_net_to_host_u32 (mp->count);
4095
4096   for (i = 0; i < n; i++)
4097     {
4098       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4099     }
4100
4101 end:
4102   vam->retval = retval;
4103   vam->result_ready = 1;
4104 }
4105
4106 static void
4107   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4108   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   vat_json_node_t root;
4112   u32 i, n;
4113   int retval = clib_net_to_host_u32 (mp->retval);
4114
4115   if (retval)
4116     goto end;
4117
4118   n = clib_net_to_host_u32 (mp->count);
4119   vat_json_init_array (&root);
4120
4121   for (i = 0; i < n; i++)
4122     {
4123       vat_json_array_add_uint (&root,
4124                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4125     }
4126
4127   vat_json_print (vam->ofp, &root);
4128   vat_json_free (&root);
4129
4130 end:
4131   vam->retval = retval;
4132   vam->result_ready = 1;
4133 }
4134
4135 static void
4136   vl_api_one_adjacencies_get_reply_t_handler
4137   (vl_api_one_adjacencies_get_reply_t * mp)
4138 {
4139   vat_main_t *vam = &vat_main;
4140   u32 i, n;
4141   int retval = clib_net_to_host_u32 (mp->retval);
4142   vl_api_one_adjacency_t *a;
4143
4144   if (retval)
4145     goto end;
4146
4147   n = clib_net_to_host_u32 (mp->count);
4148
4149   for (i = 0; i < n; i++)
4150     {
4151       a = &mp->adjacencies[i];
4152       print (vam->ofp, "%U %40U",
4153              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4154              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4155     }
4156
4157 end:
4158   vam->retval = retval;
4159   vam->result_ready = 1;
4160 }
4161
4162 static void
4163   vl_api_one_adjacencies_get_reply_t_handler_json
4164   (vl_api_one_adjacencies_get_reply_t * mp)
4165 {
4166   u8 *s = 0;
4167   vat_main_t *vam = &vat_main;
4168   vat_json_node_t *e = 0, root;
4169   u32 i, n;
4170   int retval = clib_net_to_host_u32 (mp->retval);
4171   vl_api_one_adjacency_t *a;
4172
4173   if (retval)
4174     goto end;
4175
4176   n = clib_net_to_host_u32 (mp->count);
4177   vat_json_init_array (&root);
4178
4179   for (i = 0; i < n; i++)
4180     {
4181       e = vat_json_array_add (&root);
4182       a = &mp->adjacencies[i];
4183
4184       vat_json_init_object (e);
4185       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4186                   a->leid_prefix_len);
4187       vec_add1 (s, 0);
4188       vat_json_object_add_string_copy (e, "leid", s);
4189       vec_free (s);
4190
4191       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4192                   a->reid_prefix_len);
4193       vec_add1 (s, 0);
4194       vat_json_object_add_string_copy (e, "reid", s);
4195       vec_free (s);
4196     }
4197
4198   vat_json_print (vam->ofp, &root);
4199   vat_json_free (&root);
4200
4201 end:
4202   vam->retval = retval;
4203   vam->result_ready = 1;
4204 }
4205
4206 static void
4207 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4208 {
4209   vat_main_t *vam = &vat_main;
4210
4211   print (vam->ofp, "%=20U",
4212          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4213          mp->ip_address);
4214 }
4215
4216 static void
4217   vl_api_one_map_server_details_t_handler_json
4218   (vl_api_one_map_server_details_t * mp)
4219 {
4220   vat_main_t *vam = &vat_main;
4221   vat_json_node_t *node = NULL;
4222   struct in6_addr ip6;
4223   struct in_addr ip4;
4224
4225   if (VAT_JSON_ARRAY != vam->json_tree.type)
4226     {
4227       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4228       vat_json_init_array (&vam->json_tree);
4229     }
4230   node = vat_json_array_add (&vam->json_tree);
4231
4232   vat_json_init_object (node);
4233   if (mp->is_ipv6)
4234     {
4235       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4236       vat_json_object_add_ip6 (node, "map-server", ip6);
4237     }
4238   else
4239     {
4240       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4241       vat_json_object_add_ip4 (node, "map-server", ip4);
4242     }
4243 }
4244
4245 static void
4246 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4247                                            * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250
4251   print (vam->ofp, "%=20U",
4252          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4253          mp->ip_address);
4254 }
4255
4256 static void
4257   vl_api_one_map_resolver_details_t_handler_json
4258   (vl_api_one_map_resolver_details_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   vat_json_node_t *node = NULL;
4262   struct in6_addr ip6;
4263   struct in_addr ip4;
4264
4265   if (VAT_JSON_ARRAY != vam->json_tree.type)
4266     {
4267       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4268       vat_json_init_array (&vam->json_tree);
4269     }
4270   node = vat_json_array_add (&vam->json_tree);
4271
4272   vat_json_init_object (node);
4273   if (mp->is_ipv6)
4274     {
4275       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4276       vat_json_object_add_ip6 (node, "map resolver", ip6);
4277     }
4278   else
4279     {
4280       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4281       vat_json_object_add_ip4 (node, "map resolver", ip4);
4282     }
4283 }
4284
4285 static void
4286 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4287 {
4288   vat_main_t *vam = &vat_main;
4289   i32 retval = ntohl (mp->retval);
4290
4291   if (0 <= retval)
4292     {
4293       print (vam->ofp, "feature: %s\ngpe: %s",
4294              mp->feature_status ? "enabled" : "disabled",
4295              mp->gpe_status ? "enabled" : "disabled");
4296     }
4297
4298   vam->retval = retval;
4299   vam->result_ready = 1;
4300 }
4301
4302 static void
4303   vl_api_show_one_status_reply_t_handler_json
4304   (vl_api_show_one_status_reply_t * mp)
4305 {
4306   vat_main_t *vam = &vat_main;
4307   vat_json_node_t node;
4308   u8 *gpe_status = NULL;
4309   u8 *feature_status = NULL;
4310
4311   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4312   feature_status = format (0, "%s",
4313                            mp->feature_status ? "enabled" : "disabled");
4314   vec_add1 (gpe_status, 0);
4315   vec_add1 (feature_status, 0);
4316
4317   vat_json_init_object (&node);
4318   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4319   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4320
4321   vec_free (gpe_status);
4322   vec_free (feature_status);
4323
4324   vat_json_print (vam->ofp, &node);
4325   vat_json_free (&node);
4326
4327   vam->retval = ntohl (mp->retval);
4328   vam->result_ready = 1;
4329 }
4330
4331 static void
4332   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4333   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   i32 retval = ntohl (mp->retval);
4337
4338   if (retval >= 0)
4339     {
4340       print (vam->ofp, "%=20s", mp->locator_set_name);
4341     }
4342
4343   vam->retval = retval;
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4349   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   vat_json_node_t *node = NULL;
4353
4354   if (VAT_JSON_ARRAY != vam->json_tree.type)
4355     {
4356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4357       vat_json_init_array (&vam->json_tree);
4358     }
4359   node = vat_json_array_add (&vam->json_tree);
4360
4361   vat_json_init_object (node);
4362   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4363
4364   vat_json_print (vam->ofp, node);
4365   vat_json_free (node);
4366
4367   vam->retval = ntohl (mp->retval);
4368   vam->result_ready = 1;
4369 }
4370
4371 static u8 *
4372 format_lisp_map_request_mode (u8 * s, va_list * args)
4373 {
4374   u32 mode = va_arg (*args, u32);
4375
4376   switch (mode)
4377     {
4378     case 0:
4379       return format (0, "dst-only");
4380     case 1:
4381       return format (0, "src-dst");
4382     }
4383   return 0;
4384 }
4385
4386 static void
4387   vl_api_show_one_map_request_mode_reply_t_handler
4388   (vl_api_show_one_map_request_mode_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392
4393   if (0 <= retval)
4394     {
4395       u32 mode = mp->mode;
4396       print (vam->ofp, "map_request_mode: %U",
4397              format_lisp_map_request_mode, mode);
4398     }
4399
4400   vam->retval = retval;
4401   vam->result_ready = 1;
4402 }
4403
4404 static void
4405   vl_api_show_one_map_request_mode_reply_t_handler_json
4406   (vl_api_show_one_map_request_mode_reply_t * mp)
4407 {
4408   vat_main_t *vam = &vat_main;
4409   vat_json_node_t node;
4410   u8 *s = 0;
4411   u32 mode;
4412
4413   mode = mp->mode;
4414   s = format (0, "%U", format_lisp_map_request_mode, mode);
4415   vec_add1 (s, 0);
4416
4417   vat_json_init_object (&node);
4418   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4419   vat_json_print (vam->ofp, &node);
4420   vat_json_free (&node);
4421
4422   vec_free (s);
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static void
4428   vl_api_one_show_xtr_mode_reply_t_handler
4429   (vl_api_one_show_xtr_mode_reply_t * mp)
4430 {
4431   vat_main_t *vam = &vat_main;
4432   i32 retval = ntohl (mp->retval);
4433
4434   if (0 <= retval)
4435     {
4436       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4437     }
4438
4439   vam->retval = retval;
4440   vam->result_ready = 1;
4441 }
4442
4443 static void
4444   vl_api_one_show_xtr_mode_reply_t_handler_json
4445   (vl_api_one_show_xtr_mode_reply_t * mp)
4446 {
4447   vat_main_t *vam = &vat_main;
4448   vat_json_node_t node;
4449   u8 *status = 0;
4450
4451   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4452   vec_add1 (status, 0);
4453
4454   vat_json_init_object (&node);
4455   vat_json_object_add_string_copy (&node, "status", status);
4456
4457   vec_free (status);
4458
4459   vat_json_print (vam->ofp, &node);
4460   vat_json_free (&node);
4461
4462   vam->retval = ntohl (mp->retval);
4463   vam->result_ready = 1;
4464 }
4465
4466 static void
4467   vl_api_one_show_pitr_mode_reply_t_handler
4468   (vl_api_one_show_pitr_mode_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   i32 retval = ntohl (mp->retval);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_one_show_pitr_mode_reply_t_handler_json
4484   (vl_api_one_show_pitr_mode_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488   u8 *status = 0;
4489
4490   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4491   vec_add1 (status, 0);
4492
4493   vat_json_init_object (&node);
4494   vat_json_object_add_string_copy (&node, "status", status);
4495
4496   vec_free (status);
4497
4498   vat_json_print (vam->ofp, &node);
4499   vat_json_free (&node);
4500
4501   vam->retval = ntohl (mp->retval);
4502   vam->result_ready = 1;
4503 }
4504
4505 static void
4506   vl_api_one_show_petr_mode_reply_t_handler
4507   (vl_api_one_show_petr_mode_reply_t * mp)
4508 {
4509   vat_main_t *vam = &vat_main;
4510   i32 retval = ntohl (mp->retval);
4511
4512   if (0 <= retval)
4513     {
4514       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4515     }
4516
4517   vam->retval = retval;
4518   vam->result_ready = 1;
4519 }
4520
4521 static void
4522   vl_api_one_show_petr_mode_reply_t_handler_json
4523   (vl_api_one_show_petr_mode_reply_t * mp)
4524 {
4525   vat_main_t *vam = &vat_main;
4526   vat_json_node_t node;
4527   u8 *status = 0;
4528
4529   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4530   vec_add1 (status, 0);
4531
4532   vat_json_init_object (&node);
4533   vat_json_object_add_string_copy (&node, "status", status);
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static void
4545   vl_api_show_one_use_petr_reply_t_handler
4546   (vl_api_show_one_use_petr_reply_t * mp)
4547 {
4548   vat_main_t *vam = &vat_main;
4549   i32 retval = ntohl (mp->retval);
4550
4551   if (0 <= retval)
4552     {
4553       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4554       if (mp->status)
4555         {
4556           print (vam->ofp, "Proxy-ETR address; %U",
4557                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4558                  mp->address);
4559         }
4560     }
4561
4562   vam->retval = retval;
4563   vam->result_ready = 1;
4564 }
4565
4566 static void
4567   vl_api_show_one_use_petr_reply_t_handler_json
4568   (vl_api_show_one_use_petr_reply_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t node;
4572   u8 *status = 0;
4573   struct in_addr ip4;
4574   struct in6_addr ip6;
4575
4576   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4577   vec_add1 (status, 0);
4578
4579   vat_json_init_object (&node);
4580   vat_json_object_add_string_copy (&node, "status", status);
4581   if (mp->status)
4582     {
4583       if (mp->is_ip4)
4584         {
4585           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4586           vat_json_object_add_ip6 (&node, "address", ip6);
4587         }
4588       else
4589         {
4590           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4591           vat_json_object_add_ip4 (&node, "address", ip4);
4592         }
4593     }
4594
4595   vec_free (status);
4596
4597   vat_json_print (vam->ofp, &node);
4598   vat_json_free (&node);
4599
4600   vam->retval = ntohl (mp->retval);
4601   vam->result_ready = 1;
4602 }
4603
4604 static void
4605   vl_api_show_one_nsh_mapping_reply_t_handler
4606   (vl_api_show_one_nsh_mapping_reply_t * mp)
4607 {
4608   vat_main_t *vam = &vat_main;
4609   i32 retval = ntohl (mp->retval);
4610
4611   if (0 <= retval)
4612     {
4613       print (vam->ofp, "%-20s%-16s",
4614              mp->is_set ? "set" : "not-set",
4615              mp->is_set ? (char *) mp->locator_set_name : "");
4616     }
4617
4618   vam->retval = retval;
4619   vam->result_ready = 1;
4620 }
4621
4622 static void
4623   vl_api_show_one_nsh_mapping_reply_t_handler_json
4624   (vl_api_show_one_nsh_mapping_reply_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t node;
4628   u8 *status = 0;
4629
4630   status = format (0, "%s", mp->is_set ? "yes" : "no");
4631   vec_add1 (status, 0);
4632
4633   vat_json_init_object (&node);
4634   vat_json_object_add_string_copy (&node, "is_set", status);
4635   if (mp->is_set)
4636     {
4637       vat_json_object_add_string_copy (&node, "locator_set",
4638                                        mp->locator_set_name);
4639     }
4640
4641   vec_free (status);
4642
4643   vat_json_print (vam->ofp, &node);
4644   vat_json_free (&node);
4645
4646   vam->retval = ntohl (mp->retval);
4647   vam->result_ready = 1;
4648 }
4649
4650 static void
4651   vl_api_show_one_map_register_ttl_reply_t_handler
4652   (vl_api_show_one_map_register_ttl_reply_t * mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   i32 retval = ntohl (mp->retval);
4656
4657   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4658
4659   if (0 <= retval)
4660     {
4661       print (vam->ofp, "ttl: %u", mp->ttl);
4662     }
4663
4664   vam->retval = retval;
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_show_one_map_register_ttl_reply_t_handler_json
4670   (vl_api_show_one_map_register_ttl_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   vat_json_node_t node;
4674
4675   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4676   vat_json_init_object (&node);
4677   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4678
4679   vat_json_print (vam->ofp, &node);
4680   vat_json_free (&node);
4681
4682   vam->retval = ntohl (mp->retval);
4683   vam->result_ready = 1;
4684 }
4685
4686 static void
4687 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4688 {
4689   vat_main_t *vam = &vat_main;
4690   i32 retval = ntohl (mp->retval);
4691
4692   if (0 <= retval)
4693     {
4694       print (vam->ofp, "%-20s%-16s",
4695              mp->status ? "enabled" : "disabled",
4696              mp->status ? (char *) mp->locator_set_name : "");
4697     }
4698
4699   vam->retval = retval;
4700   vam->result_ready = 1;
4701 }
4702
4703 static void
4704 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4705 {
4706   vat_main_t *vam = &vat_main;
4707   vat_json_node_t node;
4708   u8 *status = 0;
4709
4710   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4711   vec_add1 (status, 0);
4712
4713   vat_json_init_object (&node);
4714   vat_json_object_add_string_copy (&node, "status", status);
4715   if (mp->status)
4716     {
4717       vat_json_object_add_string_copy (&node, "locator_set",
4718                                        mp->locator_set_name);
4719     }
4720
4721   vec_free (status);
4722
4723   vat_json_print (vam->ofp, &node);
4724   vat_json_free (&node);
4725
4726   vam->retval = ntohl (mp->retval);
4727   vam->result_ready = 1;
4728 }
4729
4730 static u8 *
4731 format_policer_type (u8 * s, va_list * va)
4732 {
4733   u32 i = va_arg (*va, u32);
4734
4735   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4736     s = format (s, "1r2c");
4737   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4738     s = format (s, "1r3c");
4739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4740     s = format (s, "2r3c-2698");
4741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4742     s = format (s, "2r3c-4115");
4743   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4744     s = format (s, "2r3c-mef5cf1");
4745   else
4746     s = format (s, "ILLEGAL");
4747   return s;
4748 }
4749
4750 static u8 *
4751 format_policer_rate_type (u8 * s, va_list * va)
4752 {
4753   u32 i = va_arg (*va, u32);
4754
4755   if (i == SSE2_QOS_RATE_KBPS)
4756     s = format (s, "kbps");
4757   else if (i == SSE2_QOS_RATE_PPS)
4758     s = format (s, "pps");
4759   else
4760     s = format (s, "ILLEGAL");
4761   return s;
4762 }
4763
4764 static u8 *
4765 format_policer_round_type (u8 * s, va_list * va)
4766 {
4767   u32 i = va_arg (*va, u32);
4768
4769   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4770     s = format (s, "closest");
4771   else if (i == SSE2_QOS_ROUND_TO_UP)
4772     s = format (s, "up");
4773   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4774     s = format (s, "down");
4775   else
4776     s = format (s, "ILLEGAL");
4777   return s;
4778 }
4779
4780 static u8 *
4781 format_policer_action_type (u8 * s, va_list * va)
4782 {
4783   u32 i = va_arg (*va, u32);
4784
4785   if (i == SSE2_QOS_ACTION_DROP)
4786     s = format (s, "drop");
4787   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4788     s = format (s, "transmit");
4789   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4790     s = format (s, "mark-and-transmit");
4791   else
4792     s = format (s, "ILLEGAL");
4793   return s;
4794 }
4795
4796 static u8 *
4797 format_dscp (u8 * s, va_list * va)
4798 {
4799   u32 i = va_arg (*va, u32);
4800   char *t = 0;
4801
4802   switch (i)
4803     {
4804 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4805       foreach_vnet_dscp
4806 #undef _
4807     default:
4808       return format (s, "ILLEGAL");
4809     }
4810   s = format (s, "%s", t);
4811   return s;
4812 }
4813
4814 static void
4815 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4816 {
4817   vat_main_t *vam = &vat_main;
4818   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4819
4820   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4821     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4822   else
4823     conform_dscp_str = format (0, "");
4824
4825   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4826     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4827   else
4828     exceed_dscp_str = format (0, "");
4829
4830   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4831     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4832   else
4833     violate_dscp_str = format (0, "");
4834
4835   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4836          "rate type %U, round type %U, %s rate, %s color-aware, "
4837          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4838          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4839          "conform action %U%s, exceed action %U%s, violate action %U%s",
4840          mp->name,
4841          format_policer_type, mp->type,
4842          ntohl (mp->cir),
4843          ntohl (mp->eir),
4844          clib_net_to_host_u64 (mp->cb),
4845          clib_net_to_host_u64 (mp->eb),
4846          format_policer_rate_type, mp->rate_type,
4847          format_policer_round_type, mp->round_type,
4848          mp->single_rate ? "single" : "dual",
4849          mp->color_aware ? "is" : "not",
4850          ntohl (mp->cir_tokens_per_period),
4851          ntohl (mp->pir_tokens_per_period),
4852          ntohl (mp->scale),
4853          ntohl (mp->current_limit),
4854          ntohl (mp->current_bucket),
4855          ntohl (mp->extended_limit),
4856          ntohl (mp->extended_bucket),
4857          clib_net_to_host_u64 (mp->last_update_time),
4858          format_policer_action_type, mp->conform_action_type,
4859          conform_dscp_str,
4860          format_policer_action_type, mp->exceed_action_type,
4861          exceed_dscp_str,
4862          format_policer_action_type, mp->violate_action_type,
4863          violate_dscp_str);
4864
4865   vec_free (conform_dscp_str);
4866   vec_free (exceed_dscp_str);
4867   vec_free (violate_dscp_str);
4868 }
4869
4870 static void vl_api_policer_details_t_handler_json
4871   (vl_api_policer_details_t * mp)
4872 {
4873   vat_main_t *vam = &vat_main;
4874   vat_json_node_t *node;
4875   u8 *rate_type_str, *round_type_str, *type_str;
4876   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4877
4878   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4879   round_type_str =
4880     format (0, "%U", format_policer_round_type, mp->round_type);
4881   type_str = format (0, "%U", format_policer_type, mp->type);
4882   conform_action_str = format (0, "%U", format_policer_action_type,
4883                                mp->conform_action_type);
4884   exceed_action_str = format (0, "%U", format_policer_action_type,
4885                               mp->exceed_action_type);
4886   violate_action_str = format (0, "%U", format_policer_action_type,
4887                                mp->violate_action_type);
4888
4889   if (VAT_JSON_ARRAY != vam->json_tree.type)
4890     {
4891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4892       vat_json_init_array (&vam->json_tree);
4893     }
4894   node = vat_json_array_add (&vam->json_tree);
4895
4896   vat_json_init_object (node);
4897   vat_json_object_add_string_copy (node, "name", mp->name);
4898   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4899   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4900   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4901   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4902   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4903   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4904   vat_json_object_add_string_copy (node, "type", type_str);
4905   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4906   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4907   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4908   vat_json_object_add_uint (node, "cir_tokens_per_period",
4909                             ntohl (mp->cir_tokens_per_period));
4910   vat_json_object_add_uint (node, "eir_tokens_per_period",
4911                             ntohl (mp->pir_tokens_per_period));
4912   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4913   vat_json_object_add_uint (node, "current_bucket",
4914                             ntohl (mp->current_bucket));
4915   vat_json_object_add_uint (node, "extended_limit",
4916                             ntohl (mp->extended_limit));
4917   vat_json_object_add_uint (node, "extended_bucket",
4918                             ntohl (mp->extended_bucket));
4919   vat_json_object_add_uint (node, "last_update_time",
4920                             ntohl (mp->last_update_time));
4921   vat_json_object_add_string_copy (node, "conform_action",
4922                                    conform_action_str);
4923   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4924     {
4925       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4926       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4927       vec_free (dscp_str);
4928     }
4929   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4930   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4931     {
4932       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4933       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4934       vec_free (dscp_str);
4935     }
4936   vat_json_object_add_string_copy (node, "violate_action",
4937                                    violate_action_str);
4938   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4939     {
4940       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4941       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4942       vec_free (dscp_str);
4943     }
4944
4945   vec_free (rate_type_str);
4946   vec_free (round_type_str);
4947   vec_free (type_str);
4948   vec_free (conform_action_str);
4949   vec_free (exceed_action_str);
4950   vec_free (violate_action_str);
4951 }
4952
4953 static void
4954 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4955                                            mp)
4956 {
4957   vat_main_t *vam = &vat_main;
4958   int i, count = ntohl (mp->count);
4959
4960   if (count > 0)
4961     print (vam->ofp, "classify table ids (%d) : ", count);
4962   for (i = 0; i < count; i++)
4963     {
4964       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4965       print (vam->ofp, (i < count - 1) ? "," : "");
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void
4972   vl_api_classify_table_ids_reply_t_handler_json
4973   (vl_api_classify_table_ids_reply_t * mp)
4974 {
4975   vat_main_t *vam = &vat_main;
4976   int i, count = ntohl (mp->count);
4977
4978   if (count > 0)
4979     {
4980       vat_json_node_t node;
4981
4982       vat_json_init_object (&node);
4983       for (i = 0; i < count; i++)
4984         {
4985           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4986         }
4987       vat_json_print (vam->ofp, &node);
4988       vat_json_free (&node);
4989     }
4990   vam->retval = ntohl (mp->retval);
4991   vam->result_ready = 1;
4992 }
4993
4994 static void
4995   vl_api_classify_table_by_interface_reply_t_handler
4996   (vl_api_classify_table_by_interface_reply_t * mp)
4997 {
4998   vat_main_t *vam = &vat_main;
4999   u32 table_id;
5000
5001   table_id = ntohl (mp->l2_table_id);
5002   if (table_id != ~0)
5003     print (vam->ofp, "l2 table id : %d", table_id);
5004   else
5005     print (vam->ofp, "l2 table id : No input ACL tables configured");
5006   table_id = ntohl (mp->ip4_table_id);
5007   if (table_id != ~0)
5008     print (vam->ofp, "ip4 table id : %d", table_id);
5009   else
5010     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5011   table_id = ntohl (mp->ip6_table_id);
5012   if (table_id != ~0)
5013     print (vam->ofp, "ip6 table id : %d", table_id);
5014   else
5015     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5016   vam->retval = ntohl (mp->retval);
5017   vam->result_ready = 1;
5018 }
5019
5020 static void
5021   vl_api_classify_table_by_interface_reply_t_handler_json
5022   (vl_api_classify_table_by_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   vat_json_init_object (&node);
5028
5029   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5030   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5031   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5032
5033   vat_json_print (vam->ofp, &node);
5034   vat_json_free (&node);
5035
5036   vam->retval = ntohl (mp->retval);
5037   vam->result_ready = 1;
5038 }
5039
5040 static void vl_api_policer_add_del_reply_t_handler
5041   (vl_api_policer_add_del_reply_t * mp)
5042 {
5043   vat_main_t *vam = &vat_main;
5044   i32 retval = ntohl (mp->retval);
5045   if (vam->async_mode)
5046     {
5047       vam->async_errors += (retval < 0);
5048     }
5049   else
5050     {
5051       vam->retval = retval;
5052       vam->result_ready = 1;
5053       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5054         /*
5055          * Note: this is just barely thread-safe, depends on
5056          * the main thread spinning waiting for an answer...
5057          */
5058         errmsg ("policer index %d", ntohl (mp->policer_index));
5059     }
5060 }
5061
5062 static void vl_api_policer_add_del_reply_t_handler_json
5063   (vl_api_policer_add_del_reply_t * mp)
5064 {
5065   vat_main_t *vam = &vat_main;
5066   vat_json_node_t node;
5067
5068   vat_json_init_object (&node);
5069   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5070   vat_json_object_add_uint (&node, "policer_index",
5071                             ntohl (mp->policer_index));
5072
5073   vat_json_print (vam->ofp, &node);
5074   vat_json_free (&node);
5075
5076   vam->retval = ntohl (mp->retval);
5077   vam->result_ready = 1;
5078 }
5079
5080 /* Format hex dump. */
5081 u8 *
5082 format_hex_bytes (u8 * s, va_list * va)
5083 {
5084   u8 *bytes = va_arg (*va, u8 *);
5085   int n_bytes = va_arg (*va, int);
5086   uword i;
5087
5088   /* Print short or long form depending on byte count. */
5089   uword short_form = n_bytes <= 32;
5090   u32 indent = format_get_indent (s);
5091
5092   if (n_bytes == 0)
5093     return s;
5094
5095   for (i = 0; i < n_bytes; i++)
5096     {
5097       if (!short_form && (i % 32) == 0)
5098         s = format (s, "%08x: ", i);
5099       s = format (s, "%02x", bytes[i]);
5100       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5101         s = format (s, "\n%U", format_white_space, indent);
5102     }
5103
5104   return s;
5105 }
5106
5107 static void
5108 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5109                                             * mp)
5110 {
5111   vat_main_t *vam = &vat_main;
5112   i32 retval = ntohl (mp->retval);
5113   if (retval == 0)
5114     {
5115       print (vam->ofp, "classify table info :");
5116       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5117              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5118              ntohl (mp->miss_next_index));
5119       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5120              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5121              ntohl (mp->match_n_vectors));
5122       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5123              ntohl (mp->mask_length));
5124     }
5125   vam->retval = retval;
5126   vam->result_ready = 1;
5127 }
5128
5129 static void
5130   vl_api_classify_table_info_reply_t_handler_json
5131   (vl_api_classify_table_info_reply_t * mp)
5132 {
5133   vat_main_t *vam = &vat_main;
5134   vat_json_node_t node;
5135
5136   i32 retval = ntohl (mp->retval);
5137   if (retval == 0)
5138     {
5139       vat_json_init_object (&node);
5140
5141       vat_json_object_add_int (&node, "sessions",
5142                                ntohl (mp->active_sessions));
5143       vat_json_object_add_int (&node, "nexttbl",
5144                                ntohl (mp->next_table_index));
5145       vat_json_object_add_int (&node, "nextnode",
5146                                ntohl (mp->miss_next_index));
5147       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5148       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5149       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5150       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5151                       ntohl (mp->mask_length), 0);
5152       vat_json_object_add_string_copy (&node, "mask", s);
5153
5154       vat_json_print (vam->ofp, &node);
5155       vat_json_free (&node);
5156     }
5157   vam->retval = ntohl (mp->retval);
5158   vam->result_ready = 1;
5159 }
5160
5161 static void
5162 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5163                                            mp)
5164 {
5165   vat_main_t *vam = &vat_main;
5166
5167   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5168          ntohl (mp->hit_next_index), ntohl (mp->advance),
5169          ntohl (mp->opaque_index));
5170   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5171          ntohl (mp->match_length));
5172 }
5173
5174 static void
5175   vl_api_classify_session_details_t_handler_json
5176   (vl_api_classify_session_details_t * mp)
5177 {
5178   vat_main_t *vam = &vat_main;
5179   vat_json_node_t *node = NULL;
5180
5181   if (VAT_JSON_ARRAY != vam->json_tree.type)
5182     {
5183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5184       vat_json_init_array (&vam->json_tree);
5185     }
5186   node = vat_json_array_add (&vam->json_tree);
5187
5188   vat_json_init_object (node);
5189   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5190   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5191   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5192   u8 *s =
5193     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5194             0);
5195   vat_json_object_add_string_copy (node, "match", s);
5196 }
5197
5198 static void vl_api_pg_create_interface_reply_t_handler
5199   (vl_api_pg_create_interface_reply_t * mp)
5200 {
5201   vat_main_t *vam = &vat_main;
5202
5203   vam->retval = ntohl (mp->retval);
5204   vam->result_ready = 1;
5205 }
5206
5207 static void vl_api_pg_create_interface_reply_t_handler_json
5208   (vl_api_pg_create_interface_reply_t * mp)
5209 {
5210   vat_main_t *vam = &vat_main;
5211   vat_json_node_t node;
5212
5213   i32 retval = ntohl (mp->retval);
5214   if (retval == 0)
5215     {
5216       vat_json_init_object (&node);
5217
5218       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5219
5220       vat_json_print (vam->ofp, &node);
5221       vat_json_free (&node);
5222     }
5223   vam->retval = ntohl (mp->retval);
5224   vam->result_ready = 1;
5225 }
5226
5227 static void vl_api_policer_classify_details_t_handler
5228   (vl_api_policer_classify_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231
5232   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5233          ntohl (mp->table_index));
5234 }
5235
5236 static void vl_api_policer_classify_details_t_handler_json
5237   (vl_api_policer_classify_details_t * mp)
5238 {
5239   vat_main_t *vam = &vat_main;
5240   vat_json_node_t *node;
5241
5242   if (VAT_JSON_ARRAY != vam->json_tree.type)
5243     {
5244       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5245       vat_json_init_array (&vam->json_tree);
5246     }
5247   node = vat_json_array_add (&vam->json_tree);
5248
5249   vat_json_init_object (node);
5250   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5251   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5252 }
5253
5254 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5255   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5256 {
5257   vat_main_t *vam = &vat_main;
5258   i32 retval = ntohl (mp->retval);
5259   if (vam->async_mode)
5260     {
5261       vam->async_errors += (retval < 0);
5262     }
5263   else
5264     {
5265       vam->retval = retval;
5266       vam->sw_if_index = ntohl (mp->sw_if_index);
5267       vam->result_ready = 1;
5268     }
5269   vam->regenerate_interface_table = 1;
5270 }
5271
5272 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5273   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5274 {
5275   vat_main_t *vam = &vat_main;
5276   vat_json_node_t node;
5277
5278   vat_json_init_object (&node);
5279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5280   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5281
5282   vat_json_print (vam->ofp, &node);
5283   vat_json_free (&node);
5284
5285   vam->retval = ntohl (mp->retval);
5286   vam->result_ready = 1;
5287 }
5288
5289 static void vl_api_flow_classify_details_t_handler
5290   (vl_api_flow_classify_details_t * mp)
5291 {
5292   vat_main_t *vam = &vat_main;
5293
5294   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5295          ntohl (mp->table_index));
5296 }
5297
5298 static void vl_api_flow_classify_details_t_handler_json
5299   (vl_api_flow_classify_details_t * mp)
5300 {
5301   vat_main_t *vam = &vat_main;
5302   vat_json_node_t *node;
5303
5304   if (VAT_JSON_ARRAY != vam->json_tree.type)
5305     {
5306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5307       vat_json_init_array (&vam->json_tree);
5308     }
5309   node = vat_json_array_add (&vam->json_tree);
5310
5311   vat_json_init_object (node);
5312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5313   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5314 }
5315
5316 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5317 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5318 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5319 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5320 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5321 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5322 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5323 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5324 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5325 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5326 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5327 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5328 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5329 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5330 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5331 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5332 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5333 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5334 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5335 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5336 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5337 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5338
5339 /*
5340  * Generate boilerplate reply handlers, which
5341  * dig the return value out of the xxx_reply_t API message,
5342  * stick it into vam->retval, and set vam->result_ready
5343  *
5344  * Could also do this by pointing N message decode slots at
5345  * a single function, but that could break in subtle ways.
5346  */
5347
5348 #define foreach_standard_reply_retval_handler           \
5349 _(sw_interface_set_flags_reply)                         \
5350 _(sw_interface_add_del_address_reply)                   \
5351 _(sw_interface_set_rx_mode_reply)                       \
5352 _(sw_interface_set_rx_placement_reply)                  \
5353 _(sw_interface_set_table_reply)                         \
5354 _(sw_interface_set_mpls_enable_reply)                   \
5355 _(sw_interface_set_vpath_reply)                         \
5356 _(sw_interface_set_vxlan_bypass_reply)                  \
5357 _(sw_interface_set_geneve_bypass_reply)                 \
5358 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5359 _(sw_interface_set_l2_bridge_reply)                     \
5360 _(bridge_domain_add_del_reply)                          \
5361 _(sw_interface_set_l2_xconnect_reply)                   \
5362 _(l2fib_add_del_reply)                                  \
5363 _(l2fib_flush_int_reply)                                \
5364 _(l2fib_flush_bd_reply)                                 \
5365 _(ip_add_del_route_reply)                               \
5366 _(ip_table_add_del_reply)                               \
5367 _(ip_mroute_add_del_reply)                              \
5368 _(mpls_route_add_del_reply)                             \
5369 _(mpls_table_add_del_reply)                             \
5370 _(mpls_ip_bind_unbind_reply)                            \
5371 _(bier_route_add_del_reply)                             \
5372 _(bier_table_add_del_reply)                             \
5373 _(proxy_arp_add_del_reply)                              \
5374 _(proxy_arp_intfc_enable_disable_reply)                 \
5375 _(sw_interface_set_unnumbered_reply)                    \
5376 _(ip_neighbor_add_del_reply)                            \
5377 _(oam_add_del_reply)                                    \
5378 _(reset_fib_reply)                                      \
5379 _(dhcp_proxy_config_reply)                              \
5380 _(dhcp_proxy_set_vss_reply)                             \
5381 _(dhcp_client_config_reply)                             \
5382 _(set_ip_flow_hash_reply)                               \
5383 _(sw_interface_ip6_enable_disable_reply)                \
5384 _(sw_interface_ip6_set_link_local_address_reply)        \
5385 _(ip6nd_proxy_add_del_reply)                            \
5386 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5387 _(sw_interface_ip6nd_ra_config_reply)                   \
5388 _(set_arp_neighbor_limit_reply)                         \
5389 _(l2_patch_add_del_reply)                               \
5390 _(sr_mpls_policy_add_reply)                             \
5391 _(sr_mpls_policy_mod_reply)                             \
5392 _(sr_mpls_policy_del_reply)                             \
5393 _(sr_policy_add_reply)                                  \
5394 _(sr_policy_mod_reply)                                  \
5395 _(sr_policy_del_reply)                                  \
5396 _(sr_localsid_add_del_reply)                            \
5397 _(sr_steering_add_del_reply)                            \
5398 _(classify_add_del_session_reply)                       \
5399 _(classify_set_interface_ip_table_reply)                \
5400 _(classify_set_interface_l2_tables_reply)               \
5401 _(l2tpv3_set_tunnel_cookies_reply)                      \
5402 _(l2tpv3_interface_enable_disable_reply)                \
5403 _(l2tpv3_set_lookup_key_reply)                          \
5404 _(l2_fib_clear_table_reply)                             \
5405 _(l2_interface_efp_filter_reply)                        \
5406 _(l2_interface_vlan_tag_rewrite_reply)                  \
5407 _(modify_vhost_user_if_reply)                           \
5408 _(delete_vhost_user_if_reply)                           \
5409 _(ip_probe_neighbor_reply)                              \
5410 _(ip_scan_neighbor_enable_disable_reply)                \
5411 _(want_ip4_arp_events_reply)                            \
5412 _(want_ip6_nd_events_reply)                             \
5413 _(want_l2_macs_events_reply)                            \
5414 _(input_acl_set_interface_reply)                        \
5415 _(ipsec_spd_add_del_reply)                              \
5416 _(ipsec_interface_add_del_spd_reply)                    \
5417 _(ipsec_spd_add_del_entry_reply)                        \
5418 _(ipsec_sad_add_del_entry_reply)                        \
5419 _(ipsec_sa_set_key_reply)                               \
5420 _(ipsec_tunnel_if_add_del_reply)                        \
5421 _(ipsec_tunnel_if_set_key_reply)                        \
5422 _(ipsec_tunnel_if_set_sa_reply)                         \
5423 _(ikev2_profile_add_del_reply)                          \
5424 _(ikev2_profile_set_auth_reply)                         \
5425 _(ikev2_profile_set_id_reply)                           \
5426 _(ikev2_profile_set_ts_reply)                           \
5427 _(ikev2_set_local_key_reply)                            \
5428 _(ikev2_set_responder_reply)                            \
5429 _(ikev2_set_ike_transforms_reply)                       \
5430 _(ikev2_set_esp_transforms_reply)                       \
5431 _(ikev2_set_sa_lifetime_reply)                          \
5432 _(ikev2_initiate_sa_init_reply)                         \
5433 _(ikev2_initiate_del_ike_sa_reply)                      \
5434 _(ikev2_initiate_del_child_sa_reply)                    \
5435 _(ikev2_initiate_rekey_child_sa_reply)                  \
5436 _(delete_loopback_reply)                                \
5437 _(bd_ip_mac_add_del_reply)                              \
5438 _(want_interface_events_reply)                          \
5439 _(want_stats_reply)                                     \
5440 _(cop_interface_enable_disable_reply)                   \
5441 _(cop_whitelist_enable_disable_reply)                   \
5442 _(sw_interface_clear_stats_reply)                       \
5443 _(ioam_enable_reply)                                    \
5444 _(ioam_disable_reply)                                   \
5445 _(one_add_del_locator_reply)                            \
5446 _(one_add_del_local_eid_reply)                          \
5447 _(one_add_del_remote_mapping_reply)                     \
5448 _(one_add_del_adjacency_reply)                          \
5449 _(one_add_del_map_resolver_reply)                       \
5450 _(one_add_del_map_server_reply)                         \
5451 _(one_enable_disable_reply)                             \
5452 _(one_rloc_probe_enable_disable_reply)                  \
5453 _(one_map_register_enable_disable_reply)                \
5454 _(one_map_register_set_ttl_reply)                       \
5455 _(one_set_transport_protocol_reply)                     \
5456 _(one_map_register_fallback_threshold_reply)            \
5457 _(one_pitr_set_locator_set_reply)                       \
5458 _(one_map_request_mode_reply)                           \
5459 _(one_add_del_map_request_itr_rlocs_reply)              \
5460 _(one_eid_table_add_del_map_reply)                      \
5461 _(one_use_petr_reply)                                   \
5462 _(one_stats_enable_disable_reply)                       \
5463 _(one_add_del_l2_arp_entry_reply)                       \
5464 _(one_add_del_ndp_entry_reply)                          \
5465 _(one_stats_flush_reply)                                \
5466 _(one_enable_disable_xtr_mode_reply)                    \
5467 _(one_enable_disable_pitr_mode_reply)                   \
5468 _(one_enable_disable_petr_mode_reply)                   \
5469 _(gpe_enable_disable_reply)                             \
5470 _(gpe_set_encap_mode_reply)                             \
5471 _(gpe_add_del_iface_reply)                              \
5472 _(gpe_add_del_native_fwd_rpath_reply)                   \
5473 _(af_packet_delete_reply)                               \
5474 _(policer_classify_set_interface_reply)                 \
5475 _(netmap_create_reply)                                  \
5476 _(netmap_delete_reply)                                  \
5477 _(set_ipfix_exporter_reply)                             \
5478 _(set_ipfix_classify_stream_reply)                      \
5479 _(ipfix_classify_table_add_del_reply)                   \
5480 _(flow_classify_set_interface_reply)                    \
5481 _(sw_interface_span_enable_disable_reply)               \
5482 _(pg_capture_reply)                                     \
5483 _(pg_enable_disable_reply)                              \
5484 _(ip_source_and_port_range_check_add_del_reply)         \
5485 _(ip_source_and_port_range_check_interface_add_del_reply)\
5486 _(delete_subif_reply)                                   \
5487 _(l2_interface_pbb_tag_rewrite_reply)                   \
5488 _(punt_reply)                                           \
5489 _(feature_enable_disable_reply)                         \
5490 _(sw_interface_tag_add_del_reply)                       \
5491 _(hw_interface_set_mtu_reply)                           \
5492 _(p2p_ethernet_add_reply)                               \
5493 _(p2p_ethernet_del_reply)                               \
5494 _(lldp_config_reply)                                    \
5495 _(sw_interface_set_lldp_reply)                          \
5496 _(tcp_configure_src_addresses_reply)                    \
5497 _(dns_enable_disable_reply)                             \
5498 _(dns_name_server_add_del_reply)                        \
5499 _(session_rule_add_del_reply)                           \
5500 _(ip_container_proxy_add_del_reply)                     \
5501 _(output_acl_set_interface_reply)                       \
5502 _(qos_record_enable_disable_reply)
5503
5504 #define _(n)                                    \
5505     static void vl_api_##n##_t_handler          \
5506     (vl_api_##n##_t * mp)                       \
5507     {                                           \
5508         vat_main_t * vam = &vat_main;           \
5509         i32 retval = ntohl(mp->retval);         \
5510         if (vam->async_mode) {                  \
5511             vam->async_errors += (retval < 0);  \
5512         } else {                                \
5513             vam->retval = retval;               \
5514             vam->result_ready = 1;              \
5515         }                                       \
5516     }
5517 foreach_standard_reply_retval_handler;
5518 #undef _
5519
5520 #define _(n)                                    \
5521     static void vl_api_##n##_t_handler_json     \
5522     (vl_api_##n##_t * mp)                       \
5523     {                                           \
5524         vat_main_t * vam = &vat_main;           \
5525         vat_json_node_t node;                   \
5526         vat_json_init_object(&node);            \
5527         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5528         vat_json_print(vam->ofp, &node);        \
5529         vam->retval = ntohl(mp->retval);        \
5530         vam->result_ready = 1;                  \
5531     }
5532 foreach_standard_reply_retval_handler;
5533 #undef _
5534
5535 /*
5536  * Table of message reply handlers, must include boilerplate handlers
5537  * we just generated
5538  */
5539
5540 #define foreach_vpe_api_reply_msg                                       \
5541 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5542 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5543 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5544 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5545 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5546 _(CLI_REPLY, cli_reply)                                                 \
5547 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5548 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5549   sw_interface_add_del_address_reply)                                   \
5550 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5551 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5552 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5553 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5554 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5555 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5556 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5557 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5558 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5559   sw_interface_set_l2_xconnect_reply)                                   \
5560 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5561   sw_interface_set_l2_bridge_reply)                                     \
5562 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5563 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5564 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5565 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5566 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5567 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5568 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5569 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5570 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5571 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5572 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5573 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5574 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5575 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5576 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5577 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5578 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5579 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5580 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5581 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5582 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5583 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5584 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5585 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5586 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5587 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5588 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5589 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5590 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5591 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5592 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5593   proxy_arp_intfc_enable_disable_reply)                                 \
5594 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5595 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5596   sw_interface_set_unnumbered_reply)                                    \
5597 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5598 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5599 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5600 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5601 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5602 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5603 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5604 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5605 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5606 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5607 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5608   sw_interface_ip6_enable_disable_reply)                                \
5609 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5610   sw_interface_ip6_set_link_local_address_reply)                        \
5611 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5612 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5613 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5614   sw_interface_ip6nd_ra_prefix_reply)                                   \
5615 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5616   sw_interface_ip6nd_ra_config_reply)                                   \
5617 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5618 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5619 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5620 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5621 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5622 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5623 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5624 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5625 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5626 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5627 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5628 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5629 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5630 classify_set_interface_ip_table_reply)                                  \
5631 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5632   classify_set_interface_l2_tables_reply)                               \
5633 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5634 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5635 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5636 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5637 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5638   l2tpv3_interface_enable_disable_reply)                                \
5639 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5640 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5641 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5642 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5643 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5644 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5645 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5646 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5647 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5648 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5649 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5650 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5651 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5652 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5653 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5654 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5655 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5656 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5657 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5658 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5659 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5660 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5661 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5662 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5663 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5664 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5665 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5666 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5667 _(L2_MACS_EVENT, l2_macs_event)                                         \
5668 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5669 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5670 _(IP_DETAILS, ip_details)                                               \
5671 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5672 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5673 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5674 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5675 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5676 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5677 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5678 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5679 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5680 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5681 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5682 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5683 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5684 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5685 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5686 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5687 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5688 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5689 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5690 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5691 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5692 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5693 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5694 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5695 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5696 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5697 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5698 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5699 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5700 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5701 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5702 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5703 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5704 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5705 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5706 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5707 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5708 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5709 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5710 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5711 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5712 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5713 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5714 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5715   one_map_register_enable_disable_reply)                                \
5716 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5717 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5718 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5719 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5720   one_map_register_fallback_threshold_reply)                            \
5721 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5722   one_rloc_probe_enable_disable_reply)                                  \
5723 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5724 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5725 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5726 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5727 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5728 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5729 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5730 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5731 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5732 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5733 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5734 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5735 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5736 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5737 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5738 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5739   show_one_stats_enable_disable_reply)                                  \
5740 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5741 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5742 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5743 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5744 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5745 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5746 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5747 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5748   one_enable_disable_pitr_mode_reply)                                   \
5749 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5750   one_enable_disable_petr_mode_reply)                                   \
5751 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5752 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5753 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5754 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5755 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5756 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5757 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5758 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5759 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5760 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5761 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5762 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5763   gpe_add_del_native_fwd_rpath_reply)                                   \
5764 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5765   gpe_fwd_entry_path_details)                                           \
5766 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5767 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5768   one_add_del_map_request_itr_rlocs_reply)                              \
5769 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5770   one_get_map_request_itr_rlocs_reply)                                  \
5771 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5772 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5773 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5774 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5775 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5776 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5777   show_one_map_register_state_reply)                                    \
5778 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5779 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5780   show_one_map_register_fallback_threshold_reply)                       \
5781 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5782 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5783 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5784 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5785 _(POLICER_DETAILS, policer_details)                                     \
5786 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5787 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5788 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5789 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5790 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5791 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5792 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5793 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5794 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5795 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5796 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5797 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5798 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5799 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5800 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5801 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5802 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5803 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5804 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5805 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5806 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5807 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5808 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5809 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5810 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5811  ip_source_and_port_range_check_add_del_reply)                          \
5812 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5813  ip_source_and_port_range_check_interface_add_del_reply)                \
5814 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5815 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5816 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5817 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5818 _(PUNT_REPLY, punt_reply)                                               \
5819 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5820 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5821 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5822 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5823 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5824 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5825 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5826 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5827 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5828 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5829 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5830 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5831 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5832 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5833 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5834 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5835 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5836 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5837 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5838 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5839 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5840 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5841 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5842
5843 #define foreach_standalone_reply_msg                                    \
5844 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5845 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5846 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5847 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5848 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5849 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5850 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5851
5852 typedef struct
5853 {
5854   u8 *name;
5855   u32 value;
5856 } name_sort_t;
5857
5858 #define STR_VTR_OP_CASE(op)     \
5859     case L2_VTR_ ## op:         \
5860         return "" # op;
5861
5862 static const char *
5863 str_vtr_op (u32 vtr_op)
5864 {
5865   switch (vtr_op)
5866     {
5867       STR_VTR_OP_CASE (DISABLED);
5868       STR_VTR_OP_CASE (PUSH_1);
5869       STR_VTR_OP_CASE (PUSH_2);
5870       STR_VTR_OP_CASE (POP_1);
5871       STR_VTR_OP_CASE (POP_2);
5872       STR_VTR_OP_CASE (TRANSLATE_1_1);
5873       STR_VTR_OP_CASE (TRANSLATE_1_2);
5874       STR_VTR_OP_CASE (TRANSLATE_2_1);
5875       STR_VTR_OP_CASE (TRANSLATE_2_2);
5876     }
5877
5878   return "UNKNOWN";
5879 }
5880
5881 static int
5882 dump_sub_interface_table (vat_main_t * vam)
5883 {
5884   const sw_interface_subif_t *sub = NULL;
5885
5886   if (vam->json_output)
5887     {
5888       clib_warning
5889         ("JSON output supported only for VPE API calls and dump_stats_table");
5890       return -99;
5891     }
5892
5893   print (vam->ofp,
5894          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5895          "Interface", "sw_if_index",
5896          "sub id", "dot1ad", "tags", "outer id",
5897          "inner id", "exact", "default", "outer any", "inner any");
5898
5899   vec_foreach (sub, vam->sw_if_subif_table)
5900   {
5901     print (vam->ofp,
5902            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5903            sub->interface_name,
5904            sub->sw_if_index,
5905            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5906            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5907            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5908            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5909     if (sub->vtr_op != L2_VTR_DISABLED)
5910       {
5911         print (vam->ofp,
5912                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5913                "tag1: %d tag2: %d ]",
5914                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5915                sub->vtr_tag1, sub->vtr_tag2);
5916       }
5917   }
5918
5919   return 0;
5920 }
5921
5922 static int
5923 name_sort_cmp (void *a1, void *a2)
5924 {
5925   name_sort_t *n1 = a1;
5926   name_sort_t *n2 = a2;
5927
5928   return strcmp ((char *) n1->name, (char *) n2->name);
5929 }
5930
5931 static int
5932 dump_interface_table (vat_main_t * vam)
5933 {
5934   hash_pair_t *p;
5935   name_sort_t *nses = 0, *ns;
5936
5937   if (vam->json_output)
5938     {
5939       clib_warning
5940         ("JSON output supported only for VPE API calls and dump_stats_table");
5941       return -99;
5942     }
5943
5944   /* *INDENT-OFF* */
5945   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5946   ({
5947     vec_add2 (nses, ns, 1);
5948     ns->name = (u8 *)(p->key);
5949     ns->value = (u32) p->value[0];
5950   }));
5951   /* *INDENT-ON* */
5952
5953   vec_sort_with_function (nses, name_sort_cmp);
5954
5955   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5956   vec_foreach (ns, nses)
5957   {
5958     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5959   }
5960   vec_free (nses);
5961   return 0;
5962 }
5963
5964 static int
5965 dump_ip_table (vat_main_t * vam, int is_ipv6)
5966 {
5967   const ip_details_t *det = NULL;
5968   const ip_address_details_t *address = NULL;
5969   u32 i = ~0;
5970
5971   print (vam->ofp, "%-12s", "sw_if_index");
5972
5973   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5974   {
5975     i++;
5976     if (!det->present)
5977       {
5978         continue;
5979       }
5980     print (vam->ofp, "%-12d", i);
5981     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5982     if (!det->addr)
5983       {
5984         continue;
5985       }
5986     vec_foreach (address, det->addr)
5987     {
5988       print (vam->ofp,
5989              "            %-30U%-13d",
5990              is_ipv6 ? format_ip6_address : format_ip4_address,
5991              address->ip, address->prefix_length);
5992     }
5993   }
5994
5995   return 0;
5996 }
5997
5998 static int
5999 dump_ipv4_table (vat_main_t * vam)
6000 {
6001   if (vam->json_output)
6002     {
6003       clib_warning
6004         ("JSON output supported only for VPE API calls and dump_stats_table");
6005       return -99;
6006     }
6007
6008   return dump_ip_table (vam, 0);
6009 }
6010
6011 static int
6012 dump_ipv6_table (vat_main_t * vam)
6013 {
6014   if (vam->json_output)
6015     {
6016       clib_warning
6017         ("JSON output supported only for VPE API calls and dump_stats_table");
6018       return -99;
6019     }
6020
6021   return dump_ip_table (vam, 1);
6022 }
6023
6024 static char *
6025 counter_type_to_str (u8 counter_type, u8 is_combined)
6026 {
6027   if (!is_combined)
6028     {
6029       switch (counter_type)
6030         {
6031         case VNET_INTERFACE_COUNTER_DROP:
6032           return "drop";
6033         case VNET_INTERFACE_COUNTER_PUNT:
6034           return "punt";
6035         case VNET_INTERFACE_COUNTER_IP4:
6036           return "ip4";
6037         case VNET_INTERFACE_COUNTER_IP6:
6038           return "ip6";
6039         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6040           return "rx-no-buf";
6041         case VNET_INTERFACE_COUNTER_RX_MISS:
6042           return "rx-miss";
6043         case VNET_INTERFACE_COUNTER_RX_ERROR:
6044           return "rx-error";
6045         case VNET_INTERFACE_COUNTER_TX_ERROR:
6046           return "tx-error";
6047         default:
6048           return "INVALID-COUNTER-TYPE";
6049         }
6050     }
6051   else
6052     {
6053       switch (counter_type)
6054         {
6055         case VNET_INTERFACE_COUNTER_RX:
6056           return "rx";
6057         case VNET_INTERFACE_COUNTER_TX:
6058           return "tx";
6059         default:
6060           return "INVALID-COUNTER-TYPE";
6061         }
6062     }
6063 }
6064
6065 static int
6066 dump_stats_table (vat_main_t * vam)
6067 {
6068   vat_json_node_t node;
6069   vat_json_node_t *msg_array;
6070   vat_json_node_t *msg;
6071   vat_json_node_t *counter_array;
6072   vat_json_node_t *counter;
6073   interface_counter_t c;
6074   u64 packets;
6075   ip4_fib_counter_t *c4;
6076   ip6_fib_counter_t *c6;
6077   ip4_nbr_counter_t *n4;
6078   ip6_nbr_counter_t *n6;
6079   int i, j;
6080
6081   if (!vam->json_output)
6082     {
6083       clib_warning ("dump_stats_table supported only in JSON format");
6084       return -99;
6085     }
6086
6087   vat_json_init_object (&node);
6088
6089   /* interface counters */
6090   msg_array = vat_json_object_add (&node, "interface_counters");
6091   vat_json_init_array (msg_array);
6092   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6093     {
6094       msg = vat_json_array_add (msg_array);
6095       vat_json_init_object (msg);
6096       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6097                                        (u8 *) counter_type_to_str (i, 0));
6098       vat_json_object_add_int (msg, "is_combined", 0);
6099       counter_array = vat_json_object_add (msg, "data");
6100       vat_json_init_array (counter_array);
6101       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6102         {
6103           packets = vam->simple_interface_counters[i][j];
6104           vat_json_array_add_uint (counter_array, packets);
6105         }
6106     }
6107   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6108     {
6109       msg = vat_json_array_add (msg_array);
6110       vat_json_init_object (msg);
6111       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6112                                        (u8 *) counter_type_to_str (i, 1));
6113       vat_json_object_add_int (msg, "is_combined", 1);
6114       counter_array = vat_json_object_add (msg, "data");
6115       vat_json_init_array (counter_array);
6116       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6117         {
6118           c = vam->combined_interface_counters[i][j];
6119           counter = vat_json_array_add (counter_array);
6120           vat_json_init_object (counter);
6121           vat_json_object_add_uint (counter, "packets", c.packets);
6122           vat_json_object_add_uint (counter, "bytes", c.bytes);
6123         }
6124     }
6125
6126   /* ip4 fib counters */
6127   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6128   vat_json_init_array (msg_array);
6129   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6130     {
6131       msg = vat_json_array_add (msg_array);
6132       vat_json_init_object (msg);
6133       vat_json_object_add_uint (msg, "vrf_id",
6134                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6135       counter_array = vat_json_object_add (msg, "c");
6136       vat_json_init_array (counter_array);
6137       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6138         {
6139           counter = vat_json_array_add (counter_array);
6140           vat_json_init_object (counter);
6141           c4 = &vam->ip4_fib_counters[i][j];
6142           vat_json_object_add_ip4 (counter, "address", c4->address);
6143           vat_json_object_add_uint (counter, "address_length",
6144                                     c4->address_length);
6145           vat_json_object_add_uint (counter, "packets", c4->packets);
6146           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6147         }
6148     }
6149
6150   /* ip6 fib counters */
6151   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6152   vat_json_init_array (msg_array);
6153   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6154     {
6155       msg = vat_json_array_add (msg_array);
6156       vat_json_init_object (msg);
6157       vat_json_object_add_uint (msg, "vrf_id",
6158                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6159       counter_array = vat_json_object_add (msg, "c");
6160       vat_json_init_array (counter_array);
6161       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6162         {
6163           counter = vat_json_array_add (counter_array);
6164           vat_json_init_object (counter);
6165           c6 = &vam->ip6_fib_counters[i][j];
6166           vat_json_object_add_ip6 (counter, "address", c6->address);
6167           vat_json_object_add_uint (counter, "address_length",
6168                                     c6->address_length);
6169           vat_json_object_add_uint (counter, "packets", c6->packets);
6170           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6171         }
6172     }
6173
6174   /* ip4 nbr counters */
6175   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6176   vat_json_init_array (msg_array);
6177   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6178     {
6179       msg = vat_json_array_add (msg_array);
6180       vat_json_init_object (msg);
6181       vat_json_object_add_uint (msg, "sw_if_index", i);
6182       counter_array = vat_json_object_add (msg, "c");
6183       vat_json_init_array (counter_array);
6184       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6185         {
6186           counter = vat_json_array_add (counter_array);
6187           vat_json_init_object (counter);
6188           n4 = &vam->ip4_nbr_counters[i][j];
6189           vat_json_object_add_ip4 (counter, "address", n4->address);
6190           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6191           vat_json_object_add_uint (counter, "packets", n4->packets);
6192           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6193         }
6194     }
6195
6196   /* ip6 nbr counters */
6197   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6198   vat_json_init_array (msg_array);
6199   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6200     {
6201       msg = vat_json_array_add (msg_array);
6202       vat_json_init_object (msg);
6203       vat_json_object_add_uint (msg, "sw_if_index", i);
6204       counter_array = vat_json_object_add (msg, "c");
6205       vat_json_init_array (counter_array);
6206       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6207         {
6208           counter = vat_json_array_add (counter_array);
6209           vat_json_init_object (counter);
6210           n6 = &vam->ip6_nbr_counters[i][j];
6211           vat_json_object_add_ip6 (counter, "address", n6->address);
6212           vat_json_object_add_uint (counter, "packets", n6->packets);
6213           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6214         }
6215     }
6216
6217   vat_json_print (vam->ofp, &node);
6218   vat_json_free (&node);
6219
6220   return 0;
6221 }
6222
6223 /*
6224  * Pass CLI buffers directly in the CLI_INBAND API message,
6225  * instead of an additional shared memory area.
6226  */
6227 static int
6228 exec_inband (vat_main_t * vam)
6229 {
6230   vl_api_cli_inband_t *mp;
6231   unformat_input_t *i = vam->input;
6232   int ret;
6233
6234   if (vec_len (i->buffer) == 0)
6235     return -1;
6236
6237   if (vam->exec_mode == 0 && unformat (i, "mode"))
6238     {
6239       vam->exec_mode = 1;
6240       return 0;
6241     }
6242   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6243     {
6244       vam->exec_mode = 0;
6245       return 0;
6246     }
6247
6248   /*
6249    * In order for the CLI command to work, it
6250    * must be a vector ending in \n, not a C-string ending
6251    * in \n\0.
6252    */
6253   u32 len = vec_len (vam->input->buffer);
6254   M2 (CLI_INBAND, mp, len);
6255   clib_memcpy (mp->cmd, vam->input->buffer, len);
6256   mp->length = htonl (len);
6257
6258   S (mp);
6259   W (ret);
6260   /* json responses may or may not include a useful reply... */
6261   if (vec_len (vam->cmd_reply))
6262     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6263   return ret;
6264 }
6265
6266 int
6267 exec (vat_main_t * vam)
6268 {
6269   return exec_inband (vam);
6270 }
6271
6272 static int
6273 api_create_loopback (vat_main_t * vam)
6274 {
6275   unformat_input_t *i = vam->input;
6276   vl_api_create_loopback_t *mp;
6277   vl_api_create_loopback_instance_t *mp_lbi;
6278   u8 mac_address[6];
6279   u8 mac_set = 0;
6280   u8 is_specified = 0;
6281   u32 user_instance = 0;
6282   int ret;
6283
6284   memset (mac_address, 0, sizeof (mac_address));
6285
6286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6287     {
6288       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6289         mac_set = 1;
6290       if (unformat (i, "instance %d", &user_instance))
6291         is_specified = 1;
6292       else
6293         break;
6294     }
6295
6296   if (is_specified)
6297     {
6298       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6299       mp_lbi->is_specified = is_specified;
6300       if (is_specified)
6301         mp_lbi->user_instance = htonl (user_instance);
6302       if (mac_set)
6303         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6304       S (mp_lbi);
6305     }
6306   else
6307     {
6308       /* Construct the API message */
6309       M (CREATE_LOOPBACK, mp);
6310       if (mac_set)
6311         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6312       S (mp);
6313     }
6314
6315   W (ret);
6316   return ret;
6317 }
6318
6319 static int
6320 api_delete_loopback (vat_main_t * vam)
6321 {
6322   unformat_input_t *i = vam->input;
6323   vl_api_delete_loopback_t *mp;
6324   u32 sw_if_index = ~0;
6325   int ret;
6326
6327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6328     {
6329       if (unformat (i, "sw_if_index %d", &sw_if_index))
6330         ;
6331       else
6332         break;
6333     }
6334
6335   if (sw_if_index == ~0)
6336     {
6337       errmsg ("missing sw_if_index");
6338       return -99;
6339     }
6340
6341   /* Construct the API message */
6342   M (DELETE_LOOPBACK, mp);
6343   mp->sw_if_index = ntohl (sw_if_index);
6344
6345   S (mp);
6346   W (ret);
6347   return ret;
6348 }
6349
6350 static int
6351 api_want_stats (vat_main_t * vam)
6352 {
6353   unformat_input_t *i = vam->input;
6354   vl_api_want_stats_t *mp;
6355   int enable = -1;
6356   int ret;
6357
6358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6359     {
6360       if (unformat (i, "enable"))
6361         enable = 1;
6362       else if (unformat (i, "disable"))
6363         enable = 0;
6364       else
6365         break;
6366     }
6367
6368   if (enable == -1)
6369     {
6370       errmsg ("missing enable|disable");
6371       return -99;
6372     }
6373
6374   M (WANT_STATS, mp);
6375   mp->enable_disable = enable;
6376
6377   S (mp);
6378   W (ret);
6379   return ret;
6380 }
6381
6382 static int
6383 api_want_interface_events (vat_main_t * vam)
6384 {
6385   unformat_input_t *i = vam->input;
6386   vl_api_want_interface_events_t *mp;
6387   int enable = -1;
6388   int ret;
6389
6390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6391     {
6392       if (unformat (i, "enable"))
6393         enable = 1;
6394       else if (unformat (i, "disable"))
6395         enable = 0;
6396       else
6397         break;
6398     }
6399
6400   if (enable == -1)
6401     {
6402       errmsg ("missing enable|disable");
6403       return -99;
6404     }
6405
6406   M (WANT_INTERFACE_EVENTS, mp);
6407   mp->enable_disable = enable;
6408
6409   vam->interface_event_display = enable;
6410
6411   S (mp);
6412   W (ret);
6413   return ret;
6414 }
6415
6416
6417 /* Note: non-static, called once to set up the initial intfc table */
6418 int
6419 api_sw_interface_dump (vat_main_t * vam)
6420 {
6421   vl_api_sw_interface_dump_t *mp;
6422   vl_api_control_ping_t *mp_ping;
6423   hash_pair_t *p;
6424   name_sort_t *nses = 0, *ns;
6425   sw_interface_subif_t *sub = NULL;
6426   int ret;
6427
6428   /* Toss the old name table */
6429   /* *INDENT-OFF* */
6430   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6431   ({
6432     vec_add2 (nses, ns, 1);
6433     ns->name = (u8 *)(p->key);
6434     ns->value = (u32) p->value[0];
6435   }));
6436   /* *INDENT-ON* */
6437
6438   hash_free (vam->sw_if_index_by_interface_name);
6439
6440   vec_foreach (ns, nses) vec_free (ns->name);
6441
6442   vec_free (nses);
6443
6444   vec_foreach (sub, vam->sw_if_subif_table)
6445   {
6446     vec_free (sub->interface_name);
6447   }
6448   vec_free (vam->sw_if_subif_table);
6449
6450   /* recreate the interface name hash table */
6451   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6452
6453   /*
6454    * Ask for all interface names. Otherwise, the epic catalog of
6455    * name filters becomes ridiculously long, and vat ends up needing
6456    * to be taught about new interface types.
6457    */
6458   M (SW_INTERFACE_DUMP, mp);
6459   S (mp);
6460
6461   /* Use a control ping for synchronization */
6462   MPING (CONTROL_PING, mp_ping);
6463   S (mp_ping);
6464
6465   W (ret);
6466   return ret;
6467 }
6468
6469 static int
6470 api_sw_interface_set_flags (vat_main_t * vam)
6471 {
6472   unformat_input_t *i = vam->input;
6473   vl_api_sw_interface_set_flags_t *mp;
6474   u32 sw_if_index;
6475   u8 sw_if_index_set = 0;
6476   u8 admin_up = 0;
6477   int ret;
6478
6479   /* Parse args required to build the message */
6480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6481     {
6482       if (unformat (i, "admin-up"))
6483         admin_up = 1;
6484       else if (unformat (i, "admin-down"))
6485         admin_up = 0;
6486       else
6487         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6490         sw_if_index_set = 1;
6491       else
6492         break;
6493     }
6494
6495   if (sw_if_index_set == 0)
6496     {
6497       errmsg ("missing interface name or sw_if_index");
6498       return -99;
6499     }
6500
6501   /* Construct the API message */
6502   M (SW_INTERFACE_SET_FLAGS, mp);
6503   mp->sw_if_index = ntohl (sw_if_index);
6504   mp->admin_up_down = admin_up;
6505
6506   /* send it... */
6507   S (mp);
6508
6509   /* Wait for a reply, return the good/bad news... */
6510   W (ret);
6511   return ret;
6512 }
6513
6514 static int
6515 api_sw_interface_set_rx_mode (vat_main_t * vam)
6516 {
6517   unformat_input_t *i = vam->input;
6518   vl_api_sw_interface_set_rx_mode_t *mp;
6519   u32 sw_if_index;
6520   u8 sw_if_index_set = 0;
6521   int ret;
6522   u8 queue_id_valid = 0;
6523   u32 queue_id;
6524   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6525
6526   /* Parse args required to build the message */
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "queue %d", &queue_id))
6530         queue_id_valid = 1;
6531       else if (unformat (i, "polling"))
6532         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6533       else if (unformat (i, "interrupt"))
6534         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6535       else if (unformat (i, "adaptive"))
6536         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6537       else
6538         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6541         sw_if_index_set = 1;
6542       else
6543         break;
6544     }
6545
6546   if (sw_if_index_set == 0)
6547     {
6548       errmsg ("missing interface name or sw_if_index");
6549       return -99;
6550     }
6551   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6552     {
6553       errmsg ("missing rx-mode");
6554       return -99;
6555     }
6556
6557   /* Construct the API message */
6558   M (SW_INTERFACE_SET_RX_MODE, mp);
6559   mp->sw_if_index = ntohl (sw_if_index);
6560   mp->mode = mode;
6561   mp->queue_id_valid = queue_id_valid;
6562   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6563
6564   /* send it... */
6565   S (mp);
6566
6567   /* Wait for a reply, return the good/bad news... */
6568   W (ret);
6569   return ret;
6570 }
6571
6572 static int
6573 api_sw_interface_set_rx_placement (vat_main_t * vam)
6574 {
6575   unformat_input_t *i = vam->input;
6576   vl_api_sw_interface_set_rx_placement_t *mp;
6577   u32 sw_if_index;
6578   u8 sw_if_index_set = 0;
6579   int ret;
6580   u8 is_main = 0;
6581   u32 queue_id, thread_index;
6582
6583   /* Parse args required to build the message */
6584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6585     {
6586       if (unformat (i, "queue %d", &queue_id))
6587         ;
6588       else if (unformat (i, "main"))
6589         is_main = 1;
6590       else if (unformat (i, "worker %d", &thread_index))
6591         ;
6592       else
6593         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         sw_if_index_set = 1;
6597       else
6598         break;
6599     }
6600
6601   if (sw_if_index_set == 0)
6602     {
6603       errmsg ("missing interface name or sw_if_index");
6604       return -99;
6605     }
6606
6607   if (is_main)
6608     thread_index = 0;
6609   /* Construct the API message */
6610   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6611   mp->sw_if_index = ntohl (sw_if_index);
6612   mp->worker_id = ntohl (thread_index);
6613   mp->queue_id = ntohl (queue_id);
6614   mp->is_main = is_main;
6615
6616   /* send it... */
6617   S (mp);
6618   /* Wait for a reply, return the good/bad news... */
6619   W (ret);
6620   return ret;
6621 }
6622
6623 static int
6624 api_sw_interface_clear_stats (vat_main_t * vam)
6625 {
6626   unformat_input_t *i = vam->input;
6627   vl_api_sw_interface_clear_stats_t *mp;
6628   u32 sw_if_index;
6629   u8 sw_if_index_set = 0;
6630   int ret;
6631
6632   /* Parse args required to build the message */
6633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6634     {
6635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6636         sw_if_index_set = 1;
6637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6638         sw_if_index_set = 1;
6639       else
6640         break;
6641     }
6642
6643   /* Construct the API message */
6644   M (SW_INTERFACE_CLEAR_STATS, mp);
6645
6646   if (sw_if_index_set == 1)
6647     mp->sw_if_index = ntohl (sw_if_index);
6648   else
6649     mp->sw_if_index = ~0;
6650
6651   /* send it... */
6652   S (mp);
6653
6654   /* Wait for a reply, return the good/bad news... */
6655   W (ret);
6656   return ret;
6657 }
6658
6659 static int
6660 api_sw_interface_add_del_address (vat_main_t * vam)
6661 {
6662   unformat_input_t *i = vam->input;
6663   vl_api_sw_interface_add_del_address_t *mp;
6664   u32 sw_if_index;
6665   u8 sw_if_index_set = 0;
6666   u8 is_add = 1, del_all = 0;
6667   u32 address_length = 0;
6668   u8 v4_address_set = 0;
6669   u8 v6_address_set = 0;
6670   ip4_address_t v4address;
6671   ip6_address_t v6address;
6672   int ret;
6673
6674   /* Parse args required to build the message */
6675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6676     {
6677       if (unformat (i, "del-all"))
6678         del_all = 1;
6679       else if (unformat (i, "del"))
6680         is_add = 0;
6681       else
6682         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6683         sw_if_index_set = 1;
6684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6685         sw_if_index_set = 1;
6686       else if (unformat (i, "%U/%d",
6687                          unformat_ip4_address, &v4address, &address_length))
6688         v4_address_set = 1;
6689       else if (unformat (i, "%U/%d",
6690                          unformat_ip6_address, &v6address, &address_length))
6691         v6_address_set = 1;
6692       else
6693         break;
6694     }
6695
6696   if (sw_if_index_set == 0)
6697     {
6698       errmsg ("missing interface name or sw_if_index");
6699       return -99;
6700     }
6701   if (v4_address_set && v6_address_set)
6702     {
6703       errmsg ("both v4 and v6 addresses set");
6704       return -99;
6705     }
6706   if (!v4_address_set && !v6_address_set && !del_all)
6707     {
6708       errmsg ("no addresses set");
6709       return -99;
6710     }
6711
6712   /* Construct the API message */
6713   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6714
6715   mp->sw_if_index = ntohl (sw_if_index);
6716   mp->is_add = is_add;
6717   mp->del_all = del_all;
6718   if (v6_address_set)
6719     {
6720       mp->is_ipv6 = 1;
6721       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6722     }
6723   else
6724     {
6725       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6726     }
6727   mp->address_length = address_length;
6728
6729   /* send it... */
6730   S (mp);
6731
6732   /* Wait for a reply, return good/bad news  */
6733   W (ret);
6734   return ret;
6735 }
6736
6737 static int
6738 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6739 {
6740   unformat_input_t *i = vam->input;
6741   vl_api_sw_interface_set_mpls_enable_t *mp;
6742   u32 sw_if_index;
6743   u8 sw_if_index_set = 0;
6744   u8 enable = 1;
6745   int ret;
6746
6747   /* Parse args required to build the message */
6748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6749     {
6750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6751         sw_if_index_set = 1;
6752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6753         sw_if_index_set = 1;
6754       else if (unformat (i, "disable"))
6755         enable = 0;
6756       else if (unformat (i, "dis"))
6757         enable = 0;
6758       else
6759         break;
6760     }
6761
6762   if (sw_if_index_set == 0)
6763     {
6764       errmsg ("missing interface name or sw_if_index");
6765       return -99;
6766     }
6767
6768   /* Construct the API message */
6769   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6770
6771   mp->sw_if_index = ntohl (sw_if_index);
6772   mp->enable = enable;
6773
6774   /* send it... */
6775   S (mp);
6776
6777   /* Wait for a reply... */
6778   W (ret);
6779   return ret;
6780 }
6781
6782 static int
6783 api_sw_interface_set_table (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_sw_interface_set_table_t *mp;
6787   u32 sw_if_index, vrf_id = 0;
6788   u8 sw_if_index_set = 0;
6789   u8 is_ipv6 = 0;
6790   int ret;
6791
6792   /* Parse args required to build the message */
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "vrf %d", &vrf_id))
6800         ;
6801       else if (unformat (i, "ipv6"))
6802         is_ipv6 = 1;
6803       else
6804         break;
6805     }
6806
6807   if (sw_if_index_set == 0)
6808     {
6809       errmsg ("missing interface name or sw_if_index");
6810       return -99;
6811     }
6812
6813   /* Construct the API message */
6814   M (SW_INTERFACE_SET_TABLE, mp);
6815
6816   mp->sw_if_index = ntohl (sw_if_index);
6817   mp->is_ipv6 = is_ipv6;
6818   mp->vrf_id = ntohl (vrf_id);
6819
6820   /* send it... */
6821   S (mp);
6822
6823   /* Wait for a reply... */
6824   W (ret);
6825   return ret;
6826 }
6827
6828 static void vl_api_sw_interface_get_table_reply_t_handler
6829   (vl_api_sw_interface_get_table_reply_t * mp)
6830 {
6831   vat_main_t *vam = &vat_main;
6832
6833   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6834
6835   vam->retval = ntohl (mp->retval);
6836   vam->result_ready = 1;
6837
6838 }
6839
6840 static void vl_api_sw_interface_get_table_reply_t_handler_json
6841   (vl_api_sw_interface_get_table_reply_t * mp)
6842 {
6843   vat_main_t *vam = &vat_main;
6844   vat_json_node_t node;
6845
6846   vat_json_init_object (&node);
6847   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6848   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6849
6850   vat_json_print (vam->ofp, &node);
6851   vat_json_free (&node);
6852
6853   vam->retval = ntohl (mp->retval);
6854   vam->result_ready = 1;
6855 }
6856
6857 static int
6858 api_sw_interface_get_table (vat_main_t * vam)
6859 {
6860   unformat_input_t *i = vam->input;
6861   vl_api_sw_interface_get_table_t *mp;
6862   u32 sw_if_index;
6863   u8 sw_if_index_set = 0;
6864   u8 is_ipv6 = 0;
6865   int ret;
6866
6867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6868     {
6869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6870         sw_if_index_set = 1;
6871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6872         sw_if_index_set = 1;
6873       else if (unformat (i, "ipv6"))
6874         is_ipv6 = 1;
6875       else
6876         break;
6877     }
6878
6879   if (sw_if_index_set == 0)
6880     {
6881       errmsg ("missing interface name or sw_if_index");
6882       return -99;
6883     }
6884
6885   M (SW_INTERFACE_GET_TABLE, mp);
6886   mp->sw_if_index = htonl (sw_if_index);
6887   mp->is_ipv6 = is_ipv6;
6888
6889   S (mp);
6890   W (ret);
6891   return ret;
6892 }
6893
6894 static int
6895 api_sw_interface_set_vpath (vat_main_t * vam)
6896 {
6897   unformat_input_t *i = vam->input;
6898   vl_api_sw_interface_set_vpath_t *mp;
6899   u32 sw_if_index = 0;
6900   u8 sw_if_index_set = 0;
6901   u8 is_enable = 0;
6902   int ret;
6903
6904   /* Parse args required to build the message */
6905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6906     {
6907       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6908         sw_if_index_set = 1;
6909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6910         sw_if_index_set = 1;
6911       else if (unformat (i, "enable"))
6912         is_enable = 1;
6913       else if (unformat (i, "disable"))
6914         is_enable = 0;
6915       else
6916         break;
6917     }
6918
6919   if (sw_if_index_set == 0)
6920     {
6921       errmsg ("missing interface name or sw_if_index");
6922       return -99;
6923     }
6924
6925   /* Construct the API message */
6926   M (SW_INTERFACE_SET_VPATH, mp);
6927
6928   mp->sw_if_index = ntohl (sw_if_index);
6929   mp->enable = is_enable;
6930
6931   /* send it... */
6932   S (mp);
6933
6934   /* Wait for a reply... */
6935   W (ret);
6936   return ret;
6937 }
6938
6939 static int
6940 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6944   u32 sw_if_index = 0;
6945   u8 sw_if_index_set = 0;
6946   u8 is_enable = 1;
6947   u8 is_ipv6 = 0;
6948   int ret;
6949
6950   /* Parse args required to build the message */
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6954         sw_if_index_set = 1;
6955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6956         sw_if_index_set = 1;
6957       else if (unformat (i, "enable"))
6958         is_enable = 1;
6959       else if (unformat (i, "disable"))
6960         is_enable = 0;
6961       else if (unformat (i, "ip4"))
6962         is_ipv6 = 0;
6963       else if (unformat (i, "ip6"))
6964         is_ipv6 = 1;
6965       else
6966         break;
6967     }
6968
6969   if (sw_if_index_set == 0)
6970     {
6971       errmsg ("missing interface name or sw_if_index");
6972       return -99;
6973     }
6974
6975   /* Construct the API message */
6976   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6977
6978   mp->sw_if_index = ntohl (sw_if_index);
6979   mp->enable = is_enable;
6980   mp->is_ipv6 = is_ipv6;
6981
6982   /* send it... */
6983   S (mp);
6984
6985   /* Wait for a reply... */
6986   W (ret);
6987   return ret;
6988 }
6989
6990 static int
6991 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6992 {
6993   unformat_input_t *i = vam->input;
6994   vl_api_sw_interface_set_geneve_bypass_t *mp;
6995   u32 sw_if_index = 0;
6996   u8 sw_if_index_set = 0;
6997   u8 is_enable = 1;
6998   u8 is_ipv6 = 0;
6999   int ret;
7000
7001   /* Parse args required to build the message */
7002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003     {
7004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005         sw_if_index_set = 1;
7006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7007         sw_if_index_set = 1;
7008       else if (unformat (i, "enable"))
7009         is_enable = 1;
7010       else if (unformat (i, "disable"))
7011         is_enable = 0;
7012       else if (unformat (i, "ip4"))
7013         is_ipv6 = 0;
7014       else if (unformat (i, "ip6"))
7015         is_ipv6 = 1;
7016       else
7017         break;
7018     }
7019
7020   if (sw_if_index_set == 0)
7021     {
7022       errmsg ("missing interface name or sw_if_index");
7023       return -99;
7024     }
7025
7026   /* Construct the API message */
7027   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7028
7029   mp->sw_if_index = ntohl (sw_if_index);
7030   mp->enable = is_enable;
7031   mp->is_ipv6 = is_ipv6;
7032
7033   /* send it... */
7034   S (mp);
7035
7036   /* Wait for a reply... */
7037   W (ret);
7038   return ret;
7039 }
7040
7041 static int
7042 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7043 {
7044   unformat_input_t *i = vam->input;
7045   vl_api_sw_interface_set_l2_xconnect_t *mp;
7046   u32 rx_sw_if_index;
7047   u8 rx_sw_if_index_set = 0;
7048   u32 tx_sw_if_index;
7049   u8 tx_sw_if_index_set = 0;
7050   u8 enable = 1;
7051   int ret;
7052
7053   /* Parse args required to build the message */
7054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7055     {
7056       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7057         rx_sw_if_index_set = 1;
7058       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7059         tx_sw_if_index_set = 1;
7060       else if (unformat (i, "rx"))
7061         {
7062           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063             {
7064               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7065                             &rx_sw_if_index))
7066                 rx_sw_if_index_set = 1;
7067             }
7068           else
7069             break;
7070         }
7071       else if (unformat (i, "tx"))
7072         {
7073           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7074             {
7075               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7076                             &tx_sw_if_index))
7077                 tx_sw_if_index_set = 1;
7078             }
7079           else
7080             break;
7081         }
7082       else if (unformat (i, "enable"))
7083         enable = 1;
7084       else if (unformat (i, "disable"))
7085         enable = 0;
7086       else
7087         break;
7088     }
7089
7090   if (rx_sw_if_index_set == 0)
7091     {
7092       errmsg ("missing rx interface name or rx_sw_if_index");
7093       return -99;
7094     }
7095
7096   if (enable && (tx_sw_if_index_set == 0))
7097     {
7098       errmsg ("missing tx interface name or tx_sw_if_index");
7099       return -99;
7100     }
7101
7102   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7103
7104   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7105   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7106   mp->enable = enable;
7107
7108   S (mp);
7109   W (ret);
7110   return ret;
7111 }
7112
7113 static int
7114 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_sw_interface_set_l2_bridge_t *mp;
7118   u32 rx_sw_if_index;
7119   u8 rx_sw_if_index_set = 0;
7120   u32 bd_id;
7121   u8 bd_id_set = 0;
7122   u8 bvi = 0;
7123   u32 shg = 0;
7124   u8 enable = 1;
7125   int ret;
7126
7127   /* Parse args required to build the message */
7128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129     {
7130       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7131         rx_sw_if_index_set = 1;
7132       else if (unformat (i, "bd_id %d", &bd_id))
7133         bd_id_set = 1;
7134       else
7135         if (unformat
7136             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7137         rx_sw_if_index_set = 1;
7138       else if (unformat (i, "shg %d", &shg))
7139         ;
7140       else if (unformat (i, "bvi"))
7141         bvi = 1;
7142       else if (unformat (i, "enable"))
7143         enable = 1;
7144       else if (unformat (i, "disable"))
7145         enable = 0;
7146       else
7147         break;
7148     }
7149
7150   if (rx_sw_if_index_set == 0)
7151     {
7152       errmsg ("missing rx interface name or sw_if_index");
7153       return -99;
7154     }
7155
7156   if (enable && (bd_id_set == 0))
7157     {
7158       errmsg ("missing bridge domain");
7159       return -99;
7160     }
7161
7162   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7163
7164   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7165   mp->bd_id = ntohl (bd_id);
7166   mp->shg = (u8) shg;
7167   mp->bvi = bvi;
7168   mp->enable = enable;
7169
7170   S (mp);
7171   W (ret);
7172   return ret;
7173 }
7174
7175 static int
7176 api_bridge_domain_dump (vat_main_t * vam)
7177 {
7178   unformat_input_t *i = vam->input;
7179   vl_api_bridge_domain_dump_t *mp;
7180   vl_api_control_ping_t *mp_ping;
7181   u32 bd_id = ~0;
7182   int ret;
7183
7184   /* Parse args required to build the message */
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "bd_id %d", &bd_id))
7188         ;
7189       else
7190         break;
7191     }
7192
7193   M (BRIDGE_DOMAIN_DUMP, mp);
7194   mp->bd_id = ntohl (bd_id);
7195   S (mp);
7196
7197   /* Use a control ping for synchronization */
7198   MPING (CONTROL_PING, mp_ping);
7199   S (mp_ping);
7200
7201   W (ret);
7202   return ret;
7203 }
7204
7205 static int
7206 api_bridge_domain_add_del (vat_main_t * vam)
7207 {
7208   unformat_input_t *i = vam->input;
7209   vl_api_bridge_domain_add_del_t *mp;
7210   u32 bd_id = ~0;
7211   u8 is_add = 1;
7212   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7213   u8 *bd_tag = NULL;
7214   u32 mac_age = 0;
7215   int ret;
7216
7217   /* Parse args required to build the message */
7218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7219     {
7220       if (unformat (i, "bd_id %d", &bd_id))
7221         ;
7222       else if (unformat (i, "flood %d", &flood))
7223         ;
7224       else if (unformat (i, "uu-flood %d", &uu_flood))
7225         ;
7226       else if (unformat (i, "forward %d", &forward))
7227         ;
7228       else if (unformat (i, "learn %d", &learn))
7229         ;
7230       else if (unformat (i, "arp-term %d", &arp_term))
7231         ;
7232       else if (unformat (i, "mac-age %d", &mac_age))
7233         ;
7234       else if (unformat (i, "bd-tag %s", &bd_tag))
7235         ;
7236       else if (unformat (i, "del"))
7237         {
7238           is_add = 0;
7239           flood = uu_flood = forward = learn = 0;
7240         }
7241       else
7242         break;
7243     }
7244
7245   if (bd_id == ~0)
7246     {
7247       errmsg ("missing bridge domain");
7248       ret = -99;
7249       goto done;
7250     }
7251
7252   if (mac_age > 255)
7253     {
7254       errmsg ("mac age must be less than 256 ");
7255       ret = -99;
7256       goto done;
7257     }
7258
7259   if ((bd_tag) && (vec_len (bd_tag) > 63))
7260     {
7261       errmsg ("bd-tag cannot be longer than 63");
7262       ret = -99;
7263       goto done;
7264     }
7265
7266   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7267
7268   mp->bd_id = ntohl (bd_id);
7269   mp->flood = flood;
7270   mp->uu_flood = uu_flood;
7271   mp->forward = forward;
7272   mp->learn = learn;
7273   mp->arp_term = arp_term;
7274   mp->is_add = is_add;
7275   mp->mac_age = (u8) mac_age;
7276   if (bd_tag)
7277     {
7278       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7279       mp->bd_tag[vec_len (bd_tag)] = 0;
7280     }
7281   S (mp);
7282   W (ret);
7283
7284 done:
7285   vec_free (bd_tag);
7286   return ret;
7287 }
7288
7289 static int
7290 api_l2fib_flush_bd (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_l2fib_flush_bd_t *mp;
7294   u32 bd_id = ~0;
7295   int ret;
7296
7297   /* Parse args required to build the message */
7298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7299     {
7300       if (unformat (i, "bd_id %d", &bd_id));
7301       else
7302         break;
7303     }
7304
7305   if (bd_id == ~0)
7306     {
7307       errmsg ("missing bridge domain");
7308       return -99;
7309     }
7310
7311   M (L2FIB_FLUSH_BD, mp);
7312
7313   mp->bd_id = htonl (bd_id);
7314
7315   S (mp);
7316   W (ret);
7317   return ret;
7318 }
7319
7320 static int
7321 api_l2fib_flush_int (vat_main_t * vam)
7322 {
7323   unformat_input_t *i = vam->input;
7324   vl_api_l2fib_flush_int_t *mp;
7325   u32 sw_if_index = ~0;
7326   int ret;
7327
7328   /* Parse args required to build the message */
7329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7330     {
7331       if (unformat (i, "sw_if_index %d", &sw_if_index));
7332       else
7333         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7334       else
7335         break;
7336     }
7337
7338   if (sw_if_index == ~0)
7339     {
7340       errmsg ("missing interface name or sw_if_index");
7341       return -99;
7342     }
7343
7344   M (L2FIB_FLUSH_INT, mp);
7345
7346   mp->sw_if_index = ntohl (sw_if_index);
7347
7348   S (mp);
7349   W (ret);
7350   return ret;
7351 }
7352
7353 static int
7354 api_l2fib_add_del (vat_main_t * vam)
7355 {
7356   unformat_input_t *i = vam->input;
7357   vl_api_l2fib_add_del_t *mp;
7358   f64 timeout;
7359   u8 mac[6] = { 0 };
7360   u8 mac_set = 0;
7361   u32 bd_id;
7362   u8 bd_id_set = 0;
7363   u32 sw_if_index = 0;
7364   u8 sw_if_index_set = 0;
7365   u8 is_add = 1;
7366   u8 static_mac = 0;
7367   u8 filter_mac = 0;
7368   u8 bvi_mac = 0;
7369   int count = 1;
7370   f64 before = 0;
7371   int j;
7372
7373   /* Parse args required to build the message */
7374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7375     {
7376       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7377         mac_set = 1;
7378       else if (unformat (i, "bd_id %d", &bd_id))
7379         bd_id_set = 1;
7380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7381         sw_if_index_set = 1;
7382       else if (unformat (i, "sw_if"))
7383         {
7384           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7385             {
7386               if (unformat
7387                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7388                 sw_if_index_set = 1;
7389             }
7390           else
7391             break;
7392         }
7393       else if (unformat (i, "static"))
7394         static_mac = 1;
7395       else if (unformat (i, "filter"))
7396         {
7397           filter_mac = 1;
7398           static_mac = 1;
7399         }
7400       else if (unformat (i, "bvi"))
7401         {
7402           bvi_mac = 1;
7403           static_mac = 1;
7404         }
7405       else if (unformat (i, "del"))
7406         is_add = 0;
7407       else if (unformat (i, "count %d", &count))
7408         ;
7409       else
7410         break;
7411     }
7412
7413   if (mac_set == 0)
7414     {
7415       errmsg ("missing mac address");
7416       return -99;
7417     }
7418
7419   if (bd_id_set == 0)
7420     {
7421       errmsg ("missing bridge domain");
7422       return -99;
7423     }
7424
7425   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7426     {
7427       errmsg ("missing interface name or sw_if_index");
7428       return -99;
7429     }
7430
7431   if (count > 1)
7432     {
7433       /* Turn on async mode */
7434       vam->async_mode = 1;
7435       vam->async_errors = 0;
7436       before = vat_time_now (vam);
7437     }
7438
7439   for (j = 0; j < count; j++)
7440     {
7441       M (L2FIB_ADD_DEL, mp);
7442
7443       clib_memcpy (mp->mac, mac, 6);
7444       mp->bd_id = ntohl (bd_id);
7445       mp->is_add = is_add;
7446       mp->sw_if_index = ntohl (sw_if_index);
7447
7448       if (is_add)
7449         {
7450           mp->static_mac = static_mac;
7451           mp->filter_mac = filter_mac;
7452           mp->bvi_mac = bvi_mac;
7453         }
7454       increment_mac_address (mac);
7455       /* send it... */
7456       S (mp);
7457     }
7458
7459   if (count > 1)
7460     {
7461       vl_api_control_ping_t *mp_ping;
7462       f64 after;
7463
7464       /* Shut off async mode */
7465       vam->async_mode = 0;
7466
7467       MPING (CONTROL_PING, mp_ping);
7468       S (mp_ping);
7469
7470       timeout = vat_time_now (vam) + 1.0;
7471       while (vat_time_now (vam) < timeout)
7472         if (vam->result_ready == 1)
7473           goto out;
7474       vam->retval = -99;
7475
7476     out:
7477       if (vam->retval == -99)
7478         errmsg ("timeout");
7479
7480       if (vam->async_errors > 0)
7481         {
7482           errmsg ("%d asynchronous errors", vam->async_errors);
7483           vam->retval = -98;
7484         }
7485       vam->async_errors = 0;
7486       after = vat_time_now (vam);
7487
7488       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7489              count, after - before, count / (after - before));
7490     }
7491   else
7492     {
7493       int ret;
7494
7495       /* Wait for a reply... */
7496       W (ret);
7497       return ret;
7498     }
7499   /* Return the good/bad news */
7500   return (vam->retval);
7501 }
7502
7503 static int
7504 api_bridge_domain_set_mac_age (vat_main_t * vam)
7505 {
7506   unformat_input_t *i = vam->input;
7507   vl_api_bridge_domain_set_mac_age_t *mp;
7508   u32 bd_id = ~0;
7509   u32 mac_age = 0;
7510   int ret;
7511
7512   /* Parse args required to build the message */
7513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7514     {
7515       if (unformat (i, "bd_id %d", &bd_id));
7516       else if (unformat (i, "mac-age %d", &mac_age));
7517       else
7518         break;
7519     }
7520
7521   if (bd_id == ~0)
7522     {
7523       errmsg ("missing bridge domain");
7524       return -99;
7525     }
7526
7527   if (mac_age > 255)
7528     {
7529       errmsg ("mac age must be less than 256 ");
7530       return -99;
7531     }
7532
7533   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7534
7535   mp->bd_id = htonl (bd_id);
7536   mp->mac_age = (u8) mac_age;
7537
7538   S (mp);
7539   W (ret);
7540   return ret;
7541 }
7542
7543 static int
7544 api_l2_flags (vat_main_t * vam)
7545 {
7546   unformat_input_t *i = vam->input;
7547   vl_api_l2_flags_t *mp;
7548   u32 sw_if_index;
7549   u32 flags = 0;
7550   u8 sw_if_index_set = 0;
7551   u8 is_set = 0;
7552   int ret;
7553
7554   /* Parse args required to build the message */
7555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556     {
7557       if (unformat (i, "sw_if_index %d", &sw_if_index))
7558         sw_if_index_set = 1;
7559       else if (unformat (i, "sw_if"))
7560         {
7561           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7562             {
7563               if (unformat
7564                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7565                 sw_if_index_set = 1;
7566             }
7567           else
7568             break;
7569         }
7570       else if (unformat (i, "learn"))
7571         flags |= L2_LEARN;
7572       else if (unformat (i, "forward"))
7573         flags |= L2_FWD;
7574       else if (unformat (i, "flood"))
7575         flags |= L2_FLOOD;
7576       else if (unformat (i, "uu-flood"))
7577         flags |= L2_UU_FLOOD;
7578       else if (unformat (i, "arp-term"))
7579         flags |= L2_ARP_TERM;
7580       else if (unformat (i, "off"))
7581         is_set = 0;
7582       else if (unformat (i, "disable"))
7583         is_set = 0;
7584       else
7585         break;
7586     }
7587
7588   if (sw_if_index_set == 0)
7589     {
7590       errmsg ("missing interface name or sw_if_index");
7591       return -99;
7592     }
7593
7594   M (L2_FLAGS, mp);
7595
7596   mp->sw_if_index = ntohl (sw_if_index);
7597   mp->feature_bitmap = ntohl (flags);
7598   mp->is_set = is_set;
7599
7600   S (mp);
7601   W (ret);
7602   return ret;
7603 }
7604
7605 static int
7606 api_bridge_flags (vat_main_t * vam)
7607 {
7608   unformat_input_t *i = vam->input;
7609   vl_api_bridge_flags_t *mp;
7610   u32 bd_id;
7611   u8 bd_id_set = 0;
7612   u8 is_set = 1;
7613   u32 flags = 0;
7614   int ret;
7615
7616   /* Parse args required to build the message */
7617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7618     {
7619       if (unformat (i, "bd_id %d", &bd_id))
7620         bd_id_set = 1;
7621       else if (unformat (i, "learn"))
7622         flags |= L2_LEARN;
7623       else if (unformat (i, "forward"))
7624         flags |= L2_FWD;
7625       else if (unformat (i, "flood"))
7626         flags |= L2_FLOOD;
7627       else if (unformat (i, "uu-flood"))
7628         flags |= L2_UU_FLOOD;
7629       else if (unformat (i, "arp-term"))
7630         flags |= L2_ARP_TERM;
7631       else if (unformat (i, "off"))
7632         is_set = 0;
7633       else if (unformat (i, "disable"))
7634         is_set = 0;
7635       else
7636         break;
7637     }
7638
7639   if (bd_id_set == 0)
7640     {
7641       errmsg ("missing bridge domain");
7642       return -99;
7643     }
7644
7645   M (BRIDGE_FLAGS, mp);
7646
7647   mp->bd_id = ntohl (bd_id);
7648   mp->feature_bitmap = ntohl (flags);
7649   mp->is_set = is_set;
7650
7651   S (mp);
7652   W (ret);
7653   return ret;
7654 }
7655
7656 static int
7657 api_bd_ip_mac_add_del (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_bd_ip_mac_add_del_t *mp;
7661   u32 bd_id;
7662   u8 is_ipv6 = 0;
7663   u8 is_add = 1;
7664   u8 bd_id_set = 0;
7665   u8 ip_set = 0;
7666   u8 mac_set = 0;
7667   ip4_address_t v4addr;
7668   ip6_address_t v6addr;
7669   u8 macaddr[6];
7670   int ret;
7671
7672
7673   /* Parse args required to build the message */
7674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7675     {
7676       if (unformat (i, "bd_id %d", &bd_id))
7677         {
7678           bd_id_set++;
7679         }
7680       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7681         {
7682           ip_set++;
7683         }
7684       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7685         {
7686           ip_set++;
7687           is_ipv6++;
7688         }
7689       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7690         {
7691           mac_set++;
7692         }
7693       else if (unformat (i, "del"))
7694         is_add = 0;
7695       else
7696         break;
7697     }
7698
7699   if (bd_id_set == 0)
7700     {
7701       errmsg ("missing bridge domain");
7702       return -99;
7703     }
7704   else if (ip_set == 0)
7705     {
7706       errmsg ("missing IP address");
7707       return -99;
7708     }
7709   else if (mac_set == 0)
7710     {
7711       errmsg ("missing MAC address");
7712       return -99;
7713     }
7714
7715   M (BD_IP_MAC_ADD_DEL, mp);
7716
7717   mp->bd_id = ntohl (bd_id);
7718   mp->is_ipv6 = is_ipv6;
7719   mp->is_add = is_add;
7720   if (is_ipv6)
7721     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7722   else
7723     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7724   clib_memcpy (mp->mac_address, macaddr, 6);
7725   S (mp);
7726   W (ret);
7727   return ret;
7728 }
7729
7730 static void vl_api_bd_ip_mac_details_t_handler
7731   (vl_api_bd_ip_mac_details_t * mp)
7732 {
7733   vat_main_t *vam = &vat_main;
7734   u8 *ip = 0;
7735
7736   if (!mp->is_ipv6)
7737     ip =
7738       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7739   else
7740     ip =
7741       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7742
7743   print (vam->ofp,
7744          "\n%-5d %-7s %-20U %-30s",
7745          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7746          format_ethernet_address, mp->mac_address, ip);
7747
7748   vec_free (ip);
7749 }
7750
7751 static void vl_api_bd_ip_mac_details_t_handler_json
7752   (vl_api_bd_ip_mac_details_t * mp)
7753 {
7754   vat_main_t *vam = &vat_main;
7755   vat_json_node_t *node = NULL;
7756
7757   if (VAT_JSON_ARRAY != vam->json_tree.type)
7758     {
7759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7760       vat_json_init_array (&vam->json_tree);
7761     }
7762   node = vat_json_array_add (&vam->json_tree);
7763
7764   vat_json_init_object (node);
7765   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7766   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7767   vat_json_object_add_string_copy (node, "mac_address",
7768                                    format (0, "%U", format_ethernet_address,
7769                                            &mp->mac_address));
7770   u8 *ip = 0;
7771
7772   if (!mp->is_ipv6)
7773     ip =
7774       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7775   else
7776     ip =
7777       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7778   vat_json_object_add_string_copy (node, "ip_address", ip);
7779   vec_free (ip);
7780 }
7781
7782 static int
7783 api_bd_ip_mac_dump (vat_main_t * vam)
7784 {
7785   unformat_input_t *i = vam->input;
7786   vl_api_bd_ip_mac_dump_t *mp;
7787   vl_api_control_ping_t *mp_ping;
7788   int ret;
7789   u32 bd_id;
7790   u8 bd_id_set = 0;
7791
7792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7793     {
7794       if (unformat (i, "bd_id %d", &bd_id))
7795         {
7796           bd_id_set++;
7797         }
7798       else
7799         break;
7800     }
7801
7802   print (vam->ofp,
7803          "\n%-5s %-7s %-20s %-30s",
7804          "bd_id", "is_ipv6", "mac_address", "ip_address");
7805
7806   /* Dump Bridge Domain Ip to Mac entries */
7807   M (BD_IP_MAC_DUMP, mp);
7808
7809   if (bd_id_set)
7810     mp->bd_id = htonl (bd_id);
7811   else
7812     mp->bd_id = ~0;
7813
7814   S (mp);
7815
7816   /* Use a control ping for synchronization */
7817   MPING (CONTROL_PING, mp_ping);
7818   S (mp_ping);
7819
7820   W (ret);
7821   return ret;
7822 }
7823
7824 static int
7825 api_tap_connect (vat_main_t * vam)
7826 {
7827   unformat_input_t *i = vam->input;
7828   vl_api_tap_connect_t *mp;
7829   u8 mac_address[6];
7830   u8 random_mac = 1;
7831   u8 name_set = 0;
7832   u8 *tap_name;
7833   u8 *tag = 0;
7834   ip4_address_t ip4_address;
7835   u32 ip4_mask_width;
7836   int ip4_address_set = 0;
7837   ip6_address_t ip6_address;
7838   u32 ip6_mask_width;
7839   int ip6_address_set = 0;
7840   int ret;
7841
7842   memset (mac_address, 0, sizeof (mac_address));
7843
7844   /* Parse args required to build the message */
7845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7846     {
7847       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7848         {
7849           random_mac = 0;
7850         }
7851       else if (unformat (i, "random-mac"))
7852         random_mac = 1;
7853       else if (unformat (i, "tapname %s", &tap_name))
7854         name_set = 1;
7855       else if (unformat (i, "tag %s", &tag))
7856         ;
7857       else if (unformat (i, "address %U/%d",
7858                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7859         ip4_address_set = 1;
7860       else if (unformat (i, "address %U/%d",
7861                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7862         ip6_address_set = 1;
7863       else
7864         break;
7865     }
7866
7867   if (name_set == 0)
7868     {
7869       errmsg ("missing tap name");
7870       return -99;
7871     }
7872   if (vec_len (tap_name) > 63)
7873     {
7874       errmsg ("tap name too long");
7875       return -99;
7876     }
7877   vec_add1 (tap_name, 0);
7878
7879   if (vec_len (tag) > 63)
7880     {
7881       errmsg ("tag too long");
7882       return -99;
7883     }
7884
7885   /* Construct the API message */
7886   M (TAP_CONNECT, mp);
7887
7888   mp->use_random_mac = random_mac;
7889   clib_memcpy (mp->mac_address, mac_address, 6);
7890   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7891   if (tag)
7892     clib_memcpy (mp->tag, tag, vec_len (tag));
7893
7894   if (ip4_address_set)
7895     {
7896       mp->ip4_address_set = 1;
7897       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7898       mp->ip4_mask_width = ip4_mask_width;
7899     }
7900   if (ip6_address_set)
7901     {
7902       mp->ip6_address_set = 1;
7903       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7904       mp->ip6_mask_width = ip6_mask_width;
7905     }
7906
7907   vec_free (tap_name);
7908   vec_free (tag);
7909
7910   /* send it... */
7911   S (mp);
7912
7913   /* Wait for a reply... */
7914   W (ret);
7915   return ret;
7916 }
7917
7918 static int
7919 api_tap_modify (vat_main_t * vam)
7920 {
7921   unformat_input_t *i = vam->input;
7922   vl_api_tap_modify_t *mp;
7923   u8 mac_address[6];
7924   u8 random_mac = 1;
7925   u8 name_set = 0;
7926   u8 *tap_name;
7927   u32 sw_if_index = ~0;
7928   u8 sw_if_index_set = 0;
7929   int ret;
7930
7931   memset (mac_address, 0, sizeof (mac_address));
7932
7933   /* Parse args required to build the message */
7934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7935     {
7936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7937         sw_if_index_set = 1;
7938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7939         sw_if_index_set = 1;
7940       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7941         {
7942           random_mac = 0;
7943         }
7944       else if (unformat (i, "random-mac"))
7945         random_mac = 1;
7946       else if (unformat (i, "tapname %s", &tap_name))
7947         name_set = 1;
7948       else
7949         break;
7950     }
7951
7952   if (sw_if_index_set == 0)
7953     {
7954       errmsg ("missing vpp interface name");
7955       return -99;
7956     }
7957   if (name_set == 0)
7958     {
7959       errmsg ("missing tap name");
7960       return -99;
7961     }
7962   if (vec_len (tap_name) > 63)
7963     {
7964       errmsg ("tap name too long");
7965     }
7966   vec_add1 (tap_name, 0);
7967
7968   /* Construct the API message */
7969   M (TAP_MODIFY, mp);
7970
7971   mp->use_random_mac = random_mac;
7972   mp->sw_if_index = ntohl (sw_if_index);
7973   clib_memcpy (mp->mac_address, mac_address, 6);
7974   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7975   vec_free (tap_name);
7976
7977   /* send it... */
7978   S (mp);
7979
7980   /* Wait for a reply... */
7981   W (ret);
7982   return ret;
7983 }
7984
7985 static int
7986 api_tap_delete (vat_main_t * vam)
7987 {
7988   unformat_input_t *i = vam->input;
7989   vl_api_tap_delete_t *mp;
7990   u32 sw_if_index = ~0;
7991   u8 sw_if_index_set = 0;
7992   int ret;
7993
7994   /* Parse args required to build the message */
7995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7996     {
7997       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7998         sw_if_index_set = 1;
7999       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8000         sw_if_index_set = 1;
8001       else
8002         break;
8003     }
8004
8005   if (sw_if_index_set == 0)
8006     {
8007       errmsg ("missing vpp interface name");
8008       return -99;
8009     }
8010
8011   /* Construct the API message */
8012   M (TAP_DELETE, mp);
8013
8014   mp->sw_if_index = ntohl (sw_if_index);
8015
8016   /* send it... */
8017   S (mp);
8018
8019   /* Wait for a reply... */
8020   W (ret);
8021   return ret;
8022 }
8023
8024 static int
8025 api_tap_create_v2 (vat_main_t * vam)
8026 {
8027   unformat_input_t *i = vam->input;
8028   vl_api_tap_create_v2_t *mp;
8029   u8 mac_address[6];
8030   u8 random_mac = 1;
8031   u32 id = ~0;
8032   u8 *host_if_name = 0;
8033   u8 *host_ns = 0;
8034   u8 host_mac_addr[6];
8035   u8 host_mac_addr_set = 0;
8036   u8 *host_bridge = 0;
8037   ip4_address_t host_ip4_addr;
8038   ip4_address_t host_ip4_gw;
8039   u8 host_ip4_gw_set = 0;
8040   u32 host_ip4_prefix_len = 0;
8041   ip6_address_t host_ip6_addr;
8042   ip6_address_t host_ip6_gw;
8043   u8 host_ip6_gw_set = 0;
8044   u32 host_ip6_prefix_len = 0;
8045   int ret;
8046   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8047
8048   memset (mac_address, 0, sizeof (mac_address));
8049
8050   /* Parse args required to build the message */
8051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8052     {
8053       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8054         {
8055           random_mac = 0;
8056         }
8057       else if (unformat (i, "id %u", &id))
8058         ;
8059       else if (unformat (i, "host-if-name %s", &host_if_name))
8060         ;
8061       else if (unformat (i, "host-ns %s", &host_ns))
8062         ;
8063       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8064                          host_mac_addr))
8065         host_mac_addr_set = 1;
8066       else if (unformat (i, "host-bridge %s", &host_bridge))
8067         ;
8068       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8069                          &host_ip4_addr, &host_ip4_prefix_len))
8070         ;
8071       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8072                          &host_ip6_addr, &host_ip6_prefix_len))
8073         ;
8074       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8075                          &host_ip4_gw))
8076         host_ip4_gw_set = 1;
8077       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8078                          &host_ip6_gw))
8079         host_ip6_gw_set = 1;
8080       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8081         ;
8082       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8083         ;
8084       else
8085         break;
8086     }
8087
8088   if (vec_len (host_if_name) > 63)
8089     {
8090       errmsg ("tap name too long. ");
8091       return -99;
8092     }
8093   if (vec_len (host_ns) > 63)
8094     {
8095       errmsg ("host name space too long. ");
8096       return -99;
8097     }
8098   if (vec_len (host_bridge) > 63)
8099     {
8100       errmsg ("host bridge name too long. ");
8101       return -99;
8102     }
8103   if (host_ip4_prefix_len > 32)
8104     {
8105       errmsg ("host ip4 prefix length not valid. ");
8106       return -99;
8107     }
8108   if (host_ip6_prefix_len > 128)
8109     {
8110       errmsg ("host ip6 prefix length not valid. ");
8111       return -99;
8112     }
8113   if (!is_pow2 (rx_ring_sz))
8114     {
8115       errmsg ("rx ring size must be power of 2. ");
8116       return -99;
8117     }
8118   if (rx_ring_sz > 32768)
8119     {
8120       errmsg ("rx ring size must be 32768 or lower. ");
8121       return -99;
8122     }
8123   if (!is_pow2 (tx_ring_sz))
8124     {
8125       errmsg ("tx ring size must be power of 2. ");
8126       return -99;
8127     }
8128   if (tx_ring_sz > 32768)
8129     {
8130       errmsg ("tx ring size must be 32768 or lower. ");
8131       return -99;
8132     }
8133
8134   /* Construct the API message */
8135   M (TAP_CREATE_V2, mp);
8136
8137   mp->use_random_mac = random_mac;
8138
8139   mp->id = ntohl (id);
8140   mp->host_namespace_set = host_ns != 0;
8141   mp->host_bridge_set = host_bridge != 0;
8142   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8143   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8144   mp->rx_ring_sz = ntohs (rx_ring_sz);
8145   mp->tx_ring_sz = ntohs (tx_ring_sz);
8146
8147   if (random_mac == 0)
8148     clib_memcpy (mp->mac_address, mac_address, 6);
8149   if (host_mac_addr_set)
8150     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8151   if (host_if_name)
8152     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8153   if (host_ns)
8154     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8155   if (host_bridge)
8156     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8157   if (host_ip4_prefix_len)
8158     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8159   if (host_ip4_prefix_len)
8160     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8161   if (host_ip4_gw_set)
8162     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8163   if (host_ip6_gw_set)
8164     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8165
8166   vec_free (host_ns);
8167   vec_free (host_if_name);
8168   vec_free (host_bridge);
8169
8170   /* send it... */
8171   S (mp);
8172
8173   /* Wait for a reply... */
8174   W (ret);
8175   return ret;
8176 }
8177
8178 static int
8179 api_tap_delete_v2 (vat_main_t * vam)
8180 {
8181   unformat_input_t *i = vam->input;
8182   vl_api_tap_delete_v2_t *mp;
8183   u32 sw_if_index = ~0;
8184   u8 sw_if_index_set = 0;
8185   int ret;
8186
8187   /* Parse args required to build the message */
8188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8189     {
8190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8191         sw_if_index_set = 1;
8192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8193         sw_if_index_set = 1;
8194       else
8195         break;
8196     }
8197
8198   if (sw_if_index_set == 0)
8199     {
8200       errmsg ("missing vpp interface name. ");
8201       return -99;
8202     }
8203
8204   /* Construct the API message */
8205   M (TAP_DELETE_V2, mp);
8206
8207   mp->sw_if_index = ntohl (sw_if_index);
8208
8209   /* send it... */
8210   S (mp);
8211
8212   /* Wait for a reply... */
8213   W (ret);
8214   return ret;
8215 }
8216
8217 static int
8218 api_bond_create (vat_main_t * vam)
8219 {
8220   unformat_input_t *i = vam->input;
8221   vl_api_bond_create_t *mp;
8222   u8 mac_address[6];
8223   u8 custom_mac = 0;
8224   int ret;
8225   u8 mode;
8226   u8 lb;
8227   u8 mode_is_set = 0;
8228
8229   memset (mac_address, 0, sizeof (mac_address));
8230   lb = BOND_LB_L2;
8231
8232   /* Parse args required to build the message */
8233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8234     {
8235       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8236         mode_is_set = 1;
8237       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8238                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8239         ;
8240       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8241                          mac_address))
8242         custom_mac = 1;
8243       else
8244         break;
8245     }
8246
8247   if (mode_is_set == 0)
8248     {
8249       errmsg ("Missing bond mode. ");
8250       return -99;
8251     }
8252
8253   /* Construct the API message */
8254   M (BOND_CREATE, mp);
8255
8256   mp->use_custom_mac = custom_mac;
8257
8258   mp->mode = mode;
8259   mp->lb = lb;
8260
8261   if (custom_mac)
8262     clib_memcpy (mp->mac_address, mac_address, 6);
8263
8264   /* send it... */
8265   S (mp);
8266
8267   /* Wait for a reply... */
8268   W (ret);
8269   return ret;
8270 }
8271
8272 static int
8273 api_bond_delete (vat_main_t * vam)
8274 {
8275   unformat_input_t *i = vam->input;
8276   vl_api_bond_delete_t *mp;
8277   u32 sw_if_index = ~0;
8278   u8 sw_if_index_set = 0;
8279   int ret;
8280
8281   /* Parse args required to build the message */
8282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8283     {
8284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8285         sw_if_index_set = 1;
8286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8287         sw_if_index_set = 1;
8288       else
8289         break;
8290     }
8291
8292   if (sw_if_index_set == 0)
8293     {
8294       errmsg ("missing vpp interface name. ");
8295       return -99;
8296     }
8297
8298   /* Construct the API message */
8299   M (BOND_DELETE, mp);
8300
8301   mp->sw_if_index = ntohl (sw_if_index);
8302
8303   /* send it... */
8304   S (mp);
8305
8306   /* Wait for a reply... */
8307   W (ret);
8308   return ret;
8309 }
8310
8311 static int
8312 api_bond_enslave (vat_main_t * vam)
8313 {
8314   unformat_input_t *i = vam->input;
8315   vl_api_bond_enslave_t *mp;
8316   u32 bond_sw_if_index;
8317   int ret;
8318   u8 is_passive;
8319   u8 is_long_timeout;
8320   u32 bond_sw_if_index_is_set = 0;
8321   u32 sw_if_index;
8322   u8 sw_if_index_is_set = 0;
8323
8324   /* Parse args required to build the message */
8325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8326     {
8327       if (unformat (i, "sw_if_index %d", &sw_if_index))
8328         sw_if_index_is_set = 1;
8329       else if (unformat (i, "bond %u", &bond_sw_if_index))
8330         bond_sw_if_index_is_set = 1;
8331       else if (unformat (i, "passive %d", &is_passive))
8332         ;
8333       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8334         ;
8335       else
8336         break;
8337     }
8338
8339   if (bond_sw_if_index_is_set == 0)
8340     {
8341       errmsg ("Missing bond sw_if_index. ");
8342       return -99;
8343     }
8344   if (sw_if_index_is_set == 0)
8345     {
8346       errmsg ("Missing slave sw_if_index. ");
8347       return -99;
8348     }
8349
8350   /* Construct the API message */
8351   M (BOND_ENSLAVE, mp);
8352
8353   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8354   mp->sw_if_index = ntohl (sw_if_index);
8355   mp->is_long_timeout = is_long_timeout;
8356   mp->is_passive = is_passive;
8357
8358   /* send it... */
8359   S (mp);
8360
8361   /* Wait for a reply... */
8362   W (ret);
8363   return ret;
8364 }
8365
8366 static int
8367 api_bond_detach_slave (vat_main_t * vam)
8368 {
8369   unformat_input_t *i = vam->input;
8370   vl_api_bond_detach_slave_t *mp;
8371   u32 sw_if_index = ~0;
8372   u8 sw_if_index_set = 0;
8373   int ret;
8374
8375   /* Parse args required to build the message */
8376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8377     {
8378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8379         sw_if_index_set = 1;
8380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8381         sw_if_index_set = 1;
8382       else
8383         break;
8384     }
8385
8386   if (sw_if_index_set == 0)
8387     {
8388       errmsg ("missing vpp interface name. ");
8389       return -99;
8390     }
8391
8392   /* Construct the API message */
8393   M (BOND_DETACH_SLAVE, mp);
8394
8395   mp->sw_if_index = ntohl (sw_if_index);
8396
8397   /* send it... */
8398   S (mp);
8399
8400   /* Wait for a reply... */
8401   W (ret);
8402   return ret;
8403 }
8404
8405 static int
8406 api_ip_table_add_del (vat_main_t * vam)
8407 {
8408   unformat_input_t *i = vam->input;
8409   vl_api_ip_table_add_del_t *mp;
8410   u32 table_id = ~0;
8411   u8 is_ipv6 = 0;
8412   u8 is_add = 1;
8413   int ret = 0;
8414
8415   /* Parse args required to build the message */
8416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8417     {
8418       if (unformat (i, "ipv6"))
8419         is_ipv6 = 1;
8420       else if (unformat (i, "del"))
8421         is_add = 0;
8422       else if (unformat (i, "add"))
8423         is_add = 1;
8424       else if (unformat (i, "table %d", &table_id))
8425         ;
8426       else
8427         {
8428           clib_warning ("parse error '%U'", format_unformat_error, i);
8429           return -99;
8430         }
8431     }
8432
8433   if (~0 == table_id)
8434     {
8435       errmsg ("missing table-ID");
8436       return -99;
8437     }
8438
8439   /* Construct the API message */
8440   M (IP_TABLE_ADD_DEL, mp);
8441
8442   mp->table_id = ntohl (table_id);
8443   mp->is_ipv6 = is_ipv6;
8444   mp->is_add = is_add;
8445
8446   /* send it... */
8447   S (mp);
8448
8449   /* Wait for a reply... */
8450   W (ret);
8451
8452   return ret;
8453 }
8454
8455 static int
8456 api_ip_add_del_route (vat_main_t * vam)
8457 {
8458   unformat_input_t *i = vam->input;
8459   vl_api_ip_add_del_route_t *mp;
8460   u32 sw_if_index = ~0, vrf_id = 0;
8461   u8 is_ipv6 = 0;
8462   u8 is_local = 0, is_drop = 0;
8463   u8 is_unreach = 0, is_prohibit = 0;
8464   u8 is_add = 1;
8465   u32 next_hop_weight = 1;
8466   u8 is_multipath = 0;
8467   u8 address_set = 0;
8468   u8 address_length_set = 0;
8469   u32 next_hop_table_id = 0;
8470   u32 resolve_attempts = 0;
8471   u32 dst_address_length = 0;
8472   u8 next_hop_set = 0;
8473   ip4_address_t v4_dst_address, v4_next_hop_address;
8474   ip6_address_t v6_dst_address, v6_next_hop_address;
8475   int count = 1;
8476   int j;
8477   f64 before = 0;
8478   u32 random_add_del = 0;
8479   u32 *random_vector = 0;
8480   uword *random_hash;
8481   u32 random_seed = 0xdeaddabe;
8482   u32 classify_table_index = ~0;
8483   u8 is_classify = 0;
8484   u8 resolve_host = 0, resolve_attached = 0;
8485   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8486   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8487   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8488
8489   /* Parse args required to build the message */
8490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8491     {
8492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8493         ;
8494       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8495         ;
8496       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8497         {
8498           address_set = 1;
8499           is_ipv6 = 0;
8500         }
8501       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8502         {
8503           address_set = 1;
8504           is_ipv6 = 1;
8505         }
8506       else if (unformat (i, "/%d", &dst_address_length))
8507         {
8508           address_length_set = 1;
8509         }
8510
8511       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8512                                          &v4_next_hop_address))
8513         {
8514           next_hop_set = 1;
8515         }
8516       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8517                                          &v6_next_hop_address))
8518         {
8519           next_hop_set = 1;
8520         }
8521       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8522         ;
8523       else if (unformat (i, "weight %d", &next_hop_weight))
8524         ;
8525       else if (unformat (i, "drop"))
8526         {
8527           is_drop = 1;
8528         }
8529       else if (unformat (i, "null-send-unreach"))
8530         {
8531           is_unreach = 1;
8532         }
8533       else if (unformat (i, "null-send-prohibit"))
8534         {
8535           is_prohibit = 1;
8536         }
8537       else if (unformat (i, "local"))
8538         {
8539           is_local = 1;
8540         }
8541       else if (unformat (i, "classify %d", &classify_table_index))
8542         {
8543           is_classify = 1;
8544         }
8545       else if (unformat (i, "del"))
8546         is_add = 0;
8547       else if (unformat (i, "add"))
8548         is_add = 1;
8549       else if (unformat (i, "resolve-via-host"))
8550         resolve_host = 1;
8551       else if (unformat (i, "resolve-via-attached"))
8552         resolve_attached = 1;
8553       else if (unformat (i, "multipath"))
8554         is_multipath = 1;
8555       else if (unformat (i, "vrf %d", &vrf_id))
8556         ;
8557       else if (unformat (i, "count %d", &count))
8558         ;
8559       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8560         ;
8561       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8562         ;
8563       else if (unformat (i, "out-label %d", &next_hop_out_label))
8564         {
8565           vl_api_fib_mpls_label_t fib_label = {
8566             .label = ntohl (next_hop_out_label),
8567             .ttl = 64,
8568             .exp = 0,
8569           };
8570           vec_add1 (next_hop_out_label_stack, fib_label);
8571         }
8572       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8573         ;
8574       else if (unformat (i, "random"))
8575         random_add_del = 1;
8576       else if (unformat (i, "seed %d", &random_seed))
8577         ;
8578       else
8579         {
8580           clib_warning ("parse error '%U'", format_unformat_error, i);
8581           return -99;
8582         }
8583     }
8584
8585   if (!next_hop_set && !is_drop && !is_local &&
8586       !is_classify && !is_unreach && !is_prohibit &&
8587       MPLS_LABEL_INVALID == next_hop_via_label)
8588     {
8589       errmsg
8590         ("next hop / local / drop / unreach / prohibit / classify not set");
8591       return -99;
8592     }
8593
8594   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8595     {
8596       errmsg ("next hop and next-hop via label set");
8597       return -99;
8598     }
8599   if (address_set == 0)
8600     {
8601       errmsg ("missing addresses");
8602       return -99;
8603     }
8604
8605   if (address_length_set == 0)
8606     {
8607       errmsg ("missing address length");
8608       return -99;
8609     }
8610
8611   /* Generate a pile of unique, random routes */
8612   if (random_add_del)
8613     {
8614       u32 this_random_address;
8615       random_hash = hash_create (count, sizeof (uword));
8616
8617       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8618       for (j = 0; j <= count; j++)
8619         {
8620           do
8621             {
8622               this_random_address = random_u32 (&random_seed);
8623               this_random_address =
8624                 clib_host_to_net_u32 (this_random_address);
8625             }
8626           while (hash_get (random_hash, this_random_address));
8627           vec_add1 (random_vector, this_random_address);
8628           hash_set (random_hash, this_random_address, 1);
8629         }
8630       hash_free (random_hash);
8631       v4_dst_address.as_u32 = random_vector[0];
8632     }
8633
8634   if (count > 1)
8635     {
8636       /* Turn on async mode */
8637       vam->async_mode = 1;
8638       vam->async_errors = 0;
8639       before = vat_time_now (vam);
8640     }
8641
8642   for (j = 0; j < count; j++)
8643     {
8644       /* Construct the API message */
8645       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8646           vec_len (next_hop_out_label_stack));
8647
8648       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8649       mp->table_id = ntohl (vrf_id);
8650
8651       mp->is_add = is_add;
8652       mp->is_drop = is_drop;
8653       mp->is_unreach = is_unreach;
8654       mp->is_prohibit = is_prohibit;
8655       mp->is_ipv6 = is_ipv6;
8656       mp->is_local = is_local;
8657       mp->is_classify = is_classify;
8658       mp->is_multipath = is_multipath;
8659       mp->is_resolve_host = resolve_host;
8660       mp->is_resolve_attached = resolve_attached;
8661       mp->next_hop_weight = next_hop_weight;
8662       mp->dst_address_length = dst_address_length;
8663       mp->next_hop_table_id = ntohl (next_hop_table_id);
8664       mp->classify_table_index = ntohl (classify_table_index);
8665       mp->next_hop_via_label = ntohl (next_hop_via_label);
8666       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8667       if (0 != mp->next_hop_n_out_labels)
8668         {
8669           memcpy (mp->next_hop_out_label_stack,
8670                   next_hop_out_label_stack,
8671                   (vec_len (next_hop_out_label_stack) *
8672                    sizeof (vl_api_fib_mpls_label_t)));
8673           vec_free (next_hop_out_label_stack);
8674         }
8675
8676       if (is_ipv6)
8677         {
8678           clib_memcpy (mp->dst_address, &v6_dst_address,
8679                        sizeof (v6_dst_address));
8680           if (next_hop_set)
8681             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8682                          sizeof (v6_next_hop_address));
8683           increment_v6_address (&v6_dst_address);
8684         }
8685       else
8686         {
8687           clib_memcpy (mp->dst_address, &v4_dst_address,
8688                        sizeof (v4_dst_address));
8689           if (next_hop_set)
8690             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8691                          sizeof (v4_next_hop_address));
8692           if (random_add_del)
8693             v4_dst_address.as_u32 = random_vector[j + 1];
8694           else
8695             increment_v4_address (&v4_dst_address);
8696         }
8697       /* send it... */
8698       S (mp);
8699       /* If we receive SIGTERM, stop now... */
8700       if (vam->do_exit)
8701         break;
8702     }
8703
8704   /* When testing multiple add/del ops, use a control-ping to sync */
8705   if (count > 1)
8706     {
8707       vl_api_control_ping_t *mp_ping;
8708       f64 after;
8709       f64 timeout;
8710
8711       /* Shut off async mode */
8712       vam->async_mode = 0;
8713
8714       MPING (CONTROL_PING, mp_ping);
8715       S (mp_ping);
8716
8717       timeout = vat_time_now (vam) + 1.0;
8718       while (vat_time_now (vam) < timeout)
8719         if (vam->result_ready == 1)
8720           goto out;
8721       vam->retval = -99;
8722
8723     out:
8724       if (vam->retval == -99)
8725         errmsg ("timeout");
8726
8727       if (vam->async_errors > 0)
8728         {
8729           errmsg ("%d asynchronous errors", vam->async_errors);
8730           vam->retval = -98;
8731         }
8732       vam->async_errors = 0;
8733       after = vat_time_now (vam);
8734
8735       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8736       if (j > 0)
8737         count = j;
8738
8739       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8740              count, after - before, count / (after - before));
8741     }
8742   else
8743     {
8744       int ret;
8745
8746       /* Wait for a reply... */
8747       W (ret);
8748       return ret;
8749     }
8750
8751   /* Return the good/bad news */
8752   return (vam->retval);
8753 }
8754
8755 static int
8756 api_ip_mroute_add_del (vat_main_t * vam)
8757 {
8758   unformat_input_t *i = vam->input;
8759   vl_api_ip_mroute_add_del_t *mp;
8760   u32 sw_if_index = ~0, vrf_id = 0;
8761   u8 is_ipv6 = 0;
8762   u8 is_local = 0;
8763   u8 is_add = 1;
8764   u8 address_set = 0;
8765   u32 grp_address_length = 0;
8766   ip4_address_t v4_grp_address, v4_src_address;
8767   ip6_address_t v6_grp_address, v6_src_address;
8768   mfib_itf_flags_t iflags = 0;
8769   mfib_entry_flags_t eflags = 0;
8770   int ret;
8771
8772   /* Parse args required to build the message */
8773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8774     {
8775       if (unformat (i, "sw_if_index %d", &sw_if_index))
8776         ;
8777       else if (unformat (i, "%U %U",
8778                          unformat_ip4_address, &v4_src_address,
8779                          unformat_ip4_address, &v4_grp_address))
8780         {
8781           grp_address_length = 64;
8782           address_set = 1;
8783           is_ipv6 = 0;
8784         }
8785       else if (unformat (i, "%U %U",
8786                          unformat_ip6_address, &v6_src_address,
8787                          unformat_ip6_address, &v6_grp_address))
8788         {
8789           grp_address_length = 256;
8790           address_set = 1;
8791           is_ipv6 = 1;
8792         }
8793       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8794         {
8795           memset (&v4_src_address, 0, sizeof (v4_src_address));
8796           grp_address_length = 32;
8797           address_set = 1;
8798           is_ipv6 = 0;
8799         }
8800       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8801         {
8802           memset (&v6_src_address, 0, sizeof (v6_src_address));
8803           grp_address_length = 128;
8804           address_set = 1;
8805           is_ipv6 = 1;
8806         }
8807       else if (unformat (i, "/%d", &grp_address_length))
8808         ;
8809       else if (unformat (i, "local"))
8810         {
8811           is_local = 1;
8812         }
8813       else if (unformat (i, "del"))
8814         is_add = 0;
8815       else if (unformat (i, "add"))
8816         is_add = 1;
8817       else if (unformat (i, "vrf %d", &vrf_id))
8818         ;
8819       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8820         ;
8821       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8822         ;
8823       else
8824         {
8825           clib_warning ("parse error '%U'", format_unformat_error, i);
8826           return -99;
8827         }
8828     }
8829
8830   if (address_set == 0)
8831     {
8832       errmsg ("missing addresses\n");
8833       return -99;
8834     }
8835
8836   /* Construct the API message */
8837   M (IP_MROUTE_ADD_DEL, mp);
8838
8839   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8840   mp->table_id = ntohl (vrf_id);
8841
8842   mp->is_add = is_add;
8843   mp->is_ipv6 = is_ipv6;
8844   mp->is_local = is_local;
8845   mp->itf_flags = ntohl (iflags);
8846   mp->entry_flags = ntohl (eflags);
8847   mp->grp_address_length = grp_address_length;
8848   mp->grp_address_length = ntohs (mp->grp_address_length);
8849
8850   if (is_ipv6)
8851     {
8852       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8853       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8854     }
8855   else
8856     {
8857       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8858       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8859
8860     }
8861
8862   /* send it... */
8863   S (mp);
8864   /* Wait for a reply... */
8865   W (ret);
8866   return ret;
8867 }
8868
8869 static int
8870 api_mpls_table_add_del (vat_main_t * vam)
8871 {
8872   unformat_input_t *i = vam->input;
8873   vl_api_mpls_table_add_del_t *mp;
8874   u32 table_id = ~0;
8875   u8 is_add = 1;
8876   int ret = 0;
8877
8878   /* Parse args required to build the message */
8879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8880     {
8881       if (unformat (i, "table %d", &table_id))
8882         ;
8883       else if (unformat (i, "del"))
8884         is_add = 0;
8885       else if (unformat (i, "add"))
8886         is_add = 1;
8887       else
8888         {
8889           clib_warning ("parse error '%U'", format_unformat_error, i);
8890           return -99;
8891         }
8892     }
8893
8894   if (~0 == table_id)
8895     {
8896       errmsg ("missing table-ID");
8897       return -99;
8898     }
8899
8900   /* Construct the API message */
8901   M (MPLS_TABLE_ADD_DEL, mp);
8902
8903   mp->mt_table_id = ntohl (table_id);
8904   mp->mt_is_add = is_add;
8905
8906   /* send it... */
8907   S (mp);
8908
8909   /* Wait for a reply... */
8910   W (ret);
8911
8912   return ret;
8913 }
8914
8915 static int
8916 api_mpls_route_add_del (vat_main_t * vam)
8917 {
8918   unformat_input_t *i = vam->input;
8919   vl_api_mpls_route_add_del_t *mp;
8920   u32 sw_if_index = ~0, table_id = 0;
8921   u8 is_add = 1;
8922   u32 next_hop_weight = 1;
8923   u8 is_multipath = 0;
8924   u32 next_hop_table_id = 0;
8925   u8 next_hop_set = 0;
8926   ip4_address_t v4_next_hop_address = {
8927     .as_u32 = 0,
8928   };
8929   ip6_address_t v6_next_hop_address = { {0} };
8930   int count = 1;
8931   int j;
8932   f64 before = 0;
8933   u32 classify_table_index = ~0;
8934   u8 is_classify = 0;
8935   u8 resolve_host = 0, resolve_attached = 0;
8936   u8 is_interface_rx = 0;
8937   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8938   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8939   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8940   mpls_label_t local_label = MPLS_LABEL_INVALID;
8941   u8 is_eos = 0;
8942   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8943
8944   /* Parse args required to build the message */
8945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8946     {
8947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8948         ;
8949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8950         ;
8951       else if (unformat (i, "%d", &local_label))
8952         ;
8953       else if (unformat (i, "eos"))
8954         is_eos = 1;
8955       else if (unformat (i, "non-eos"))
8956         is_eos = 0;
8957       else if (unformat (i, "via %U", unformat_ip4_address,
8958                          &v4_next_hop_address))
8959         {
8960           next_hop_set = 1;
8961           next_hop_proto = DPO_PROTO_IP4;
8962         }
8963       else if (unformat (i, "via %U", unformat_ip6_address,
8964                          &v6_next_hop_address))
8965         {
8966           next_hop_set = 1;
8967           next_hop_proto = DPO_PROTO_IP6;
8968         }
8969       else if (unformat (i, "weight %d", &next_hop_weight))
8970         ;
8971       else if (unformat (i, "classify %d", &classify_table_index))
8972         {
8973           is_classify = 1;
8974         }
8975       else if (unformat (i, "del"))
8976         is_add = 0;
8977       else if (unformat (i, "add"))
8978         is_add = 1;
8979       else if (unformat (i, "resolve-via-host"))
8980         resolve_host = 1;
8981       else if (unformat (i, "resolve-via-attached"))
8982         resolve_attached = 1;
8983       else if (unformat (i, "multipath"))
8984         is_multipath = 1;
8985       else if (unformat (i, "count %d", &count))
8986         ;
8987       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
8988         {
8989           next_hop_set = 1;
8990           next_hop_proto = DPO_PROTO_IP4;
8991         }
8992       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
8993         {
8994           next_hop_set = 1;
8995           next_hop_proto = DPO_PROTO_IP6;
8996         }
8997       else
8998         if (unformat
8999             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9000              &sw_if_index))
9001         {
9002           next_hop_set = 1;
9003           next_hop_proto = DPO_PROTO_ETHERNET;
9004           is_interface_rx = 1;
9005         }
9006       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9007         {
9008           next_hop_set = 1;
9009           next_hop_proto = DPO_PROTO_ETHERNET;
9010           is_interface_rx = 1;
9011         }
9012       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9013         next_hop_set = 1;
9014       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9015         next_hop_set = 1;
9016       else if (unformat (i, "out-label %d", &next_hop_out_label))
9017         {
9018           vl_api_fib_mpls_label_t fib_label = {
9019             .label = ntohl (next_hop_out_label),
9020             .ttl = 64,
9021             .exp = 0,
9022           };
9023           vec_add1 (next_hop_out_label_stack, fib_label);
9024         }
9025       else
9026         {
9027           clib_warning ("parse error '%U'", format_unformat_error, i);
9028           return -99;
9029         }
9030     }
9031
9032   if (!next_hop_set && !is_classify)
9033     {
9034       errmsg ("next hop / classify not set");
9035       return -99;
9036     }
9037
9038   if (MPLS_LABEL_INVALID == local_label)
9039     {
9040       errmsg ("missing label");
9041       return -99;
9042     }
9043
9044   if (count > 1)
9045     {
9046       /* Turn on async mode */
9047       vam->async_mode = 1;
9048       vam->async_errors = 0;
9049       before = vat_time_now (vam);
9050     }
9051
9052   for (j = 0; j < count; j++)
9053     {
9054       /* Construct the API message */
9055       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9056           vec_len (next_hop_out_label_stack));
9057
9058       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9059       mp->mr_table_id = ntohl (table_id);
9060
9061       mp->mr_is_add = is_add;
9062       mp->mr_next_hop_proto = next_hop_proto;
9063       mp->mr_is_classify = is_classify;
9064       mp->mr_is_multipath = is_multipath;
9065       mp->mr_is_resolve_host = resolve_host;
9066       mp->mr_is_resolve_attached = resolve_attached;
9067       mp->mr_is_interface_rx = is_interface_rx;
9068       mp->mr_next_hop_weight = next_hop_weight;
9069       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9070       mp->mr_classify_table_index = ntohl (classify_table_index);
9071       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9072       mp->mr_label = ntohl (local_label);
9073       mp->mr_eos = is_eos;
9074
9075       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9076       if (0 != mp->mr_next_hop_n_out_labels)
9077         {
9078           memcpy (mp->mr_next_hop_out_label_stack,
9079                   next_hop_out_label_stack,
9080                   vec_len (next_hop_out_label_stack) *
9081                   sizeof (vl_api_fib_mpls_label_t));
9082           vec_free (next_hop_out_label_stack);
9083         }
9084
9085       if (next_hop_set)
9086         {
9087           if (DPO_PROTO_IP4 == next_hop_proto)
9088             {
9089               clib_memcpy (mp->mr_next_hop,
9090                            &v4_next_hop_address,
9091                            sizeof (v4_next_hop_address));
9092             }
9093           else if (DPO_PROTO_IP6 == next_hop_proto)
9094
9095             {
9096               clib_memcpy (mp->mr_next_hop,
9097                            &v6_next_hop_address,
9098                            sizeof (v6_next_hop_address));
9099             }
9100         }
9101       local_label++;
9102
9103       /* send it... */
9104       S (mp);
9105       /* If we receive SIGTERM, stop now... */
9106       if (vam->do_exit)
9107         break;
9108     }
9109
9110   /* When testing multiple add/del ops, use a control-ping to sync */
9111   if (count > 1)
9112     {
9113       vl_api_control_ping_t *mp_ping;
9114       f64 after;
9115       f64 timeout;
9116
9117       /* Shut off async mode */
9118       vam->async_mode = 0;
9119
9120       MPING (CONTROL_PING, mp_ping);
9121       S (mp_ping);
9122
9123       timeout = vat_time_now (vam) + 1.0;
9124       while (vat_time_now (vam) < timeout)
9125         if (vam->result_ready == 1)
9126           goto out;
9127       vam->retval = -99;
9128
9129     out:
9130       if (vam->retval == -99)
9131         errmsg ("timeout");
9132
9133       if (vam->async_errors > 0)
9134         {
9135           errmsg ("%d asynchronous errors", vam->async_errors);
9136           vam->retval = -98;
9137         }
9138       vam->async_errors = 0;
9139       after = vat_time_now (vam);
9140
9141       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9142       if (j > 0)
9143         count = j;
9144
9145       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9146              count, after - before, count / (after - before));
9147     }
9148   else
9149     {
9150       int ret;
9151
9152       /* Wait for a reply... */
9153       W (ret);
9154       return ret;
9155     }
9156
9157   /* Return the good/bad news */
9158   return (vam->retval);
9159 }
9160
9161 static int
9162 api_mpls_ip_bind_unbind (vat_main_t * vam)
9163 {
9164   unformat_input_t *i = vam->input;
9165   vl_api_mpls_ip_bind_unbind_t *mp;
9166   u32 ip_table_id = 0;
9167   u8 is_bind = 1;
9168   u8 is_ip4 = 1;
9169   ip4_address_t v4_address;
9170   ip6_address_t v6_address;
9171   u32 address_length;
9172   u8 address_set = 0;
9173   mpls_label_t local_label = MPLS_LABEL_INVALID;
9174   int ret;
9175
9176   /* Parse args required to build the message */
9177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9178     {
9179       if (unformat (i, "%U/%d", unformat_ip4_address,
9180                     &v4_address, &address_length))
9181         {
9182           is_ip4 = 1;
9183           address_set = 1;
9184         }
9185       else if (unformat (i, "%U/%d", unformat_ip6_address,
9186                          &v6_address, &address_length))
9187         {
9188           is_ip4 = 0;
9189           address_set = 1;
9190         }
9191       else if (unformat (i, "%d", &local_label))
9192         ;
9193       else if (unformat (i, "table-id %d", &ip_table_id))
9194         ;
9195       else if (unformat (i, "unbind"))
9196         is_bind = 0;
9197       else if (unformat (i, "bind"))
9198         is_bind = 1;
9199       else
9200         {
9201           clib_warning ("parse error '%U'", format_unformat_error, i);
9202           return -99;
9203         }
9204     }
9205
9206   if (!address_set)
9207     {
9208       errmsg ("IP addres not set");
9209       return -99;
9210     }
9211
9212   if (MPLS_LABEL_INVALID == local_label)
9213     {
9214       errmsg ("missing label");
9215       return -99;
9216     }
9217
9218   /* Construct the API message */
9219   M (MPLS_IP_BIND_UNBIND, mp);
9220
9221   mp->mb_is_bind = is_bind;
9222   mp->mb_is_ip4 = is_ip4;
9223   mp->mb_ip_table_id = ntohl (ip_table_id);
9224   mp->mb_mpls_table_id = 0;
9225   mp->mb_label = ntohl (local_label);
9226   mp->mb_address_length = address_length;
9227
9228   if (is_ip4)
9229     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9230   else
9231     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9232
9233   /* send it... */
9234   S (mp);
9235
9236   /* Wait for a reply... */
9237   W (ret);
9238   return ret;
9239 }
9240
9241 static int
9242 api_sr_mpls_policy_add (vat_main_t * vam)
9243 {
9244   unformat_input_t *i = vam->input;
9245   vl_api_sr_mpls_policy_add_t *mp;
9246   u32 bsid = 0;
9247   u32 weight = 1;
9248   u8 type = 0;
9249   u8 n_segments = 0;
9250   u32 sid;
9251   u32 *segments = NULL;
9252   int ret;
9253
9254   /* Parse args required to build the message */
9255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9256     {
9257       if (unformat (i, "bsid %d", &bsid))
9258         ;
9259       else if (unformat (i, "weight %d", &weight))
9260         ;
9261       else if (unformat (i, "spray"))
9262         type = 1;
9263       else if (unformat (i, "next %d", &sid))
9264         {
9265           n_segments += 1;
9266           vec_add1 (segments, htonl (sid));
9267         }
9268       else
9269         {
9270           clib_warning ("parse error '%U'", format_unformat_error, i);
9271           return -99;
9272         }
9273     }
9274
9275   if (bsid == 0)
9276     {
9277       errmsg ("bsid not set");
9278       return -99;
9279     }
9280
9281   if (n_segments == 0)
9282     {
9283       errmsg ("no sid in segment stack");
9284       return -99;
9285     }
9286
9287   /* Construct the API message */
9288   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9289
9290   mp->bsid = htonl (bsid);
9291   mp->weight = htonl (weight);
9292   mp->type = type;
9293   mp->n_segments = n_segments;
9294   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9295   vec_free (segments);
9296
9297   /* send it... */
9298   S (mp);
9299
9300   /* Wait for a reply... */
9301   W (ret);
9302   return ret;
9303 }
9304
9305 static int
9306 api_sr_mpls_policy_del (vat_main_t * vam)
9307 {
9308   unformat_input_t *i = vam->input;
9309   vl_api_sr_mpls_policy_del_t *mp;
9310   u32 bsid = 0;
9311   int ret;
9312
9313   /* Parse args required to build the message */
9314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9315     {
9316       if (unformat (i, "bsid %d", &bsid))
9317         ;
9318       else
9319         {
9320           clib_warning ("parse error '%U'", format_unformat_error, i);
9321           return -99;
9322         }
9323     }
9324
9325   if (bsid == 0)
9326     {
9327       errmsg ("bsid not set");
9328       return -99;
9329     }
9330
9331   /* Construct the API message */
9332   M (SR_MPLS_POLICY_DEL, mp);
9333
9334   mp->bsid = htonl (bsid);
9335
9336   /* send it... */
9337   S (mp);
9338
9339   /* Wait for a reply... */
9340   W (ret);
9341   return ret;
9342 }
9343
9344 static int
9345 api_bier_table_add_del (vat_main_t * vam)
9346 {
9347   unformat_input_t *i = vam->input;
9348   vl_api_bier_table_add_del_t *mp;
9349   u8 is_add = 1;
9350   u32 set = 0, sub_domain = 0, hdr_len = 3;
9351   mpls_label_t local_label = MPLS_LABEL_INVALID;
9352   int ret;
9353
9354   /* Parse args required to build the message */
9355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9356     {
9357       if (unformat (i, "sub-domain %d", &sub_domain))
9358         ;
9359       else if (unformat (i, "set %d", &set))
9360         ;
9361       else if (unformat (i, "label %d", &local_label))
9362         ;
9363       else if (unformat (i, "hdr-len %d", &hdr_len))
9364         ;
9365       else if (unformat (i, "add"))
9366         is_add = 1;
9367       else if (unformat (i, "del"))
9368         is_add = 0;
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (MPLS_LABEL_INVALID == local_label)
9377     {
9378       errmsg ("missing label\n");
9379       return -99;
9380     }
9381
9382   /* Construct the API message */
9383   M (BIER_TABLE_ADD_DEL, mp);
9384
9385   mp->bt_is_add = is_add;
9386   mp->bt_label = ntohl (local_label);
9387   mp->bt_tbl_id.bt_set = set;
9388   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9389   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9390
9391   /* send it... */
9392   S (mp);
9393
9394   /* Wait for a reply... */
9395   W (ret);
9396
9397   return (ret);
9398 }
9399
9400 static int
9401 api_bier_route_add_del (vat_main_t * vam)
9402 {
9403   unformat_input_t *i = vam->input;
9404   vl_api_bier_route_add_del_t *mp;
9405   u8 is_add = 1;
9406   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9407   ip4_address_t v4_next_hop_address;
9408   ip6_address_t v6_next_hop_address;
9409   u8 next_hop_set = 0;
9410   u8 next_hop_proto_is_ip4 = 1;
9411   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9412   int ret;
9413
9414   /* Parse args required to build the message */
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9418         {
9419           next_hop_proto_is_ip4 = 1;
9420           next_hop_set = 1;
9421         }
9422       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9423         {
9424           next_hop_proto_is_ip4 = 0;
9425           next_hop_set = 1;
9426         }
9427       if (unformat (i, "sub-domain %d", &sub_domain))
9428         ;
9429       else if (unformat (i, "set %d", &set))
9430         ;
9431       else if (unformat (i, "hdr-len %d", &hdr_len))
9432         ;
9433       else if (unformat (i, "bp %d", &bp))
9434         ;
9435       else if (unformat (i, "add"))
9436         is_add = 1;
9437       else if (unformat (i, "del"))
9438         is_add = 0;
9439       else if (unformat (i, "out-label %d", &next_hop_out_label))
9440         ;
9441       else
9442         {
9443           clib_warning ("parse error '%U'", format_unformat_error, i);
9444           return -99;
9445         }
9446     }
9447
9448   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9449     {
9450       errmsg ("next hop / label set\n");
9451       return -99;
9452     }
9453   if (0 == bp)
9454     {
9455       errmsg ("bit=position not set\n");
9456       return -99;
9457     }
9458
9459   /* Construct the API message */
9460   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9461
9462   mp->br_is_add = is_add;
9463   mp->br_tbl_id.bt_set = set;
9464   mp->br_tbl_id.bt_sub_domain = sub_domain;
9465   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9466   mp->br_bp = ntohs (bp);
9467   mp->br_n_paths = 1;
9468   mp->br_paths[0].n_labels = 1;
9469   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9470   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9471
9472   if (next_hop_proto_is_ip4)
9473     {
9474       clib_memcpy (mp->br_paths[0].next_hop,
9475                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9476     }
9477   else
9478     {
9479       clib_memcpy (mp->br_paths[0].next_hop,
9480                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9481     }
9482
9483   /* send it... */
9484   S (mp);
9485
9486   /* Wait for a reply... */
9487   W (ret);
9488
9489   return (ret);
9490 }
9491
9492 static int
9493 api_proxy_arp_add_del (vat_main_t * vam)
9494 {
9495   unformat_input_t *i = vam->input;
9496   vl_api_proxy_arp_add_del_t *mp;
9497   u32 vrf_id = 0;
9498   u8 is_add = 1;
9499   ip4_address_t lo, hi;
9500   u8 range_set = 0;
9501   int ret;
9502
9503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9504     {
9505       if (unformat (i, "vrf %d", &vrf_id))
9506         ;
9507       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9508                          unformat_ip4_address, &hi))
9509         range_set = 1;
9510       else if (unformat (i, "del"))
9511         is_add = 0;
9512       else
9513         {
9514           clib_warning ("parse error '%U'", format_unformat_error, i);
9515           return -99;
9516         }
9517     }
9518
9519   if (range_set == 0)
9520     {
9521       errmsg ("address range not set");
9522       return -99;
9523     }
9524
9525   M (PROXY_ARP_ADD_DEL, mp);
9526
9527   mp->proxy.vrf_id = ntohl (vrf_id);
9528   mp->is_add = is_add;
9529   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9530   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9531
9532   S (mp);
9533   W (ret);
9534   return ret;
9535 }
9536
9537 static int
9538 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9539 {
9540   unformat_input_t *i = vam->input;
9541   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9542   u32 sw_if_index;
9543   u8 enable = 1;
9544   u8 sw_if_index_set = 0;
9545   int ret;
9546
9547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9548     {
9549       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9550         sw_if_index_set = 1;
9551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9552         sw_if_index_set = 1;
9553       else if (unformat (i, "enable"))
9554         enable = 1;
9555       else if (unformat (i, "disable"))
9556         enable = 0;
9557       else
9558         {
9559           clib_warning ("parse error '%U'", format_unformat_error, i);
9560           return -99;
9561         }
9562     }
9563
9564   if (sw_if_index_set == 0)
9565     {
9566       errmsg ("missing interface name or sw_if_index");
9567       return -99;
9568     }
9569
9570   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9571
9572   mp->sw_if_index = ntohl (sw_if_index);
9573   mp->enable_disable = enable;
9574
9575   S (mp);
9576   W (ret);
9577   return ret;
9578 }
9579
9580 static int
9581 api_mpls_tunnel_add_del (vat_main_t * vam)
9582 {
9583   unformat_input_t *i = vam->input;
9584   vl_api_mpls_tunnel_add_del_t *mp;
9585
9586   u8 is_add = 1;
9587   u8 l2_only = 0;
9588   u32 sw_if_index = ~0;
9589   u32 next_hop_sw_if_index = ~0;
9590   u32 next_hop_proto_is_ip4 = 1;
9591
9592   u32 next_hop_table_id = 0;
9593   ip4_address_t v4_next_hop_address = {
9594     .as_u32 = 0,
9595   };
9596   ip6_address_t v6_next_hop_address = { {0} };
9597   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9598   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9599   int ret;
9600
9601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9602     {
9603       if (unformat (i, "add"))
9604         is_add = 1;
9605       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9606         is_add = 0;
9607       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9608         ;
9609       else if (unformat (i, "via %U",
9610                          unformat_ip4_address, &v4_next_hop_address))
9611         {
9612           next_hop_proto_is_ip4 = 1;
9613         }
9614       else if (unformat (i, "via %U",
9615                          unformat_ip6_address, &v6_next_hop_address))
9616         {
9617           next_hop_proto_is_ip4 = 0;
9618         }
9619       else if (unformat (i, "via-label %d", &next_hop_via_label))
9620         ;
9621       else if (unformat (i, "l2-only"))
9622         l2_only = 1;
9623       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9624         ;
9625       else if (unformat (i, "out-label %d", &next_hop_out_label))
9626         vec_add1 (labels, ntohl (next_hop_out_label));
9627       else
9628         {
9629           clib_warning ("parse error '%U'", format_unformat_error, i);
9630           return -99;
9631         }
9632     }
9633
9634   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9635
9636   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9637   mp->mt_sw_if_index = ntohl (sw_if_index);
9638   mp->mt_is_add = is_add;
9639   mp->mt_l2_only = l2_only;
9640   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9641   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9642   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9643
9644   mp->mt_next_hop_n_out_labels = vec_len (labels);
9645
9646   if (0 != mp->mt_next_hop_n_out_labels)
9647     {
9648       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9649                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9650       vec_free (labels);
9651     }
9652
9653   if (next_hop_proto_is_ip4)
9654     {
9655       clib_memcpy (mp->mt_next_hop,
9656                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9657     }
9658   else
9659     {
9660       clib_memcpy (mp->mt_next_hop,
9661                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9662     }
9663
9664   S (mp);
9665   W (ret);
9666   return ret;
9667 }
9668
9669 static int
9670 api_sw_interface_set_unnumbered (vat_main_t * vam)
9671 {
9672   unformat_input_t *i = vam->input;
9673   vl_api_sw_interface_set_unnumbered_t *mp;
9674   u32 sw_if_index;
9675   u32 unnum_sw_index = ~0;
9676   u8 is_add = 1;
9677   u8 sw_if_index_set = 0;
9678   int ret;
9679
9680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9683         sw_if_index_set = 1;
9684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9685         sw_if_index_set = 1;
9686       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9687         ;
9688       else if (unformat (i, "del"))
9689         is_add = 0;
9690       else
9691         {
9692           clib_warning ("parse error '%U'", format_unformat_error, i);
9693           return -99;
9694         }
9695     }
9696
9697   if (sw_if_index_set == 0)
9698     {
9699       errmsg ("missing interface name or sw_if_index");
9700       return -99;
9701     }
9702
9703   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9704
9705   mp->sw_if_index = ntohl (sw_if_index);
9706   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9707   mp->is_add = is_add;
9708
9709   S (mp);
9710   W (ret);
9711   return ret;
9712 }
9713
9714 static int
9715 api_ip_neighbor_add_del (vat_main_t * vam)
9716 {
9717   unformat_input_t *i = vam->input;
9718   vl_api_ip_neighbor_add_del_t *mp;
9719   u32 sw_if_index;
9720   u8 sw_if_index_set = 0;
9721   u8 is_add = 1;
9722   u8 is_static = 0;
9723   u8 is_no_fib_entry = 0;
9724   u8 mac_address[6];
9725   u8 mac_set = 0;
9726   u8 v4_address_set = 0;
9727   u8 v6_address_set = 0;
9728   ip4_address_t v4address;
9729   ip6_address_t v6address;
9730   int ret;
9731
9732   memset (mac_address, 0, sizeof (mac_address));
9733
9734   /* Parse args required to build the message */
9735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9736     {
9737       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9738         {
9739           mac_set = 1;
9740         }
9741       else if (unformat (i, "del"))
9742         is_add = 0;
9743       else
9744         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9745         sw_if_index_set = 1;
9746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9747         sw_if_index_set = 1;
9748       else if (unformat (i, "is_static"))
9749         is_static = 1;
9750       else if (unformat (i, "no-fib-entry"))
9751         is_no_fib_entry = 1;
9752       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9753         v4_address_set = 1;
9754       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9755         v6_address_set = 1;
9756       else
9757         {
9758           clib_warning ("parse error '%U'", format_unformat_error, i);
9759           return -99;
9760         }
9761     }
9762
9763   if (sw_if_index_set == 0)
9764     {
9765       errmsg ("missing interface name or sw_if_index");
9766       return -99;
9767     }
9768   if (v4_address_set && v6_address_set)
9769     {
9770       errmsg ("both v4 and v6 addresses set");
9771       return -99;
9772     }
9773   if (!v4_address_set && !v6_address_set)
9774     {
9775       errmsg ("no address set");
9776       return -99;
9777     }
9778
9779   /* Construct the API message */
9780   M (IP_NEIGHBOR_ADD_DEL, mp);
9781
9782   mp->sw_if_index = ntohl (sw_if_index);
9783   mp->is_add = is_add;
9784   mp->is_static = is_static;
9785   mp->is_no_adj_fib = is_no_fib_entry;
9786   if (mac_set)
9787     clib_memcpy (mp->mac_address, mac_address, 6);
9788   if (v6_address_set)
9789     {
9790       mp->is_ipv6 = 1;
9791       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9792     }
9793   else
9794     {
9795       /* mp->is_ipv6 = 0; via memset in M macro above */
9796       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9797     }
9798
9799   /* send it... */
9800   S (mp);
9801
9802   /* Wait for a reply, return good/bad news  */
9803   W (ret);
9804   return ret;
9805 }
9806
9807 static int
9808 api_create_vlan_subif (vat_main_t * vam)
9809 {
9810   unformat_input_t *i = vam->input;
9811   vl_api_create_vlan_subif_t *mp;
9812   u32 sw_if_index;
9813   u8 sw_if_index_set = 0;
9814   u32 vlan_id;
9815   u8 vlan_id_set = 0;
9816   int ret;
9817
9818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9819     {
9820       if (unformat (i, "sw_if_index %d", &sw_if_index))
9821         sw_if_index_set = 1;
9822       else
9823         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9824         sw_if_index_set = 1;
9825       else if (unformat (i, "vlan %d", &vlan_id))
9826         vlan_id_set = 1;
9827       else
9828         {
9829           clib_warning ("parse error '%U'", format_unformat_error, i);
9830           return -99;
9831         }
9832     }
9833
9834   if (sw_if_index_set == 0)
9835     {
9836       errmsg ("missing interface name or sw_if_index");
9837       return -99;
9838     }
9839
9840   if (vlan_id_set == 0)
9841     {
9842       errmsg ("missing vlan_id");
9843       return -99;
9844     }
9845   M (CREATE_VLAN_SUBIF, mp);
9846
9847   mp->sw_if_index = ntohl (sw_if_index);
9848   mp->vlan_id = ntohl (vlan_id);
9849
9850   S (mp);
9851   W (ret);
9852   return ret;
9853 }
9854
9855 #define foreach_create_subif_bit                \
9856 _(no_tags)                                      \
9857 _(one_tag)                                      \
9858 _(two_tags)                                     \
9859 _(dot1ad)                                       \
9860 _(exact_match)                                  \
9861 _(default_sub)                                  \
9862 _(outer_vlan_id_any)                            \
9863 _(inner_vlan_id_any)
9864
9865 static int
9866 api_create_subif (vat_main_t * vam)
9867 {
9868   unformat_input_t *i = vam->input;
9869   vl_api_create_subif_t *mp;
9870   u32 sw_if_index;
9871   u8 sw_if_index_set = 0;
9872   u32 sub_id;
9873   u8 sub_id_set = 0;
9874   u32 no_tags = 0;
9875   u32 one_tag = 0;
9876   u32 two_tags = 0;
9877   u32 dot1ad = 0;
9878   u32 exact_match = 0;
9879   u32 default_sub = 0;
9880   u32 outer_vlan_id_any = 0;
9881   u32 inner_vlan_id_any = 0;
9882   u32 tmp;
9883   u16 outer_vlan_id = 0;
9884   u16 inner_vlan_id = 0;
9885   int ret;
9886
9887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9888     {
9889       if (unformat (i, "sw_if_index %d", &sw_if_index))
9890         sw_if_index_set = 1;
9891       else
9892         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9893         sw_if_index_set = 1;
9894       else if (unformat (i, "sub_id %d", &sub_id))
9895         sub_id_set = 1;
9896       else if (unformat (i, "outer_vlan_id %d", &tmp))
9897         outer_vlan_id = tmp;
9898       else if (unformat (i, "inner_vlan_id %d", &tmp))
9899         inner_vlan_id = tmp;
9900
9901 #define _(a) else if (unformat (i, #a)) a = 1 ;
9902       foreach_create_subif_bit
9903 #undef _
9904         else
9905         {
9906           clib_warning ("parse error '%U'", format_unformat_error, i);
9907           return -99;
9908         }
9909     }
9910
9911   if (sw_if_index_set == 0)
9912     {
9913       errmsg ("missing interface name or sw_if_index");
9914       return -99;
9915     }
9916
9917   if (sub_id_set == 0)
9918     {
9919       errmsg ("missing sub_id");
9920       return -99;
9921     }
9922   M (CREATE_SUBIF, mp);
9923
9924   mp->sw_if_index = ntohl (sw_if_index);
9925   mp->sub_id = ntohl (sub_id);
9926
9927 #define _(a) mp->a = a;
9928   foreach_create_subif_bit;
9929 #undef _
9930
9931   mp->outer_vlan_id = ntohs (outer_vlan_id);
9932   mp->inner_vlan_id = ntohs (inner_vlan_id);
9933
9934   S (mp);
9935   W (ret);
9936   return ret;
9937 }
9938
9939 static int
9940 api_oam_add_del (vat_main_t * vam)
9941 {
9942   unformat_input_t *i = vam->input;
9943   vl_api_oam_add_del_t *mp;
9944   u32 vrf_id = 0;
9945   u8 is_add = 1;
9946   ip4_address_t src, dst;
9947   u8 src_set = 0;
9948   u8 dst_set = 0;
9949   int ret;
9950
9951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9952     {
9953       if (unformat (i, "vrf %d", &vrf_id))
9954         ;
9955       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9956         src_set = 1;
9957       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9958         dst_set = 1;
9959       else if (unformat (i, "del"))
9960         is_add = 0;
9961       else
9962         {
9963           clib_warning ("parse error '%U'", format_unformat_error, i);
9964           return -99;
9965         }
9966     }
9967
9968   if (src_set == 0)
9969     {
9970       errmsg ("missing src addr");
9971       return -99;
9972     }
9973
9974   if (dst_set == 0)
9975     {
9976       errmsg ("missing dst addr");
9977       return -99;
9978     }
9979
9980   M (OAM_ADD_DEL, mp);
9981
9982   mp->vrf_id = ntohl (vrf_id);
9983   mp->is_add = is_add;
9984   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9985   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9986
9987   S (mp);
9988   W (ret);
9989   return ret;
9990 }
9991
9992 static int
9993 api_reset_fib (vat_main_t * vam)
9994 {
9995   unformat_input_t *i = vam->input;
9996   vl_api_reset_fib_t *mp;
9997   u32 vrf_id = 0;
9998   u8 is_ipv6 = 0;
9999   u8 vrf_id_set = 0;
10000
10001   int ret;
10002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10003     {
10004       if (unformat (i, "vrf %d", &vrf_id))
10005         vrf_id_set = 1;
10006       else if (unformat (i, "ipv6"))
10007         is_ipv6 = 1;
10008       else
10009         {
10010           clib_warning ("parse error '%U'", format_unformat_error, i);
10011           return -99;
10012         }
10013     }
10014
10015   if (vrf_id_set == 0)
10016     {
10017       errmsg ("missing vrf id");
10018       return -99;
10019     }
10020
10021   M (RESET_FIB, mp);
10022
10023   mp->vrf_id = ntohl (vrf_id);
10024   mp->is_ipv6 = is_ipv6;
10025
10026   S (mp);
10027   W (ret);
10028   return ret;
10029 }
10030
10031 static int
10032 api_dhcp_proxy_config (vat_main_t * vam)
10033 {
10034   unformat_input_t *i = vam->input;
10035   vl_api_dhcp_proxy_config_t *mp;
10036   u32 rx_vrf_id = 0;
10037   u32 server_vrf_id = 0;
10038   u8 is_add = 1;
10039   u8 v4_address_set = 0;
10040   u8 v6_address_set = 0;
10041   ip4_address_t v4address;
10042   ip6_address_t v6address;
10043   u8 v4_src_address_set = 0;
10044   u8 v6_src_address_set = 0;
10045   ip4_address_t v4srcaddress;
10046   ip6_address_t v6srcaddress;
10047   int ret;
10048
10049   /* Parse args required to build the message */
10050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10051     {
10052       if (unformat (i, "del"))
10053         is_add = 0;
10054       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10055         ;
10056       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10057         ;
10058       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10059         v4_address_set = 1;
10060       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10061         v6_address_set = 1;
10062       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10063         v4_src_address_set = 1;
10064       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10065         v6_src_address_set = 1;
10066       else
10067         break;
10068     }
10069
10070   if (v4_address_set && v6_address_set)
10071     {
10072       errmsg ("both v4 and v6 server addresses set");
10073       return -99;
10074     }
10075   if (!v4_address_set && !v6_address_set)
10076     {
10077       errmsg ("no server addresses set");
10078       return -99;
10079     }
10080
10081   if (v4_src_address_set && v6_src_address_set)
10082     {
10083       errmsg ("both v4 and v6  src addresses set");
10084       return -99;
10085     }
10086   if (!v4_src_address_set && !v6_src_address_set)
10087     {
10088       errmsg ("no src addresses set");
10089       return -99;
10090     }
10091
10092   if (!(v4_src_address_set && v4_address_set) &&
10093       !(v6_src_address_set && v6_address_set))
10094     {
10095       errmsg ("no matching server and src addresses set");
10096       return -99;
10097     }
10098
10099   /* Construct the API message */
10100   M (DHCP_PROXY_CONFIG, mp);
10101
10102   mp->is_add = is_add;
10103   mp->rx_vrf_id = ntohl (rx_vrf_id);
10104   mp->server_vrf_id = ntohl (server_vrf_id);
10105   if (v6_address_set)
10106     {
10107       mp->is_ipv6 = 1;
10108       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10109       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10110     }
10111   else
10112     {
10113       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10114       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10115     }
10116
10117   /* send it... */
10118   S (mp);
10119
10120   /* Wait for a reply, return good/bad news  */
10121   W (ret);
10122   return ret;
10123 }
10124
10125 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10126 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10127
10128 static void
10129 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10130 {
10131   vat_main_t *vam = &vat_main;
10132   u32 i, count = mp->count;
10133   vl_api_dhcp_server_t *s;
10134
10135   if (mp->is_ipv6)
10136     print (vam->ofp,
10137            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10138            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10139            ntohl (mp->rx_vrf_id),
10140            format_ip6_address, mp->dhcp_src_address,
10141            mp->vss_type, mp->vss_vpn_ascii_id,
10142            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10143   else
10144     print (vam->ofp,
10145            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10146            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10147            ntohl (mp->rx_vrf_id),
10148            format_ip4_address, mp->dhcp_src_address,
10149            mp->vss_type, mp->vss_vpn_ascii_id,
10150            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10151
10152   for (i = 0; i < count; i++)
10153     {
10154       s = &mp->servers[i];
10155
10156       if (mp->is_ipv6)
10157         print (vam->ofp,
10158                " Server Table-ID %d, Server Address %U",
10159                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10160       else
10161         print (vam->ofp,
10162                " Server Table-ID %d, Server Address %U",
10163                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10164     }
10165 }
10166
10167 static void vl_api_dhcp_proxy_details_t_handler_json
10168   (vl_api_dhcp_proxy_details_t * mp)
10169 {
10170   vat_main_t *vam = &vat_main;
10171   vat_json_node_t *node = NULL;
10172   u32 i, count = mp->count;
10173   struct in_addr ip4;
10174   struct in6_addr ip6;
10175   vl_api_dhcp_server_t *s;
10176
10177   if (VAT_JSON_ARRAY != vam->json_tree.type)
10178     {
10179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10180       vat_json_init_array (&vam->json_tree);
10181     }
10182   node = vat_json_array_add (&vam->json_tree);
10183
10184   vat_json_init_object (node);
10185   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10186   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10187                              sizeof (mp->vss_type));
10188   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10189                                    mp->vss_vpn_ascii_id);
10190   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10191   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10192
10193   if (mp->is_ipv6)
10194     {
10195       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10196       vat_json_object_add_ip6 (node, "src_address", ip6);
10197     }
10198   else
10199     {
10200       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10201       vat_json_object_add_ip4 (node, "src_address", ip4);
10202     }
10203
10204   for (i = 0; i < count; i++)
10205     {
10206       s = &mp->servers[i];
10207
10208       vat_json_object_add_uint (node, "server-table-id",
10209                                 ntohl (s->server_vrf_id));
10210
10211       if (mp->is_ipv6)
10212         {
10213           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10214           vat_json_object_add_ip4 (node, "src_address", ip4);
10215         }
10216       else
10217         {
10218           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10219           vat_json_object_add_ip6 (node, "server_address", ip6);
10220         }
10221     }
10222 }
10223
10224 static int
10225 api_dhcp_proxy_dump (vat_main_t * vam)
10226 {
10227   unformat_input_t *i = vam->input;
10228   vl_api_control_ping_t *mp_ping;
10229   vl_api_dhcp_proxy_dump_t *mp;
10230   u8 is_ipv6 = 0;
10231   int ret;
10232
10233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10234     {
10235       if (unformat (i, "ipv6"))
10236         is_ipv6 = 1;
10237       else
10238         {
10239           clib_warning ("parse error '%U'", format_unformat_error, i);
10240           return -99;
10241         }
10242     }
10243
10244   M (DHCP_PROXY_DUMP, mp);
10245
10246   mp->is_ip6 = is_ipv6;
10247   S (mp);
10248
10249   /* Use a control ping for synchronization */
10250   MPING (CONTROL_PING, mp_ping);
10251   S (mp_ping);
10252
10253   W (ret);
10254   return ret;
10255 }
10256
10257 static int
10258 api_dhcp_proxy_set_vss (vat_main_t * vam)
10259 {
10260   unformat_input_t *i = vam->input;
10261   vl_api_dhcp_proxy_set_vss_t *mp;
10262   u8 is_ipv6 = 0;
10263   u8 is_add = 1;
10264   u32 tbl_id = ~0;
10265   u8 vss_type = VSS_TYPE_DEFAULT;
10266   u8 *vpn_ascii_id = 0;
10267   u32 oui = 0;
10268   u32 fib_id = 0;
10269   int ret;
10270
10271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10272     {
10273       if (unformat (i, "tbl_id %d", &tbl_id))
10274         ;
10275       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10276         vss_type = VSS_TYPE_ASCII;
10277       else if (unformat (i, "fib_id %d", &fib_id))
10278         vss_type = VSS_TYPE_VPN_ID;
10279       else if (unformat (i, "oui %d", &oui))
10280         vss_type = VSS_TYPE_VPN_ID;
10281       else if (unformat (i, "ipv6"))
10282         is_ipv6 = 1;
10283       else if (unformat (i, "del"))
10284         is_add = 0;
10285       else
10286         break;
10287     }
10288
10289   if (tbl_id == ~0)
10290     {
10291       errmsg ("missing tbl_id ");
10292       vec_free (vpn_ascii_id);
10293       return -99;
10294     }
10295
10296   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10297     {
10298       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10299       vec_free (vpn_ascii_id);
10300       return -99;
10301     }
10302
10303   M (DHCP_PROXY_SET_VSS, mp);
10304   mp->tbl_id = ntohl (tbl_id);
10305   mp->vss_type = vss_type;
10306   if (vpn_ascii_id)
10307     {
10308       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10309       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10310     }
10311   mp->vpn_index = ntohl (fib_id);
10312   mp->oui = ntohl (oui);
10313   mp->is_ipv6 = is_ipv6;
10314   mp->is_add = is_add;
10315
10316   S (mp);
10317   W (ret);
10318
10319   vec_free (vpn_ascii_id);
10320   return ret;
10321 }
10322
10323 static int
10324 api_dhcp_client_config (vat_main_t * vam)
10325 {
10326   unformat_input_t *i = vam->input;
10327   vl_api_dhcp_client_config_t *mp;
10328   u32 sw_if_index;
10329   u8 sw_if_index_set = 0;
10330   u8 is_add = 1;
10331   u8 *hostname = 0;
10332   u8 disable_event = 0;
10333   int ret;
10334
10335   /* Parse args required to build the message */
10336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10337     {
10338       if (unformat (i, "del"))
10339         is_add = 0;
10340       else
10341         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10342         sw_if_index_set = 1;
10343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10344         sw_if_index_set = 1;
10345       else if (unformat (i, "hostname %s", &hostname))
10346         ;
10347       else if (unformat (i, "disable_event"))
10348         disable_event = 1;
10349       else
10350         break;
10351     }
10352
10353   if (sw_if_index_set == 0)
10354     {
10355       errmsg ("missing interface name or sw_if_index");
10356       return -99;
10357     }
10358
10359   if (vec_len (hostname) > 63)
10360     {
10361       errmsg ("hostname too long");
10362     }
10363   vec_add1 (hostname, 0);
10364
10365   /* Construct the API message */
10366   M (DHCP_CLIENT_CONFIG, mp);
10367
10368   mp->is_add = is_add;
10369   mp->client.sw_if_index = htonl (sw_if_index);
10370   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10371   vec_free (hostname);
10372   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10373   mp->client.pid = htonl (getpid ());
10374
10375   /* send it... */
10376   S (mp);
10377
10378   /* Wait for a reply, return good/bad news  */
10379   W (ret);
10380   return ret;
10381 }
10382
10383 static int
10384 api_set_ip_flow_hash (vat_main_t * vam)
10385 {
10386   unformat_input_t *i = vam->input;
10387   vl_api_set_ip_flow_hash_t *mp;
10388   u32 vrf_id = 0;
10389   u8 is_ipv6 = 0;
10390   u8 vrf_id_set = 0;
10391   u8 src = 0;
10392   u8 dst = 0;
10393   u8 sport = 0;
10394   u8 dport = 0;
10395   u8 proto = 0;
10396   u8 reverse = 0;
10397   int ret;
10398
10399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10400     {
10401       if (unformat (i, "vrf %d", &vrf_id))
10402         vrf_id_set = 1;
10403       else if (unformat (i, "ipv6"))
10404         is_ipv6 = 1;
10405       else if (unformat (i, "src"))
10406         src = 1;
10407       else if (unformat (i, "dst"))
10408         dst = 1;
10409       else if (unformat (i, "sport"))
10410         sport = 1;
10411       else if (unformat (i, "dport"))
10412         dport = 1;
10413       else if (unformat (i, "proto"))
10414         proto = 1;
10415       else if (unformat (i, "reverse"))
10416         reverse = 1;
10417
10418       else
10419         {
10420           clib_warning ("parse error '%U'", format_unformat_error, i);
10421           return -99;
10422         }
10423     }
10424
10425   if (vrf_id_set == 0)
10426     {
10427       errmsg ("missing vrf id");
10428       return -99;
10429     }
10430
10431   M (SET_IP_FLOW_HASH, mp);
10432   mp->src = src;
10433   mp->dst = dst;
10434   mp->sport = sport;
10435   mp->dport = dport;
10436   mp->proto = proto;
10437   mp->reverse = reverse;
10438   mp->vrf_id = ntohl (vrf_id);
10439   mp->is_ipv6 = is_ipv6;
10440
10441   S (mp);
10442   W (ret);
10443   return ret;
10444 }
10445
10446 static int
10447 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10448 {
10449   unformat_input_t *i = vam->input;
10450   vl_api_sw_interface_ip6_enable_disable_t *mp;
10451   u32 sw_if_index;
10452   u8 sw_if_index_set = 0;
10453   u8 enable = 0;
10454   int ret;
10455
10456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10457     {
10458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10459         sw_if_index_set = 1;
10460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10461         sw_if_index_set = 1;
10462       else if (unformat (i, "enable"))
10463         enable = 1;
10464       else if (unformat (i, "disable"))
10465         enable = 0;
10466       else
10467         {
10468           clib_warning ("parse error '%U'", format_unformat_error, i);
10469           return -99;
10470         }
10471     }
10472
10473   if (sw_if_index_set == 0)
10474     {
10475       errmsg ("missing interface name or sw_if_index");
10476       return -99;
10477     }
10478
10479   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10480
10481   mp->sw_if_index = ntohl (sw_if_index);
10482   mp->enable = enable;
10483
10484   S (mp);
10485   W (ret);
10486   return ret;
10487 }
10488
10489 static int
10490 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10491 {
10492   unformat_input_t *i = vam->input;
10493   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10494   u32 sw_if_index;
10495   u8 sw_if_index_set = 0;
10496   u8 v6_address_set = 0;
10497   ip6_address_t v6address;
10498   int ret;
10499
10500   /* Parse args required to build the message */
10501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10502     {
10503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10504         sw_if_index_set = 1;
10505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10506         sw_if_index_set = 1;
10507       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10508         v6_address_set = 1;
10509       else
10510         break;
10511     }
10512
10513   if (sw_if_index_set == 0)
10514     {
10515       errmsg ("missing interface name or sw_if_index");
10516       return -99;
10517     }
10518   if (!v6_address_set)
10519     {
10520       errmsg ("no address set");
10521       return -99;
10522     }
10523
10524   /* Construct the API message */
10525   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10526
10527   mp->sw_if_index = ntohl (sw_if_index);
10528   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10529
10530   /* send it... */
10531   S (mp);
10532
10533   /* Wait for a reply, return good/bad news  */
10534   W (ret);
10535   return ret;
10536 }
10537
10538 static int
10539 api_ip6nd_proxy_add_del (vat_main_t * vam)
10540 {
10541   unformat_input_t *i = vam->input;
10542   vl_api_ip6nd_proxy_add_del_t *mp;
10543   u32 sw_if_index = ~0;
10544   u8 v6_address_set = 0;
10545   ip6_address_t v6address;
10546   u8 is_del = 0;
10547   int ret;
10548
10549   /* Parse args required to build the message */
10550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10553         ;
10554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10555         ;
10556       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10557         v6_address_set = 1;
10558       if (unformat (i, "del"))
10559         is_del = 1;
10560       else
10561         {
10562           clib_warning ("parse error '%U'", format_unformat_error, i);
10563           return -99;
10564         }
10565     }
10566
10567   if (sw_if_index == ~0)
10568     {
10569       errmsg ("missing interface name or sw_if_index");
10570       return -99;
10571     }
10572   if (!v6_address_set)
10573     {
10574       errmsg ("no address set");
10575       return -99;
10576     }
10577
10578   /* Construct the API message */
10579   M (IP6ND_PROXY_ADD_DEL, mp);
10580
10581   mp->is_del = is_del;
10582   mp->sw_if_index = ntohl (sw_if_index);
10583   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10584
10585   /* send it... */
10586   S (mp);
10587
10588   /* Wait for a reply, return good/bad news  */
10589   W (ret);
10590   return ret;
10591 }
10592
10593 static int
10594 api_ip6nd_proxy_dump (vat_main_t * vam)
10595 {
10596   vl_api_ip6nd_proxy_dump_t *mp;
10597   vl_api_control_ping_t *mp_ping;
10598   int ret;
10599
10600   M (IP6ND_PROXY_DUMP, mp);
10601
10602   S (mp);
10603
10604   /* Use a control ping for synchronization */
10605   MPING (CONTROL_PING, mp_ping);
10606   S (mp_ping);
10607
10608   W (ret);
10609   return ret;
10610 }
10611
10612 static void vl_api_ip6nd_proxy_details_t_handler
10613   (vl_api_ip6nd_proxy_details_t * mp)
10614 {
10615   vat_main_t *vam = &vat_main;
10616
10617   print (vam->ofp, "host %U sw_if_index %d",
10618          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10619 }
10620
10621 static void vl_api_ip6nd_proxy_details_t_handler_json
10622   (vl_api_ip6nd_proxy_details_t * mp)
10623 {
10624   vat_main_t *vam = &vat_main;
10625   struct in6_addr ip6;
10626   vat_json_node_t *node = NULL;
10627
10628   if (VAT_JSON_ARRAY != vam->json_tree.type)
10629     {
10630       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10631       vat_json_init_array (&vam->json_tree);
10632     }
10633   node = vat_json_array_add (&vam->json_tree);
10634
10635   vat_json_init_object (node);
10636   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10637
10638   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10639   vat_json_object_add_ip6 (node, "host", ip6);
10640 }
10641
10642 static int
10643 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10644 {
10645   unformat_input_t *i = vam->input;
10646   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10647   u32 sw_if_index;
10648   u8 sw_if_index_set = 0;
10649   u32 address_length = 0;
10650   u8 v6_address_set = 0;
10651   ip6_address_t v6address;
10652   u8 use_default = 0;
10653   u8 no_advertise = 0;
10654   u8 off_link = 0;
10655   u8 no_autoconfig = 0;
10656   u8 no_onlink = 0;
10657   u8 is_no = 0;
10658   u32 val_lifetime = 0;
10659   u32 pref_lifetime = 0;
10660   int ret;
10661
10662   /* Parse args required to build the message */
10663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10664     {
10665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10666         sw_if_index_set = 1;
10667       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10668         sw_if_index_set = 1;
10669       else if (unformat (i, "%U/%d",
10670                          unformat_ip6_address, &v6address, &address_length))
10671         v6_address_set = 1;
10672       else if (unformat (i, "val_life %d", &val_lifetime))
10673         ;
10674       else if (unformat (i, "pref_life %d", &pref_lifetime))
10675         ;
10676       else if (unformat (i, "def"))
10677         use_default = 1;
10678       else if (unformat (i, "noadv"))
10679         no_advertise = 1;
10680       else if (unformat (i, "offl"))
10681         off_link = 1;
10682       else if (unformat (i, "noauto"))
10683         no_autoconfig = 1;
10684       else if (unformat (i, "nolink"))
10685         no_onlink = 1;
10686       else if (unformat (i, "isno"))
10687         is_no = 1;
10688       else
10689         {
10690           clib_warning ("parse error '%U'", format_unformat_error, i);
10691           return -99;
10692         }
10693     }
10694
10695   if (sw_if_index_set == 0)
10696     {
10697       errmsg ("missing interface name or sw_if_index");
10698       return -99;
10699     }
10700   if (!v6_address_set)
10701     {
10702       errmsg ("no address set");
10703       return -99;
10704     }
10705
10706   /* Construct the API message */
10707   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10708
10709   mp->sw_if_index = ntohl (sw_if_index);
10710   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10711   mp->address_length = address_length;
10712   mp->use_default = use_default;
10713   mp->no_advertise = no_advertise;
10714   mp->off_link = off_link;
10715   mp->no_autoconfig = no_autoconfig;
10716   mp->no_onlink = no_onlink;
10717   mp->is_no = is_no;
10718   mp->val_lifetime = ntohl (val_lifetime);
10719   mp->pref_lifetime = ntohl (pref_lifetime);
10720
10721   /* send it... */
10722   S (mp);
10723
10724   /* Wait for a reply, return good/bad news  */
10725   W (ret);
10726   return ret;
10727 }
10728
10729 static int
10730 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10731 {
10732   unformat_input_t *i = vam->input;
10733   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10734   u32 sw_if_index;
10735   u8 sw_if_index_set = 0;
10736   u8 suppress = 0;
10737   u8 managed = 0;
10738   u8 other = 0;
10739   u8 ll_option = 0;
10740   u8 send_unicast = 0;
10741   u8 cease = 0;
10742   u8 is_no = 0;
10743   u8 default_router = 0;
10744   u32 max_interval = 0;
10745   u32 min_interval = 0;
10746   u32 lifetime = 0;
10747   u32 initial_count = 0;
10748   u32 initial_interval = 0;
10749   int ret;
10750
10751
10752   /* Parse args required to build the message */
10753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10754     {
10755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10756         sw_if_index_set = 1;
10757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10758         sw_if_index_set = 1;
10759       else if (unformat (i, "maxint %d", &max_interval))
10760         ;
10761       else if (unformat (i, "minint %d", &min_interval))
10762         ;
10763       else if (unformat (i, "life %d", &lifetime))
10764         ;
10765       else if (unformat (i, "count %d", &initial_count))
10766         ;
10767       else if (unformat (i, "interval %d", &initial_interval))
10768         ;
10769       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10770         suppress = 1;
10771       else if (unformat (i, "managed"))
10772         managed = 1;
10773       else if (unformat (i, "other"))
10774         other = 1;
10775       else if (unformat (i, "ll"))
10776         ll_option = 1;
10777       else if (unformat (i, "send"))
10778         send_unicast = 1;
10779       else if (unformat (i, "cease"))
10780         cease = 1;
10781       else if (unformat (i, "isno"))
10782         is_no = 1;
10783       else if (unformat (i, "def"))
10784         default_router = 1;
10785       else
10786         {
10787           clib_warning ("parse error '%U'", format_unformat_error, i);
10788           return -99;
10789         }
10790     }
10791
10792   if (sw_if_index_set == 0)
10793     {
10794       errmsg ("missing interface name or sw_if_index");
10795       return -99;
10796     }
10797
10798   /* Construct the API message */
10799   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10800
10801   mp->sw_if_index = ntohl (sw_if_index);
10802   mp->max_interval = ntohl (max_interval);
10803   mp->min_interval = ntohl (min_interval);
10804   mp->lifetime = ntohl (lifetime);
10805   mp->initial_count = ntohl (initial_count);
10806   mp->initial_interval = ntohl (initial_interval);
10807   mp->suppress = suppress;
10808   mp->managed = managed;
10809   mp->other = other;
10810   mp->ll_option = ll_option;
10811   mp->send_unicast = send_unicast;
10812   mp->cease = cease;
10813   mp->is_no = is_no;
10814   mp->default_router = default_router;
10815
10816   /* send it... */
10817   S (mp);
10818
10819   /* Wait for a reply, return good/bad news  */
10820   W (ret);
10821   return ret;
10822 }
10823
10824 static int
10825 api_set_arp_neighbor_limit (vat_main_t * vam)
10826 {
10827   unformat_input_t *i = vam->input;
10828   vl_api_set_arp_neighbor_limit_t *mp;
10829   u32 arp_nbr_limit;
10830   u8 limit_set = 0;
10831   u8 is_ipv6 = 0;
10832   int ret;
10833
10834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10835     {
10836       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10837         limit_set = 1;
10838       else if (unformat (i, "ipv6"))
10839         is_ipv6 = 1;
10840       else
10841         {
10842           clib_warning ("parse error '%U'", format_unformat_error, i);
10843           return -99;
10844         }
10845     }
10846
10847   if (limit_set == 0)
10848     {
10849       errmsg ("missing limit value");
10850       return -99;
10851     }
10852
10853   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10854
10855   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10856   mp->is_ipv6 = is_ipv6;
10857
10858   S (mp);
10859   W (ret);
10860   return ret;
10861 }
10862
10863 static int
10864 api_l2_patch_add_del (vat_main_t * vam)
10865 {
10866   unformat_input_t *i = vam->input;
10867   vl_api_l2_patch_add_del_t *mp;
10868   u32 rx_sw_if_index;
10869   u8 rx_sw_if_index_set = 0;
10870   u32 tx_sw_if_index;
10871   u8 tx_sw_if_index_set = 0;
10872   u8 is_add = 1;
10873   int ret;
10874
10875   /* Parse args required to build the message */
10876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10879         rx_sw_if_index_set = 1;
10880       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10881         tx_sw_if_index_set = 1;
10882       else if (unformat (i, "rx"))
10883         {
10884           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10885             {
10886               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10887                             &rx_sw_if_index))
10888                 rx_sw_if_index_set = 1;
10889             }
10890           else
10891             break;
10892         }
10893       else if (unformat (i, "tx"))
10894         {
10895           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10896             {
10897               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10898                             &tx_sw_if_index))
10899                 tx_sw_if_index_set = 1;
10900             }
10901           else
10902             break;
10903         }
10904       else if (unformat (i, "del"))
10905         is_add = 0;
10906       else
10907         break;
10908     }
10909
10910   if (rx_sw_if_index_set == 0)
10911     {
10912       errmsg ("missing rx interface name or rx_sw_if_index");
10913       return -99;
10914     }
10915
10916   if (tx_sw_if_index_set == 0)
10917     {
10918       errmsg ("missing tx interface name or tx_sw_if_index");
10919       return -99;
10920     }
10921
10922   M (L2_PATCH_ADD_DEL, mp);
10923
10924   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10925   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10926   mp->is_add = is_add;
10927
10928   S (mp);
10929   W (ret);
10930   return ret;
10931 }
10932
10933 u8 is_del;
10934 u8 localsid_addr[16];
10935 u8 end_psp;
10936 u8 behavior;
10937 u32 sw_if_index;
10938 u32 vlan_index;
10939 u32 fib_table;
10940 u8 nh_addr[16];
10941
10942 static int
10943 api_sr_localsid_add_del (vat_main_t * vam)
10944 {
10945   unformat_input_t *i = vam->input;
10946   vl_api_sr_localsid_add_del_t *mp;
10947
10948   u8 is_del;
10949   ip6_address_t localsid;
10950   u8 end_psp = 0;
10951   u8 behavior = ~0;
10952   u32 sw_if_index;
10953   u32 fib_table = ~(u32) 0;
10954   ip6_address_t nh_addr6;
10955   ip4_address_t nh_addr4;
10956   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10957   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10958
10959   bool nexthop_set = 0;
10960
10961   int ret;
10962
10963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10964     {
10965       if (unformat (i, "del"))
10966         is_del = 1;
10967       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10968       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10969         nexthop_set = 1;
10970       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10971         nexthop_set = 1;
10972       else if (unformat (i, "behavior %u", &behavior));
10973       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10974       else if (unformat (i, "fib-table %u", &fib_table));
10975       else if (unformat (i, "end.psp %u", &behavior));
10976       else
10977         break;
10978     }
10979
10980   M (SR_LOCALSID_ADD_DEL, mp);
10981
10982   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10983   if (nexthop_set)
10984     {
10985       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
10986       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
10987     }
10988   mp->behavior = behavior;
10989   mp->sw_if_index = ntohl (sw_if_index);
10990   mp->fib_table = ntohl (fib_table);
10991   mp->end_psp = end_psp;
10992   mp->is_del = is_del;
10993
10994   S (mp);
10995   W (ret);
10996   return ret;
10997 }
10998
10999 static int
11000 api_ioam_enable (vat_main_t * vam)
11001 {
11002   unformat_input_t *input = vam->input;
11003   vl_api_ioam_enable_t *mp;
11004   u32 id = 0;
11005   int has_trace_option = 0;
11006   int has_pot_option = 0;
11007   int has_seqno_option = 0;
11008   int has_analyse_option = 0;
11009   int ret;
11010
11011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11012     {
11013       if (unformat (input, "trace"))
11014         has_trace_option = 1;
11015       else if (unformat (input, "pot"))
11016         has_pot_option = 1;
11017       else if (unformat (input, "seqno"))
11018         has_seqno_option = 1;
11019       else if (unformat (input, "analyse"))
11020         has_analyse_option = 1;
11021       else
11022         break;
11023     }
11024   M (IOAM_ENABLE, mp);
11025   mp->id = htons (id);
11026   mp->seqno = has_seqno_option;
11027   mp->analyse = has_analyse_option;
11028   mp->pot_enable = has_pot_option;
11029   mp->trace_enable = has_trace_option;
11030
11031   S (mp);
11032   W (ret);
11033   return ret;
11034 }
11035
11036
11037 static int
11038 api_ioam_disable (vat_main_t * vam)
11039 {
11040   vl_api_ioam_disable_t *mp;
11041   int ret;
11042
11043   M (IOAM_DISABLE, mp);
11044   S (mp);
11045   W (ret);
11046   return ret;
11047 }
11048
11049 #define foreach_tcp_proto_field                 \
11050 _(src_port)                                     \
11051 _(dst_port)
11052
11053 #define foreach_udp_proto_field                 \
11054 _(src_port)                                     \
11055 _(dst_port)
11056
11057 #define foreach_ip4_proto_field                 \
11058 _(src_address)                                  \
11059 _(dst_address)                                  \
11060 _(tos)                                          \
11061 _(length)                                       \
11062 _(fragment_id)                                  \
11063 _(ttl)                                          \
11064 _(protocol)                                     \
11065 _(checksum)
11066
11067 typedef struct
11068 {
11069   u16 src_port, dst_port;
11070 } tcpudp_header_t;
11071
11072 #if VPP_API_TEST_BUILTIN == 0
11073 uword
11074 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11075 {
11076   u8 **maskp = va_arg (*args, u8 **);
11077   u8 *mask = 0;
11078   u8 found_something = 0;
11079   tcp_header_t *tcp;
11080
11081 #define _(a) u8 a=0;
11082   foreach_tcp_proto_field;
11083 #undef _
11084
11085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11086     {
11087       if (0);
11088 #define _(a) else if (unformat (input, #a)) a=1;
11089       foreach_tcp_proto_field
11090 #undef _
11091         else
11092         break;
11093     }
11094
11095 #define _(a) found_something += a;
11096   foreach_tcp_proto_field;
11097 #undef _
11098
11099   if (found_something == 0)
11100     return 0;
11101
11102   vec_validate (mask, sizeof (*tcp) - 1);
11103
11104   tcp = (tcp_header_t *) mask;
11105
11106 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11107   foreach_tcp_proto_field;
11108 #undef _
11109
11110   *maskp = mask;
11111   return 1;
11112 }
11113
11114 uword
11115 unformat_udp_mask (unformat_input_t * input, va_list * args)
11116 {
11117   u8 **maskp = va_arg (*args, u8 **);
11118   u8 *mask = 0;
11119   u8 found_something = 0;
11120   udp_header_t *udp;
11121
11122 #define _(a) u8 a=0;
11123   foreach_udp_proto_field;
11124 #undef _
11125
11126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11127     {
11128       if (0);
11129 #define _(a) else if (unformat (input, #a)) a=1;
11130       foreach_udp_proto_field
11131 #undef _
11132         else
11133         break;
11134     }
11135
11136 #define _(a) found_something += a;
11137   foreach_udp_proto_field;
11138 #undef _
11139
11140   if (found_something == 0)
11141     return 0;
11142
11143   vec_validate (mask, sizeof (*udp) - 1);
11144
11145   udp = (udp_header_t *) mask;
11146
11147 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11148   foreach_udp_proto_field;
11149 #undef _
11150
11151   *maskp = mask;
11152   return 1;
11153 }
11154
11155 uword
11156 unformat_l4_mask (unformat_input_t * input, va_list * args)
11157 {
11158   u8 **maskp = va_arg (*args, u8 **);
11159   u16 src_port = 0, dst_port = 0;
11160   tcpudp_header_t *tcpudp;
11161
11162   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11163     {
11164       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11165         return 1;
11166       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11167         return 1;
11168       else if (unformat (input, "src_port"))
11169         src_port = 0xFFFF;
11170       else if (unformat (input, "dst_port"))
11171         dst_port = 0xFFFF;
11172       else
11173         return 0;
11174     }
11175
11176   if (!src_port && !dst_port)
11177     return 0;
11178
11179   u8 *mask = 0;
11180   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11181
11182   tcpudp = (tcpudp_header_t *) mask;
11183   tcpudp->src_port = src_port;
11184   tcpudp->dst_port = dst_port;
11185
11186   *maskp = mask;
11187
11188   return 1;
11189 }
11190
11191 uword
11192 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11193 {
11194   u8 **maskp = va_arg (*args, u8 **);
11195   u8 *mask = 0;
11196   u8 found_something = 0;
11197   ip4_header_t *ip;
11198
11199 #define _(a) u8 a=0;
11200   foreach_ip4_proto_field;
11201 #undef _
11202   u8 version = 0;
11203   u8 hdr_length = 0;
11204
11205
11206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11207     {
11208       if (unformat (input, "version"))
11209         version = 1;
11210       else if (unformat (input, "hdr_length"))
11211         hdr_length = 1;
11212       else if (unformat (input, "src"))
11213         src_address = 1;
11214       else if (unformat (input, "dst"))
11215         dst_address = 1;
11216       else if (unformat (input, "proto"))
11217         protocol = 1;
11218
11219 #define _(a) else if (unformat (input, #a)) a=1;
11220       foreach_ip4_proto_field
11221 #undef _
11222         else
11223         break;
11224     }
11225
11226 #define _(a) found_something += a;
11227   foreach_ip4_proto_field;
11228 #undef _
11229
11230   if (found_something == 0)
11231     return 0;
11232
11233   vec_validate (mask, sizeof (*ip) - 1);
11234
11235   ip = (ip4_header_t *) mask;
11236
11237 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11238   foreach_ip4_proto_field;
11239 #undef _
11240
11241   ip->ip_version_and_header_length = 0;
11242
11243   if (version)
11244     ip->ip_version_and_header_length |= 0xF0;
11245
11246   if (hdr_length)
11247     ip->ip_version_and_header_length |= 0x0F;
11248
11249   *maskp = mask;
11250   return 1;
11251 }
11252
11253 #define foreach_ip6_proto_field                 \
11254 _(src_address)                                  \
11255 _(dst_address)                                  \
11256 _(payload_length)                               \
11257 _(hop_limit)                                    \
11258 _(protocol)
11259
11260 uword
11261 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11262 {
11263   u8 **maskp = va_arg (*args, u8 **);
11264   u8 *mask = 0;
11265   u8 found_something = 0;
11266   ip6_header_t *ip;
11267   u32 ip_version_traffic_class_and_flow_label;
11268
11269 #define _(a) u8 a=0;
11270   foreach_ip6_proto_field;
11271 #undef _
11272   u8 version = 0;
11273   u8 traffic_class = 0;
11274   u8 flow_label = 0;
11275
11276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11277     {
11278       if (unformat (input, "version"))
11279         version = 1;
11280       else if (unformat (input, "traffic-class"))
11281         traffic_class = 1;
11282       else if (unformat (input, "flow-label"))
11283         flow_label = 1;
11284       else if (unformat (input, "src"))
11285         src_address = 1;
11286       else if (unformat (input, "dst"))
11287         dst_address = 1;
11288       else if (unformat (input, "proto"))
11289         protocol = 1;
11290
11291 #define _(a) else if (unformat (input, #a)) a=1;
11292       foreach_ip6_proto_field
11293 #undef _
11294         else
11295         break;
11296     }
11297
11298 #define _(a) found_something += a;
11299   foreach_ip6_proto_field;
11300 #undef _
11301
11302   if (found_something == 0)
11303     return 0;
11304
11305   vec_validate (mask, sizeof (*ip) - 1);
11306
11307   ip = (ip6_header_t *) mask;
11308
11309 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11310   foreach_ip6_proto_field;
11311 #undef _
11312
11313   ip_version_traffic_class_and_flow_label = 0;
11314
11315   if (version)
11316     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11317
11318   if (traffic_class)
11319     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11320
11321   if (flow_label)
11322     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11323
11324   ip->ip_version_traffic_class_and_flow_label =
11325     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11326
11327   *maskp = mask;
11328   return 1;
11329 }
11330
11331 uword
11332 unformat_l3_mask (unformat_input_t * input, va_list * args)
11333 {
11334   u8 **maskp = va_arg (*args, u8 **);
11335
11336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11337     {
11338       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11339         return 1;
11340       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11341         return 1;
11342       else
11343         break;
11344     }
11345   return 0;
11346 }
11347
11348 uword
11349 unformat_l2_mask (unformat_input_t * input, va_list * args)
11350 {
11351   u8 **maskp = va_arg (*args, u8 **);
11352   u8 *mask = 0;
11353   u8 src = 0;
11354   u8 dst = 0;
11355   u8 proto = 0;
11356   u8 tag1 = 0;
11357   u8 tag2 = 0;
11358   u8 ignore_tag1 = 0;
11359   u8 ignore_tag2 = 0;
11360   u8 cos1 = 0;
11361   u8 cos2 = 0;
11362   u8 dot1q = 0;
11363   u8 dot1ad = 0;
11364   int len = 14;
11365
11366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11367     {
11368       if (unformat (input, "src"))
11369         src = 1;
11370       else if (unformat (input, "dst"))
11371         dst = 1;
11372       else if (unformat (input, "proto"))
11373         proto = 1;
11374       else if (unformat (input, "tag1"))
11375         tag1 = 1;
11376       else if (unformat (input, "tag2"))
11377         tag2 = 1;
11378       else if (unformat (input, "ignore-tag1"))
11379         ignore_tag1 = 1;
11380       else if (unformat (input, "ignore-tag2"))
11381         ignore_tag2 = 1;
11382       else if (unformat (input, "cos1"))
11383         cos1 = 1;
11384       else if (unformat (input, "cos2"))
11385         cos2 = 1;
11386       else if (unformat (input, "dot1q"))
11387         dot1q = 1;
11388       else if (unformat (input, "dot1ad"))
11389         dot1ad = 1;
11390       else
11391         break;
11392     }
11393   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11394        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11395     return 0;
11396
11397   if (tag1 || ignore_tag1 || cos1 || dot1q)
11398     len = 18;
11399   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11400     len = 22;
11401
11402   vec_validate (mask, len - 1);
11403
11404   if (dst)
11405     memset (mask, 0xff, 6);
11406
11407   if (src)
11408     memset (mask + 6, 0xff, 6);
11409
11410   if (tag2 || dot1ad)
11411     {
11412       /* inner vlan tag */
11413       if (tag2)
11414         {
11415           mask[19] = 0xff;
11416           mask[18] = 0x0f;
11417         }
11418       if (cos2)
11419         mask[18] |= 0xe0;
11420       if (proto)
11421         mask[21] = mask[20] = 0xff;
11422       if (tag1)
11423         {
11424           mask[15] = 0xff;
11425           mask[14] = 0x0f;
11426         }
11427       if (cos1)
11428         mask[14] |= 0xe0;
11429       *maskp = mask;
11430       return 1;
11431     }
11432   if (tag1 | dot1q)
11433     {
11434       if (tag1)
11435         {
11436           mask[15] = 0xff;
11437           mask[14] = 0x0f;
11438         }
11439       if (cos1)
11440         mask[14] |= 0xe0;
11441       if (proto)
11442         mask[16] = mask[17] = 0xff;
11443
11444       *maskp = mask;
11445       return 1;
11446     }
11447   if (cos2)
11448     mask[18] |= 0xe0;
11449   if (cos1)
11450     mask[14] |= 0xe0;
11451   if (proto)
11452     mask[12] = mask[13] = 0xff;
11453
11454   *maskp = mask;
11455   return 1;
11456 }
11457
11458 uword
11459 unformat_classify_mask (unformat_input_t * input, va_list * args)
11460 {
11461   u8 **maskp = va_arg (*args, u8 **);
11462   u32 *skipp = va_arg (*args, u32 *);
11463   u32 *matchp = va_arg (*args, u32 *);
11464   u32 match;
11465   u8 *mask = 0;
11466   u8 *l2 = 0;
11467   u8 *l3 = 0;
11468   u8 *l4 = 0;
11469   int i;
11470
11471   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11472     {
11473       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11474         ;
11475       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11476         ;
11477       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11478         ;
11479       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11480         ;
11481       else
11482         break;
11483     }
11484
11485   if (l4 && !l3)
11486     {
11487       vec_free (mask);
11488       vec_free (l2);
11489       vec_free (l4);
11490       return 0;
11491     }
11492
11493   if (mask || l2 || l3 || l4)
11494     {
11495       if (l2 || l3 || l4)
11496         {
11497           /* "With a free Ethernet header in every package" */
11498           if (l2 == 0)
11499             vec_validate (l2, 13);
11500           mask = l2;
11501           if (vec_len (l3))
11502             {
11503               vec_append (mask, l3);
11504               vec_free (l3);
11505             }
11506           if (vec_len (l4))
11507             {
11508               vec_append (mask, l4);
11509               vec_free (l4);
11510             }
11511         }
11512
11513       /* Scan forward looking for the first significant mask octet */
11514       for (i = 0; i < vec_len (mask); i++)
11515         if (mask[i])
11516           break;
11517
11518       /* compute (skip, match) params */
11519       *skipp = i / sizeof (u32x4);
11520       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11521
11522       /* Pad mask to an even multiple of the vector size */
11523       while (vec_len (mask) % sizeof (u32x4))
11524         vec_add1 (mask, 0);
11525
11526       match = vec_len (mask) / sizeof (u32x4);
11527
11528       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11529         {
11530           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11531           if (*tmp || *(tmp + 1))
11532             break;
11533           match--;
11534         }
11535       if (match == 0)
11536         clib_warning ("BUG: match 0");
11537
11538       _vec_len (mask) = match * sizeof (u32x4);
11539
11540       *matchp = match;
11541       *maskp = mask;
11542
11543       return 1;
11544     }
11545
11546   return 0;
11547 }
11548 #endif /* VPP_API_TEST_BUILTIN */
11549
11550 #define foreach_l2_next                         \
11551 _(drop, DROP)                                   \
11552 _(ethernet, ETHERNET_INPUT)                     \
11553 _(ip4, IP4_INPUT)                               \
11554 _(ip6, IP6_INPUT)
11555
11556 uword
11557 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11558 {
11559   u32 *miss_next_indexp = va_arg (*args, u32 *);
11560   u32 next_index = 0;
11561   u32 tmp;
11562
11563 #define _(n,N) \
11564   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11565   foreach_l2_next;
11566 #undef _
11567
11568   if (unformat (input, "%d", &tmp))
11569     {
11570       next_index = tmp;
11571       goto out;
11572     }
11573
11574   return 0;
11575
11576 out:
11577   *miss_next_indexp = next_index;
11578   return 1;
11579 }
11580
11581 #define foreach_ip_next                         \
11582 _(drop, DROP)                                   \
11583 _(local, LOCAL)                                 \
11584 _(rewrite, REWRITE)
11585
11586 uword
11587 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11588 {
11589   u32 *miss_next_indexp = va_arg (*args, u32 *);
11590   u32 next_index = 0;
11591   u32 tmp;
11592
11593 #define _(n,N) \
11594   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11595   foreach_ip_next;
11596 #undef _
11597
11598   if (unformat (input, "%d", &tmp))
11599     {
11600       next_index = tmp;
11601       goto out;
11602     }
11603
11604   return 0;
11605
11606 out:
11607   *miss_next_indexp = next_index;
11608   return 1;
11609 }
11610
11611 #define foreach_acl_next                        \
11612 _(deny, DENY)
11613
11614 uword
11615 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11616 {
11617   u32 *miss_next_indexp = va_arg (*args, u32 *);
11618   u32 next_index = 0;
11619   u32 tmp;
11620
11621 #define _(n,N) \
11622   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11623   foreach_acl_next;
11624 #undef _
11625
11626   if (unformat (input, "permit"))
11627     {
11628       next_index = ~0;
11629       goto out;
11630     }
11631   else if (unformat (input, "%d", &tmp))
11632     {
11633       next_index = tmp;
11634       goto out;
11635     }
11636
11637   return 0;
11638
11639 out:
11640   *miss_next_indexp = next_index;
11641   return 1;
11642 }
11643
11644 uword
11645 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11646 {
11647   u32 *r = va_arg (*args, u32 *);
11648
11649   if (unformat (input, "conform-color"))
11650     *r = POLICE_CONFORM;
11651   else if (unformat (input, "exceed-color"))
11652     *r = POLICE_EXCEED;
11653   else
11654     return 0;
11655
11656   return 1;
11657 }
11658
11659 static int
11660 api_classify_add_del_table (vat_main_t * vam)
11661 {
11662   unformat_input_t *i = vam->input;
11663   vl_api_classify_add_del_table_t *mp;
11664
11665   u32 nbuckets = 2;
11666   u32 skip = ~0;
11667   u32 match = ~0;
11668   int is_add = 1;
11669   int del_chain = 0;
11670   u32 table_index = ~0;
11671   u32 next_table_index = ~0;
11672   u32 miss_next_index = ~0;
11673   u32 memory_size = 32 << 20;
11674   u8 *mask = 0;
11675   u32 current_data_flag = 0;
11676   int current_data_offset = 0;
11677   int ret;
11678
11679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11680     {
11681       if (unformat (i, "del"))
11682         is_add = 0;
11683       else if (unformat (i, "del-chain"))
11684         {
11685           is_add = 0;
11686           del_chain = 1;
11687         }
11688       else if (unformat (i, "buckets %d", &nbuckets))
11689         ;
11690       else if (unformat (i, "memory_size %d", &memory_size))
11691         ;
11692       else if (unformat (i, "skip %d", &skip))
11693         ;
11694       else if (unformat (i, "match %d", &match))
11695         ;
11696       else if (unformat (i, "table %d", &table_index))
11697         ;
11698       else if (unformat (i, "mask %U", unformat_classify_mask,
11699                          &mask, &skip, &match))
11700         ;
11701       else if (unformat (i, "next-table %d", &next_table_index))
11702         ;
11703       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11704                          &miss_next_index))
11705         ;
11706       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11707                          &miss_next_index))
11708         ;
11709       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11710                          &miss_next_index))
11711         ;
11712       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11713         ;
11714       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11715         ;
11716       else
11717         break;
11718     }
11719
11720   if (is_add && mask == 0)
11721     {
11722       errmsg ("Mask required");
11723       return -99;
11724     }
11725
11726   if (is_add && skip == ~0)
11727     {
11728       errmsg ("skip count required");
11729       return -99;
11730     }
11731
11732   if (is_add && match == ~0)
11733     {
11734       errmsg ("match count required");
11735       return -99;
11736     }
11737
11738   if (!is_add && table_index == ~0)
11739     {
11740       errmsg ("table index required for delete");
11741       return -99;
11742     }
11743
11744   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11745
11746   mp->is_add = is_add;
11747   mp->del_chain = del_chain;
11748   mp->table_index = ntohl (table_index);
11749   mp->nbuckets = ntohl (nbuckets);
11750   mp->memory_size = ntohl (memory_size);
11751   mp->skip_n_vectors = ntohl (skip);
11752   mp->match_n_vectors = ntohl (match);
11753   mp->next_table_index = ntohl (next_table_index);
11754   mp->miss_next_index = ntohl (miss_next_index);
11755   mp->current_data_flag = ntohl (current_data_flag);
11756   mp->current_data_offset = ntohl (current_data_offset);
11757   mp->mask_len = ntohl (vec_len (mask));
11758   clib_memcpy (mp->mask, mask, vec_len (mask));
11759
11760   vec_free (mask);
11761
11762   S (mp);
11763   W (ret);
11764   return ret;
11765 }
11766
11767 #if VPP_API_TEST_BUILTIN == 0
11768 uword
11769 unformat_l4_match (unformat_input_t * input, va_list * args)
11770 {
11771   u8 **matchp = va_arg (*args, u8 **);
11772
11773   u8 *proto_header = 0;
11774   int src_port = 0;
11775   int dst_port = 0;
11776
11777   tcpudp_header_t h;
11778
11779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11780     {
11781       if (unformat (input, "src_port %d", &src_port))
11782         ;
11783       else if (unformat (input, "dst_port %d", &dst_port))
11784         ;
11785       else
11786         return 0;
11787     }
11788
11789   h.src_port = clib_host_to_net_u16 (src_port);
11790   h.dst_port = clib_host_to_net_u16 (dst_port);
11791   vec_validate (proto_header, sizeof (h) - 1);
11792   memcpy (proto_header, &h, sizeof (h));
11793
11794   *matchp = proto_header;
11795
11796   return 1;
11797 }
11798
11799 uword
11800 unformat_ip4_match (unformat_input_t * input, va_list * args)
11801 {
11802   u8 **matchp = va_arg (*args, u8 **);
11803   u8 *match = 0;
11804   ip4_header_t *ip;
11805   int version = 0;
11806   u32 version_val;
11807   int hdr_length = 0;
11808   u32 hdr_length_val;
11809   int src = 0, dst = 0;
11810   ip4_address_t src_val, dst_val;
11811   int proto = 0;
11812   u32 proto_val;
11813   int tos = 0;
11814   u32 tos_val;
11815   int length = 0;
11816   u32 length_val;
11817   int fragment_id = 0;
11818   u32 fragment_id_val;
11819   int ttl = 0;
11820   int ttl_val;
11821   int checksum = 0;
11822   u32 checksum_val;
11823
11824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11825     {
11826       if (unformat (input, "version %d", &version_val))
11827         version = 1;
11828       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11829         hdr_length = 1;
11830       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11831         src = 1;
11832       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11833         dst = 1;
11834       else if (unformat (input, "proto %d", &proto_val))
11835         proto = 1;
11836       else if (unformat (input, "tos %d", &tos_val))
11837         tos = 1;
11838       else if (unformat (input, "length %d", &length_val))
11839         length = 1;
11840       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11841         fragment_id = 1;
11842       else if (unformat (input, "ttl %d", &ttl_val))
11843         ttl = 1;
11844       else if (unformat (input, "checksum %d", &checksum_val))
11845         checksum = 1;
11846       else
11847         break;
11848     }
11849
11850   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11851       + ttl + checksum == 0)
11852     return 0;
11853
11854   /*
11855    * Aligned because we use the real comparison functions
11856    */
11857   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11858
11859   ip = (ip4_header_t *) match;
11860
11861   /* These are realistically matched in practice */
11862   if (src)
11863     ip->src_address.as_u32 = src_val.as_u32;
11864
11865   if (dst)
11866     ip->dst_address.as_u32 = dst_val.as_u32;
11867
11868   if (proto)
11869     ip->protocol = proto_val;
11870
11871
11872   /* These are not, but they're included for completeness */
11873   if (version)
11874     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11875
11876   if (hdr_length)
11877     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11878
11879   if (tos)
11880     ip->tos = tos_val;
11881
11882   if (length)
11883     ip->length = clib_host_to_net_u16 (length_val);
11884
11885   if (ttl)
11886     ip->ttl = ttl_val;
11887
11888   if (checksum)
11889     ip->checksum = clib_host_to_net_u16 (checksum_val);
11890
11891   *matchp = match;
11892   return 1;
11893 }
11894
11895 uword
11896 unformat_ip6_match (unformat_input_t * input, va_list * args)
11897 {
11898   u8 **matchp = va_arg (*args, u8 **);
11899   u8 *match = 0;
11900   ip6_header_t *ip;
11901   int version = 0;
11902   u32 version_val;
11903   u8 traffic_class = 0;
11904   u32 traffic_class_val = 0;
11905   u8 flow_label = 0;
11906   u8 flow_label_val;
11907   int src = 0, dst = 0;
11908   ip6_address_t src_val, dst_val;
11909   int proto = 0;
11910   u32 proto_val;
11911   int payload_length = 0;
11912   u32 payload_length_val;
11913   int hop_limit = 0;
11914   int hop_limit_val;
11915   u32 ip_version_traffic_class_and_flow_label;
11916
11917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (input, "version %d", &version_val))
11920         version = 1;
11921       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11922         traffic_class = 1;
11923       else if (unformat (input, "flow_label %d", &flow_label_val))
11924         flow_label = 1;
11925       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11926         src = 1;
11927       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11928         dst = 1;
11929       else if (unformat (input, "proto %d", &proto_val))
11930         proto = 1;
11931       else if (unformat (input, "payload_length %d", &payload_length_val))
11932         payload_length = 1;
11933       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11934         hop_limit = 1;
11935       else
11936         break;
11937     }
11938
11939   if (version + traffic_class + flow_label + src + dst + proto +
11940       payload_length + hop_limit == 0)
11941     return 0;
11942
11943   /*
11944    * Aligned because we use the real comparison functions
11945    */
11946   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11947
11948   ip = (ip6_header_t *) match;
11949
11950   if (src)
11951     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11952
11953   if (dst)
11954     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11955
11956   if (proto)
11957     ip->protocol = proto_val;
11958
11959   ip_version_traffic_class_and_flow_label = 0;
11960
11961   if (version)
11962     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11963
11964   if (traffic_class)
11965     ip_version_traffic_class_and_flow_label |=
11966       (traffic_class_val & 0xFF) << 20;
11967
11968   if (flow_label)
11969     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11970
11971   ip->ip_version_traffic_class_and_flow_label =
11972     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11973
11974   if (payload_length)
11975     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11976
11977   if (hop_limit)
11978     ip->hop_limit = hop_limit_val;
11979
11980   *matchp = match;
11981   return 1;
11982 }
11983
11984 uword
11985 unformat_l3_match (unformat_input_t * input, va_list * args)
11986 {
11987   u8 **matchp = va_arg (*args, u8 **);
11988
11989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11990     {
11991       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11992         return 1;
11993       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11994         return 1;
11995       else
11996         break;
11997     }
11998   return 0;
11999 }
12000
12001 uword
12002 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12003 {
12004   u8 *tagp = va_arg (*args, u8 *);
12005   u32 tag;
12006
12007   if (unformat (input, "%d", &tag))
12008     {
12009       tagp[0] = (tag >> 8) & 0x0F;
12010       tagp[1] = tag & 0xFF;
12011       return 1;
12012     }
12013
12014   return 0;
12015 }
12016
12017 uword
12018 unformat_l2_match (unformat_input_t * input, va_list * args)
12019 {
12020   u8 **matchp = va_arg (*args, u8 **);
12021   u8 *match = 0;
12022   u8 src = 0;
12023   u8 src_val[6];
12024   u8 dst = 0;
12025   u8 dst_val[6];
12026   u8 proto = 0;
12027   u16 proto_val;
12028   u8 tag1 = 0;
12029   u8 tag1_val[2];
12030   u8 tag2 = 0;
12031   u8 tag2_val[2];
12032   int len = 14;
12033   u8 ignore_tag1 = 0;
12034   u8 ignore_tag2 = 0;
12035   u8 cos1 = 0;
12036   u8 cos2 = 0;
12037   u32 cos1_val = 0;
12038   u32 cos2_val = 0;
12039
12040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12041     {
12042       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12043         src = 1;
12044       else
12045         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12046         dst = 1;
12047       else if (unformat (input, "proto %U",
12048                          unformat_ethernet_type_host_byte_order, &proto_val))
12049         proto = 1;
12050       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12051         tag1 = 1;
12052       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12053         tag2 = 1;
12054       else if (unformat (input, "ignore-tag1"))
12055         ignore_tag1 = 1;
12056       else if (unformat (input, "ignore-tag2"))
12057         ignore_tag2 = 1;
12058       else if (unformat (input, "cos1 %d", &cos1_val))
12059         cos1 = 1;
12060       else if (unformat (input, "cos2 %d", &cos2_val))
12061         cos2 = 1;
12062       else
12063         break;
12064     }
12065   if ((src + dst + proto + tag1 + tag2 +
12066        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12067     return 0;
12068
12069   if (tag1 || ignore_tag1 || cos1)
12070     len = 18;
12071   if (tag2 || ignore_tag2 || cos2)
12072     len = 22;
12073
12074   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12075
12076   if (dst)
12077     clib_memcpy (match, dst_val, 6);
12078
12079   if (src)
12080     clib_memcpy (match + 6, src_val, 6);
12081
12082   if (tag2)
12083     {
12084       /* inner vlan tag */
12085       match[19] = tag2_val[1];
12086       match[18] = tag2_val[0];
12087       if (cos2)
12088         match[18] |= (cos2_val & 0x7) << 5;
12089       if (proto)
12090         {
12091           match[21] = proto_val & 0xff;
12092           match[20] = proto_val >> 8;
12093         }
12094       if (tag1)
12095         {
12096           match[15] = tag1_val[1];
12097           match[14] = tag1_val[0];
12098         }
12099       if (cos1)
12100         match[14] |= (cos1_val & 0x7) << 5;
12101       *matchp = match;
12102       return 1;
12103     }
12104   if (tag1)
12105     {
12106       match[15] = tag1_val[1];
12107       match[14] = tag1_val[0];
12108       if (proto)
12109         {
12110           match[17] = proto_val & 0xff;
12111           match[16] = proto_val >> 8;
12112         }
12113       if (cos1)
12114         match[14] |= (cos1_val & 0x7) << 5;
12115
12116       *matchp = match;
12117       return 1;
12118     }
12119   if (cos2)
12120     match[18] |= (cos2_val & 0x7) << 5;
12121   if (cos1)
12122     match[14] |= (cos1_val & 0x7) << 5;
12123   if (proto)
12124     {
12125       match[13] = proto_val & 0xff;
12126       match[12] = proto_val >> 8;
12127     }
12128
12129   *matchp = match;
12130   return 1;
12131 }
12132
12133 uword
12134 unformat_qos_source (unformat_input_t * input, va_list * args)
12135 {
12136   int *qs = va_arg (*args, int *);
12137
12138   if (unformat (input, "ip"))
12139     *qs = QOS_SOURCE_IP;
12140   else if (unformat (input, "mpls"))
12141     *qs = QOS_SOURCE_MPLS;
12142   else if (unformat (input, "ext"))
12143     *qs = QOS_SOURCE_EXT;
12144   else if (unformat (input, "vlan"))
12145     *qs = QOS_SOURCE_VLAN;
12146   else
12147     return 0;
12148
12149   return 1;
12150 }
12151 #endif
12152
12153 uword
12154 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12155 {
12156   u8 **matchp = va_arg (*args, u8 **);
12157   u32 skip_n_vectors = va_arg (*args, u32);
12158   u32 match_n_vectors = va_arg (*args, u32);
12159
12160   u8 *match = 0;
12161   u8 *l2 = 0;
12162   u8 *l3 = 0;
12163   u8 *l4 = 0;
12164
12165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12166     {
12167       if (unformat (input, "hex %U", unformat_hex_string, &match))
12168         ;
12169       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12170         ;
12171       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12172         ;
12173       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12174         ;
12175       else
12176         break;
12177     }
12178
12179   if (l4 && !l3)
12180     {
12181       vec_free (match);
12182       vec_free (l2);
12183       vec_free (l4);
12184       return 0;
12185     }
12186
12187   if (match || l2 || l3 || l4)
12188     {
12189       if (l2 || l3 || l4)
12190         {
12191           /* "Win a free Ethernet header in every packet" */
12192           if (l2 == 0)
12193             vec_validate_aligned (l2, 13, sizeof (u32x4));
12194           match = l2;
12195           if (vec_len (l3))
12196             {
12197               vec_append_aligned (match, l3, sizeof (u32x4));
12198               vec_free (l3);
12199             }
12200           if (vec_len (l4))
12201             {
12202               vec_append_aligned (match, l4, sizeof (u32x4));
12203               vec_free (l4);
12204             }
12205         }
12206
12207       /* Make sure the vector is big enough even if key is all 0's */
12208       vec_validate_aligned
12209         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12210          sizeof (u32x4));
12211
12212       /* Set size, include skipped vectors */
12213       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12214
12215       *matchp = match;
12216
12217       return 1;
12218     }
12219
12220   return 0;
12221 }
12222
12223 static int
12224 api_classify_add_del_session (vat_main_t * vam)
12225 {
12226   unformat_input_t *i = vam->input;
12227   vl_api_classify_add_del_session_t *mp;
12228   int is_add = 1;
12229   u32 table_index = ~0;
12230   u32 hit_next_index = ~0;
12231   u32 opaque_index = ~0;
12232   u8 *match = 0;
12233   i32 advance = 0;
12234   u32 skip_n_vectors = 0;
12235   u32 match_n_vectors = 0;
12236   u32 action = 0;
12237   u32 metadata = 0;
12238   int ret;
12239
12240   /*
12241    * Warning: you have to supply skip_n and match_n
12242    * because the API client cant simply look at the classify
12243    * table object.
12244    */
12245
12246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (i, "del"))
12249         is_add = 0;
12250       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12251                          &hit_next_index))
12252         ;
12253       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12254                          &hit_next_index))
12255         ;
12256       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12257                          &hit_next_index))
12258         ;
12259       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12260         ;
12261       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12262         ;
12263       else if (unformat (i, "opaque-index %d", &opaque_index))
12264         ;
12265       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12266         ;
12267       else if (unformat (i, "match_n %d", &match_n_vectors))
12268         ;
12269       else if (unformat (i, "match %U", api_unformat_classify_match,
12270                          &match, skip_n_vectors, match_n_vectors))
12271         ;
12272       else if (unformat (i, "advance %d", &advance))
12273         ;
12274       else if (unformat (i, "table-index %d", &table_index))
12275         ;
12276       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12277         action = 1;
12278       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12279         action = 2;
12280       else if (unformat (i, "action %d", &action))
12281         ;
12282       else if (unformat (i, "metadata %d", &metadata))
12283         ;
12284       else
12285         break;
12286     }
12287
12288   if (table_index == ~0)
12289     {
12290       errmsg ("Table index required");
12291       return -99;
12292     }
12293
12294   if (is_add && match == 0)
12295     {
12296       errmsg ("Match value required");
12297       return -99;
12298     }
12299
12300   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12301
12302   mp->is_add = is_add;
12303   mp->table_index = ntohl (table_index);
12304   mp->hit_next_index = ntohl (hit_next_index);
12305   mp->opaque_index = ntohl (opaque_index);
12306   mp->advance = ntohl (advance);
12307   mp->action = action;
12308   mp->metadata = ntohl (metadata);
12309   mp->match_len = ntohl (vec_len (match));
12310   clib_memcpy (mp->match, match, vec_len (match));
12311   vec_free (match);
12312
12313   S (mp);
12314   W (ret);
12315   return ret;
12316 }
12317
12318 static int
12319 api_classify_set_interface_ip_table (vat_main_t * vam)
12320 {
12321   unformat_input_t *i = vam->input;
12322   vl_api_classify_set_interface_ip_table_t *mp;
12323   u32 sw_if_index;
12324   int sw_if_index_set;
12325   u32 table_index = ~0;
12326   u8 is_ipv6 = 0;
12327   int ret;
12328
12329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12332         sw_if_index_set = 1;
12333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12334         sw_if_index_set = 1;
12335       else if (unformat (i, "table %d", &table_index))
12336         ;
12337       else
12338         {
12339           clib_warning ("parse error '%U'", format_unformat_error, i);
12340           return -99;
12341         }
12342     }
12343
12344   if (sw_if_index_set == 0)
12345     {
12346       errmsg ("missing interface name or sw_if_index");
12347       return -99;
12348     }
12349
12350
12351   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12352
12353   mp->sw_if_index = ntohl (sw_if_index);
12354   mp->table_index = ntohl (table_index);
12355   mp->is_ipv6 = is_ipv6;
12356
12357   S (mp);
12358   W (ret);
12359   return ret;
12360 }
12361
12362 static int
12363 api_classify_set_interface_l2_tables (vat_main_t * vam)
12364 {
12365   unformat_input_t *i = vam->input;
12366   vl_api_classify_set_interface_l2_tables_t *mp;
12367   u32 sw_if_index;
12368   int sw_if_index_set;
12369   u32 ip4_table_index = ~0;
12370   u32 ip6_table_index = ~0;
12371   u32 other_table_index = ~0;
12372   u32 is_input = 1;
12373   int ret;
12374
12375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12376     {
12377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12378         sw_if_index_set = 1;
12379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12380         sw_if_index_set = 1;
12381       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12382         ;
12383       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12384         ;
12385       else if (unformat (i, "other-table %d", &other_table_index))
12386         ;
12387       else if (unformat (i, "is-input %d", &is_input))
12388         ;
12389       else
12390         {
12391           clib_warning ("parse error '%U'", format_unformat_error, i);
12392           return -99;
12393         }
12394     }
12395
12396   if (sw_if_index_set == 0)
12397     {
12398       errmsg ("missing interface name or sw_if_index");
12399       return -99;
12400     }
12401
12402
12403   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12404
12405   mp->sw_if_index = ntohl (sw_if_index);
12406   mp->ip4_table_index = ntohl (ip4_table_index);
12407   mp->ip6_table_index = ntohl (ip6_table_index);
12408   mp->other_table_index = ntohl (other_table_index);
12409   mp->is_input = (u8) is_input;
12410
12411   S (mp);
12412   W (ret);
12413   return ret;
12414 }
12415
12416 static int
12417 api_set_ipfix_exporter (vat_main_t * vam)
12418 {
12419   unformat_input_t *i = vam->input;
12420   vl_api_set_ipfix_exporter_t *mp;
12421   ip4_address_t collector_address;
12422   u8 collector_address_set = 0;
12423   u32 collector_port = ~0;
12424   ip4_address_t src_address;
12425   u8 src_address_set = 0;
12426   u32 vrf_id = ~0;
12427   u32 path_mtu = ~0;
12428   u32 template_interval = ~0;
12429   u8 udp_checksum = 0;
12430   int ret;
12431
12432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12433     {
12434       if (unformat (i, "collector_address %U", unformat_ip4_address,
12435                     &collector_address))
12436         collector_address_set = 1;
12437       else if (unformat (i, "collector_port %d", &collector_port))
12438         ;
12439       else if (unformat (i, "src_address %U", unformat_ip4_address,
12440                          &src_address))
12441         src_address_set = 1;
12442       else if (unformat (i, "vrf_id %d", &vrf_id))
12443         ;
12444       else if (unformat (i, "path_mtu %d", &path_mtu))
12445         ;
12446       else if (unformat (i, "template_interval %d", &template_interval))
12447         ;
12448       else if (unformat (i, "udp_checksum"))
12449         udp_checksum = 1;
12450       else
12451         break;
12452     }
12453
12454   if (collector_address_set == 0)
12455     {
12456       errmsg ("collector_address required");
12457       return -99;
12458     }
12459
12460   if (src_address_set == 0)
12461     {
12462       errmsg ("src_address required");
12463       return -99;
12464     }
12465
12466   M (SET_IPFIX_EXPORTER, mp);
12467
12468   memcpy (mp->collector_address, collector_address.data,
12469           sizeof (collector_address.data));
12470   mp->collector_port = htons ((u16) collector_port);
12471   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12472   mp->vrf_id = htonl (vrf_id);
12473   mp->path_mtu = htonl (path_mtu);
12474   mp->template_interval = htonl (template_interval);
12475   mp->udp_checksum = udp_checksum;
12476
12477   S (mp);
12478   W (ret);
12479   return ret;
12480 }
12481
12482 static int
12483 api_set_ipfix_classify_stream (vat_main_t * vam)
12484 {
12485   unformat_input_t *i = vam->input;
12486   vl_api_set_ipfix_classify_stream_t *mp;
12487   u32 domain_id = 0;
12488   u32 src_port = UDP_DST_PORT_ipfix;
12489   int ret;
12490
12491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12492     {
12493       if (unformat (i, "domain %d", &domain_id))
12494         ;
12495       else if (unformat (i, "src_port %d", &src_port))
12496         ;
12497       else
12498         {
12499           errmsg ("unknown input `%U'", format_unformat_error, i);
12500           return -99;
12501         }
12502     }
12503
12504   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12505
12506   mp->domain_id = htonl (domain_id);
12507   mp->src_port = htons ((u16) src_port);
12508
12509   S (mp);
12510   W (ret);
12511   return ret;
12512 }
12513
12514 static int
12515 api_ipfix_classify_table_add_del (vat_main_t * vam)
12516 {
12517   unformat_input_t *i = vam->input;
12518   vl_api_ipfix_classify_table_add_del_t *mp;
12519   int is_add = -1;
12520   u32 classify_table_index = ~0;
12521   u8 ip_version = 0;
12522   u8 transport_protocol = 255;
12523   int ret;
12524
12525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12526     {
12527       if (unformat (i, "add"))
12528         is_add = 1;
12529       else if (unformat (i, "del"))
12530         is_add = 0;
12531       else if (unformat (i, "table %d", &classify_table_index))
12532         ;
12533       else if (unformat (i, "ip4"))
12534         ip_version = 4;
12535       else if (unformat (i, "ip6"))
12536         ip_version = 6;
12537       else if (unformat (i, "tcp"))
12538         transport_protocol = 6;
12539       else if (unformat (i, "udp"))
12540         transport_protocol = 17;
12541       else
12542         {
12543           errmsg ("unknown input `%U'", format_unformat_error, i);
12544           return -99;
12545         }
12546     }
12547
12548   if (is_add == -1)
12549     {
12550       errmsg ("expecting: add|del");
12551       return -99;
12552     }
12553   if (classify_table_index == ~0)
12554     {
12555       errmsg ("classifier table not specified");
12556       return -99;
12557     }
12558   if (ip_version == 0)
12559     {
12560       errmsg ("IP version not specified");
12561       return -99;
12562     }
12563
12564   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12565
12566   mp->is_add = is_add;
12567   mp->table_id = htonl (classify_table_index);
12568   mp->ip_version = ip_version;
12569   mp->transport_protocol = transport_protocol;
12570
12571   S (mp);
12572   W (ret);
12573   return ret;
12574 }
12575
12576 static int
12577 api_get_node_index (vat_main_t * vam)
12578 {
12579   unformat_input_t *i = vam->input;
12580   vl_api_get_node_index_t *mp;
12581   u8 *name = 0;
12582   int ret;
12583
12584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12585     {
12586       if (unformat (i, "node %s", &name))
12587         ;
12588       else
12589         break;
12590     }
12591   if (name == 0)
12592     {
12593       errmsg ("node name required");
12594       return -99;
12595     }
12596   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12597     {
12598       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12599       return -99;
12600     }
12601
12602   M (GET_NODE_INDEX, mp);
12603   clib_memcpy (mp->node_name, name, vec_len (name));
12604   vec_free (name);
12605
12606   S (mp);
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_get_next_index (vat_main_t * vam)
12613 {
12614   unformat_input_t *i = vam->input;
12615   vl_api_get_next_index_t *mp;
12616   u8 *node_name = 0, *next_node_name = 0;
12617   int ret;
12618
12619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12620     {
12621       if (unformat (i, "node-name %s", &node_name))
12622         ;
12623       else if (unformat (i, "next-node-name %s", &next_node_name))
12624         break;
12625     }
12626
12627   if (node_name == 0)
12628     {
12629       errmsg ("node name required");
12630       return -99;
12631     }
12632   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12633     {
12634       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12635       return -99;
12636     }
12637
12638   if (next_node_name == 0)
12639     {
12640       errmsg ("next node name required");
12641       return -99;
12642     }
12643   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12644     {
12645       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12646       return -99;
12647     }
12648
12649   M (GET_NEXT_INDEX, mp);
12650   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12651   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12652   vec_free (node_name);
12653   vec_free (next_node_name);
12654
12655   S (mp);
12656   W (ret);
12657   return ret;
12658 }
12659
12660 static int
12661 api_add_node_next (vat_main_t * vam)
12662 {
12663   unformat_input_t *i = vam->input;
12664   vl_api_add_node_next_t *mp;
12665   u8 *name = 0;
12666   u8 *next = 0;
12667   int ret;
12668
12669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12670     {
12671       if (unformat (i, "node %s", &name))
12672         ;
12673       else if (unformat (i, "next %s", &next))
12674         ;
12675       else
12676         break;
12677     }
12678   if (name == 0)
12679     {
12680       errmsg ("node name required");
12681       return -99;
12682     }
12683   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12684     {
12685       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12686       return -99;
12687     }
12688   if (next == 0)
12689     {
12690       errmsg ("next node required");
12691       return -99;
12692     }
12693   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12694     {
12695       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12696       return -99;
12697     }
12698
12699   M (ADD_NODE_NEXT, mp);
12700   clib_memcpy (mp->node_name, name, vec_len (name));
12701   clib_memcpy (mp->next_name, next, vec_len (next));
12702   vec_free (name);
12703   vec_free (next);
12704
12705   S (mp);
12706   W (ret);
12707   return ret;
12708 }
12709
12710 static int
12711 api_l2tpv3_create_tunnel (vat_main_t * vam)
12712 {
12713   unformat_input_t *i = vam->input;
12714   ip6_address_t client_address, our_address;
12715   int client_address_set = 0;
12716   int our_address_set = 0;
12717   u32 local_session_id = 0;
12718   u32 remote_session_id = 0;
12719   u64 local_cookie = 0;
12720   u64 remote_cookie = 0;
12721   u8 l2_sublayer_present = 0;
12722   vl_api_l2tpv3_create_tunnel_t *mp;
12723   int ret;
12724
12725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12726     {
12727       if (unformat (i, "client_address %U", unformat_ip6_address,
12728                     &client_address))
12729         client_address_set = 1;
12730       else if (unformat (i, "our_address %U", unformat_ip6_address,
12731                          &our_address))
12732         our_address_set = 1;
12733       else if (unformat (i, "local_session_id %d", &local_session_id))
12734         ;
12735       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12736         ;
12737       else if (unformat (i, "local_cookie %lld", &local_cookie))
12738         ;
12739       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12740         ;
12741       else if (unformat (i, "l2-sublayer-present"))
12742         l2_sublayer_present = 1;
12743       else
12744         break;
12745     }
12746
12747   if (client_address_set == 0)
12748     {
12749       errmsg ("client_address required");
12750       return -99;
12751     }
12752
12753   if (our_address_set == 0)
12754     {
12755       errmsg ("our_address required");
12756       return -99;
12757     }
12758
12759   M (L2TPV3_CREATE_TUNNEL, mp);
12760
12761   clib_memcpy (mp->client_address, client_address.as_u8,
12762                sizeof (mp->client_address));
12763
12764   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12765
12766   mp->local_session_id = ntohl (local_session_id);
12767   mp->remote_session_id = ntohl (remote_session_id);
12768   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12769   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12770   mp->l2_sublayer_present = l2_sublayer_present;
12771   mp->is_ipv6 = 1;
12772
12773   S (mp);
12774   W (ret);
12775   return ret;
12776 }
12777
12778 static int
12779 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12780 {
12781   unformat_input_t *i = vam->input;
12782   u32 sw_if_index;
12783   u8 sw_if_index_set = 0;
12784   u64 new_local_cookie = 0;
12785   u64 new_remote_cookie = 0;
12786   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12787   int ret;
12788
12789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12790     {
12791       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12792         sw_if_index_set = 1;
12793       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12794         sw_if_index_set = 1;
12795       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12796         ;
12797       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12798         ;
12799       else
12800         break;
12801     }
12802
12803   if (sw_if_index_set == 0)
12804     {
12805       errmsg ("missing interface name or sw_if_index");
12806       return -99;
12807     }
12808
12809   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12810
12811   mp->sw_if_index = ntohl (sw_if_index);
12812   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12813   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12814
12815   S (mp);
12816   W (ret);
12817   return ret;
12818 }
12819
12820 static int
12821 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12822 {
12823   unformat_input_t *i = vam->input;
12824   vl_api_l2tpv3_interface_enable_disable_t *mp;
12825   u32 sw_if_index;
12826   u8 sw_if_index_set = 0;
12827   u8 enable_disable = 1;
12828   int ret;
12829
12830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12831     {
12832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12833         sw_if_index_set = 1;
12834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12835         sw_if_index_set = 1;
12836       else if (unformat (i, "enable"))
12837         enable_disable = 1;
12838       else if (unformat (i, "disable"))
12839         enable_disable = 0;
12840       else
12841         break;
12842     }
12843
12844   if (sw_if_index_set == 0)
12845     {
12846       errmsg ("missing interface name or sw_if_index");
12847       return -99;
12848     }
12849
12850   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12851
12852   mp->sw_if_index = ntohl (sw_if_index);
12853   mp->enable_disable = enable_disable;
12854
12855   S (mp);
12856   W (ret);
12857   return ret;
12858 }
12859
12860 static int
12861 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12862 {
12863   unformat_input_t *i = vam->input;
12864   vl_api_l2tpv3_set_lookup_key_t *mp;
12865   u8 key = ~0;
12866   int ret;
12867
12868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12869     {
12870       if (unformat (i, "lookup_v6_src"))
12871         key = L2T_LOOKUP_SRC_ADDRESS;
12872       else if (unformat (i, "lookup_v6_dst"))
12873         key = L2T_LOOKUP_DST_ADDRESS;
12874       else if (unformat (i, "lookup_session_id"))
12875         key = L2T_LOOKUP_SESSION_ID;
12876       else
12877         break;
12878     }
12879
12880   if (key == (u8) ~ 0)
12881     {
12882       errmsg ("l2tp session lookup key unset");
12883       return -99;
12884     }
12885
12886   M (L2TPV3_SET_LOOKUP_KEY, mp);
12887
12888   mp->key = key;
12889
12890   S (mp);
12891   W (ret);
12892   return ret;
12893 }
12894
12895 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12896   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12897 {
12898   vat_main_t *vam = &vat_main;
12899
12900   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12901          format_ip6_address, mp->our_address,
12902          format_ip6_address, mp->client_address,
12903          clib_net_to_host_u32 (mp->sw_if_index));
12904
12905   print (vam->ofp,
12906          "   local cookies %016llx %016llx remote cookie %016llx",
12907          clib_net_to_host_u64 (mp->local_cookie[0]),
12908          clib_net_to_host_u64 (mp->local_cookie[1]),
12909          clib_net_to_host_u64 (mp->remote_cookie));
12910
12911   print (vam->ofp, "   local session-id %d remote session-id %d",
12912          clib_net_to_host_u32 (mp->local_session_id),
12913          clib_net_to_host_u32 (mp->remote_session_id));
12914
12915   print (vam->ofp, "   l2 specific sublayer %s\n",
12916          mp->l2_sublayer_present ? "preset" : "absent");
12917
12918 }
12919
12920 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12921   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12922 {
12923   vat_main_t *vam = &vat_main;
12924   vat_json_node_t *node = NULL;
12925   struct in6_addr addr;
12926
12927   if (VAT_JSON_ARRAY != vam->json_tree.type)
12928     {
12929       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12930       vat_json_init_array (&vam->json_tree);
12931     }
12932   node = vat_json_array_add (&vam->json_tree);
12933
12934   vat_json_init_object (node);
12935
12936   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12937   vat_json_object_add_ip6 (node, "our_address", addr);
12938   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12939   vat_json_object_add_ip6 (node, "client_address", addr);
12940
12941   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12942   vat_json_init_array (lc);
12943   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12944   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12945   vat_json_object_add_uint (node, "remote_cookie",
12946                             clib_net_to_host_u64 (mp->remote_cookie));
12947
12948   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12949   vat_json_object_add_uint (node, "local_session_id",
12950                             clib_net_to_host_u32 (mp->local_session_id));
12951   vat_json_object_add_uint (node, "remote_session_id",
12952                             clib_net_to_host_u32 (mp->remote_session_id));
12953   vat_json_object_add_string_copy (node, "l2_sublayer",
12954                                    mp->l2_sublayer_present ? (u8 *) "present"
12955                                    : (u8 *) "absent");
12956 }
12957
12958 static int
12959 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12960 {
12961   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12962   vl_api_control_ping_t *mp_ping;
12963   int ret;
12964
12965   /* Get list of l2tpv3-tunnel interfaces */
12966   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12967   S (mp);
12968
12969   /* Use a control ping for synchronization */
12970   MPING (CONTROL_PING, mp_ping);
12971   S (mp_ping);
12972
12973   W (ret);
12974   return ret;
12975 }
12976
12977
12978 static void vl_api_sw_interface_tap_details_t_handler
12979   (vl_api_sw_interface_tap_details_t * mp)
12980 {
12981   vat_main_t *vam = &vat_main;
12982
12983   print (vam->ofp, "%-16s %d",
12984          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12985 }
12986
12987 static void vl_api_sw_interface_tap_details_t_handler_json
12988   (vl_api_sw_interface_tap_details_t * mp)
12989 {
12990   vat_main_t *vam = &vat_main;
12991   vat_json_node_t *node = NULL;
12992
12993   if (VAT_JSON_ARRAY != vam->json_tree.type)
12994     {
12995       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12996       vat_json_init_array (&vam->json_tree);
12997     }
12998   node = vat_json_array_add (&vam->json_tree);
12999
13000   vat_json_init_object (node);
13001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13002   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13003 }
13004
13005 static int
13006 api_sw_interface_tap_dump (vat_main_t * vam)
13007 {
13008   vl_api_sw_interface_tap_dump_t *mp;
13009   vl_api_control_ping_t *mp_ping;
13010   int ret;
13011
13012   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13013   /* Get list of tap interfaces */
13014   M (SW_INTERFACE_TAP_DUMP, mp);
13015   S (mp);
13016
13017   /* Use a control ping for synchronization */
13018   MPING (CONTROL_PING, mp_ping);
13019   S (mp_ping);
13020
13021   W (ret);
13022   return ret;
13023 }
13024
13025 static void vl_api_sw_interface_tap_v2_details_t_handler
13026   (vl_api_sw_interface_tap_v2_details_t * mp)
13027 {
13028   vat_main_t *vam = &vat_main;
13029
13030   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13031                     mp->host_ip4_prefix_len);
13032   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13033                     mp->host_ip6_prefix_len);
13034
13035   print (vam->ofp,
13036          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13037          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13038          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13039          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13040          mp->host_bridge, ip4, ip6);
13041
13042   vec_free (ip4);
13043   vec_free (ip6);
13044 }
13045
13046 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13047   (vl_api_sw_interface_tap_v2_details_t * mp)
13048 {
13049   vat_main_t *vam = &vat_main;
13050   vat_json_node_t *node = NULL;
13051
13052   if (VAT_JSON_ARRAY != vam->json_tree.type)
13053     {
13054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13055       vat_json_init_array (&vam->json_tree);
13056     }
13057   node = vat_json_array_add (&vam->json_tree);
13058
13059   vat_json_init_object (node);
13060   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13061   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13062   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13063   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13064   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13065   vat_json_object_add_string_copy (node, "host_mac_addr",
13066                                    format (0, "%U", format_ethernet_address,
13067                                            &mp->host_mac_addr));
13068   vat_json_object_add_string_copy (node, "host_namespace",
13069                                    mp->host_namespace);
13070   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13071   vat_json_object_add_string_copy (node, "host_ip4_addr",
13072                                    format (0, "%U/%d", format_ip4_address,
13073                                            mp->host_ip4_addr,
13074                                            mp->host_ip4_prefix_len));
13075   vat_json_object_add_string_copy (node, "host_ip6_addr",
13076                                    format (0, "%U/%d", format_ip6_address,
13077                                            mp->host_ip6_addr,
13078                                            mp->host_ip6_prefix_len));
13079
13080 }
13081
13082 static int
13083 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13084 {
13085   vl_api_sw_interface_tap_v2_dump_t *mp;
13086   vl_api_control_ping_t *mp_ping;
13087   int ret;
13088
13089   print (vam->ofp,
13090          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13091          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13092          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13093          "host_ip6_addr");
13094
13095   /* Get list of tap interfaces */
13096   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13097   S (mp);
13098
13099   /* Use a control ping for synchronization */
13100   MPING (CONTROL_PING, mp_ping);
13101   S (mp_ping);
13102
13103   W (ret);
13104   return ret;
13105 }
13106
13107 static int
13108 api_vxlan_offload_rx (vat_main_t * vam)
13109 {
13110   unformat_input_t *line_input = vam->input;
13111   vl_api_vxlan_offload_rx_t *mp;
13112   u32 hw_if_index = ~0, rx_if_index = ~0;
13113   u8 is_add = 1;
13114   int ret;
13115
13116   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13117     {
13118       if (unformat (line_input, "del"))
13119         is_add = 0;
13120       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13121                          &hw_if_index))
13122         ;
13123       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13124         ;
13125       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13126                          &rx_if_index))
13127         ;
13128       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13129         ;
13130       else
13131         {
13132           errmsg ("parse error '%U'", format_unformat_error, line_input);
13133           return -99;
13134         }
13135     }
13136
13137   if (hw_if_index == ~0)
13138     {
13139       errmsg ("no hw interface");
13140       return -99;
13141     }
13142
13143   if (rx_if_index == ~0)
13144     {
13145       errmsg ("no rx tunnel");
13146       return -99;
13147     }
13148
13149   M (VXLAN_OFFLOAD_RX, mp);
13150
13151   mp->hw_if_index = ntohl (hw_if_index);
13152   mp->sw_if_index = ntohl (rx_if_index);
13153   mp->enable = is_add;
13154
13155   S (mp);
13156   W (ret);
13157   return ret;
13158 }
13159
13160 static uword unformat_vxlan_decap_next
13161   (unformat_input_t * input, va_list * args)
13162 {
13163   u32 *result = va_arg (*args, u32 *);
13164   u32 tmp;
13165
13166   if (unformat (input, "l2"))
13167     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13168   else if (unformat (input, "%d", &tmp))
13169     *result = tmp;
13170   else
13171     return 0;
13172   return 1;
13173 }
13174
13175 static int
13176 api_vxlan_add_del_tunnel (vat_main_t * vam)
13177 {
13178   unformat_input_t *line_input = vam->input;
13179   vl_api_vxlan_add_del_tunnel_t *mp;
13180   ip46_address_t src, dst;
13181   u8 is_add = 1;
13182   u8 ipv4_set = 0, ipv6_set = 0;
13183   u8 src_set = 0;
13184   u8 dst_set = 0;
13185   u8 grp_set = 0;
13186   u32 instance = ~0;
13187   u32 mcast_sw_if_index = ~0;
13188   u32 encap_vrf_id = 0;
13189   u32 decap_next_index = ~0;
13190   u32 vni = 0;
13191   int ret;
13192
13193   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13194   memset (&src, 0, sizeof src);
13195   memset (&dst, 0, sizeof dst);
13196
13197   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13198     {
13199       if (unformat (line_input, "del"))
13200         is_add = 0;
13201       else if (unformat (line_input, "instance %d", &instance))
13202         ;
13203       else
13204         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13205         {
13206           ipv4_set = 1;
13207           src_set = 1;
13208         }
13209       else
13210         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13211         {
13212           ipv4_set = 1;
13213           dst_set = 1;
13214         }
13215       else
13216         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13217         {
13218           ipv6_set = 1;
13219           src_set = 1;
13220         }
13221       else
13222         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13223         {
13224           ipv6_set = 1;
13225           dst_set = 1;
13226         }
13227       else if (unformat (line_input, "group %U %U",
13228                          unformat_ip4_address, &dst.ip4,
13229                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13230         {
13231           grp_set = dst_set = 1;
13232           ipv4_set = 1;
13233         }
13234       else if (unformat (line_input, "group %U",
13235                          unformat_ip4_address, &dst.ip4))
13236         {
13237           grp_set = dst_set = 1;
13238           ipv4_set = 1;
13239         }
13240       else if (unformat (line_input, "group %U %U",
13241                          unformat_ip6_address, &dst.ip6,
13242                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13243         {
13244           grp_set = dst_set = 1;
13245           ipv6_set = 1;
13246         }
13247       else if (unformat (line_input, "group %U",
13248                          unformat_ip6_address, &dst.ip6))
13249         {
13250           grp_set = dst_set = 1;
13251           ipv6_set = 1;
13252         }
13253       else
13254         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13255         ;
13256       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13257         ;
13258       else if (unformat (line_input, "decap-next %U",
13259                          unformat_vxlan_decap_next, &decap_next_index))
13260         ;
13261       else if (unformat (line_input, "vni %d", &vni))
13262         ;
13263       else
13264         {
13265           errmsg ("parse error '%U'", format_unformat_error, line_input);
13266           return -99;
13267         }
13268     }
13269
13270   if (src_set == 0)
13271     {
13272       errmsg ("tunnel src address not specified");
13273       return -99;
13274     }
13275   if (dst_set == 0)
13276     {
13277       errmsg ("tunnel dst address not specified");
13278       return -99;
13279     }
13280
13281   if (grp_set && !ip46_address_is_multicast (&dst))
13282     {
13283       errmsg ("tunnel group address not multicast");
13284       return -99;
13285     }
13286   if (grp_set && mcast_sw_if_index == ~0)
13287     {
13288       errmsg ("tunnel nonexistent multicast device");
13289       return -99;
13290     }
13291   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13292     {
13293       errmsg ("tunnel dst address must be unicast");
13294       return -99;
13295     }
13296
13297
13298   if (ipv4_set && ipv6_set)
13299     {
13300       errmsg ("both IPv4 and IPv6 addresses specified");
13301       return -99;
13302     }
13303
13304   if ((vni == 0) || (vni >> 24))
13305     {
13306       errmsg ("vni not specified or out of range");
13307       return -99;
13308     }
13309
13310   M (VXLAN_ADD_DEL_TUNNEL, mp);
13311
13312   if (ipv6_set)
13313     {
13314       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13315       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13316     }
13317   else
13318     {
13319       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13320       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13321     }
13322
13323   mp->instance = htonl (instance);
13324   mp->encap_vrf_id = ntohl (encap_vrf_id);
13325   mp->decap_next_index = ntohl (decap_next_index);
13326   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13327   mp->vni = ntohl (vni);
13328   mp->is_add = is_add;
13329   mp->is_ipv6 = ipv6_set;
13330
13331   S (mp);
13332   W (ret);
13333   return ret;
13334 }
13335
13336 static void vl_api_vxlan_tunnel_details_t_handler
13337   (vl_api_vxlan_tunnel_details_t * mp)
13338 {
13339   vat_main_t *vam = &vat_main;
13340   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13341   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13342
13343   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13344          ntohl (mp->sw_if_index),
13345          ntohl (mp->instance),
13346          format_ip46_address, &src, IP46_TYPE_ANY,
13347          format_ip46_address, &dst, IP46_TYPE_ANY,
13348          ntohl (mp->encap_vrf_id),
13349          ntohl (mp->decap_next_index), ntohl (mp->vni),
13350          ntohl (mp->mcast_sw_if_index));
13351 }
13352
13353 static void vl_api_vxlan_tunnel_details_t_handler_json
13354   (vl_api_vxlan_tunnel_details_t * mp)
13355 {
13356   vat_main_t *vam = &vat_main;
13357   vat_json_node_t *node = NULL;
13358
13359   if (VAT_JSON_ARRAY != vam->json_tree.type)
13360     {
13361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13362       vat_json_init_array (&vam->json_tree);
13363     }
13364   node = vat_json_array_add (&vam->json_tree);
13365
13366   vat_json_init_object (node);
13367   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13368
13369   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13370
13371   if (mp->is_ipv6)
13372     {
13373       struct in6_addr ip6;
13374
13375       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13376       vat_json_object_add_ip6 (node, "src_address", ip6);
13377       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13378       vat_json_object_add_ip6 (node, "dst_address", ip6);
13379     }
13380   else
13381     {
13382       struct in_addr ip4;
13383
13384       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13385       vat_json_object_add_ip4 (node, "src_address", ip4);
13386       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13387       vat_json_object_add_ip4 (node, "dst_address", ip4);
13388     }
13389   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13390   vat_json_object_add_uint (node, "decap_next_index",
13391                             ntohl (mp->decap_next_index));
13392   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13393   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13394   vat_json_object_add_uint (node, "mcast_sw_if_index",
13395                             ntohl (mp->mcast_sw_if_index));
13396 }
13397
13398 static int
13399 api_vxlan_tunnel_dump (vat_main_t * vam)
13400 {
13401   unformat_input_t *i = vam->input;
13402   vl_api_vxlan_tunnel_dump_t *mp;
13403   vl_api_control_ping_t *mp_ping;
13404   u32 sw_if_index;
13405   u8 sw_if_index_set = 0;
13406   int ret;
13407
13408   /* Parse args required to build the message */
13409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13410     {
13411       if (unformat (i, "sw_if_index %d", &sw_if_index))
13412         sw_if_index_set = 1;
13413       else
13414         break;
13415     }
13416
13417   if (sw_if_index_set == 0)
13418     {
13419       sw_if_index = ~0;
13420     }
13421
13422   if (!vam->json_output)
13423     {
13424       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13425              "sw_if_index", "instance", "src_address", "dst_address",
13426              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13427     }
13428
13429   /* Get list of vxlan-tunnel interfaces */
13430   M (VXLAN_TUNNEL_DUMP, mp);
13431
13432   mp->sw_if_index = htonl (sw_if_index);
13433
13434   S (mp);
13435
13436   /* Use a control ping for synchronization */
13437   MPING (CONTROL_PING, mp_ping);
13438   S (mp_ping);
13439
13440   W (ret);
13441   return ret;
13442 }
13443
13444 static uword unformat_geneve_decap_next
13445   (unformat_input_t * input, va_list * args)
13446 {
13447   u32 *result = va_arg (*args, u32 *);
13448   u32 tmp;
13449
13450   if (unformat (input, "l2"))
13451     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13452   else if (unformat (input, "%d", &tmp))
13453     *result = tmp;
13454   else
13455     return 0;
13456   return 1;
13457 }
13458
13459 static int
13460 api_geneve_add_del_tunnel (vat_main_t * vam)
13461 {
13462   unformat_input_t *line_input = vam->input;
13463   vl_api_geneve_add_del_tunnel_t *mp;
13464   ip46_address_t src, dst;
13465   u8 is_add = 1;
13466   u8 ipv4_set = 0, ipv6_set = 0;
13467   u8 src_set = 0;
13468   u8 dst_set = 0;
13469   u8 grp_set = 0;
13470   u32 mcast_sw_if_index = ~0;
13471   u32 encap_vrf_id = 0;
13472   u32 decap_next_index = ~0;
13473   u32 vni = 0;
13474   int ret;
13475
13476   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13477   memset (&src, 0, sizeof src);
13478   memset (&dst, 0, sizeof dst);
13479
13480   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13481     {
13482       if (unformat (line_input, "del"))
13483         is_add = 0;
13484       else
13485         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13486         {
13487           ipv4_set = 1;
13488           src_set = 1;
13489         }
13490       else
13491         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13492         {
13493           ipv4_set = 1;
13494           dst_set = 1;
13495         }
13496       else
13497         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13498         {
13499           ipv6_set = 1;
13500           src_set = 1;
13501         }
13502       else
13503         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13504         {
13505           ipv6_set = 1;
13506           dst_set = 1;
13507         }
13508       else if (unformat (line_input, "group %U %U",
13509                          unformat_ip4_address, &dst.ip4,
13510                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13511         {
13512           grp_set = dst_set = 1;
13513           ipv4_set = 1;
13514         }
13515       else if (unformat (line_input, "group %U",
13516                          unformat_ip4_address, &dst.ip4))
13517         {
13518           grp_set = dst_set = 1;
13519           ipv4_set = 1;
13520         }
13521       else if (unformat (line_input, "group %U %U",
13522                          unformat_ip6_address, &dst.ip6,
13523                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13524         {
13525           grp_set = dst_set = 1;
13526           ipv6_set = 1;
13527         }
13528       else if (unformat (line_input, "group %U",
13529                          unformat_ip6_address, &dst.ip6))
13530         {
13531           grp_set = dst_set = 1;
13532           ipv6_set = 1;
13533         }
13534       else
13535         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13536         ;
13537       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13538         ;
13539       else if (unformat (line_input, "decap-next %U",
13540                          unformat_geneve_decap_next, &decap_next_index))
13541         ;
13542       else if (unformat (line_input, "vni %d", &vni))
13543         ;
13544       else
13545         {
13546           errmsg ("parse error '%U'", format_unformat_error, line_input);
13547           return -99;
13548         }
13549     }
13550
13551   if (src_set == 0)
13552     {
13553       errmsg ("tunnel src address not specified");
13554       return -99;
13555     }
13556   if (dst_set == 0)
13557     {
13558       errmsg ("tunnel dst address not specified");
13559       return -99;
13560     }
13561
13562   if (grp_set && !ip46_address_is_multicast (&dst))
13563     {
13564       errmsg ("tunnel group address not multicast");
13565       return -99;
13566     }
13567   if (grp_set && mcast_sw_if_index == ~0)
13568     {
13569       errmsg ("tunnel nonexistent multicast device");
13570       return -99;
13571     }
13572   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13573     {
13574       errmsg ("tunnel dst address must be unicast");
13575       return -99;
13576     }
13577
13578
13579   if (ipv4_set && ipv6_set)
13580     {
13581       errmsg ("both IPv4 and IPv6 addresses specified");
13582       return -99;
13583     }
13584
13585   if ((vni == 0) || (vni >> 24))
13586     {
13587       errmsg ("vni not specified or out of range");
13588       return -99;
13589     }
13590
13591   M (GENEVE_ADD_DEL_TUNNEL, mp);
13592
13593   if (ipv6_set)
13594     {
13595       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13596       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13597     }
13598   else
13599     {
13600       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13601       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13602     }
13603   mp->encap_vrf_id = ntohl (encap_vrf_id);
13604   mp->decap_next_index = ntohl (decap_next_index);
13605   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13606   mp->vni = ntohl (vni);
13607   mp->is_add = is_add;
13608   mp->is_ipv6 = ipv6_set;
13609
13610   S (mp);
13611   W (ret);
13612   return ret;
13613 }
13614
13615 static void vl_api_geneve_tunnel_details_t_handler
13616   (vl_api_geneve_tunnel_details_t * mp)
13617 {
13618   vat_main_t *vam = &vat_main;
13619   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13620   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13621
13622   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13623          ntohl (mp->sw_if_index),
13624          format_ip46_address, &src, IP46_TYPE_ANY,
13625          format_ip46_address, &dst, IP46_TYPE_ANY,
13626          ntohl (mp->encap_vrf_id),
13627          ntohl (mp->decap_next_index), ntohl (mp->vni),
13628          ntohl (mp->mcast_sw_if_index));
13629 }
13630
13631 static void vl_api_geneve_tunnel_details_t_handler_json
13632   (vl_api_geneve_tunnel_details_t * mp)
13633 {
13634   vat_main_t *vam = &vat_main;
13635   vat_json_node_t *node = NULL;
13636
13637   if (VAT_JSON_ARRAY != vam->json_tree.type)
13638     {
13639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13640       vat_json_init_array (&vam->json_tree);
13641     }
13642   node = vat_json_array_add (&vam->json_tree);
13643
13644   vat_json_init_object (node);
13645   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13646   if (mp->is_ipv6)
13647     {
13648       struct in6_addr ip6;
13649
13650       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13651       vat_json_object_add_ip6 (node, "src_address", ip6);
13652       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13653       vat_json_object_add_ip6 (node, "dst_address", ip6);
13654     }
13655   else
13656     {
13657       struct in_addr ip4;
13658
13659       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13660       vat_json_object_add_ip4 (node, "src_address", ip4);
13661       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13662       vat_json_object_add_ip4 (node, "dst_address", ip4);
13663     }
13664   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13665   vat_json_object_add_uint (node, "decap_next_index",
13666                             ntohl (mp->decap_next_index));
13667   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13668   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13669   vat_json_object_add_uint (node, "mcast_sw_if_index",
13670                             ntohl (mp->mcast_sw_if_index));
13671 }
13672
13673 static int
13674 api_geneve_tunnel_dump (vat_main_t * vam)
13675 {
13676   unformat_input_t *i = vam->input;
13677   vl_api_geneve_tunnel_dump_t *mp;
13678   vl_api_control_ping_t *mp_ping;
13679   u32 sw_if_index;
13680   u8 sw_if_index_set = 0;
13681   int ret;
13682
13683   /* Parse args required to build the message */
13684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (i, "sw_if_index %d", &sw_if_index))
13687         sw_if_index_set = 1;
13688       else
13689         break;
13690     }
13691
13692   if (sw_if_index_set == 0)
13693     {
13694       sw_if_index = ~0;
13695     }
13696
13697   if (!vam->json_output)
13698     {
13699       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13700              "sw_if_index", "local_address", "remote_address",
13701              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13702     }
13703
13704   /* Get list of geneve-tunnel interfaces */
13705   M (GENEVE_TUNNEL_DUMP, mp);
13706
13707   mp->sw_if_index = htonl (sw_if_index);
13708
13709   S (mp);
13710
13711   /* Use a control ping for synchronization */
13712   M (CONTROL_PING, mp_ping);
13713   S (mp_ping);
13714
13715   W (ret);
13716   return ret;
13717 }
13718
13719 static int
13720 api_gre_add_del_tunnel (vat_main_t * vam)
13721 {
13722   unformat_input_t *line_input = vam->input;
13723   vl_api_gre_add_del_tunnel_t *mp;
13724   ip4_address_t src4, dst4;
13725   ip6_address_t src6, dst6;
13726   u8 is_add = 1;
13727   u8 ipv4_set = 0;
13728   u8 ipv6_set = 0;
13729   u8 t_type = GRE_TUNNEL_TYPE_L3;
13730   u8 src_set = 0;
13731   u8 dst_set = 0;
13732   u32 outer_fib_id = 0;
13733   u32 session_id = 0;
13734   u32 instance = ~0;
13735   int ret;
13736
13737   memset (&src4, 0, sizeof src4);
13738   memset (&dst4, 0, sizeof dst4);
13739   memset (&src6, 0, sizeof src6);
13740   memset (&dst6, 0, sizeof dst6);
13741
13742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13743     {
13744       if (unformat (line_input, "del"))
13745         is_add = 0;
13746       else if (unformat (line_input, "instance %d", &instance))
13747         ;
13748       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13749         {
13750           src_set = 1;
13751           ipv4_set = 1;
13752         }
13753       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13754         {
13755           dst_set = 1;
13756           ipv4_set = 1;
13757         }
13758       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13759         {
13760           src_set = 1;
13761           ipv6_set = 1;
13762         }
13763       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13764         {
13765           dst_set = 1;
13766           ipv6_set = 1;
13767         }
13768       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13769         ;
13770       else if (unformat (line_input, "teb"))
13771         t_type = GRE_TUNNEL_TYPE_TEB;
13772       else if (unformat (line_input, "erspan %d", &session_id))
13773         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13774       else
13775         {
13776           errmsg ("parse error '%U'", format_unformat_error, line_input);
13777           return -99;
13778         }
13779     }
13780
13781   if (src_set == 0)
13782     {
13783       errmsg ("tunnel src address not specified");
13784       return -99;
13785     }
13786   if (dst_set == 0)
13787     {
13788       errmsg ("tunnel dst address not specified");
13789       return -99;
13790     }
13791   if (ipv4_set && ipv6_set)
13792     {
13793       errmsg ("both IPv4 and IPv6 addresses specified");
13794       return -99;
13795     }
13796
13797
13798   M (GRE_ADD_DEL_TUNNEL, mp);
13799
13800   if (ipv4_set)
13801     {
13802       clib_memcpy (&mp->src_address, &src4, 4);
13803       clib_memcpy (&mp->dst_address, &dst4, 4);
13804     }
13805   else
13806     {
13807       clib_memcpy (&mp->src_address, &src6, 16);
13808       clib_memcpy (&mp->dst_address, &dst6, 16);
13809     }
13810   mp->instance = htonl (instance);
13811   mp->outer_fib_id = htonl (outer_fib_id);
13812   mp->is_add = is_add;
13813   mp->session_id = htons ((u16) session_id);
13814   mp->tunnel_type = t_type;
13815   mp->is_ipv6 = ipv6_set;
13816
13817   S (mp);
13818   W (ret);
13819   return ret;
13820 }
13821
13822 static void vl_api_gre_tunnel_details_t_handler
13823   (vl_api_gre_tunnel_details_t * mp)
13824 {
13825   vat_main_t *vam = &vat_main;
13826   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13827   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13828
13829   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13830          ntohl (mp->sw_if_index),
13831          ntohl (mp->instance),
13832          format_ip46_address, &src, IP46_TYPE_ANY,
13833          format_ip46_address, &dst, IP46_TYPE_ANY,
13834          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13835 }
13836
13837 static void vl_api_gre_tunnel_details_t_handler_json
13838   (vl_api_gre_tunnel_details_t * mp)
13839 {
13840   vat_main_t *vam = &vat_main;
13841   vat_json_node_t *node = NULL;
13842   struct in_addr ip4;
13843   struct in6_addr ip6;
13844
13845   if (VAT_JSON_ARRAY != vam->json_tree.type)
13846     {
13847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13848       vat_json_init_array (&vam->json_tree);
13849     }
13850   node = vat_json_array_add (&vam->json_tree);
13851
13852   vat_json_init_object (node);
13853   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13854   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13855   if (!mp->is_ipv6)
13856     {
13857       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13858       vat_json_object_add_ip4 (node, "src_address", ip4);
13859       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13860       vat_json_object_add_ip4 (node, "dst_address", ip4);
13861     }
13862   else
13863     {
13864       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13865       vat_json_object_add_ip6 (node, "src_address", ip6);
13866       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13867       vat_json_object_add_ip6 (node, "dst_address", ip6);
13868     }
13869   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13870   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13871   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13872   vat_json_object_add_uint (node, "session_id", mp->session_id);
13873 }
13874
13875 static int
13876 api_gre_tunnel_dump (vat_main_t * vam)
13877 {
13878   unformat_input_t *i = vam->input;
13879   vl_api_gre_tunnel_dump_t *mp;
13880   vl_api_control_ping_t *mp_ping;
13881   u32 sw_if_index;
13882   u8 sw_if_index_set = 0;
13883   int ret;
13884
13885   /* Parse args required to build the message */
13886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (i, "sw_if_index %d", &sw_if_index))
13889         sw_if_index_set = 1;
13890       else
13891         break;
13892     }
13893
13894   if (sw_if_index_set == 0)
13895     {
13896       sw_if_index = ~0;
13897     }
13898
13899   if (!vam->json_output)
13900     {
13901       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13902              "sw_if_index", "instance", "src_address", "dst_address",
13903              "tunnel_type", "outer_fib_id", "session_id");
13904     }
13905
13906   /* Get list of gre-tunnel interfaces */
13907   M (GRE_TUNNEL_DUMP, mp);
13908
13909   mp->sw_if_index = htonl (sw_if_index);
13910
13911   S (mp);
13912
13913   /* Use a control ping for synchronization */
13914   MPING (CONTROL_PING, mp_ping);
13915   S (mp_ping);
13916
13917   W (ret);
13918   return ret;
13919 }
13920
13921 static int
13922 api_l2_fib_clear_table (vat_main_t * vam)
13923 {
13924 //  unformat_input_t * i = vam->input;
13925   vl_api_l2_fib_clear_table_t *mp;
13926   int ret;
13927
13928   M (L2_FIB_CLEAR_TABLE, mp);
13929
13930   S (mp);
13931   W (ret);
13932   return ret;
13933 }
13934
13935 static int
13936 api_l2_interface_efp_filter (vat_main_t * vam)
13937 {
13938   unformat_input_t *i = vam->input;
13939   vl_api_l2_interface_efp_filter_t *mp;
13940   u32 sw_if_index;
13941   u8 enable = 1;
13942   u8 sw_if_index_set = 0;
13943   int ret;
13944
13945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13946     {
13947       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13948         sw_if_index_set = 1;
13949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13950         sw_if_index_set = 1;
13951       else if (unformat (i, "enable"))
13952         enable = 1;
13953       else if (unformat (i, "disable"))
13954         enable = 0;
13955       else
13956         {
13957           clib_warning ("parse error '%U'", format_unformat_error, i);
13958           return -99;
13959         }
13960     }
13961
13962   if (sw_if_index_set == 0)
13963     {
13964       errmsg ("missing sw_if_index");
13965       return -99;
13966     }
13967
13968   M (L2_INTERFACE_EFP_FILTER, mp);
13969
13970   mp->sw_if_index = ntohl (sw_if_index);
13971   mp->enable_disable = enable;
13972
13973   S (mp);
13974   W (ret);
13975   return ret;
13976 }
13977
13978 #define foreach_vtr_op                          \
13979 _("disable",  L2_VTR_DISABLED)                  \
13980 _("push-1",  L2_VTR_PUSH_1)                     \
13981 _("push-2",  L2_VTR_PUSH_2)                     \
13982 _("pop-1",  L2_VTR_POP_1)                       \
13983 _("pop-2",  L2_VTR_POP_2)                       \
13984 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13985 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13986 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13987 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13988
13989 static int
13990 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13991 {
13992   unformat_input_t *i = vam->input;
13993   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13994   u32 sw_if_index;
13995   u8 sw_if_index_set = 0;
13996   u8 vtr_op_set = 0;
13997   u32 vtr_op = 0;
13998   u32 push_dot1q = 1;
13999   u32 tag1 = ~0;
14000   u32 tag2 = ~0;
14001   int ret;
14002
14003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14004     {
14005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14006         sw_if_index_set = 1;
14007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14008         sw_if_index_set = 1;
14009       else if (unformat (i, "vtr_op %d", &vtr_op))
14010         vtr_op_set = 1;
14011 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14012       foreach_vtr_op
14013 #undef _
14014         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14015         ;
14016       else if (unformat (i, "tag1 %d", &tag1))
14017         ;
14018       else if (unformat (i, "tag2 %d", &tag2))
14019         ;
14020       else
14021         {
14022           clib_warning ("parse error '%U'", format_unformat_error, i);
14023           return -99;
14024         }
14025     }
14026
14027   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14028     {
14029       errmsg ("missing vtr operation or sw_if_index");
14030       return -99;
14031     }
14032
14033   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14034   mp->sw_if_index = ntohl (sw_if_index);
14035   mp->vtr_op = ntohl (vtr_op);
14036   mp->push_dot1q = ntohl (push_dot1q);
14037   mp->tag1 = ntohl (tag1);
14038   mp->tag2 = ntohl (tag2);
14039
14040   S (mp);
14041   W (ret);
14042   return ret;
14043 }
14044
14045 static int
14046 api_create_vhost_user_if (vat_main_t * vam)
14047 {
14048   unformat_input_t *i = vam->input;
14049   vl_api_create_vhost_user_if_t *mp;
14050   u8 *file_name;
14051   u8 is_server = 0;
14052   u8 file_name_set = 0;
14053   u32 custom_dev_instance = ~0;
14054   u8 hwaddr[6];
14055   u8 use_custom_mac = 0;
14056   u8 *tag = 0;
14057   int ret;
14058
14059   /* Shut up coverity */
14060   memset (hwaddr, 0, sizeof (hwaddr));
14061
14062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14063     {
14064       if (unformat (i, "socket %s", &file_name))
14065         {
14066           file_name_set = 1;
14067         }
14068       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14069         ;
14070       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14071         use_custom_mac = 1;
14072       else if (unformat (i, "server"))
14073         is_server = 1;
14074       else if (unformat (i, "tag %s", &tag))
14075         ;
14076       else
14077         break;
14078     }
14079
14080   if (file_name_set == 0)
14081     {
14082       errmsg ("missing socket file name");
14083       return -99;
14084     }
14085
14086   if (vec_len (file_name) > 255)
14087     {
14088       errmsg ("socket file name too long");
14089       return -99;
14090     }
14091   vec_add1 (file_name, 0);
14092
14093   M (CREATE_VHOST_USER_IF, mp);
14094
14095   mp->is_server = is_server;
14096   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14097   vec_free (file_name);
14098   if (custom_dev_instance != ~0)
14099     {
14100       mp->renumber = 1;
14101       mp->custom_dev_instance = ntohl (custom_dev_instance);
14102     }
14103   mp->use_custom_mac = use_custom_mac;
14104   clib_memcpy (mp->mac_address, hwaddr, 6);
14105   if (tag)
14106     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14107   vec_free (tag);
14108
14109   S (mp);
14110   W (ret);
14111   return ret;
14112 }
14113
14114 static int
14115 api_modify_vhost_user_if (vat_main_t * vam)
14116 {
14117   unformat_input_t *i = vam->input;
14118   vl_api_modify_vhost_user_if_t *mp;
14119   u8 *file_name;
14120   u8 is_server = 0;
14121   u8 file_name_set = 0;
14122   u32 custom_dev_instance = ~0;
14123   u8 sw_if_index_set = 0;
14124   u32 sw_if_index = (u32) ~ 0;
14125   int ret;
14126
14127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14128     {
14129       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14130         sw_if_index_set = 1;
14131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14132         sw_if_index_set = 1;
14133       else if (unformat (i, "socket %s", &file_name))
14134         {
14135           file_name_set = 1;
14136         }
14137       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14138         ;
14139       else if (unformat (i, "server"))
14140         is_server = 1;
14141       else
14142         break;
14143     }
14144
14145   if (sw_if_index_set == 0)
14146     {
14147       errmsg ("missing sw_if_index or interface name");
14148       return -99;
14149     }
14150
14151   if (file_name_set == 0)
14152     {
14153       errmsg ("missing socket file name");
14154       return -99;
14155     }
14156
14157   if (vec_len (file_name) > 255)
14158     {
14159       errmsg ("socket file name too long");
14160       return -99;
14161     }
14162   vec_add1 (file_name, 0);
14163
14164   M (MODIFY_VHOST_USER_IF, mp);
14165
14166   mp->sw_if_index = ntohl (sw_if_index);
14167   mp->is_server = is_server;
14168   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14169   vec_free (file_name);
14170   if (custom_dev_instance != ~0)
14171     {
14172       mp->renumber = 1;
14173       mp->custom_dev_instance = ntohl (custom_dev_instance);
14174     }
14175
14176   S (mp);
14177   W (ret);
14178   return ret;
14179 }
14180
14181 static int
14182 api_delete_vhost_user_if (vat_main_t * vam)
14183 {
14184   unformat_input_t *i = vam->input;
14185   vl_api_delete_vhost_user_if_t *mp;
14186   u32 sw_if_index = ~0;
14187   u8 sw_if_index_set = 0;
14188   int ret;
14189
14190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14191     {
14192       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14193         sw_if_index_set = 1;
14194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14195         sw_if_index_set = 1;
14196       else
14197         break;
14198     }
14199
14200   if (sw_if_index_set == 0)
14201     {
14202       errmsg ("missing sw_if_index or interface name");
14203       return -99;
14204     }
14205
14206
14207   M (DELETE_VHOST_USER_IF, mp);
14208
14209   mp->sw_if_index = ntohl (sw_if_index);
14210
14211   S (mp);
14212   W (ret);
14213   return ret;
14214 }
14215
14216 static void vl_api_sw_interface_vhost_user_details_t_handler
14217   (vl_api_sw_interface_vhost_user_details_t * mp)
14218 {
14219   vat_main_t *vam = &vat_main;
14220
14221   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14222          (char *) mp->interface_name,
14223          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14224          clib_net_to_host_u64 (mp->features), mp->is_server,
14225          ntohl (mp->num_regions), (char *) mp->sock_filename);
14226   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14227 }
14228
14229 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14230   (vl_api_sw_interface_vhost_user_details_t * mp)
14231 {
14232   vat_main_t *vam = &vat_main;
14233   vat_json_node_t *node = NULL;
14234
14235   if (VAT_JSON_ARRAY != vam->json_tree.type)
14236     {
14237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14238       vat_json_init_array (&vam->json_tree);
14239     }
14240   node = vat_json_array_add (&vam->json_tree);
14241
14242   vat_json_init_object (node);
14243   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14244   vat_json_object_add_string_copy (node, "interface_name",
14245                                    mp->interface_name);
14246   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14247                             ntohl (mp->virtio_net_hdr_sz));
14248   vat_json_object_add_uint (node, "features",
14249                             clib_net_to_host_u64 (mp->features));
14250   vat_json_object_add_uint (node, "is_server", mp->is_server);
14251   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14252   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14253   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14254 }
14255
14256 static int
14257 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14258 {
14259   vl_api_sw_interface_vhost_user_dump_t *mp;
14260   vl_api_control_ping_t *mp_ping;
14261   int ret;
14262   print (vam->ofp,
14263          "Interface name            idx hdr_sz features server regions filename");
14264
14265   /* Get list of vhost-user interfaces */
14266   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14267   S (mp);
14268
14269   /* Use a control ping for synchronization */
14270   MPING (CONTROL_PING, mp_ping);
14271   S (mp_ping);
14272
14273   W (ret);
14274   return ret;
14275 }
14276
14277 static int
14278 api_show_version (vat_main_t * vam)
14279 {
14280   vl_api_show_version_t *mp;
14281   int ret;
14282
14283   M (SHOW_VERSION, mp);
14284
14285   S (mp);
14286   W (ret);
14287   return ret;
14288 }
14289
14290
14291 static int
14292 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14293 {
14294   unformat_input_t *line_input = vam->input;
14295   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14296   ip4_address_t local4, remote4;
14297   ip6_address_t local6, remote6;
14298   u8 is_add = 1;
14299   u8 ipv4_set = 0, ipv6_set = 0;
14300   u8 local_set = 0;
14301   u8 remote_set = 0;
14302   u8 grp_set = 0;
14303   u32 mcast_sw_if_index = ~0;
14304   u32 encap_vrf_id = 0;
14305   u32 decap_vrf_id = 0;
14306   u8 protocol = ~0;
14307   u32 vni;
14308   u8 vni_set = 0;
14309   int ret;
14310
14311   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14312   memset (&local4, 0, sizeof local4);
14313   memset (&remote4, 0, sizeof remote4);
14314   memset (&local6, 0, sizeof local6);
14315   memset (&remote6, 0, sizeof remote6);
14316
14317   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14318     {
14319       if (unformat (line_input, "del"))
14320         is_add = 0;
14321       else if (unformat (line_input, "local %U",
14322                          unformat_ip4_address, &local4))
14323         {
14324           local_set = 1;
14325           ipv4_set = 1;
14326         }
14327       else if (unformat (line_input, "remote %U",
14328                          unformat_ip4_address, &remote4))
14329         {
14330           remote_set = 1;
14331           ipv4_set = 1;
14332         }
14333       else if (unformat (line_input, "local %U",
14334                          unformat_ip6_address, &local6))
14335         {
14336           local_set = 1;
14337           ipv6_set = 1;
14338         }
14339       else if (unformat (line_input, "remote %U",
14340                          unformat_ip6_address, &remote6))
14341         {
14342           remote_set = 1;
14343           ipv6_set = 1;
14344         }
14345       else if (unformat (line_input, "group %U %U",
14346                          unformat_ip4_address, &remote4,
14347                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14348         {
14349           grp_set = remote_set = 1;
14350           ipv4_set = 1;
14351         }
14352       else if (unformat (line_input, "group %U",
14353                          unformat_ip4_address, &remote4))
14354         {
14355           grp_set = remote_set = 1;
14356           ipv4_set = 1;
14357         }
14358       else if (unformat (line_input, "group %U %U",
14359                          unformat_ip6_address, &remote6,
14360                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14361         {
14362           grp_set = remote_set = 1;
14363           ipv6_set = 1;
14364         }
14365       else if (unformat (line_input, "group %U",
14366                          unformat_ip6_address, &remote6))
14367         {
14368           grp_set = remote_set = 1;
14369           ipv6_set = 1;
14370         }
14371       else
14372         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14373         ;
14374       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14375         ;
14376       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14377         ;
14378       else if (unformat (line_input, "vni %d", &vni))
14379         vni_set = 1;
14380       else if (unformat (line_input, "next-ip4"))
14381         protocol = 1;
14382       else if (unformat (line_input, "next-ip6"))
14383         protocol = 2;
14384       else if (unformat (line_input, "next-ethernet"))
14385         protocol = 3;
14386       else if (unformat (line_input, "next-nsh"))
14387         protocol = 4;
14388       else
14389         {
14390           errmsg ("parse error '%U'", format_unformat_error, line_input);
14391           return -99;
14392         }
14393     }
14394
14395   if (local_set == 0)
14396     {
14397       errmsg ("tunnel local address not specified");
14398       return -99;
14399     }
14400   if (remote_set == 0)
14401     {
14402       errmsg ("tunnel remote address not specified");
14403       return -99;
14404     }
14405   if (grp_set && mcast_sw_if_index == ~0)
14406     {
14407       errmsg ("tunnel nonexistent multicast device");
14408       return -99;
14409     }
14410   if (ipv4_set && ipv6_set)
14411     {
14412       errmsg ("both IPv4 and IPv6 addresses specified");
14413       return -99;
14414     }
14415
14416   if (vni_set == 0)
14417     {
14418       errmsg ("vni not specified");
14419       return -99;
14420     }
14421
14422   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14423
14424
14425   if (ipv6_set)
14426     {
14427       clib_memcpy (&mp->local, &local6, sizeof (local6));
14428       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14429     }
14430   else
14431     {
14432       clib_memcpy (&mp->local, &local4, sizeof (local4));
14433       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14434     }
14435
14436   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14437   mp->encap_vrf_id = ntohl (encap_vrf_id);
14438   mp->decap_vrf_id = ntohl (decap_vrf_id);
14439   mp->protocol = protocol;
14440   mp->vni = ntohl (vni);
14441   mp->is_add = is_add;
14442   mp->is_ipv6 = ipv6_set;
14443
14444   S (mp);
14445   W (ret);
14446   return ret;
14447 }
14448
14449 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14450   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14451 {
14452   vat_main_t *vam = &vat_main;
14453   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14454   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14455
14456   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14457          ntohl (mp->sw_if_index),
14458          format_ip46_address, &local, IP46_TYPE_ANY,
14459          format_ip46_address, &remote, IP46_TYPE_ANY,
14460          ntohl (mp->vni), mp->protocol,
14461          ntohl (mp->mcast_sw_if_index),
14462          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14463 }
14464
14465
14466 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14467   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14468 {
14469   vat_main_t *vam = &vat_main;
14470   vat_json_node_t *node = NULL;
14471   struct in_addr ip4;
14472   struct in6_addr ip6;
14473
14474   if (VAT_JSON_ARRAY != vam->json_tree.type)
14475     {
14476       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14477       vat_json_init_array (&vam->json_tree);
14478     }
14479   node = vat_json_array_add (&vam->json_tree);
14480
14481   vat_json_init_object (node);
14482   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14483   if (mp->is_ipv6)
14484     {
14485       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14486       vat_json_object_add_ip6 (node, "local", ip6);
14487       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14488       vat_json_object_add_ip6 (node, "remote", ip6);
14489     }
14490   else
14491     {
14492       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14493       vat_json_object_add_ip4 (node, "local", ip4);
14494       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14495       vat_json_object_add_ip4 (node, "remote", ip4);
14496     }
14497   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14498   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14499   vat_json_object_add_uint (node, "mcast_sw_if_index",
14500                             ntohl (mp->mcast_sw_if_index));
14501   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14502   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14503   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14504 }
14505
14506 static int
14507 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14508 {
14509   unformat_input_t *i = vam->input;
14510   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14511   vl_api_control_ping_t *mp_ping;
14512   u32 sw_if_index;
14513   u8 sw_if_index_set = 0;
14514   int ret;
14515
14516   /* Parse args required to build the message */
14517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14518     {
14519       if (unformat (i, "sw_if_index %d", &sw_if_index))
14520         sw_if_index_set = 1;
14521       else
14522         break;
14523     }
14524
14525   if (sw_if_index_set == 0)
14526     {
14527       sw_if_index = ~0;
14528     }
14529
14530   if (!vam->json_output)
14531     {
14532       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14533              "sw_if_index", "local", "remote", "vni",
14534              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14535     }
14536
14537   /* Get list of vxlan-tunnel interfaces */
14538   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14539
14540   mp->sw_if_index = htonl (sw_if_index);
14541
14542   S (mp);
14543
14544   /* Use a control ping for synchronization */
14545   MPING (CONTROL_PING, mp_ping);
14546   S (mp_ping);
14547
14548   W (ret);
14549   return ret;
14550 }
14551
14552 static void vl_api_l2_fib_table_details_t_handler
14553   (vl_api_l2_fib_table_details_t * mp)
14554 {
14555   vat_main_t *vam = &vat_main;
14556
14557   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14558          "       %d       %d     %d",
14559          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14560          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14561          mp->bvi_mac);
14562 }
14563
14564 static void vl_api_l2_fib_table_details_t_handler_json
14565   (vl_api_l2_fib_table_details_t * mp)
14566 {
14567   vat_main_t *vam = &vat_main;
14568   vat_json_node_t *node = NULL;
14569
14570   if (VAT_JSON_ARRAY != vam->json_tree.type)
14571     {
14572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14573       vat_json_init_array (&vam->json_tree);
14574     }
14575   node = vat_json_array_add (&vam->json_tree);
14576
14577   vat_json_init_object (node);
14578   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14579   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14580   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14581   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14582   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14583   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14584 }
14585
14586 static int
14587 api_l2_fib_table_dump (vat_main_t * vam)
14588 {
14589   unformat_input_t *i = vam->input;
14590   vl_api_l2_fib_table_dump_t *mp;
14591   vl_api_control_ping_t *mp_ping;
14592   u32 bd_id;
14593   u8 bd_id_set = 0;
14594   int ret;
14595
14596   /* Parse args required to build the message */
14597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14598     {
14599       if (unformat (i, "bd_id %d", &bd_id))
14600         bd_id_set = 1;
14601       else
14602         break;
14603     }
14604
14605   if (bd_id_set == 0)
14606     {
14607       errmsg ("missing bridge domain");
14608       return -99;
14609     }
14610
14611   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14612
14613   /* Get list of l2 fib entries */
14614   M (L2_FIB_TABLE_DUMP, mp);
14615
14616   mp->bd_id = ntohl (bd_id);
14617   S (mp);
14618
14619   /* Use a control ping for synchronization */
14620   MPING (CONTROL_PING, mp_ping);
14621   S (mp_ping);
14622
14623   W (ret);
14624   return ret;
14625 }
14626
14627
14628 static int
14629 api_interface_name_renumber (vat_main_t * vam)
14630 {
14631   unformat_input_t *line_input = vam->input;
14632   vl_api_interface_name_renumber_t *mp;
14633   u32 sw_if_index = ~0;
14634   u32 new_show_dev_instance = ~0;
14635   int ret;
14636
14637   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14638     {
14639       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14640                     &sw_if_index))
14641         ;
14642       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14643         ;
14644       else if (unformat (line_input, "new_show_dev_instance %d",
14645                          &new_show_dev_instance))
14646         ;
14647       else
14648         break;
14649     }
14650
14651   if (sw_if_index == ~0)
14652     {
14653       errmsg ("missing interface name or sw_if_index");
14654       return -99;
14655     }
14656
14657   if (new_show_dev_instance == ~0)
14658     {
14659       errmsg ("missing new_show_dev_instance");
14660       return -99;
14661     }
14662
14663   M (INTERFACE_NAME_RENUMBER, mp);
14664
14665   mp->sw_if_index = ntohl (sw_if_index);
14666   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14667
14668   S (mp);
14669   W (ret);
14670   return ret;
14671 }
14672
14673 static int
14674 api_ip_probe_neighbor (vat_main_t * vam)
14675 {
14676   unformat_input_t *i = vam->input;
14677   vl_api_ip_probe_neighbor_t *mp;
14678   u8 int_set = 0;
14679   u8 adr_set = 0;
14680   u8 is_ipv6 = 0;
14681   u8 dst_adr[16];
14682   u32 sw_if_index;
14683   int ret;
14684
14685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14686     {
14687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14688         int_set = 1;
14689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14690         int_set = 1;
14691       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14692         adr_set = 1;
14693       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14694         {
14695           adr_set = 1;
14696           is_ipv6 = 1;
14697         }
14698       else
14699         break;
14700     }
14701
14702   if (int_set == 0)
14703     {
14704       errmsg ("missing interface");
14705       return -99;
14706     }
14707
14708   if (adr_set == 0)
14709     {
14710       errmsg ("missing addresses");
14711       return -99;
14712     }
14713
14714   M (IP_PROBE_NEIGHBOR, mp);
14715
14716   mp->sw_if_index = ntohl (sw_if_index);
14717   mp->is_ipv6 = is_ipv6;
14718   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14719
14720   S (mp);
14721   W (ret);
14722   return ret;
14723 }
14724
14725 static int
14726 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14727 {
14728   unformat_input_t *i = vam->input;
14729   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14730   u8 mode = IP_SCAN_V46_NEIGHBORS;
14731   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14732   int ret;
14733
14734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14735     {
14736       if (unformat (i, "ip4"))
14737         mode = IP_SCAN_V4_NEIGHBORS;
14738       else if (unformat (i, "ip6"))
14739         mode = IP_SCAN_V6_NEIGHBORS;
14740       if (unformat (i, "both"))
14741         mode = IP_SCAN_V46_NEIGHBORS;
14742       else if (unformat (i, "disable"))
14743         mode = IP_SCAN_DISABLED;
14744       else if (unformat (i, "interval %d", &interval))
14745         ;
14746       else if (unformat (i, "max-time %d", &time))
14747         ;
14748       else if (unformat (i, "max-update %d", &update))
14749         ;
14750       else if (unformat (i, "delay %d", &delay))
14751         ;
14752       else if (unformat (i, "stale %d", &stale))
14753         ;
14754       else
14755         break;
14756     }
14757
14758   if (interval > 255)
14759     {
14760       errmsg ("interval cannot exceed 255 minutes.");
14761       return -99;
14762     }
14763   if (time > 255)
14764     {
14765       errmsg ("max-time cannot exceed 255 usec.");
14766       return -99;
14767     }
14768   if (update > 255)
14769     {
14770       errmsg ("max-update cannot exceed 255.");
14771       return -99;
14772     }
14773   if (delay > 255)
14774     {
14775       errmsg ("delay cannot exceed 255 msec.");
14776       return -99;
14777     }
14778   if (stale > 255)
14779     {
14780       errmsg ("stale cannot exceed 255 minutes.");
14781       return -99;
14782     }
14783
14784   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14785   mp->mode = mode;
14786   mp->scan_interval = interval;
14787   mp->max_proc_time = time;
14788   mp->max_update = update;
14789   mp->scan_int_delay = delay;
14790   mp->stale_threshold = stale;
14791
14792   S (mp);
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_want_ip4_arp_events (vat_main_t * vam)
14799 {
14800   unformat_input_t *line_input = vam->input;
14801   vl_api_want_ip4_arp_events_t *mp;
14802   ip4_address_t address;
14803   int address_set = 0;
14804   u32 enable_disable = 1;
14805   int ret;
14806
14807   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14808     {
14809       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14810         address_set = 1;
14811       else if (unformat (line_input, "del"))
14812         enable_disable = 0;
14813       else
14814         break;
14815     }
14816
14817   if (address_set == 0)
14818     {
14819       errmsg ("missing addresses");
14820       return -99;
14821     }
14822
14823   M (WANT_IP4_ARP_EVENTS, mp);
14824   mp->enable_disable = enable_disable;
14825   mp->pid = htonl (getpid ());
14826   mp->address = address.as_u32;
14827
14828   S (mp);
14829   W (ret);
14830   return ret;
14831 }
14832
14833 static int
14834 api_want_ip6_nd_events (vat_main_t * vam)
14835 {
14836   unformat_input_t *line_input = vam->input;
14837   vl_api_want_ip6_nd_events_t *mp;
14838   ip6_address_t address;
14839   int address_set = 0;
14840   u32 enable_disable = 1;
14841   int ret;
14842
14843   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14844     {
14845       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14846         address_set = 1;
14847       else if (unformat (line_input, "del"))
14848         enable_disable = 0;
14849       else
14850         break;
14851     }
14852
14853   if (address_set == 0)
14854     {
14855       errmsg ("missing addresses");
14856       return -99;
14857     }
14858
14859   M (WANT_IP6_ND_EVENTS, mp);
14860   mp->enable_disable = enable_disable;
14861   mp->pid = htonl (getpid ());
14862   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14863
14864   S (mp);
14865   W (ret);
14866   return ret;
14867 }
14868
14869 static int
14870 api_want_l2_macs_events (vat_main_t * vam)
14871 {
14872   unformat_input_t *line_input = vam->input;
14873   vl_api_want_l2_macs_events_t *mp;
14874   u8 enable_disable = 1;
14875   u32 scan_delay = 0;
14876   u32 max_macs_in_event = 0;
14877   u32 learn_limit = 0;
14878   int ret;
14879
14880   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14881     {
14882       if (unformat (line_input, "learn-limit %d", &learn_limit))
14883         ;
14884       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14885         ;
14886       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14887         ;
14888       else if (unformat (line_input, "disable"))
14889         enable_disable = 0;
14890       else
14891         break;
14892     }
14893
14894   M (WANT_L2_MACS_EVENTS, mp);
14895   mp->enable_disable = enable_disable;
14896   mp->pid = htonl (getpid ());
14897   mp->learn_limit = htonl (learn_limit);
14898   mp->scan_delay = (u8) scan_delay;
14899   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14900   S (mp);
14901   W (ret);
14902   return ret;
14903 }
14904
14905 static int
14906 api_input_acl_set_interface (vat_main_t * vam)
14907 {
14908   unformat_input_t *i = vam->input;
14909   vl_api_input_acl_set_interface_t *mp;
14910   u32 sw_if_index;
14911   int sw_if_index_set;
14912   u32 ip4_table_index = ~0;
14913   u32 ip6_table_index = ~0;
14914   u32 l2_table_index = ~0;
14915   u8 is_add = 1;
14916   int ret;
14917
14918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14919     {
14920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14921         sw_if_index_set = 1;
14922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14923         sw_if_index_set = 1;
14924       else if (unformat (i, "del"))
14925         is_add = 0;
14926       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14927         ;
14928       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14929         ;
14930       else if (unformat (i, "l2-table %d", &l2_table_index))
14931         ;
14932       else
14933         {
14934           clib_warning ("parse error '%U'", format_unformat_error, i);
14935           return -99;
14936         }
14937     }
14938
14939   if (sw_if_index_set == 0)
14940     {
14941       errmsg ("missing interface name or sw_if_index");
14942       return -99;
14943     }
14944
14945   M (INPUT_ACL_SET_INTERFACE, mp);
14946
14947   mp->sw_if_index = ntohl (sw_if_index);
14948   mp->ip4_table_index = ntohl (ip4_table_index);
14949   mp->ip6_table_index = ntohl (ip6_table_index);
14950   mp->l2_table_index = ntohl (l2_table_index);
14951   mp->is_add = is_add;
14952
14953   S (mp);
14954   W (ret);
14955   return ret;
14956 }
14957
14958 static int
14959 api_output_acl_set_interface (vat_main_t * vam)
14960 {
14961   unformat_input_t *i = vam->input;
14962   vl_api_output_acl_set_interface_t *mp;
14963   u32 sw_if_index;
14964   int sw_if_index_set;
14965   u32 ip4_table_index = ~0;
14966   u32 ip6_table_index = ~0;
14967   u32 l2_table_index = ~0;
14968   u8 is_add = 1;
14969   int ret;
14970
14971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14972     {
14973       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14974         sw_if_index_set = 1;
14975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14976         sw_if_index_set = 1;
14977       else if (unformat (i, "del"))
14978         is_add = 0;
14979       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14980         ;
14981       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14982         ;
14983       else if (unformat (i, "l2-table %d", &l2_table_index))
14984         ;
14985       else
14986         {
14987           clib_warning ("parse error '%U'", format_unformat_error, i);
14988           return -99;
14989         }
14990     }
14991
14992   if (sw_if_index_set == 0)
14993     {
14994       errmsg ("missing interface name or sw_if_index");
14995       return -99;
14996     }
14997
14998   M (OUTPUT_ACL_SET_INTERFACE, mp);
14999
15000   mp->sw_if_index = ntohl (sw_if_index);
15001   mp->ip4_table_index = ntohl (ip4_table_index);
15002   mp->ip6_table_index = ntohl (ip6_table_index);
15003   mp->l2_table_index = ntohl (l2_table_index);
15004   mp->is_add = is_add;
15005
15006   S (mp);
15007   W (ret);
15008   return ret;
15009 }
15010
15011 static int
15012 api_ip_address_dump (vat_main_t * vam)
15013 {
15014   unformat_input_t *i = vam->input;
15015   vl_api_ip_address_dump_t *mp;
15016   vl_api_control_ping_t *mp_ping;
15017   u32 sw_if_index = ~0;
15018   u8 sw_if_index_set = 0;
15019   u8 ipv4_set = 0;
15020   u8 ipv6_set = 0;
15021   int ret;
15022
15023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15024     {
15025       if (unformat (i, "sw_if_index %d", &sw_if_index))
15026         sw_if_index_set = 1;
15027       else
15028         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15029         sw_if_index_set = 1;
15030       else if (unformat (i, "ipv4"))
15031         ipv4_set = 1;
15032       else if (unformat (i, "ipv6"))
15033         ipv6_set = 1;
15034       else
15035         break;
15036     }
15037
15038   if (ipv4_set && ipv6_set)
15039     {
15040       errmsg ("ipv4 and ipv6 flags cannot be both set");
15041       return -99;
15042     }
15043
15044   if ((!ipv4_set) && (!ipv6_set))
15045     {
15046       errmsg ("no ipv4 nor ipv6 flag set");
15047       return -99;
15048     }
15049
15050   if (sw_if_index_set == 0)
15051     {
15052       errmsg ("missing interface name or sw_if_index");
15053       return -99;
15054     }
15055
15056   vam->current_sw_if_index = sw_if_index;
15057   vam->is_ipv6 = ipv6_set;
15058
15059   M (IP_ADDRESS_DUMP, mp);
15060   mp->sw_if_index = ntohl (sw_if_index);
15061   mp->is_ipv6 = ipv6_set;
15062   S (mp);
15063
15064   /* Use a control ping for synchronization */
15065   MPING (CONTROL_PING, mp_ping);
15066   S (mp_ping);
15067
15068   W (ret);
15069   return ret;
15070 }
15071
15072 static int
15073 api_ip_dump (vat_main_t * vam)
15074 {
15075   vl_api_ip_dump_t *mp;
15076   vl_api_control_ping_t *mp_ping;
15077   unformat_input_t *in = vam->input;
15078   int ipv4_set = 0;
15079   int ipv6_set = 0;
15080   int is_ipv6;
15081   int i;
15082   int ret;
15083
15084   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15085     {
15086       if (unformat (in, "ipv4"))
15087         ipv4_set = 1;
15088       else if (unformat (in, "ipv6"))
15089         ipv6_set = 1;
15090       else
15091         break;
15092     }
15093
15094   if (ipv4_set && ipv6_set)
15095     {
15096       errmsg ("ipv4 and ipv6 flags cannot be both set");
15097       return -99;
15098     }
15099
15100   if ((!ipv4_set) && (!ipv6_set))
15101     {
15102       errmsg ("no ipv4 nor ipv6 flag set");
15103       return -99;
15104     }
15105
15106   is_ipv6 = ipv6_set;
15107   vam->is_ipv6 = is_ipv6;
15108
15109   /* free old data */
15110   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15111     {
15112       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15113     }
15114   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15115
15116   M (IP_DUMP, mp);
15117   mp->is_ipv6 = ipv6_set;
15118   S (mp);
15119
15120   /* Use a control ping for synchronization */
15121   MPING (CONTROL_PING, mp_ping);
15122   S (mp_ping);
15123
15124   W (ret);
15125   return ret;
15126 }
15127
15128 static int
15129 api_ipsec_spd_add_del (vat_main_t * vam)
15130 {
15131   unformat_input_t *i = vam->input;
15132   vl_api_ipsec_spd_add_del_t *mp;
15133   u32 spd_id = ~0;
15134   u8 is_add = 1;
15135   int ret;
15136
15137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15138     {
15139       if (unformat (i, "spd_id %d", &spd_id))
15140         ;
15141       else if (unformat (i, "del"))
15142         is_add = 0;
15143       else
15144         {
15145           clib_warning ("parse error '%U'", format_unformat_error, i);
15146           return -99;
15147         }
15148     }
15149   if (spd_id == ~0)
15150     {
15151       errmsg ("spd_id must be set");
15152       return -99;
15153     }
15154
15155   M (IPSEC_SPD_ADD_DEL, mp);
15156
15157   mp->spd_id = ntohl (spd_id);
15158   mp->is_add = is_add;
15159
15160   S (mp);
15161   W (ret);
15162   return ret;
15163 }
15164
15165 static int
15166 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15167 {
15168   unformat_input_t *i = vam->input;
15169   vl_api_ipsec_interface_add_del_spd_t *mp;
15170   u32 sw_if_index;
15171   u8 sw_if_index_set = 0;
15172   u32 spd_id = (u32) ~ 0;
15173   u8 is_add = 1;
15174   int ret;
15175
15176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15177     {
15178       if (unformat (i, "del"))
15179         is_add = 0;
15180       else if (unformat (i, "spd_id %d", &spd_id))
15181         ;
15182       else
15183         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15184         sw_if_index_set = 1;
15185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15186         sw_if_index_set = 1;
15187       else
15188         {
15189           clib_warning ("parse error '%U'", format_unformat_error, i);
15190           return -99;
15191         }
15192
15193     }
15194
15195   if (spd_id == (u32) ~ 0)
15196     {
15197       errmsg ("spd_id must be set");
15198       return -99;
15199     }
15200
15201   if (sw_if_index_set == 0)
15202     {
15203       errmsg ("missing interface name or sw_if_index");
15204       return -99;
15205     }
15206
15207   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15208
15209   mp->spd_id = ntohl (spd_id);
15210   mp->sw_if_index = ntohl (sw_if_index);
15211   mp->is_add = is_add;
15212
15213   S (mp);
15214   W (ret);
15215   return ret;
15216 }
15217
15218 static int
15219 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15220 {
15221   unformat_input_t *i = vam->input;
15222   vl_api_ipsec_spd_add_del_entry_t *mp;
15223   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15224   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15225   i32 priority = 0;
15226   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15227   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15228   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15229   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15230   int ret;
15231
15232   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15233   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15234   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15235   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15236   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15237   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15238
15239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (i, "del"))
15242         is_add = 0;
15243       if (unformat (i, "outbound"))
15244         is_outbound = 1;
15245       if (unformat (i, "inbound"))
15246         is_outbound = 0;
15247       else if (unformat (i, "spd_id %d", &spd_id))
15248         ;
15249       else if (unformat (i, "sa_id %d", &sa_id))
15250         ;
15251       else if (unformat (i, "priority %d", &priority))
15252         ;
15253       else if (unformat (i, "protocol %d", &protocol))
15254         ;
15255       else if (unformat (i, "lport_start %d", &lport_start))
15256         ;
15257       else if (unformat (i, "lport_stop %d", &lport_stop))
15258         ;
15259       else if (unformat (i, "rport_start %d", &rport_start))
15260         ;
15261       else if (unformat (i, "rport_stop %d", &rport_stop))
15262         ;
15263       else
15264         if (unformat
15265             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15266         {
15267           is_ipv6 = 0;
15268           is_ip_any = 0;
15269         }
15270       else
15271         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15272         {
15273           is_ipv6 = 0;
15274           is_ip_any = 0;
15275         }
15276       else
15277         if (unformat
15278             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15279         {
15280           is_ipv6 = 0;
15281           is_ip_any = 0;
15282         }
15283       else
15284         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15285         {
15286           is_ipv6 = 0;
15287           is_ip_any = 0;
15288         }
15289       else
15290         if (unformat
15291             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15292         {
15293           is_ipv6 = 1;
15294           is_ip_any = 0;
15295         }
15296       else
15297         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15298         {
15299           is_ipv6 = 1;
15300           is_ip_any = 0;
15301         }
15302       else
15303         if (unformat
15304             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15305         {
15306           is_ipv6 = 1;
15307           is_ip_any = 0;
15308         }
15309       else
15310         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15311         {
15312           is_ipv6 = 1;
15313           is_ip_any = 0;
15314         }
15315       else
15316         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15317         {
15318           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15319             {
15320               clib_warning ("unsupported action: 'resolve'");
15321               return -99;
15322             }
15323         }
15324       else
15325         {
15326           clib_warning ("parse error '%U'", format_unformat_error, i);
15327           return -99;
15328         }
15329
15330     }
15331
15332   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15333
15334   mp->spd_id = ntohl (spd_id);
15335   mp->priority = ntohl (priority);
15336   mp->is_outbound = is_outbound;
15337
15338   mp->is_ipv6 = is_ipv6;
15339   if (is_ipv6 || is_ip_any)
15340     {
15341       clib_memcpy (mp->remote_address_start, &raddr6_start,
15342                    sizeof (ip6_address_t));
15343       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15344                    sizeof (ip6_address_t));
15345       clib_memcpy (mp->local_address_start, &laddr6_start,
15346                    sizeof (ip6_address_t));
15347       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15348                    sizeof (ip6_address_t));
15349     }
15350   else
15351     {
15352       clib_memcpy (mp->remote_address_start, &raddr4_start,
15353                    sizeof (ip4_address_t));
15354       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15355                    sizeof (ip4_address_t));
15356       clib_memcpy (mp->local_address_start, &laddr4_start,
15357                    sizeof (ip4_address_t));
15358       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15359                    sizeof (ip4_address_t));
15360     }
15361   mp->protocol = (u8) protocol;
15362   mp->local_port_start = ntohs ((u16) lport_start);
15363   mp->local_port_stop = ntohs ((u16) lport_stop);
15364   mp->remote_port_start = ntohs ((u16) rport_start);
15365   mp->remote_port_stop = ntohs ((u16) rport_stop);
15366   mp->policy = (u8) policy;
15367   mp->sa_id = ntohl (sa_id);
15368   mp->is_add = is_add;
15369   mp->is_ip_any = is_ip_any;
15370   S (mp);
15371   W (ret);
15372   return ret;
15373 }
15374
15375 static int
15376 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15377 {
15378   unformat_input_t *i = vam->input;
15379   vl_api_ipsec_sad_add_del_entry_t *mp;
15380   u32 sad_id = 0, spi = 0;
15381   u8 *ck = 0, *ik = 0;
15382   u8 is_add = 1;
15383
15384   u8 protocol = IPSEC_PROTOCOL_AH;
15385   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15386   u32 crypto_alg = 0, integ_alg = 0;
15387   ip4_address_t tun_src4;
15388   ip4_address_t tun_dst4;
15389   ip6_address_t tun_src6;
15390   ip6_address_t tun_dst6;
15391   int ret;
15392
15393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15394     {
15395       if (unformat (i, "del"))
15396         is_add = 0;
15397       else if (unformat (i, "sad_id %d", &sad_id))
15398         ;
15399       else if (unformat (i, "spi %d", &spi))
15400         ;
15401       else if (unformat (i, "esp"))
15402         protocol = IPSEC_PROTOCOL_ESP;
15403       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15404         {
15405           is_tunnel = 1;
15406           is_tunnel_ipv6 = 0;
15407         }
15408       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15409         {
15410           is_tunnel = 1;
15411           is_tunnel_ipv6 = 0;
15412         }
15413       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15414         {
15415           is_tunnel = 1;
15416           is_tunnel_ipv6 = 1;
15417         }
15418       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15419         {
15420           is_tunnel = 1;
15421           is_tunnel_ipv6 = 1;
15422         }
15423       else
15424         if (unformat
15425             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15426         {
15427           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15428             {
15429               clib_warning ("unsupported crypto-alg: '%U'",
15430                             format_ipsec_crypto_alg, crypto_alg);
15431               return -99;
15432             }
15433         }
15434       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15435         ;
15436       else
15437         if (unformat
15438             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15439         {
15440           if (integ_alg >= IPSEC_INTEG_N_ALG)
15441             {
15442               clib_warning ("unsupported integ-alg: '%U'",
15443                             format_ipsec_integ_alg, integ_alg);
15444               return -99;
15445             }
15446         }
15447       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15448         ;
15449       else
15450         {
15451           clib_warning ("parse error '%U'", format_unformat_error, i);
15452           return -99;
15453         }
15454
15455     }
15456
15457   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15458
15459   mp->sad_id = ntohl (sad_id);
15460   mp->is_add = is_add;
15461   mp->protocol = protocol;
15462   mp->spi = ntohl (spi);
15463   mp->is_tunnel = is_tunnel;
15464   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15465   mp->crypto_algorithm = crypto_alg;
15466   mp->integrity_algorithm = integ_alg;
15467   mp->crypto_key_length = vec_len (ck);
15468   mp->integrity_key_length = vec_len (ik);
15469
15470   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15471     mp->crypto_key_length = sizeof (mp->crypto_key);
15472
15473   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15474     mp->integrity_key_length = sizeof (mp->integrity_key);
15475
15476   if (ck)
15477     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15478   if (ik)
15479     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15480
15481   if (is_tunnel)
15482     {
15483       if (is_tunnel_ipv6)
15484         {
15485           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15486                        sizeof (ip6_address_t));
15487           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15488                        sizeof (ip6_address_t));
15489         }
15490       else
15491         {
15492           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15493                        sizeof (ip4_address_t));
15494           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15495                        sizeof (ip4_address_t));
15496         }
15497     }
15498
15499   S (mp);
15500   W (ret);
15501   return ret;
15502 }
15503
15504 static int
15505 api_ipsec_sa_set_key (vat_main_t * vam)
15506 {
15507   unformat_input_t *i = vam->input;
15508   vl_api_ipsec_sa_set_key_t *mp;
15509   u32 sa_id;
15510   u8 *ck = 0, *ik = 0;
15511   int ret;
15512
15513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15514     {
15515       if (unformat (i, "sa_id %d", &sa_id))
15516         ;
15517       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15518         ;
15519       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15520         ;
15521       else
15522         {
15523           clib_warning ("parse error '%U'", format_unformat_error, i);
15524           return -99;
15525         }
15526     }
15527
15528   M (IPSEC_SA_SET_KEY, mp);
15529
15530   mp->sa_id = ntohl (sa_id);
15531   mp->crypto_key_length = vec_len (ck);
15532   mp->integrity_key_length = vec_len (ik);
15533
15534   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15535     mp->crypto_key_length = sizeof (mp->crypto_key);
15536
15537   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15538     mp->integrity_key_length = sizeof (mp->integrity_key);
15539
15540   if (ck)
15541     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15542   if (ik)
15543     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15544
15545   S (mp);
15546   W (ret);
15547   return ret;
15548 }
15549
15550 static int
15551 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15552 {
15553   unformat_input_t *i = vam->input;
15554   vl_api_ipsec_tunnel_if_add_del_t *mp;
15555   u32 local_spi = 0, remote_spi = 0;
15556   u32 crypto_alg = 0, integ_alg = 0;
15557   u8 *lck = NULL, *rck = NULL;
15558   u8 *lik = NULL, *rik = NULL;
15559   ip4_address_t local_ip = { {0} };
15560   ip4_address_t remote_ip = { {0} };
15561   u8 is_add = 1;
15562   u8 esn = 0;
15563   u8 anti_replay = 0;
15564   u8 renumber = 0;
15565   u32 instance = ~0;
15566   int ret;
15567
15568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15569     {
15570       if (unformat (i, "del"))
15571         is_add = 0;
15572       else if (unformat (i, "esn"))
15573         esn = 1;
15574       else if (unformat (i, "anti_replay"))
15575         anti_replay = 1;
15576       else if (unformat (i, "local_spi %d", &local_spi))
15577         ;
15578       else if (unformat (i, "remote_spi %d", &remote_spi))
15579         ;
15580       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15581         ;
15582       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15583         ;
15584       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15585         ;
15586       else
15587         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15588         ;
15589       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15590         ;
15591       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15592         ;
15593       else
15594         if (unformat
15595             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15596         {
15597           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15598             {
15599               errmsg ("unsupported crypto-alg: '%U'\n",
15600                       format_ipsec_crypto_alg, crypto_alg);
15601               return -99;
15602             }
15603         }
15604       else
15605         if (unformat
15606             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15607         {
15608           if (integ_alg >= IPSEC_INTEG_N_ALG)
15609             {
15610               errmsg ("unsupported integ-alg: '%U'\n",
15611                       format_ipsec_integ_alg, integ_alg);
15612               return -99;
15613             }
15614         }
15615       else if (unformat (i, "instance %u", &instance))
15616         renumber = 1;
15617       else
15618         {
15619           errmsg ("parse error '%U'\n", format_unformat_error, i);
15620           return -99;
15621         }
15622     }
15623
15624   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15625
15626   mp->is_add = is_add;
15627   mp->esn = esn;
15628   mp->anti_replay = anti_replay;
15629
15630   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15631   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15632
15633   mp->local_spi = htonl (local_spi);
15634   mp->remote_spi = htonl (remote_spi);
15635   mp->crypto_alg = (u8) crypto_alg;
15636
15637   mp->local_crypto_key_len = 0;
15638   if (lck)
15639     {
15640       mp->local_crypto_key_len = vec_len (lck);
15641       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15642         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15643       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15644     }
15645
15646   mp->remote_crypto_key_len = 0;
15647   if (rck)
15648     {
15649       mp->remote_crypto_key_len = vec_len (rck);
15650       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15651         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15652       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15653     }
15654
15655   mp->integ_alg = (u8) integ_alg;
15656
15657   mp->local_integ_key_len = 0;
15658   if (lik)
15659     {
15660       mp->local_integ_key_len = vec_len (lik);
15661       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15662         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15663       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15664     }
15665
15666   mp->remote_integ_key_len = 0;
15667   if (rik)
15668     {
15669       mp->remote_integ_key_len = vec_len (rik);
15670       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15671         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15672       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15673     }
15674
15675   if (renumber)
15676     {
15677       mp->renumber = renumber;
15678       mp->show_instance = ntohl (instance);
15679     }
15680
15681   S (mp);
15682   W (ret);
15683   return ret;
15684 }
15685
15686 static void
15687 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15688 {
15689   vat_main_t *vam = &vat_main;
15690
15691   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15692          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15693          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15694          "tunnel_src_addr %U tunnel_dst_addr %U "
15695          "salt %u seq_outbound %lu last_seq_inbound %lu "
15696          "replay_window %lu total_data_size %lu\n",
15697          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15698          mp->protocol,
15699          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15700          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15701          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15702          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15703          mp->tunnel_src_addr,
15704          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15705          mp->tunnel_dst_addr,
15706          ntohl (mp->salt),
15707          clib_net_to_host_u64 (mp->seq_outbound),
15708          clib_net_to_host_u64 (mp->last_seq_inbound),
15709          clib_net_to_host_u64 (mp->replay_window),
15710          clib_net_to_host_u64 (mp->total_data_size));
15711 }
15712
15713 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15714 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15715
15716 static void vl_api_ipsec_sa_details_t_handler_json
15717   (vl_api_ipsec_sa_details_t * mp)
15718 {
15719   vat_main_t *vam = &vat_main;
15720   vat_json_node_t *node = NULL;
15721   struct in_addr src_ip4, dst_ip4;
15722   struct in6_addr src_ip6, dst_ip6;
15723
15724   if (VAT_JSON_ARRAY != vam->json_tree.type)
15725     {
15726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15727       vat_json_init_array (&vam->json_tree);
15728     }
15729   node = vat_json_array_add (&vam->json_tree);
15730
15731   vat_json_init_object (node);
15732   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15733   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15734   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15735   vat_json_object_add_uint (node, "proto", mp->protocol);
15736   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15737   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15738   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15739   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15740   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15741   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15742   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15743                              mp->crypto_key_len);
15744   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15745                              mp->integ_key_len);
15746   if (mp->is_tunnel_ip6)
15747     {
15748       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15749       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15750       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15751       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15752     }
15753   else
15754     {
15755       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15756       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15757       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15758       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15759     }
15760   vat_json_object_add_uint (node, "replay_window",
15761                             clib_net_to_host_u64 (mp->replay_window));
15762   vat_json_object_add_uint (node, "total_data_size",
15763                             clib_net_to_host_u64 (mp->total_data_size));
15764
15765 }
15766
15767 static int
15768 api_ipsec_sa_dump (vat_main_t * vam)
15769 {
15770   unformat_input_t *i = vam->input;
15771   vl_api_ipsec_sa_dump_t *mp;
15772   vl_api_control_ping_t *mp_ping;
15773   u32 sa_id = ~0;
15774   int ret;
15775
15776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15777     {
15778       if (unformat (i, "sa_id %d", &sa_id))
15779         ;
15780       else
15781         {
15782           clib_warning ("parse error '%U'", format_unformat_error, i);
15783           return -99;
15784         }
15785     }
15786
15787   M (IPSEC_SA_DUMP, mp);
15788
15789   mp->sa_id = ntohl (sa_id);
15790
15791   S (mp);
15792
15793   /* Use a control ping for synchronization */
15794   M (CONTROL_PING, mp_ping);
15795   S (mp_ping);
15796
15797   W (ret);
15798   return ret;
15799 }
15800
15801 static int
15802 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15803 {
15804   unformat_input_t *i = vam->input;
15805   vl_api_ipsec_tunnel_if_set_key_t *mp;
15806   u32 sw_if_index = ~0;
15807   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15808   u8 *key = 0;
15809   u32 alg = ~0;
15810   int ret;
15811
15812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15813     {
15814       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15815         ;
15816       else
15817         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15818         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15819       else
15820         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15821         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15822       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15823         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15824       else
15825         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15826         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15827       else if (unformat (i, "%U", unformat_hex_string, &key))
15828         ;
15829       else
15830         {
15831           clib_warning ("parse error '%U'", format_unformat_error, i);
15832           return -99;
15833         }
15834     }
15835
15836   if (sw_if_index == ~0)
15837     {
15838       errmsg ("interface must be specified");
15839       return -99;
15840     }
15841
15842   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15843     {
15844       errmsg ("key type must be specified");
15845       return -99;
15846     }
15847
15848   if (alg == ~0)
15849     {
15850       errmsg ("algorithm must be specified");
15851       return -99;
15852     }
15853
15854   if (vec_len (key) == 0)
15855     {
15856       errmsg ("key must be specified");
15857       return -99;
15858     }
15859
15860   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15861
15862   mp->sw_if_index = htonl (sw_if_index);
15863   mp->alg = alg;
15864   mp->key_type = key_type;
15865   mp->key_len = vec_len (key);
15866   clib_memcpy (mp->key, key, vec_len (key));
15867
15868   S (mp);
15869   W (ret);
15870
15871   return ret;
15872 }
15873
15874 static int
15875 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15876 {
15877   unformat_input_t *i = vam->input;
15878   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15879   u32 sw_if_index = ~0;
15880   u32 sa_id = ~0;
15881   u8 is_outbound = (u8) ~ 0;
15882   int ret;
15883
15884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15885     {
15886       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15887         ;
15888       else if (unformat (i, "sa_id %d", &sa_id))
15889         ;
15890       else if (unformat (i, "outbound"))
15891         is_outbound = 1;
15892       else if (unformat (i, "inbound"))
15893         is_outbound = 0;
15894       else
15895         {
15896           clib_warning ("parse error '%U'", format_unformat_error, i);
15897           return -99;
15898         }
15899     }
15900
15901   if (sw_if_index == ~0)
15902     {
15903       errmsg ("interface must be specified");
15904       return -99;
15905     }
15906
15907   if (sa_id == ~0)
15908     {
15909       errmsg ("SA ID must be specified");
15910       return -99;
15911     }
15912
15913   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15914
15915   mp->sw_if_index = htonl (sw_if_index);
15916   mp->sa_id = htonl (sa_id);
15917   mp->is_outbound = is_outbound;
15918
15919   S (mp);
15920   W (ret);
15921
15922   return ret;
15923 }
15924
15925 static int
15926 api_ikev2_profile_add_del (vat_main_t * vam)
15927 {
15928   unformat_input_t *i = vam->input;
15929   vl_api_ikev2_profile_add_del_t *mp;
15930   u8 is_add = 1;
15931   u8 *name = 0;
15932   int ret;
15933
15934   const char *valid_chars = "a-zA-Z0-9_";
15935
15936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15937     {
15938       if (unformat (i, "del"))
15939         is_add = 0;
15940       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15941         vec_add1 (name, 0);
15942       else
15943         {
15944           errmsg ("parse error '%U'", format_unformat_error, i);
15945           return -99;
15946         }
15947     }
15948
15949   if (!vec_len (name))
15950     {
15951       errmsg ("profile name must be specified");
15952       return -99;
15953     }
15954
15955   if (vec_len (name) > 64)
15956     {
15957       errmsg ("profile name too long");
15958       return -99;
15959     }
15960
15961   M (IKEV2_PROFILE_ADD_DEL, mp);
15962
15963   clib_memcpy (mp->name, name, vec_len (name));
15964   mp->is_add = is_add;
15965   vec_free (name);
15966
15967   S (mp);
15968   W (ret);
15969   return ret;
15970 }
15971
15972 static int
15973 api_ikev2_profile_set_auth (vat_main_t * vam)
15974 {
15975   unformat_input_t *i = vam->input;
15976   vl_api_ikev2_profile_set_auth_t *mp;
15977   u8 *name = 0;
15978   u8 *data = 0;
15979   u32 auth_method = 0;
15980   u8 is_hex = 0;
15981   int ret;
15982
15983   const char *valid_chars = "a-zA-Z0-9_";
15984
15985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15986     {
15987       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15988         vec_add1 (name, 0);
15989       else if (unformat (i, "auth_method %U",
15990                          unformat_ikev2_auth_method, &auth_method))
15991         ;
15992       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
15993         is_hex = 1;
15994       else if (unformat (i, "auth_data %v", &data))
15995         ;
15996       else
15997         {
15998           errmsg ("parse error '%U'", format_unformat_error, i);
15999           return -99;
16000         }
16001     }
16002
16003   if (!vec_len (name))
16004     {
16005       errmsg ("profile name must be specified");
16006       return -99;
16007     }
16008
16009   if (vec_len (name) > 64)
16010     {
16011       errmsg ("profile name too long");
16012       return -99;
16013     }
16014
16015   if (!vec_len (data))
16016     {
16017       errmsg ("auth_data must be specified");
16018       return -99;
16019     }
16020
16021   if (!auth_method)
16022     {
16023       errmsg ("auth_method must be specified");
16024       return -99;
16025     }
16026
16027   M (IKEV2_PROFILE_SET_AUTH, mp);
16028
16029   mp->is_hex = is_hex;
16030   mp->auth_method = (u8) auth_method;
16031   mp->data_len = vec_len (data);
16032   clib_memcpy (mp->name, name, vec_len (name));
16033   clib_memcpy (mp->data, data, vec_len (data));
16034   vec_free (name);
16035   vec_free (data);
16036
16037   S (mp);
16038   W (ret);
16039   return ret;
16040 }
16041
16042 static int
16043 api_ikev2_profile_set_id (vat_main_t * vam)
16044 {
16045   unformat_input_t *i = vam->input;
16046   vl_api_ikev2_profile_set_id_t *mp;
16047   u8 *name = 0;
16048   u8 *data = 0;
16049   u8 is_local = 0;
16050   u32 id_type = 0;
16051   ip4_address_t ip4;
16052   int ret;
16053
16054   const char *valid_chars = "a-zA-Z0-9_";
16055
16056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16057     {
16058       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16059         vec_add1 (name, 0);
16060       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16061         ;
16062       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16063         {
16064           data = vec_new (u8, 4);
16065           clib_memcpy (data, ip4.as_u8, 4);
16066         }
16067       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16068         ;
16069       else if (unformat (i, "id_data %v", &data))
16070         ;
16071       else if (unformat (i, "local"))
16072         is_local = 1;
16073       else if (unformat (i, "remote"))
16074         is_local = 0;
16075       else
16076         {
16077           errmsg ("parse error '%U'", format_unformat_error, i);
16078           return -99;
16079         }
16080     }
16081
16082   if (!vec_len (name))
16083     {
16084       errmsg ("profile name must be specified");
16085       return -99;
16086     }
16087
16088   if (vec_len (name) > 64)
16089     {
16090       errmsg ("profile name too long");
16091       return -99;
16092     }
16093
16094   if (!vec_len (data))
16095     {
16096       errmsg ("id_data must be specified");
16097       return -99;
16098     }
16099
16100   if (!id_type)
16101     {
16102       errmsg ("id_type must be specified");
16103       return -99;
16104     }
16105
16106   M (IKEV2_PROFILE_SET_ID, mp);
16107
16108   mp->is_local = is_local;
16109   mp->id_type = (u8) id_type;
16110   mp->data_len = vec_len (data);
16111   clib_memcpy (mp->name, name, vec_len (name));
16112   clib_memcpy (mp->data, data, vec_len (data));
16113   vec_free (name);
16114   vec_free (data);
16115
16116   S (mp);
16117   W (ret);
16118   return ret;
16119 }
16120
16121 static int
16122 api_ikev2_profile_set_ts (vat_main_t * vam)
16123 {
16124   unformat_input_t *i = vam->input;
16125   vl_api_ikev2_profile_set_ts_t *mp;
16126   u8 *name = 0;
16127   u8 is_local = 0;
16128   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16129   ip4_address_t start_addr, end_addr;
16130
16131   const char *valid_chars = "a-zA-Z0-9_";
16132   int ret;
16133
16134   start_addr.as_u32 = 0;
16135   end_addr.as_u32 = (u32) ~ 0;
16136
16137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16138     {
16139       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16140         vec_add1 (name, 0);
16141       else if (unformat (i, "protocol %d", &proto))
16142         ;
16143       else if (unformat (i, "start_port %d", &start_port))
16144         ;
16145       else if (unformat (i, "end_port %d", &end_port))
16146         ;
16147       else
16148         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16149         ;
16150       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16151         ;
16152       else if (unformat (i, "local"))
16153         is_local = 1;
16154       else if (unformat (i, "remote"))
16155         is_local = 0;
16156       else
16157         {
16158           errmsg ("parse error '%U'", format_unformat_error, i);
16159           return -99;
16160         }
16161     }
16162
16163   if (!vec_len (name))
16164     {
16165       errmsg ("profile name must be specified");
16166       return -99;
16167     }
16168
16169   if (vec_len (name) > 64)
16170     {
16171       errmsg ("profile name too long");
16172       return -99;
16173     }
16174
16175   M (IKEV2_PROFILE_SET_TS, mp);
16176
16177   mp->is_local = is_local;
16178   mp->proto = (u8) proto;
16179   mp->start_port = (u16) start_port;
16180   mp->end_port = (u16) end_port;
16181   mp->start_addr = start_addr.as_u32;
16182   mp->end_addr = end_addr.as_u32;
16183   clib_memcpy (mp->name, name, vec_len (name));
16184   vec_free (name);
16185
16186   S (mp);
16187   W (ret);
16188   return ret;
16189 }
16190
16191 static int
16192 api_ikev2_set_local_key (vat_main_t * vam)
16193 {
16194   unformat_input_t *i = vam->input;
16195   vl_api_ikev2_set_local_key_t *mp;
16196   u8 *file = 0;
16197   int ret;
16198
16199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16200     {
16201       if (unformat (i, "file %v", &file))
16202         vec_add1 (file, 0);
16203       else
16204         {
16205           errmsg ("parse error '%U'", format_unformat_error, i);
16206           return -99;
16207         }
16208     }
16209
16210   if (!vec_len (file))
16211     {
16212       errmsg ("RSA key file must be specified");
16213       return -99;
16214     }
16215
16216   if (vec_len (file) > 256)
16217     {
16218       errmsg ("file name too long");
16219       return -99;
16220     }
16221
16222   M (IKEV2_SET_LOCAL_KEY, mp);
16223
16224   clib_memcpy (mp->key_file, file, vec_len (file));
16225   vec_free (file);
16226
16227   S (mp);
16228   W (ret);
16229   return ret;
16230 }
16231
16232 static int
16233 api_ikev2_set_responder (vat_main_t * vam)
16234 {
16235   unformat_input_t *i = vam->input;
16236   vl_api_ikev2_set_responder_t *mp;
16237   int ret;
16238   u8 *name = 0;
16239   u32 sw_if_index = ~0;
16240   ip4_address_t address;
16241
16242   const char *valid_chars = "a-zA-Z0-9_";
16243
16244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16245     {
16246       if (unformat
16247           (i, "%U interface %d address %U", unformat_token, valid_chars,
16248            &name, &sw_if_index, unformat_ip4_address, &address))
16249         vec_add1 (name, 0);
16250       else
16251         {
16252           errmsg ("parse error '%U'", format_unformat_error, i);
16253           return -99;
16254         }
16255     }
16256
16257   if (!vec_len (name))
16258     {
16259       errmsg ("profile name must be specified");
16260       return -99;
16261     }
16262
16263   if (vec_len (name) > 64)
16264     {
16265       errmsg ("profile name too long");
16266       return -99;
16267     }
16268
16269   M (IKEV2_SET_RESPONDER, mp);
16270
16271   clib_memcpy (mp->name, name, vec_len (name));
16272   vec_free (name);
16273
16274   mp->sw_if_index = sw_if_index;
16275   clib_memcpy (mp->address, &address, sizeof (address));
16276
16277   S (mp);
16278   W (ret);
16279   return ret;
16280 }
16281
16282 static int
16283 api_ikev2_set_ike_transforms (vat_main_t * vam)
16284 {
16285   unformat_input_t *i = vam->input;
16286   vl_api_ikev2_set_ike_transforms_t *mp;
16287   int ret;
16288   u8 *name = 0;
16289   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16290
16291   const char *valid_chars = "a-zA-Z0-9_";
16292
16293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16294     {
16295       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16296                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16297         vec_add1 (name, 0);
16298       else
16299         {
16300           errmsg ("parse error '%U'", format_unformat_error, i);
16301           return -99;
16302         }
16303     }
16304
16305   if (!vec_len (name))
16306     {
16307       errmsg ("profile name must be specified");
16308       return -99;
16309     }
16310
16311   if (vec_len (name) > 64)
16312     {
16313       errmsg ("profile name too long");
16314       return -99;
16315     }
16316
16317   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16318
16319   clib_memcpy (mp->name, name, vec_len (name));
16320   vec_free (name);
16321   mp->crypto_alg = crypto_alg;
16322   mp->crypto_key_size = crypto_key_size;
16323   mp->integ_alg = integ_alg;
16324   mp->dh_group = dh_group;
16325
16326   S (mp);
16327   W (ret);
16328   return ret;
16329 }
16330
16331
16332 static int
16333 api_ikev2_set_esp_transforms (vat_main_t * vam)
16334 {
16335   unformat_input_t *i = vam->input;
16336   vl_api_ikev2_set_esp_transforms_t *mp;
16337   int ret;
16338   u8 *name = 0;
16339   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16340
16341   const char *valid_chars = "a-zA-Z0-9_";
16342
16343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16344     {
16345       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16346                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16347         vec_add1 (name, 0);
16348       else
16349         {
16350           errmsg ("parse error '%U'", format_unformat_error, i);
16351           return -99;
16352         }
16353     }
16354
16355   if (!vec_len (name))
16356     {
16357       errmsg ("profile name must be specified");
16358       return -99;
16359     }
16360
16361   if (vec_len (name) > 64)
16362     {
16363       errmsg ("profile name too long");
16364       return -99;
16365     }
16366
16367   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16368
16369   clib_memcpy (mp->name, name, vec_len (name));
16370   vec_free (name);
16371   mp->crypto_alg = crypto_alg;
16372   mp->crypto_key_size = crypto_key_size;
16373   mp->integ_alg = integ_alg;
16374   mp->dh_group = dh_group;
16375
16376   S (mp);
16377   W (ret);
16378   return ret;
16379 }
16380
16381 static int
16382 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16383 {
16384   unformat_input_t *i = vam->input;
16385   vl_api_ikev2_set_sa_lifetime_t *mp;
16386   int ret;
16387   u8 *name = 0;
16388   u64 lifetime, lifetime_maxdata;
16389   u32 lifetime_jitter, handover;
16390
16391   const char *valid_chars = "a-zA-Z0-9_";
16392
16393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16394     {
16395       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16396                     &lifetime, &lifetime_jitter, &handover,
16397                     &lifetime_maxdata))
16398         vec_add1 (name, 0);
16399       else
16400         {
16401           errmsg ("parse error '%U'", format_unformat_error, i);
16402           return -99;
16403         }
16404     }
16405
16406   if (!vec_len (name))
16407     {
16408       errmsg ("profile name must be specified");
16409       return -99;
16410     }
16411
16412   if (vec_len (name) > 64)
16413     {
16414       errmsg ("profile name too long");
16415       return -99;
16416     }
16417
16418   M (IKEV2_SET_SA_LIFETIME, mp);
16419
16420   clib_memcpy (mp->name, name, vec_len (name));
16421   vec_free (name);
16422   mp->lifetime = lifetime;
16423   mp->lifetime_jitter = lifetime_jitter;
16424   mp->handover = handover;
16425   mp->lifetime_maxdata = lifetime_maxdata;
16426
16427   S (mp);
16428   W (ret);
16429   return ret;
16430 }
16431
16432 static int
16433 api_ikev2_initiate_sa_init (vat_main_t * vam)
16434 {
16435   unformat_input_t *i = vam->input;
16436   vl_api_ikev2_initiate_sa_init_t *mp;
16437   int ret;
16438   u8 *name = 0;
16439
16440   const char *valid_chars = "a-zA-Z0-9_";
16441
16442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16443     {
16444       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16445         vec_add1 (name, 0);
16446       else
16447         {
16448           errmsg ("parse error '%U'", format_unformat_error, i);
16449           return -99;
16450         }
16451     }
16452
16453   if (!vec_len (name))
16454     {
16455       errmsg ("profile name must be specified");
16456       return -99;
16457     }
16458
16459   if (vec_len (name) > 64)
16460     {
16461       errmsg ("profile name too long");
16462       return -99;
16463     }
16464
16465   M (IKEV2_INITIATE_SA_INIT, mp);
16466
16467   clib_memcpy (mp->name, name, vec_len (name));
16468   vec_free (name);
16469
16470   S (mp);
16471   W (ret);
16472   return ret;
16473 }
16474
16475 static int
16476 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16477 {
16478   unformat_input_t *i = vam->input;
16479   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16480   int ret;
16481   u64 ispi;
16482
16483
16484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16485     {
16486       if (unformat (i, "%lx", &ispi))
16487         ;
16488       else
16489         {
16490           errmsg ("parse error '%U'", format_unformat_error, i);
16491           return -99;
16492         }
16493     }
16494
16495   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16496
16497   mp->ispi = ispi;
16498
16499   S (mp);
16500   W (ret);
16501   return ret;
16502 }
16503
16504 static int
16505 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16506 {
16507   unformat_input_t *i = vam->input;
16508   vl_api_ikev2_initiate_del_child_sa_t *mp;
16509   int ret;
16510   u32 ispi;
16511
16512
16513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16514     {
16515       if (unformat (i, "%x", &ispi))
16516         ;
16517       else
16518         {
16519           errmsg ("parse error '%U'", format_unformat_error, i);
16520           return -99;
16521         }
16522     }
16523
16524   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16525
16526   mp->ispi = ispi;
16527
16528   S (mp);
16529   W (ret);
16530   return ret;
16531 }
16532
16533 static int
16534 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16535 {
16536   unformat_input_t *i = vam->input;
16537   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16538   int ret;
16539   u32 ispi;
16540
16541
16542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16543     {
16544       if (unformat (i, "%x", &ispi))
16545         ;
16546       else
16547         {
16548           errmsg ("parse error '%U'", format_unformat_error, i);
16549           return -99;
16550         }
16551     }
16552
16553   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16554
16555   mp->ispi = ispi;
16556
16557   S (mp);
16558   W (ret);
16559   return ret;
16560 }
16561
16562 static int
16563 api_get_first_msg_id (vat_main_t * vam)
16564 {
16565   vl_api_get_first_msg_id_t *mp;
16566   unformat_input_t *i = vam->input;
16567   u8 *name;
16568   u8 name_set = 0;
16569   int ret;
16570
16571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (i, "client %s", &name))
16574         name_set = 1;
16575       else
16576         break;
16577     }
16578
16579   if (name_set == 0)
16580     {
16581       errmsg ("missing client name");
16582       return -99;
16583     }
16584   vec_add1 (name, 0);
16585
16586   if (vec_len (name) > 63)
16587     {
16588       errmsg ("client name too long");
16589       return -99;
16590     }
16591
16592   M (GET_FIRST_MSG_ID, mp);
16593   clib_memcpy (mp->name, name, vec_len (name));
16594   S (mp);
16595   W (ret);
16596   return ret;
16597 }
16598
16599 static int
16600 api_cop_interface_enable_disable (vat_main_t * vam)
16601 {
16602   unformat_input_t *line_input = vam->input;
16603   vl_api_cop_interface_enable_disable_t *mp;
16604   u32 sw_if_index = ~0;
16605   u8 enable_disable = 1;
16606   int ret;
16607
16608   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16609     {
16610       if (unformat (line_input, "disable"))
16611         enable_disable = 0;
16612       if (unformat (line_input, "enable"))
16613         enable_disable = 1;
16614       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16615                          vam, &sw_if_index))
16616         ;
16617       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16618         ;
16619       else
16620         break;
16621     }
16622
16623   if (sw_if_index == ~0)
16624     {
16625       errmsg ("missing interface name or sw_if_index");
16626       return -99;
16627     }
16628
16629   /* Construct the API message */
16630   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16631   mp->sw_if_index = ntohl (sw_if_index);
16632   mp->enable_disable = enable_disable;
16633
16634   /* send it... */
16635   S (mp);
16636   /* Wait for the reply */
16637   W (ret);
16638   return ret;
16639 }
16640
16641 static int
16642 api_cop_whitelist_enable_disable (vat_main_t * vam)
16643 {
16644   unformat_input_t *line_input = vam->input;
16645   vl_api_cop_whitelist_enable_disable_t *mp;
16646   u32 sw_if_index = ~0;
16647   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16648   u32 fib_id = 0;
16649   int ret;
16650
16651   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16652     {
16653       if (unformat (line_input, "ip4"))
16654         ip4 = 1;
16655       else if (unformat (line_input, "ip6"))
16656         ip6 = 1;
16657       else if (unformat (line_input, "default"))
16658         default_cop = 1;
16659       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16660                          vam, &sw_if_index))
16661         ;
16662       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16663         ;
16664       else if (unformat (line_input, "fib-id %d", &fib_id))
16665         ;
16666       else
16667         break;
16668     }
16669
16670   if (sw_if_index == ~0)
16671     {
16672       errmsg ("missing interface name or sw_if_index");
16673       return -99;
16674     }
16675
16676   /* Construct the API message */
16677   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16678   mp->sw_if_index = ntohl (sw_if_index);
16679   mp->fib_id = ntohl (fib_id);
16680   mp->ip4 = ip4;
16681   mp->ip6 = ip6;
16682   mp->default_cop = default_cop;
16683
16684   /* send it... */
16685   S (mp);
16686   /* Wait for the reply */
16687   W (ret);
16688   return ret;
16689 }
16690
16691 static int
16692 api_get_node_graph (vat_main_t * vam)
16693 {
16694   vl_api_get_node_graph_t *mp;
16695   int ret;
16696
16697   M (GET_NODE_GRAPH, mp);
16698
16699   /* send it... */
16700   S (mp);
16701   /* Wait for the reply */
16702   W (ret);
16703   return ret;
16704 }
16705
16706 /* *INDENT-OFF* */
16707 /** Used for parsing LISP eids */
16708 typedef CLIB_PACKED(struct{
16709   u8 addr[16];   /**< eid address */
16710   u32 len;       /**< prefix length if IP */
16711   u8 type;      /**< type of eid */
16712 }) lisp_eid_vat_t;
16713 /* *INDENT-ON* */
16714
16715 static uword
16716 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16717 {
16718   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16719
16720   memset (a, 0, sizeof (a[0]));
16721
16722   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16723     {
16724       a->type = 0;              /* ipv4 type */
16725     }
16726   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16727     {
16728       a->type = 1;              /* ipv6 type */
16729     }
16730   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16731     {
16732       a->type = 2;              /* mac type */
16733     }
16734   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16735     {
16736       a->type = 3;              /* NSH type */
16737       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16738       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16739     }
16740   else
16741     {
16742       return 0;
16743     }
16744
16745   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16746     {
16747       return 0;
16748     }
16749
16750   return 1;
16751 }
16752
16753 static int
16754 lisp_eid_size_vat (u8 type)
16755 {
16756   switch (type)
16757     {
16758     case 0:
16759       return 4;
16760     case 1:
16761       return 16;
16762     case 2:
16763       return 6;
16764     case 3:
16765       return 5;
16766     }
16767   return 0;
16768 }
16769
16770 static void
16771 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16772 {
16773   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16774 }
16775
16776 static int
16777 api_one_add_del_locator_set (vat_main_t * vam)
16778 {
16779   unformat_input_t *input = vam->input;
16780   vl_api_one_add_del_locator_set_t *mp;
16781   u8 is_add = 1;
16782   u8 *locator_set_name = NULL;
16783   u8 locator_set_name_set = 0;
16784   vl_api_local_locator_t locator, *locators = 0;
16785   u32 sw_if_index, priority, weight;
16786   u32 data_len = 0;
16787
16788   int ret;
16789   /* Parse args required to build the message */
16790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16791     {
16792       if (unformat (input, "del"))
16793         {
16794           is_add = 0;
16795         }
16796       else if (unformat (input, "locator-set %s", &locator_set_name))
16797         {
16798           locator_set_name_set = 1;
16799         }
16800       else if (unformat (input, "sw_if_index %u p %u w %u",
16801                          &sw_if_index, &priority, &weight))
16802         {
16803           locator.sw_if_index = htonl (sw_if_index);
16804           locator.priority = priority;
16805           locator.weight = weight;
16806           vec_add1 (locators, locator);
16807         }
16808       else
16809         if (unformat
16810             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16811              &sw_if_index, &priority, &weight))
16812         {
16813           locator.sw_if_index = htonl (sw_if_index);
16814           locator.priority = priority;
16815           locator.weight = weight;
16816           vec_add1 (locators, locator);
16817         }
16818       else
16819         break;
16820     }
16821
16822   if (locator_set_name_set == 0)
16823     {
16824       errmsg ("missing locator-set name");
16825       vec_free (locators);
16826       return -99;
16827     }
16828
16829   if (vec_len (locator_set_name) > 64)
16830     {
16831       errmsg ("locator-set name too long");
16832       vec_free (locator_set_name);
16833       vec_free (locators);
16834       return -99;
16835     }
16836   vec_add1 (locator_set_name, 0);
16837
16838   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16839
16840   /* Construct the API message */
16841   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16842
16843   mp->is_add = is_add;
16844   clib_memcpy (mp->locator_set_name, locator_set_name,
16845                vec_len (locator_set_name));
16846   vec_free (locator_set_name);
16847
16848   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16849   if (locators)
16850     clib_memcpy (mp->locators, locators, data_len);
16851   vec_free (locators);
16852
16853   /* send it... */
16854   S (mp);
16855
16856   /* Wait for a reply... */
16857   W (ret);
16858   return ret;
16859 }
16860
16861 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16862
16863 static int
16864 api_one_add_del_locator (vat_main_t * vam)
16865 {
16866   unformat_input_t *input = vam->input;
16867   vl_api_one_add_del_locator_t *mp;
16868   u32 tmp_if_index = ~0;
16869   u32 sw_if_index = ~0;
16870   u8 sw_if_index_set = 0;
16871   u8 sw_if_index_if_name_set = 0;
16872   u32 priority = ~0;
16873   u8 priority_set = 0;
16874   u32 weight = ~0;
16875   u8 weight_set = 0;
16876   u8 is_add = 1;
16877   u8 *locator_set_name = NULL;
16878   u8 locator_set_name_set = 0;
16879   int ret;
16880
16881   /* Parse args required to build the message */
16882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16883     {
16884       if (unformat (input, "del"))
16885         {
16886           is_add = 0;
16887         }
16888       else if (unformat (input, "locator-set %s", &locator_set_name))
16889         {
16890           locator_set_name_set = 1;
16891         }
16892       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16893                          &tmp_if_index))
16894         {
16895           sw_if_index_if_name_set = 1;
16896           sw_if_index = tmp_if_index;
16897         }
16898       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16899         {
16900           sw_if_index_set = 1;
16901           sw_if_index = tmp_if_index;
16902         }
16903       else if (unformat (input, "p %d", &priority))
16904         {
16905           priority_set = 1;
16906         }
16907       else if (unformat (input, "w %d", &weight))
16908         {
16909           weight_set = 1;
16910         }
16911       else
16912         break;
16913     }
16914
16915   if (locator_set_name_set == 0)
16916     {
16917       errmsg ("missing locator-set name");
16918       return -99;
16919     }
16920
16921   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16922     {
16923       errmsg ("missing sw_if_index");
16924       vec_free (locator_set_name);
16925       return -99;
16926     }
16927
16928   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16929     {
16930       errmsg ("cannot use both params interface name and sw_if_index");
16931       vec_free (locator_set_name);
16932       return -99;
16933     }
16934
16935   if (priority_set == 0)
16936     {
16937       errmsg ("missing locator-set priority");
16938       vec_free (locator_set_name);
16939       return -99;
16940     }
16941
16942   if (weight_set == 0)
16943     {
16944       errmsg ("missing locator-set weight");
16945       vec_free (locator_set_name);
16946       return -99;
16947     }
16948
16949   if (vec_len (locator_set_name) > 64)
16950     {
16951       errmsg ("locator-set name too long");
16952       vec_free (locator_set_name);
16953       return -99;
16954     }
16955   vec_add1 (locator_set_name, 0);
16956
16957   /* Construct the API message */
16958   M (ONE_ADD_DEL_LOCATOR, mp);
16959
16960   mp->is_add = is_add;
16961   mp->sw_if_index = ntohl (sw_if_index);
16962   mp->priority = priority;
16963   mp->weight = weight;
16964   clib_memcpy (mp->locator_set_name, locator_set_name,
16965                vec_len (locator_set_name));
16966   vec_free (locator_set_name);
16967
16968   /* send it... */
16969   S (mp);
16970
16971   /* Wait for a reply... */
16972   W (ret);
16973   return ret;
16974 }
16975
16976 #define api_lisp_add_del_locator api_one_add_del_locator
16977
16978 uword
16979 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16980 {
16981   u32 *key_id = va_arg (*args, u32 *);
16982   u8 *s = 0;
16983
16984   if (unformat (input, "%s", &s))
16985     {
16986       if (!strcmp ((char *) s, "sha1"))
16987         key_id[0] = HMAC_SHA_1_96;
16988       else if (!strcmp ((char *) s, "sha256"))
16989         key_id[0] = HMAC_SHA_256_128;
16990       else
16991         {
16992           clib_warning ("invalid key_id: '%s'", s);
16993           key_id[0] = HMAC_NO_KEY;
16994         }
16995     }
16996   else
16997     return 0;
16998
16999   vec_free (s);
17000   return 1;
17001 }
17002
17003 static int
17004 api_one_add_del_local_eid (vat_main_t * vam)
17005 {
17006   unformat_input_t *input = vam->input;
17007   vl_api_one_add_del_local_eid_t *mp;
17008   u8 is_add = 1;
17009   u8 eid_set = 0;
17010   lisp_eid_vat_t _eid, *eid = &_eid;
17011   u8 *locator_set_name = 0;
17012   u8 locator_set_name_set = 0;
17013   u32 vni = 0;
17014   u16 key_id = 0;
17015   u8 *key = 0;
17016   int ret;
17017
17018   /* Parse args required to build the message */
17019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17020     {
17021       if (unformat (input, "del"))
17022         {
17023           is_add = 0;
17024         }
17025       else if (unformat (input, "vni %d", &vni))
17026         {
17027           ;
17028         }
17029       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17030         {
17031           eid_set = 1;
17032         }
17033       else if (unformat (input, "locator-set %s", &locator_set_name))
17034         {
17035           locator_set_name_set = 1;
17036         }
17037       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17038         ;
17039       else if (unformat (input, "secret-key %_%v%_", &key))
17040         ;
17041       else
17042         break;
17043     }
17044
17045   if (locator_set_name_set == 0)
17046     {
17047       errmsg ("missing locator-set name");
17048       return -99;
17049     }
17050
17051   if (0 == eid_set)
17052     {
17053       errmsg ("EID address not set!");
17054       vec_free (locator_set_name);
17055       return -99;
17056     }
17057
17058   if (key && (0 == key_id))
17059     {
17060       errmsg ("invalid key_id!");
17061       return -99;
17062     }
17063
17064   if (vec_len (key) > 64)
17065     {
17066       errmsg ("key too long");
17067       vec_free (key);
17068       return -99;
17069     }
17070
17071   if (vec_len (locator_set_name) > 64)
17072     {
17073       errmsg ("locator-set name too long");
17074       vec_free (locator_set_name);
17075       return -99;
17076     }
17077   vec_add1 (locator_set_name, 0);
17078
17079   /* Construct the API message */
17080   M (ONE_ADD_DEL_LOCAL_EID, mp);
17081
17082   mp->is_add = is_add;
17083   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17084   mp->eid_type = eid->type;
17085   mp->prefix_len = eid->len;
17086   mp->vni = clib_host_to_net_u32 (vni);
17087   mp->key_id = clib_host_to_net_u16 (key_id);
17088   clib_memcpy (mp->locator_set_name, locator_set_name,
17089                vec_len (locator_set_name));
17090   clib_memcpy (mp->key, key, vec_len (key));
17091
17092   vec_free (locator_set_name);
17093   vec_free (key);
17094
17095   /* send it... */
17096   S (mp);
17097
17098   /* Wait for a reply... */
17099   W (ret);
17100   return ret;
17101 }
17102
17103 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17104
17105 static int
17106 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17107 {
17108   u32 dp_table = 0, vni = 0;;
17109   unformat_input_t *input = vam->input;
17110   vl_api_gpe_add_del_fwd_entry_t *mp;
17111   u8 is_add = 1;
17112   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17113   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17114   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17115   u32 action = ~0, w;
17116   ip4_address_t rmt_rloc4, lcl_rloc4;
17117   ip6_address_t rmt_rloc6, lcl_rloc6;
17118   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17119   int ret;
17120
17121   memset (&rloc, 0, sizeof (rloc));
17122
17123   /* Parse args required to build the message */
17124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17125     {
17126       if (unformat (input, "del"))
17127         is_add = 0;
17128       else if (unformat (input, "add"))
17129         is_add = 1;
17130       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17131         {
17132           rmt_eid_set = 1;
17133         }
17134       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17135         {
17136           lcl_eid_set = 1;
17137         }
17138       else if (unformat (input, "vrf %d", &dp_table))
17139         ;
17140       else if (unformat (input, "bd %d", &dp_table))
17141         ;
17142       else if (unformat (input, "vni %d", &vni))
17143         ;
17144       else if (unformat (input, "w %d", &w))
17145         {
17146           if (!curr_rloc)
17147             {
17148               errmsg ("No RLOC configured for setting priority/weight!");
17149               return -99;
17150             }
17151           curr_rloc->weight = w;
17152         }
17153       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17154                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17155         {
17156           rloc.is_ip4 = 1;
17157
17158           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17159           rloc.weight = 0;
17160           vec_add1 (lcl_locs, rloc);
17161
17162           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17163           vec_add1 (rmt_locs, rloc);
17164           /* weight saved in rmt loc */
17165           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17166         }
17167       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17168                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17169         {
17170           rloc.is_ip4 = 0;
17171           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17172           rloc.weight = 0;
17173           vec_add1 (lcl_locs, rloc);
17174
17175           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17176           vec_add1 (rmt_locs, rloc);
17177           /* weight saved in rmt loc */
17178           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17179         }
17180       else if (unformat (input, "action %d", &action))
17181         {
17182           ;
17183         }
17184       else
17185         {
17186           clib_warning ("parse error '%U'", format_unformat_error, input);
17187           return -99;
17188         }
17189     }
17190
17191   if (!rmt_eid_set)
17192     {
17193       errmsg ("remote eid addresses not set");
17194       return -99;
17195     }
17196
17197   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17198     {
17199       errmsg ("eid types don't match");
17200       return -99;
17201     }
17202
17203   if (0 == rmt_locs && (u32) ~ 0 == action)
17204     {
17205       errmsg ("action not set for negative mapping");
17206       return -99;
17207     }
17208
17209   /* Construct the API message */
17210   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17211       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17212
17213   mp->is_add = is_add;
17214   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17215   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17216   mp->eid_type = rmt_eid->type;
17217   mp->dp_table = clib_host_to_net_u32 (dp_table);
17218   mp->vni = clib_host_to_net_u32 (vni);
17219   mp->rmt_len = rmt_eid->len;
17220   mp->lcl_len = lcl_eid->len;
17221   mp->action = action;
17222
17223   if (0 != rmt_locs && 0 != lcl_locs)
17224     {
17225       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17226       clib_memcpy (mp->locs, lcl_locs,
17227                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17228
17229       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17230       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17231                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17232     }
17233   vec_free (lcl_locs);
17234   vec_free (rmt_locs);
17235
17236   /* send it... */
17237   S (mp);
17238
17239   /* Wait for a reply... */
17240   W (ret);
17241   return ret;
17242 }
17243
17244 static int
17245 api_one_add_del_map_server (vat_main_t * vam)
17246 {
17247   unformat_input_t *input = vam->input;
17248   vl_api_one_add_del_map_server_t *mp;
17249   u8 is_add = 1;
17250   u8 ipv4_set = 0;
17251   u8 ipv6_set = 0;
17252   ip4_address_t ipv4;
17253   ip6_address_t ipv6;
17254   int ret;
17255
17256   /* Parse args required to build the message */
17257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17258     {
17259       if (unformat (input, "del"))
17260         {
17261           is_add = 0;
17262         }
17263       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17264         {
17265           ipv4_set = 1;
17266         }
17267       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17268         {
17269           ipv6_set = 1;
17270         }
17271       else
17272         break;
17273     }
17274
17275   if (ipv4_set && ipv6_set)
17276     {
17277       errmsg ("both eid v4 and v6 addresses set");
17278       return -99;
17279     }
17280
17281   if (!ipv4_set && !ipv6_set)
17282     {
17283       errmsg ("eid addresses not set");
17284       return -99;
17285     }
17286
17287   /* Construct the API message */
17288   M (ONE_ADD_DEL_MAP_SERVER, mp);
17289
17290   mp->is_add = is_add;
17291   if (ipv6_set)
17292     {
17293       mp->is_ipv6 = 1;
17294       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17295     }
17296   else
17297     {
17298       mp->is_ipv6 = 0;
17299       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17300     }
17301
17302   /* send it... */
17303   S (mp);
17304
17305   /* Wait for a reply... */
17306   W (ret);
17307   return ret;
17308 }
17309
17310 #define api_lisp_add_del_map_server api_one_add_del_map_server
17311
17312 static int
17313 api_one_add_del_map_resolver (vat_main_t * vam)
17314 {
17315   unformat_input_t *input = vam->input;
17316   vl_api_one_add_del_map_resolver_t *mp;
17317   u8 is_add = 1;
17318   u8 ipv4_set = 0;
17319   u8 ipv6_set = 0;
17320   ip4_address_t ipv4;
17321   ip6_address_t ipv6;
17322   int ret;
17323
17324   /* Parse args required to build the message */
17325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17326     {
17327       if (unformat (input, "del"))
17328         {
17329           is_add = 0;
17330         }
17331       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17332         {
17333           ipv4_set = 1;
17334         }
17335       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17336         {
17337           ipv6_set = 1;
17338         }
17339       else
17340         break;
17341     }
17342
17343   if (ipv4_set && ipv6_set)
17344     {
17345       errmsg ("both eid v4 and v6 addresses set");
17346       return -99;
17347     }
17348
17349   if (!ipv4_set && !ipv6_set)
17350     {
17351       errmsg ("eid addresses not set");
17352       return -99;
17353     }
17354
17355   /* Construct the API message */
17356   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17357
17358   mp->is_add = is_add;
17359   if (ipv6_set)
17360     {
17361       mp->is_ipv6 = 1;
17362       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17363     }
17364   else
17365     {
17366       mp->is_ipv6 = 0;
17367       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17368     }
17369
17370   /* send it... */
17371   S (mp);
17372
17373   /* Wait for a reply... */
17374   W (ret);
17375   return ret;
17376 }
17377
17378 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17379
17380 static int
17381 api_lisp_gpe_enable_disable (vat_main_t * vam)
17382 {
17383   unformat_input_t *input = vam->input;
17384   vl_api_gpe_enable_disable_t *mp;
17385   u8 is_set = 0;
17386   u8 is_en = 1;
17387   int ret;
17388
17389   /* Parse args required to build the message */
17390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17391     {
17392       if (unformat (input, "enable"))
17393         {
17394           is_set = 1;
17395           is_en = 1;
17396         }
17397       else if (unformat (input, "disable"))
17398         {
17399           is_set = 1;
17400           is_en = 0;
17401         }
17402       else
17403         break;
17404     }
17405
17406   if (is_set == 0)
17407     {
17408       errmsg ("Value not set");
17409       return -99;
17410     }
17411
17412   /* Construct the API message */
17413   M (GPE_ENABLE_DISABLE, mp);
17414
17415   mp->is_en = is_en;
17416
17417   /* send it... */
17418   S (mp);
17419
17420   /* Wait for a reply... */
17421   W (ret);
17422   return ret;
17423 }
17424
17425 static int
17426 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17427 {
17428   unformat_input_t *input = vam->input;
17429   vl_api_one_rloc_probe_enable_disable_t *mp;
17430   u8 is_set = 0;
17431   u8 is_en = 0;
17432   int ret;
17433
17434   /* Parse args required to build the message */
17435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17436     {
17437       if (unformat (input, "enable"))
17438         {
17439           is_set = 1;
17440           is_en = 1;
17441         }
17442       else if (unformat (input, "disable"))
17443         is_set = 1;
17444       else
17445         break;
17446     }
17447
17448   if (!is_set)
17449     {
17450       errmsg ("Value not set");
17451       return -99;
17452     }
17453
17454   /* Construct the API message */
17455   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17456
17457   mp->is_enabled = is_en;
17458
17459   /* send it... */
17460   S (mp);
17461
17462   /* Wait for a reply... */
17463   W (ret);
17464   return ret;
17465 }
17466
17467 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17468
17469 static int
17470 api_one_map_register_enable_disable (vat_main_t * vam)
17471 {
17472   unformat_input_t *input = vam->input;
17473   vl_api_one_map_register_enable_disable_t *mp;
17474   u8 is_set = 0;
17475   u8 is_en = 0;
17476   int ret;
17477
17478   /* Parse args required to build the message */
17479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17480     {
17481       if (unformat (input, "enable"))
17482         {
17483           is_set = 1;
17484           is_en = 1;
17485         }
17486       else if (unformat (input, "disable"))
17487         is_set = 1;
17488       else
17489         break;
17490     }
17491
17492   if (!is_set)
17493     {
17494       errmsg ("Value not set");
17495       return -99;
17496     }
17497
17498   /* Construct the API message */
17499   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17500
17501   mp->is_enabled = is_en;
17502
17503   /* send it... */
17504   S (mp);
17505
17506   /* Wait for a reply... */
17507   W (ret);
17508   return ret;
17509 }
17510
17511 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17512
17513 static int
17514 api_one_enable_disable (vat_main_t * vam)
17515 {
17516   unformat_input_t *input = vam->input;
17517   vl_api_one_enable_disable_t *mp;
17518   u8 is_set = 0;
17519   u8 is_en = 0;
17520   int ret;
17521
17522   /* Parse args required to build the message */
17523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17524     {
17525       if (unformat (input, "enable"))
17526         {
17527           is_set = 1;
17528           is_en = 1;
17529         }
17530       else if (unformat (input, "disable"))
17531         {
17532           is_set = 1;
17533         }
17534       else
17535         break;
17536     }
17537
17538   if (!is_set)
17539     {
17540       errmsg ("Value not set");
17541       return -99;
17542     }
17543
17544   /* Construct the API message */
17545   M (ONE_ENABLE_DISABLE, mp);
17546
17547   mp->is_en = is_en;
17548
17549   /* send it... */
17550   S (mp);
17551
17552   /* Wait for a reply... */
17553   W (ret);
17554   return ret;
17555 }
17556
17557 #define api_lisp_enable_disable api_one_enable_disable
17558
17559 static int
17560 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17561 {
17562   unformat_input_t *input = vam->input;
17563   vl_api_one_enable_disable_xtr_mode_t *mp;
17564   u8 is_set = 0;
17565   u8 is_en = 0;
17566   int ret;
17567
17568   /* Parse args required to build the message */
17569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17570     {
17571       if (unformat (input, "enable"))
17572         {
17573           is_set = 1;
17574           is_en = 1;
17575         }
17576       else if (unformat (input, "disable"))
17577         {
17578           is_set = 1;
17579         }
17580       else
17581         break;
17582     }
17583
17584   if (!is_set)
17585     {
17586       errmsg ("Value not set");
17587       return -99;
17588     }
17589
17590   /* Construct the API message */
17591   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17592
17593   mp->is_en = is_en;
17594
17595   /* send it... */
17596   S (mp);
17597
17598   /* Wait for a reply... */
17599   W (ret);
17600   return ret;
17601 }
17602
17603 static int
17604 api_one_show_xtr_mode (vat_main_t * vam)
17605 {
17606   vl_api_one_show_xtr_mode_t *mp;
17607   int ret;
17608
17609   /* Construct the API message */
17610   M (ONE_SHOW_XTR_MODE, mp);
17611
17612   /* send it... */
17613   S (mp);
17614
17615   /* Wait for a reply... */
17616   W (ret);
17617   return ret;
17618 }
17619
17620 static int
17621 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17622 {
17623   unformat_input_t *input = vam->input;
17624   vl_api_one_enable_disable_pitr_mode_t *mp;
17625   u8 is_set = 0;
17626   u8 is_en = 0;
17627   int ret;
17628
17629   /* Parse args required to build the message */
17630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17631     {
17632       if (unformat (input, "enable"))
17633         {
17634           is_set = 1;
17635           is_en = 1;
17636         }
17637       else if (unformat (input, "disable"))
17638         {
17639           is_set = 1;
17640         }
17641       else
17642         break;
17643     }
17644
17645   if (!is_set)
17646     {
17647       errmsg ("Value not set");
17648       return -99;
17649     }
17650
17651   /* Construct the API message */
17652   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17653
17654   mp->is_en = is_en;
17655
17656   /* send it... */
17657   S (mp);
17658
17659   /* Wait for a reply... */
17660   W (ret);
17661   return ret;
17662 }
17663
17664 static int
17665 api_one_show_pitr_mode (vat_main_t * vam)
17666 {
17667   vl_api_one_show_pitr_mode_t *mp;
17668   int ret;
17669
17670   /* Construct the API message */
17671   M (ONE_SHOW_PITR_MODE, mp);
17672
17673   /* send it... */
17674   S (mp);
17675
17676   /* Wait for a reply... */
17677   W (ret);
17678   return ret;
17679 }
17680
17681 static int
17682 api_one_enable_disable_petr_mode (vat_main_t * vam)
17683 {
17684   unformat_input_t *input = vam->input;
17685   vl_api_one_enable_disable_petr_mode_t *mp;
17686   u8 is_set = 0;
17687   u8 is_en = 0;
17688   int ret;
17689
17690   /* Parse args required to build the message */
17691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17692     {
17693       if (unformat (input, "enable"))
17694         {
17695           is_set = 1;
17696           is_en = 1;
17697         }
17698       else if (unformat (input, "disable"))
17699         {
17700           is_set = 1;
17701         }
17702       else
17703         break;
17704     }
17705
17706   if (!is_set)
17707     {
17708       errmsg ("Value not set");
17709       return -99;
17710     }
17711
17712   /* Construct the API message */
17713   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17714
17715   mp->is_en = is_en;
17716
17717   /* send it... */
17718   S (mp);
17719
17720   /* Wait for a reply... */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 static int
17726 api_one_show_petr_mode (vat_main_t * vam)
17727 {
17728   vl_api_one_show_petr_mode_t *mp;
17729   int ret;
17730
17731   /* Construct the API message */
17732   M (ONE_SHOW_PETR_MODE, mp);
17733
17734   /* send it... */
17735   S (mp);
17736
17737   /* Wait for a reply... */
17738   W (ret);
17739   return ret;
17740 }
17741
17742 static int
17743 api_show_one_map_register_state (vat_main_t * vam)
17744 {
17745   vl_api_show_one_map_register_state_t *mp;
17746   int ret;
17747
17748   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17749
17750   /* send */
17751   S (mp);
17752
17753   /* wait for reply */
17754   W (ret);
17755   return ret;
17756 }
17757
17758 #define api_show_lisp_map_register_state api_show_one_map_register_state
17759
17760 static int
17761 api_show_one_rloc_probe_state (vat_main_t * vam)
17762 {
17763   vl_api_show_one_rloc_probe_state_t *mp;
17764   int ret;
17765
17766   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17767
17768   /* send */
17769   S (mp);
17770
17771   /* wait for reply */
17772   W (ret);
17773   return ret;
17774 }
17775
17776 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17777
17778 static int
17779 api_one_add_del_ndp_entry (vat_main_t * vam)
17780 {
17781   vl_api_one_add_del_ndp_entry_t *mp;
17782   unformat_input_t *input = vam->input;
17783   u8 is_add = 1;
17784   u8 mac_set = 0;
17785   u8 bd_set = 0;
17786   u8 ip_set = 0;
17787   u8 mac[6] = { 0, };
17788   u8 ip6[16] = { 0, };
17789   u32 bd = ~0;
17790   int ret;
17791
17792   /* Parse args required to build the message */
17793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17794     {
17795       if (unformat (input, "del"))
17796         is_add = 0;
17797       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17798         mac_set = 1;
17799       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17800         ip_set = 1;
17801       else if (unformat (input, "bd %d", &bd))
17802         bd_set = 1;
17803       else
17804         {
17805           errmsg ("parse error '%U'", format_unformat_error, input);
17806           return -99;
17807         }
17808     }
17809
17810   if (!bd_set || !ip_set || (!mac_set && is_add))
17811     {
17812       errmsg ("Missing BD, IP or MAC!");
17813       return -99;
17814     }
17815
17816   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17817   mp->is_add = is_add;
17818   clib_memcpy (mp->mac, mac, 6);
17819   mp->bd = clib_host_to_net_u32 (bd);
17820   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17821
17822   /* send */
17823   S (mp);
17824
17825   /* wait for reply */
17826   W (ret);
17827   return ret;
17828 }
17829
17830 static int
17831 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17832 {
17833   vl_api_one_add_del_l2_arp_entry_t *mp;
17834   unformat_input_t *input = vam->input;
17835   u8 is_add = 1;
17836   u8 mac_set = 0;
17837   u8 bd_set = 0;
17838   u8 ip_set = 0;
17839   u8 mac[6] = { 0, };
17840   u32 ip4 = 0, bd = ~0;
17841   int ret;
17842
17843   /* Parse args required to build the message */
17844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17845     {
17846       if (unformat (input, "del"))
17847         is_add = 0;
17848       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17849         mac_set = 1;
17850       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17851         ip_set = 1;
17852       else if (unformat (input, "bd %d", &bd))
17853         bd_set = 1;
17854       else
17855         {
17856           errmsg ("parse error '%U'", format_unformat_error, input);
17857           return -99;
17858         }
17859     }
17860
17861   if (!bd_set || !ip_set || (!mac_set && is_add))
17862     {
17863       errmsg ("Missing BD, IP or MAC!");
17864       return -99;
17865     }
17866
17867   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17868   mp->is_add = is_add;
17869   clib_memcpy (mp->mac, mac, 6);
17870   mp->bd = clib_host_to_net_u32 (bd);
17871   mp->ip4 = ip4;
17872
17873   /* send */
17874   S (mp);
17875
17876   /* wait for reply */
17877   W (ret);
17878   return ret;
17879 }
17880
17881 static int
17882 api_one_ndp_bd_get (vat_main_t * vam)
17883 {
17884   vl_api_one_ndp_bd_get_t *mp;
17885   int ret;
17886
17887   M (ONE_NDP_BD_GET, mp);
17888
17889   /* send */
17890   S (mp);
17891
17892   /* wait for reply */
17893   W (ret);
17894   return ret;
17895 }
17896
17897 static int
17898 api_one_ndp_entries_get (vat_main_t * vam)
17899 {
17900   vl_api_one_ndp_entries_get_t *mp;
17901   unformat_input_t *input = vam->input;
17902   u8 bd_set = 0;
17903   u32 bd = ~0;
17904   int ret;
17905
17906   /* Parse args required to build the message */
17907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17908     {
17909       if (unformat (input, "bd %d", &bd))
17910         bd_set = 1;
17911       else
17912         {
17913           errmsg ("parse error '%U'", format_unformat_error, input);
17914           return -99;
17915         }
17916     }
17917
17918   if (!bd_set)
17919     {
17920       errmsg ("Expected bridge domain!");
17921       return -99;
17922     }
17923
17924   M (ONE_NDP_ENTRIES_GET, mp);
17925   mp->bd = clib_host_to_net_u32 (bd);
17926
17927   /* send */
17928   S (mp);
17929
17930   /* wait for reply */
17931   W (ret);
17932   return ret;
17933 }
17934
17935 static int
17936 api_one_l2_arp_bd_get (vat_main_t * vam)
17937 {
17938   vl_api_one_l2_arp_bd_get_t *mp;
17939   int ret;
17940
17941   M (ONE_L2_ARP_BD_GET, mp);
17942
17943   /* send */
17944   S (mp);
17945
17946   /* wait for reply */
17947   W (ret);
17948   return ret;
17949 }
17950
17951 static int
17952 api_one_l2_arp_entries_get (vat_main_t * vam)
17953 {
17954   vl_api_one_l2_arp_entries_get_t *mp;
17955   unformat_input_t *input = vam->input;
17956   u8 bd_set = 0;
17957   u32 bd = ~0;
17958   int ret;
17959
17960   /* Parse args required to build the message */
17961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17962     {
17963       if (unformat (input, "bd %d", &bd))
17964         bd_set = 1;
17965       else
17966         {
17967           errmsg ("parse error '%U'", format_unformat_error, input);
17968           return -99;
17969         }
17970     }
17971
17972   if (!bd_set)
17973     {
17974       errmsg ("Expected bridge domain!");
17975       return -99;
17976     }
17977
17978   M (ONE_L2_ARP_ENTRIES_GET, mp);
17979   mp->bd = clib_host_to_net_u32 (bd);
17980
17981   /* send */
17982   S (mp);
17983
17984   /* wait for reply */
17985   W (ret);
17986   return ret;
17987 }
17988
17989 static int
17990 api_one_stats_enable_disable (vat_main_t * vam)
17991 {
17992   vl_api_one_stats_enable_disable_t *mp;
17993   unformat_input_t *input = vam->input;
17994   u8 is_set = 0;
17995   u8 is_en = 0;
17996   int ret;
17997
17998   /* Parse args required to build the message */
17999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18000     {
18001       if (unformat (input, "enable"))
18002         {
18003           is_set = 1;
18004           is_en = 1;
18005         }
18006       else if (unformat (input, "disable"))
18007         {
18008           is_set = 1;
18009         }
18010       else
18011         break;
18012     }
18013
18014   if (!is_set)
18015     {
18016       errmsg ("Value not set");
18017       return -99;
18018     }
18019
18020   M (ONE_STATS_ENABLE_DISABLE, mp);
18021   mp->is_en = is_en;
18022
18023   /* send */
18024   S (mp);
18025
18026   /* wait for reply */
18027   W (ret);
18028   return ret;
18029 }
18030
18031 static int
18032 api_show_one_stats_enable_disable (vat_main_t * vam)
18033 {
18034   vl_api_show_one_stats_enable_disable_t *mp;
18035   int ret;
18036
18037   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18038
18039   /* send */
18040   S (mp);
18041
18042   /* wait for reply */
18043   W (ret);
18044   return ret;
18045 }
18046
18047 static int
18048 api_show_one_map_request_mode (vat_main_t * vam)
18049 {
18050   vl_api_show_one_map_request_mode_t *mp;
18051   int ret;
18052
18053   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18054
18055   /* send */
18056   S (mp);
18057
18058   /* wait for reply */
18059   W (ret);
18060   return ret;
18061 }
18062
18063 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18064
18065 static int
18066 api_one_map_request_mode (vat_main_t * vam)
18067 {
18068   unformat_input_t *input = vam->input;
18069   vl_api_one_map_request_mode_t *mp;
18070   u8 mode = 0;
18071   int ret;
18072
18073   /* Parse args required to build the message */
18074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18075     {
18076       if (unformat (input, "dst-only"))
18077         mode = 0;
18078       else if (unformat (input, "src-dst"))
18079         mode = 1;
18080       else
18081         {
18082           errmsg ("parse error '%U'", format_unformat_error, input);
18083           return -99;
18084         }
18085     }
18086
18087   M (ONE_MAP_REQUEST_MODE, mp);
18088
18089   mp->mode = mode;
18090
18091   /* send */
18092   S (mp);
18093
18094   /* wait for reply */
18095   W (ret);
18096   return ret;
18097 }
18098
18099 #define api_lisp_map_request_mode api_one_map_request_mode
18100
18101 /**
18102  * Enable/disable ONE proxy ITR.
18103  *
18104  * @param vam vpp API test context
18105  * @return return code
18106  */
18107 static int
18108 api_one_pitr_set_locator_set (vat_main_t * vam)
18109 {
18110   u8 ls_name_set = 0;
18111   unformat_input_t *input = vam->input;
18112   vl_api_one_pitr_set_locator_set_t *mp;
18113   u8 is_add = 1;
18114   u8 *ls_name = 0;
18115   int ret;
18116
18117   /* Parse args required to build the message */
18118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18119     {
18120       if (unformat (input, "del"))
18121         is_add = 0;
18122       else if (unformat (input, "locator-set %s", &ls_name))
18123         ls_name_set = 1;
18124       else
18125         {
18126           errmsg ("parse error '%U'", format_unformat_error, input);
18127           return -99;
18128         }
18129     }
18130
18131   if (!ls_name_set)
18132     {
18133       errmsg ("locator-set name not set!");
18134       return -99;
18135     }
18136
18137   M (ONE_PITR_SET_LOCATOR_SET, mp);
18138
18139   mp->is_add = is_add;
18140   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18141   vec_free (ls_name);
18142
18143   /* send */
18144   S (mp);
18145
18146   /* wait for reply */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18152
18153 static int
18154 api_one_nsh_set_locator_set (vat_main_t * vam)
18155 {
18156   u8 ls_name_set = 0;
18157   unformat_input_t *input = vam->input;
18158   vl_api_one_nsh_set_locator_set_t *mp;
18159   u8 is_add = 1;
18160   u8 *ls_name = 0;
18161   int ret;
18162
18163   /* Parse args required to build the message */
18164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18165     {
18166       if (unformat (input, "del"))
18167         is_add = 0;
18168       else if (unformat (input, "ls %s", &ls_name))
18169         ls_name_set = 1;
18170       else
18171         {
18172           errmsg ("parse error '%U'", format_unformat_error, input);
18173           return -99;
18174         }
18175     }
18176
18177   if (!ls_name_set && is_add)
18178     {
18179       errmsg ("locator-set name not set!");
18180       return -99;
18181     }
18182
18183   M (ONE_NSH_SET_LOCATOR_SET, mp);
18184
18185   mp->is_add = is_add;
18186   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18187   vec_free (ls_name);
18188
18189   /* send */
18190   S (mp);
18191
18192   /* wait for reply */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_show_one_pitr (vat_main_t * vam)
18199 {
18200   vl_api_show_one_pitr_t *mp;
18201   int ret;
18202
18203   if (!vam->json_output)
18204     {
18205       print (vam->ofp, "%=20s", "lisp status:");
18206     }
18207
18208   M (SHOW_ONE_PITR, mp);
18209   /* send it... */
18210   S (mp);
18211
18212   /* Wait for a reply... */
18213   W (ret);
18214   return ret;
18215 }
18216
18217 #define api_show_lisp_pitr api_show_one_pitr
18218
18219 static int
18220 api_one_use_petr (vat_main_t * vam)
18221 {
18222   unformat_input_t *input = vam->input;
18223   vl_api_one_use_petr_t *mp;
18224   u8 is_add = 0;
18225   ip_address_t ip;
18226   int ret;
18227
18228   memset (&ip, 0, sizeof (ip));
18229
18230   /* Parse args required to build the message */
18231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18232     {
18233       if (unformat (input, "disable"))
18234         is_add = 0;
18235       else
18236         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18237         {
18238           is_add = 1;
18239           ip_addr_version (&ip) = IP4;
18240         }
18241       else
18242         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18243         {
18244           is_add = 1;
18245           ip_addr_version (&ip) = IP6;
18246         }
18247       else
18248         {
18249           errmsg ("parse error '%U'", format_unformat_error, input);
18250           return -99;
18251         }
18252     }
18253
18254   M (ONE_USE_PETR, mp);
18255
18256   mp->is_add = is_add;
18257   if (is_add)
18258     {
18259       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18260       if (mp->is_ip4)
18261         clib_memcpy (mp->address, &ip, 4);
18262       else
18263         clib_memcpy (mp->address, &ip, 16);
18264     }
18265
18266   /* send */
18267   S (mp);
18268
18269   /* wait for reply */
18270   W (ret);
18271   return ret;
18272 }
18273
18274 #define api_lisp_use_petr api_one_use_petr
18275
18276 static int
18277 api_show_one_nsh_mapping (vat_main_t * vam)
18278 {
18279   vl_api_show_one_use_petr_t *mp;
18280   int ret;
18281
18282   if (!vam->json_output)
18283     {
18284       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18285     }
18286
18287   M (SHOW_ONE_NSH_MAPPING, mp);
18288   /* send it... */
18289   S (mp);
18290
18291   /* Wait for a reply... */
18292   W (ret);
18293   return ret;
18294 }
18295
18296 static int
18297 api_show_one_use_petr (vat_main_t * vam)
18298 {
18299   vl_api_show_one_use_petr_t *mp;
18300   int ret;
18301
18302   if (!vam->json_output)
18303     {
18304       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18305     }
18306
18307   M (SHOW_ONE_USE_PETR, mp);
18308   /* send it... */
18309   S (mp);
18310
18311   /* Wait for a reply... */
18312   W (ret);
18313   return ret;
18314 }
18315
18316 #define api_show_lisp_use_petr api_show_one_use_petr
18317
18318 /**
18319  * Add/delete mapping between vni and vrf
18320  */
18321 static int
18322 api_one_eid_table_add_del_map (vat_main_t * vam)
18323 {
18324   unformat_input_t *input = vam->input;
18325   vl_api_one_eid_table_add_del_map_t *mp;
18326   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18327   u32 vni, vrf, bd_index;
18328   int ret;
18329
18330   /* Parse args required to build the message */
18331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18332     {
18333       if (unformat (input, "del"))
18334         is_add = 0;
18335       else if (unformat (input, "vrf %d", &vrf))
18336         vrf_set = 1;
18337       else if (unformat (input, "bd_index %d", &bd_index))
18338         bd_index_set = 1;
18339       else if (unformat (input, "vni %d", &vni))
18340         vni_set = 1;
18341       else
18342         break;
18343     }
18344
18345   if (!vni_set || (!vrf_set && !bd_index_set))
18346     {
18347       errmsg ("missing arguments!");
18348       return -99;
18349     }
18350
18351   if (vrf_set && bd_index_set)
18352     {
18353       errmsg ("error: both vrf and bd entered!");
18354       return -99;
18355     }
18356
18357   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18358
18359   mp->is_add = is_add;
18360   mp->vni = htonl (vni);
18361   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18362   mp->is_l2 = bd_index_set;
18363
18364   /* send */
18365   S (mp);
18366
18367   /* wait for reply */
18368   W (ret);
18369   return ret;
18370 }
18371
18372 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18373
18374 uword
18375 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18376 {
18377   u32 *action = va_arg (*args, u32 *);
18378   u8 *s = 0;
18379
18380   if (unformat (input, "%s", &s))
18381     {
18382       if (!strcmp ((char *) s, "no-action"))
18383         action[0] = 0;
18384       else if (!strcmp ((char *) s, "natively-forward"))
18385         action[0] = 1;
18386       else if (!strcmp ((char *) s, "send-map-request"))
18387         action[0] = 2;
18388       else if (!strcmp ((char *) s, "drop"))
18389         action[0] = 3;
18390       else
18391         {
18392           clib_warning ("invalid action: '%s'", s);
18393           action[0] = 3;
18394         }
18395     }
18396   else
18397     return 0;
18398
18399   vec_free (s);
18400   return 1;
18401 }
18402
18403 /**
18404  * Add/del remote mapping to/from ONE control plane
18405  *
18406  * @param vam vpp API test context
18407  * @return return code
18408  */
18409 static int
18410 api_one_add_del_remote_mapping (vat_main_t * vam)
18411 {
18412   unformat_input_t *input = vam->input;
18413   vl_api_one_add_del_remote_mapping_t *mp;
18414   u32 vni = 0;
18415   lisp_eid_vat_t _eid, *eid = &_eid;
18416   lisp_eid_vat_t _seid, *seid = &_seid;
18417   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18418   u32 action = ~0, p, w, data_len;
18419   ip4_address_t rloc4;
18420   ip6_address_t rloc6;
18421   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18422   int ret;
18423
18424   memset (&rloc, 0, sizeof (rloc));
18425
18426   /* Parse args required to build the message */
18427   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18428     {
18429       if (unformat (input, "del-all"))
18430         {
18431           del_all = 1;
18432         }
18433       else if (unformat (input, "del"))
18434         {
18435           is_add = 0;
18436         }
18437       else if (unformat (input, "add"))
18438         {
18439           is_add = 1;
18440         }
18441       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18442         {
18443           eid_set = 1;
18444         }
18445       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18446         {
18447           seid_set = 1;
18448         }
18449       else if (unformat (input, "vni %d", &vni))
18450         {
18451           ;
18452         }
18453       else if (unformat (input, "p %d w %d", &p, &w))
18454         {
18455           if (!curr_rloc)
18456             {
18457               errmsg ("No RLOC configured for setting priority/weight!");
18458               return -99;
18459             }
18460           curr_rloc->priority = p;
18461           curr_rloc->weight = w;
18462         }
18463       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18464         {
18465           rloc.is_ip4 = 1;
18466           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18467           vec_add1 (rlocs, rloc);
18468           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18469         }
18470       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18471         {
18472           rloc.is_ip4 = 0;
18473           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18474           vec_add1 (rlocs, rloc);
18475           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18476         }
18477       else if (unformat (input, "action %U",
18478                          unformat_negative_mapping_action, &action))
18479         {
18480           ;
18481         }
18482       else
18483         {
18484           clib_warning ("parse error '%U'", format_unformat_error, input);
18485           return -99;
18486         }
18487     }
18488
18489   if (0 == eid_set)
18490     {
18491       errmsg ("missing params!");
18492       return -99;
18493     }
18494
18495   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18496     {
18497       errmsg ("no action set for negative map-reply!");
18498       return -99;
18499     }
18500
18501   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18502
18503   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18504   mp->is_add = is_add;
18505   mp->vni = htonl (vni);
18506   mp->action = (u8) action;
18507   mp->is_src_dst = seid_set;
18508   mp->eid_len = eid->len;
18509   mp->seid_len = seid->len;
18510   mp->del_all = del_all;
18511   mp->eid_type = eid->type;
18512   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18513   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18514
18515   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18516   clib_memcpy (mp->rlocs, rlocs, data_len);
18517   vec_free (rlocs);
18518
18519   /* send it... */
18520   S (mp);
18521
18522   /* Wait for a reply... */
18523   W (ret);
18524   return ret;
18525 }
18526
18527 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18528
18529 /**
18530  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18531  * forwarding entries in data-plane accordingly.
18532  *
18533  * @param vam vpp API test context
18534  * @return return code
18535  */
18536 static int
18537 api_one_add_del_adjacency (vat_main_t * vam)
18538 {
18539   unformat_input_t *input = vam->input;
18540   vl_api_one_add_del_adjacency_t *mp;
18541   u32 vni = 0;
18542   ip4_address_t leid4, reid4;
18543   ip6_address_t leid6, reid6;
18544   u8 reid_mac[6] = { 0 };
18545   u8 leid_mac[6] = { 0 };
18546   u8 reid_type, leid_type;
18547   u32 leid_len = 0, reid_len = 0, len;
18548   u8 is_add = 1;
18549   int ret;
18550
18551   leid_type = reid_type = (u8) ~ 0;
18552
18553   /* Parse args required to build the message */
18554   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18555     {
18556       if (unformat (input, "del"))
18557         {
18558           is_add = 0;
18559         }
18560       else if (unformat (input, "add"))
18561         {
18562           is_add = 1;
18563         }
18564       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18565                          &reid4, &len))
18566         {
18567           reid_type = 0;        /* ipv4 */
18568           reid_len = len;
18569         }
18570       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18571                          &reid6, &len))
18572         {
18573           reid_type = 1;        /* ipv6 */
18574           reid_len = len;
18575         }
18576       else if (unformat (input, "reid %U", unformat_ethernet_address,
18577                          reid_mac))
18578         {
18579           reid_type = 2;        /* mac */
18580         }
18581       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18582                          &leid4, &len))
18583         {
18584           leid_type = 0;        /* ipv4 */
18585           leid_len = len;
18586         }
18587       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18588                          &leid6, &len))
18589         {
18590           leid_type = 1;        /* ipv6 */
18591           leid_len = len;
18592         }
18593       else if (unformat (input, "leid %U", unformat_ethernet_address,
18594                          leid_mac))
18595         {
18596           leid_type = 2;        /* mac */
18597         }
18598       else if (unformat (input, "vni %d", &vni))
18599         {
18600           ;
18601         }
18602       else
18603         {
18604           errmsg ("parse error '%U'", format_unformat_error, input);
18605           return -99;
18606         }
18607     }
18608
18609   if ((u8) ~ 0 == reid_type)
18610     {
18611       errmsg ("missing params!");
18612       return -99;
18613     }
18614
18615   if (leid_type != reid_type)
18616     {
18617       errmsg ("remote and local EIDs are of different types!");
18618       return -99;
18619     }
18620
18621   M (ONE_ADD_DEL_ADJACENCY, mp);
18622   mp->is_add = is_add;
18623   mp->vni = htonl (vni);
18624   mp->leid_len = leid_len;
18625   mp->reid_len = reid_len;
18626   mp->eid_type = reid_type;
18627
18628   switch (mp->eid_type)
18629     {
18630     case 0:
18631       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18632       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18633       break;
18634     case 1:
18635       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18636       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18637       break;
18638     case 2:
18639       clib_memcpy (mp->leid, leid_mac, 6);
18640       clib_memcpy (mp->reid, reid_mac, 6);
18641       break;
18642     default:
18643       errmsg ("unknown EID type %d!", mp->eid_type);
18644       return 0;
18645     }
18646
18647   /* send it... */
18648   S (mp);
18649
18650   /* Wait for a reply... */
18651   W (ret);
18652   return ret;
18653 }
18654
18655 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18656
18657 uword
18658 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18659 {
18660   u32 *mode = va_arg (*args, u32 *);
18661
18662   if (unformat (input, "lisp"))
18663     *mode = 0;
18664   else if (unformat (input, "vxlan"))
18665     *mode = 1;
18666   else
18667     return 0;
18668
18669   return 1;
18670 }
18671
18672 static int
18673 api_gpe_get_encap_mode (vat_main_t * vam)
18674 {
18675   vl_api_gpe_get_encap_mode_t *mp;
18676   int ret;
18677
18678   /* Construct the API message */
18679   M (GPE_GET_ENCAP_MODE, mp);
18680
18681   /* send it... */
18682   S (mp);
18683
18684   /* Wait for a reply... */
18685   W (ret);
18686   return ret;
18687 }
18688
18689 static int
18690 api_gpe_set_encap_mode (vat_main_t * vam)
18691 {
18692   unformat_input_t *input = vam->input;
18693   vl_api_gpe_set_encap_mode_t *mp;
18694   int ret;
18695   u32 mode = 0;
18696
18697   /* Parse args required to build the message */
18698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18699     {
18700       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18701         ;
18702       else
18703         break;
18704     }
18705
18706   /* Construct the API message */
18707   M (GPE_SET_ENCAP_MODE, mp);
18708
18709   mp->mode = mode;
18710
18711   /* send it... */
18712   S (mp);
18713
18714   /* Wait for a reply... */
18715   W (ret);
18716   return ret;
18717 }
18718
18719 static int
18720 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18721 {
18722   unformat_input_t *input = vam->input;
18723   vl_api_gpe_add_del_iface_t *mp;
18724   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18725   u32 dp_table = 0, vni = 0;
18726   int ret;
18727
18728   /* Parse args required to build the message */
18729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18730     {
18731       if (unformat (input, "up"))
18732         {
18733           action_set = 1;
18734           is_add = 1;
18735         }
18736       else if (unformat (input, "down"))
18737         {
18738           action_set = 1;
18739           is_add = 0;
18740         }
18741       else if (unformat (input, "table_id %d", &dp_table))
18742         {
18743           dp_table_set = 1;
18744         }
18745       else if (unformat (input, "bd_id %d", &dp_table))
18746         {
18747           dp_table_set = 1;
18748           is_l2 = 1;
18749         }
18750       else if (unformat (input, "vni %d", &vni))
18751         {
18752           vni_set = 1;
18753         }
18754       else
18755         break;
18756     }
18757
18758   if (action_set == 0)
18759     {
18760       errmsg ("Action not set");
18761       return -99;
18762     }
18763   if (dp_table_set == 0 || vni_set == 0)
18764     {
18765       errmsg ("vni and dp_table must be set");
18766       return -99;
18767     }
18768
18769   /* Construct the API message */
18770   M (GPE_ADD_DEL_IFACE, mp);
18771
18772   mp->is_add = is_add;
18773   mp->dp_table = clib_host_to_net_u32 (dp_table);
18774   mp->is_l2 = is_l2;
18775   mp->vni = clib_host_to_net_u32 (vni);
18776
18777   /* send it... */
18778   S (mp);
18779
18780   /* Wait for a reply... */
18781   W (ret);
18782   return ret;
18783 }
18784
18785 static int
18786 api_one_map_register_fallback_threshold (vat_main_t * vam)
18787 {
18788   unformat_input_t *input = vam->input;
18789   vl_api_one_map_register_fallback_threshold_t *mp;
18790   u32 value = 0;
18791   u8 is_set = 0;
18792   int ret;
18793
18794   /* Parse args required to build the message */
18795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18796     {
18797       if (unformat (input, "%u", &value))
18798         is_set = 1;
18799       else
18800         {
18801           clib_warning ("parse error '%U'", format_unformat_error, input);
18802           return -99;
18803         }
18804     }
18805
18806   if (!is_set)
18807     {
18808       errmsg ("fallback threshold value is missing!");
18809       return -99;
18810     }
18811
18812   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18813   mp->value = clib_host_to_net_u32 (value);
18814
18815   /* send it... */
18816   S (mp);
18817
18818   /* Wait for a reply... */
18819   W (ret);
18820   return ret;
18821 }
18822
18823 static int
18824 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18825 {
18826   vl_api_show_one_map_register_fallback_threshold_t *mp;
18827   int ret;
18828
18829   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18830
18831   /* send it... */
18832   S (mp);
18833
18834   /* Wait for a reply... */
18835   W (ret);
18836   return ret;
18837 }
18838
18839 uword
18840 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18841 {
18842   u32 *proto = va_arg (*args, u32 *);
18843
18844   if (unformat (input, "udp"))
18845     *proto = 1;
18846   else if (unformat (input, "api"))
18847     *proto = 2;
18848   else
18849     return 0;
18850
18851   return 1;
18852 }
18853
18854 static int
18855 api_one_set_transport_protocol (vat_main_t * vam)
18856 {
18857   unformat_input_t *input = vam->input;
18858   vl_api_one_set_transport_protocol_t *mp;
18859   u8 is_set = 0;
18860   u32 protocol = 0;
18861   int ret;
18862
18863   /* Parse args required to build the message */
18864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18865     {
18866       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18867         is_set = 1;
18868       else
18869         {
18870           clib_warning ("parse error '%U'", format_unformat_error, input);
18871           return -99;
18872         }
18873     }
18874
18875   if (!is_set)
18876     {
18877       errmsg ("Transport protocol missing!");
18878       return -99;
18879     }
18880
18881   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18882   mp->protocol = (u8) protocol;
18883
18884   /* send it... */
18885   S (mp);
18886
18887   /* Wait for a reply... */
18888   W (ret);
18889   return ret;
18890 }
18891
18892 static int
18893 api_one_get_transport_protocol (vat_main_t * vam)
18894 {
18895   vl_api_one_get_transport_protocol_t *mp;
18896   int ret;
18897
18898   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18899
18900   /* send it... */
18901   S (mp);
18902
18903   /* Wait for a reply... */
18904   W (ret);
18905   return ret;
18906 }
18907
18908 static int
18909 api_one_map_register_set_ttl (vat_main_t * vam)
18910 {
18911   unformat_input_t *input = vam->input;
18912   vl_api_one_map_register_set_ttl_t *mp;
18913   u32 ttl = 0;
18914   u8 is_set = 0;
18915   int ret;
18916
18917   /* Parse args required to build the message */
18918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18919     {
18920       if (unformat (input, "%u", &ttl))
18921         is_set = 1;
18922       else
18923         {
18924           clib_warning ("parse error '%U'", format_unformat_error, input);
18925           return -99;
18926         }
18927     }
18928
18929   if (!is_set)
18930     {
18931       errmsg ("TTL value missing!");
18932       return -99;
18933     }
18934
18935   M (ONE_MAP_REGISTER_SET_TTL, mp);
18936   mp->ttl = clib_host_to_net_u32 (ttl);
18937
18938   /* send it... */
18939   S (mp);
18940
18941   /* Wait for a reply... */
18942   W (ret);
18943   return ret;
18944 }
18945
18946 static int
18947 api_show_one_map_register_ttl (vat_main_t * vam)
18948 {
18949   vl_api_show_one_map_register_ttl_t *mp;
18950   int ret;
18951
18952   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18953
18954   /* send it... */
18955   S (mp);
18956
18957   /* Wait for a reply... */
18958   W (ret);
18959   return ret;
18960 }
18961
18962 /**
18963  * Add/del map request itr rlocs from ONE control plane and updates
18964  *
18965  * @param vam vpp API test context
18966  * @return return code
18967  */
18968 static int
18969 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18970 {
18971   unformat_input_t *input = vam->input;
18972   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18973   u8 *locator_set_name = 0;
18974   u8 locator_set_name_set = 0;
18975   u8 is_add = 1;
18976   int ret;
18977
18978   /* Parse args required to build the message */
18979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18980     {
18981       if (unformat (input, "del"))
18982         {
18983           is_add = 0;
18984         }
18985       else if (unformat (input, "%_%v%_", &locator_set_name))
18986         {
18987           locator_set_name_set = 1;
18988         }
18989       else
18990         {
18991           clib_warning ("parse error '%U'", format_unformat_error, input);
18992           return -99;
18993         }
18994     }
18995
18996   if (is_add && !locator_set_name_set)
18997     {
18998       errmsg ("itr-rloc is not set!");
18999       return -99;
19000     }
19001
19002   if (is_add && vec_len (locator_set_name) > 64)
19003     {
19004       errmsg ("itr-rloc locator-set name too long");
19005       vec_free (locator_set_name);
19006       return -99;
19007     }
19008
19009   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19010   mp->is_add = is_add;
19011   if (is_add)
19012     {
19013       clib_memcpy (mp->locator_set_name, locator_set_name,
19014                    vec_len (locator_set_name));
19015     }
19016   else
19017     {
19018       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19019     }
19020   vec_free (locator_set_name);
19021
19022   /* send it... */
19023   S (mp);
19024
19025   /* Wait for a reply... */
19026   W (ret);
19027   return ret;
19028 }
19029
19030 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19031
19032 static int
19033 api_one_locator_dump (vat_main_t * vam)
19034 {
19035   unformat_input_t *input = vam->input;
19036   vl_api_one_locator_dump_t *mp;
19037   vl_api_control_ping_t *mp_ping;
19038   u8 is_index_set = 0, is_name_set = 0;
19039   u8 *ls_name = 0;
19040   u32 ls_index = ~0;
19041   int ret;
19042
19043   /* Parse args required to build the message */
19044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19045     {
19046       if (unformat (input, "ls_name %_%v%_", &ls_name))
19047         {
19048           is_name_set = 1;
19049         }
19050       else if (unformat (input, "ls_index %d", &ls_index))
19051         {
19052           is_index_set = 1;
19053         }
19054       else
19055         {
19056           errmsg ("parse error '%U'", format_unformat_error, input);
19057           return -99;
19058         }
19059     }
19060
19061   if (!is_index_set && !is_name_set)
19062     {
19063       errmsg ("error: expected one of index or name!");
19064       return -99;
19065     }
19066
19067   if (is_index_set && is_name_set)
19068     {
19069       errmsg ("error: only one param expected!");
19070       return -99;
19071     }
19072
19073   if (vec_len (ls_name) > 62)
19074     {
19075       errmsg ("error: locator set name too long!");
19076       return -99;
19077     }
19078
19079   if (!vam->json_output)
19080     {
19081       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19082     }
19083
19084   M (ONE_LOCATOR_DUMP, mp);
19085   mp->is_index_set = is_index_set;
19086
19087   if (is_index_set)
19088     mp->ls_index = clib_host_to_net_u32 (ls_index);
19089   else
19090     {
19091       vec_add1 (ls_name, 0);
19092       strncpy ((char *) mp->ls_name, (char *) ls_name,
19093                sizeof (mp->ls_name) - 1);
19094     }
19095
19096   /* send it... */
19097   S (mp);
19098
19099   /* Use a control ping for synchronization */
19100   MPING (CONTROL_PING, mp_ping);
19101   S (mp_ping);
19102
19103   /* Wait for a reply... */
19104   W (ret);
19105   return ret;
19106 }
19107
19108 #define api_lisp_locator_dump api_one_locator_dump
19109
19110 static int
19111 api_one_locator_set_dump (vat_main_t * vam)
19112 {
19113   vl_api_one_locator_set_dump_t *mp;
19114   vl_api_control_ping_t *mp_ping;
19115   unformat_input_t *input = vam->input;
19116   u8 filter = 0;
19117   int ret;
19118
19119   /* Parse args required to build the message */
19120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19121     {
19122       if (unformat (input, "local"))
19123         {
19124           filter = 1;
19125         }
19126       else if (unformat (input, "remote"))
19127         {
19128           filter = 2;
19129         }
19130       else
19131         {
19132           errmsg ("parse error '%U'", format_unformat_error, input);
19133           return -99;
19134         }
19135     }
19136
19137   if (!vam->json_output)
19138     {
19139       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19140     }
19141
19142   M (ONE_LOCATOR_SET_DUMP, mp);
19143
19144   mp->filter = filter;
19145
19146   /* send it... */
19147   S (mp);
19148
19149   /* Use a control ping for synchronization */
19150   MPING (CONTROL_PING, mp_ping);
19151   S (mp_ping);
19152
19153   /* Wait for a reply... */
19154   W (ret);
19155   return ret;
19156 }
19157
19158 #define api_lisp_locator_set_dump api_one_locator_set_dump
19159
19160 static int
19161 api_one_eid_table_map_dump (vat_main_t * vam)
19162 {
19163   u8 is_l2 = 0;
19164   u8 mode_set = 0;
19165   unformat_input_t *input = vam->input;
19166   vl_api_one_eid_table_map_dump_t *mp;
19167   vl_api_control_ping_t *mp_ping;
19168   int ret;
19169
19170   /* Parse args required to build the message */
19171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19172     {
19173       if (unformat (input, "l2"))
19174         {
19175           is_l2 = 1;
19176           mode_set = 1;
19177         }
19178       else if (unformat (input, "l3"))
19179         {
19180           is_l2 = 0;
19181           mode_set = 1;
19182         }
19183       else
19184         {
19185           errmsg ("parse error '%U'", format_unformat_error, input);
19186           return -99;
19187         }
19188     }
19189
19190   if (!mode_set)
19191     {
19192       errmsg ("expected one of 'l2' or 'l3' parameter!");
19193       return -99;
19194     }
19195
19196   if (!vam->json_output)
19197     {
19198       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19199     }
19200
19201   M (ONE_EID_TABLE_MAP_DUMP, mp);
19202   mp->is_l2 = is_l2;
19203
19204   /* send it... */
19205   S (mp);
19206
19207   /* Use a control ping for synchronization */
19208   MPING (CONTROL_PING, mp_ping);
19209   S (mp_ping);
19210
19211   /* Wait for a reply... */
19212   W (ret);
19213   return ret;
19214 }
19215
19216 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19217
19218 static int
19219 api_one_eid_table_vni_dump (vat_main_t * vam)
19220 {
19221   vl_api_one_eid_table_vni_dump_t *mp;
19222   vl_api_control_ping_t *mp_ping;
19223   int ret;
19224
19225   if (!vam->json_output)
19226     {
19227       print (vam->ofp, "VNI");
19228     }
19229
19230   M (ONE_EID_TABLE_VNI_DUMP, mp);
19231
19232   /* send it... */
19233   S (mp);
19234
19235   /* Use a control ping for synchronization */
19236   MPING (CONTROL_PING, mp_ping);
19237   S (mp_ping);
19238
19239   /* Wait for a reply... */
19240   W (ret);
19241   return ret;
19242 }
19243
19244 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19245
19246 static int
19247 api_one_eid_table_dump (vat_main_t * vam)
19248 {
19249   unformat_input_t *i = vam->input;
19250   vl_api_one_eid_table_dump_t *mp;
19251   vl_api_control_ping_t *mp_ping;
19252   struct in_addr ip4;
19253   struct in6_addr ip6;
19254   u8 mac[6];
19255   u8 eid_type = ~0, eid_set = 0;
19256   u32 prefix_length = ~0, t, vni = 0;
19257   u8 filter = 0;
19258   int ret;
19259   lisp_nsh_api_t nsh;
19260
19261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19262     {
19263       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19264         {
19265           eid_set = 1;
19266           eid_type = 0;
19267           prefix_length = t;
19268         }
19269       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19270         {
19271           eid_set = 1;
19272           eid_type = 1;
19273           prefix_length = t;
19274         }
19275       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19276         {
19277           eid_set = 1;
19278           eid_type = 2;
19279         }
19280       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19281         {
19282           eid_set = 1;
19283           eid_type = 3;
19284         }
19285       else if (unformat (i, "vni %d", &t))
19286         {
19287           vni = t;
19288         }
19289       else if (unformat (i, "local"))
19290         {
19291           filter = 1;
19292         }
19293       else if (unformat (i, "remote"))
19294         {
19295           filter = 2;
19296         }
19297       else
19298         {
19299           errmsg ("parse error '%U'", format_unformat_error, i);
19300           return -99;
19301         }
19302     }
19303
19304   if (!vam->json_output)
19305     {
19306       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19307              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19308     }
19309
19310   M (ONE_EID_TABLE_DUMP, mp);
19311
19312   mp->filter = filter;
19313   if (eid_set)
19314     {
19315       mp->eid_set = 1;
19316       mp->vni = htonl (vni);
19317       mp->eid_type = eid_type;
19318       switch (eid_type)
19319         {
19320         case 0:
19321           mp->prefix_length = prefix_length;
19322           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19323           break;
19324         case 1:
19325           mp->prefix_length = prefix_length;
19326           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19327           break;
19328         case 2:
19329           clib_memcpy (mp->eid, mac, sizeof (mac));
19330           break;
19331         case 3:
19332           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19333           break;
19334         default:
19335           errmsg ("unknown EID type %d!", eid_type);
19336           return -99;
19337         }
19338     }
19339
19340   /* send it... */
19341   S (mp);
19342
19343   /* Use a control ping for synchronization */
19344   MPING (CONTROL_PING, mp_ping);
19345   S (mp_ping);
19346
19347   /* Wait for a reply... */
19348   W (ret);
19349   return ret;
19350 }
19351
19352 #define api_lisp_eid_table_dump api_one_eid_table_dump
19353
19354 static int
19355 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19356 {
19357   unformat_input_t *i = vam->input;
19358   vl_api_gpe_fwd_entries_get_t *mp;
19359   u8 vni_set = 0;
19360   u32 vni = ~0;
19361   int ret;
19362
19363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19364     {
19365       if (unformat (i, "vni %d", &vni))
19366         {
19367           vni_set = 1;
19368         }
19369       else
19370         {
19371           errmsg ("parse error '%U'", format_unformat_error, i);
19372           return -99;
19373         }
19374     }
19375
19376   if (!vni_set)
19377     {
19378       errmsg ("vni not set!");
19379       return -99;
19380     }
19381
19382   if (!vam->json_output)
19383     {
19384       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19385              "leid", "reid");
19386     }
19387
19388   M (GPE_FWD_ENTRIES_GET, mp);
19389   mp->vni = clib_host_to_net_u32 (vni);
19390
19391   /* send it... */
19392   S (mp);
19393
19394   /* Wait for a reply... */
19395   W (ret);
19396   return ret;
19397 }
19398
19399 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19400 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19401 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19402 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19403 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19404 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19405 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19406 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19407
19408 static int
19409 api_one_adjacencies_get (vat_main_t * vam)
19410 {
19411   unformat_input_t *i = vam->input;
19412   vl_api_one_adjacencies_get_t *mp;
19413   u8 vni_set = 0;
19414   u32 vni = ~0;
19415   int ret;
19416
19417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19418     {
19419       if (unformat (i, "vni %d", &vni))
19420         {
19421           vni_set = 1;
19422         }
19423       else
19424         {
19425           errmsg ("parse error '%U'", format_unformat_error, i);
19426           return -99;
19427         }
19428     }
19429
19430   if (!vni_set)
19431     {
19432       errmsg ("vni not set!");
19433       return -99;
19434     }
19435
19436   if (!vam->json_output)
19437     {
19438       print (vam->ofp, "%s %40s", "leid", "reid");
19439     }
19440
19441   M (ONE_ADJACENCIES_GET, mp);
19442   mp->vni = clib_host_to_net_u32 (vni);
19443
19444   /* send it... */
19445   S (mp);
19446
19447   /* Wait for a reply... */
19448   W (ret);
19449   return ret;
19450 }
19451
19452 #define api_lisp_adjacencies_get api_one_adjacencies_get
19453
19454 static int
19455 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19456 {
19457   unformat_input_t *i = vam->input;
19458   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19459   int ret;
19460   u8 ip_family_set = 0, is_ip4 = 1;
19461
19462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19463     {
19464       if (unformat (i, "ip4"))
19465         {
19466           ip_family_set = 1;
19467           is_ip4 = 1;
19468         }
19469       else if (unformat (i, "ip6"))
19470         {
19471           ip_family_set = 1;
19472           is_ip4 = 0;
19473         }
19474       else
19475         {
19476           errmsg ("parse error '%U'", format_unformat_error, i);
19477           return -99;
19478         }
19479     }
19480
19481   if (!ip_family_set)
19482     {
19483       errmsg ("ip family not set!");
19484       return -99;
19485     }
19486
19487   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19488   mp->is_ip4 = is_ip4;
19489
19490   /* send it... */
19491   S (mp);
19492
19493   /* Wait for a reply... */
19494   W (ret);
19495   return ret;
19496 }
19497
19498 static int
19499 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19500 {
19501   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19502   int ret;
19503
19504   if (!vam->json_output)
19505     {
19506       print (vam->ofp, "VNIs");
19507     }
19508
19509   M (GPE_FWD_ENTRY_VNIS_GET, mp);
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_add_del_native_fwd_rpath (vat_main_t * vam)
19521 {
19522   unformat_input_t *i = vam->input;
19523   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19524   int ret = 0;
19525   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19526   struct in_addr ip4;
19527   struct in6_addr ip6;
19528   u32 table_id = 0, nh_sw_if_index = ~0;
19529
19530   memset (&ip4, 0, sizeof (ip4));
19531   memset (&ip6, 0, sizeof (ip6));
19532
19533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19534     {
19535       if (unformat (i, "del"))
19536         is_add = 0;
19537       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19538                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19539         {
19540           ip_set = 1;
19541           is_ip4 = 1;
19542         }
19543       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19544                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19545         {
19546           ip_set = 1;
19547           is_ip4 = 0;
19548         }
19549       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19550         {
19551           ip_set = 1;
19552           is_ip4 = 1;
19553           nh_sw_if_index = ~0;
19554         }
19555       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19556         {
19557           ip_set = 1;
19558           is_ip4 = 0;
19559           nh_sw_if_index = ~0;
19560         }
19561       else if (unformat (i, "table %d", &table_id))
19562         ;
19563       else
19564         {
19565           errmsg ("parse error '%U'", format_unformat_error, i);
19566           return -99;
19567         }
19568     }
19569
19570   if (!ip_set)
19571     {
19572       errmsg ("nh addr not set!");
19573       return -99;
19574     }
19575
19576   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19577   mp->is_add = is_add;
19578   mp->table_id = clib_host_to_net_u32 (table_id);
19579   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19580   mp->is_ip4 = is_ip4;
19581   if (is_ip4)
19582     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19583   else
19584     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19585
19586   /* send it... */
19587   S (mp);
19588
19589   /* Wait for a reply... */
19590   W (ret);
19591   return ret;
19592 }
19593
19594 static int
19595 api_one_map_server_dump (vat_main_t * vam)
19596 {
19597   vl_api_one_map_server_dump_t *mp;
19598   vl_api_control_ping_t *mp_ping;
19599   int ret;
19600
19601   if (!vam->json_output)
19602     {
19603       print (vam->ofp, "%=20s", "Map server");
19604     }
19605
19606   M (ONE_MAP_SERVER_DUMP, mp);
19607   /* send it... */
19608   S (mp);
19609
19610   /* Use a control ping for synchronization */
19611   MPING (CONTROL_PING, mp_ping);
19612   S (mp_ping);
19613
19614   /* Wait for a reply... */
19615   W (ret);
19616   return ret;
19617 }
19618
19619 #define api_lisp_map_server_dump api_one_map_server_dump
19620
19621 static int
19622 api_one_map_resolver_dump (vat_main_t * vam)
19623 {
19624   vl_api_one_map_resolver_dump_t *mp;
19625   vl_api_control_ping_t *mp_ping;
19626   int ret;
19627
19628   if (!vam->json_output)
19629     {
19630       print (vam->ofp, "%=20s", "Map resolver");
19631     }
19632
19633   M (ONE_MAP_RESOLVER_DUMP, mp);
19634   /* send it... */
19635   S (mp);
19636
19637   /* Use a control ping for synchronization */
19638   MPING (CONTROL_PING, mp_ping);
19639   S (mp_ping);
19640
19641   /* Wait for a reply... */
19642   W (ret);
19643   return ret;
19644 }
19645
19646 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19647
19648 static int
19649 api_one_stats_flush (vat_main_t * vam)
19650 {
19651   vl_api_one_stats_flush_t *mp;
19652   int ret = 0;
19653
19654   M (ONE_STATS_FLUSH, mp);
19655   S (mp);
19656   W (ret);
19657   return ret;
19658 }
19659
19660 static int
19661 api_one_stats_dump (vat_main_t * vam)
19662 {
19663   vl_api_one_stats_dump_t *mp;
19664   vl_api_control_ping_t *mp_ping;
19665   int ret;
19666
19667   M (ONE_STATS_DUMP, mp);
19668   /* send it... */
19669   S (mp);
19670
19671   /* Use a control ping for synchronization */
19672   MPING (CONTROL_PING, mp_ping);
19673   S (mp_ping);
19674
19675   /* Wait for a reply... */
19676   W (ret);
19677   return ret;
19678 }
19679
19680 static int
19681 api_show_one_status (vat_main_t * vam)
19682 {
19683   vl_api_show_one_status_t *mp;
19684   int ret;
19685
19686   if (!vam->json_output)
19687     {
19688       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19689     }
19690
19691   M (SHOW_ONE_STATUS, mp);
19692   /* send it... */
19693   S (mp);
19694   /* Wait for a reply... */
19695   W (ret);
19696   return ret;
19697 }
19698
19699 #define api_show_lisp_status api_show_one_status
19700
19701 static int
19702 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19703 {
19704   vl_api_gpe_fwd_entry_path_dump_t *mp;
19705   vl_api_control_ping_t *mp_ping;
19706   unformat_input_t *i = vam->input;
19707   u32 fwd_entry_index = ~0;
19708   int ret;
19709
19710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19711     {
19712       if (unformat (i, "index %d", &fwd_entry_index))
19713         ;
19714       else
19715         break;
19716     }
19717
19718   if (~0 == fwd_entry_index)
19719     {
19720       errmsg ("no index specified!");
19721       return -99;
19722     }
19723
19724   if (!vam->json_output)
19725     {
19726       print (vam->ofp, "first line");
19727     }
19728
19729   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19730
19731   /* send it... */
19732   S (mp);
19733   /* Use a control ping for synchronization */
19734   MPING (CONTROL_PING, mp_ping);
19735   S (mp_ping);
19736
19737   /* Wait for a reply... */
19738   W (ret);
19739   return ret;
19740 }
19741
19742 static int
19743 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19744 {
19745   vl_api_one_get_map_request_itr_rlocs_t *mp;
19746   int ret;
19747
19748   if (!vam->json_output)
19749     {
19750       print (vam->ofp, "%=20s", "itr-rlocs:");
19751     }
19752
19753   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19754   /* send it... */
19755   S (mp);
19756   /* Wait for a reply... */
19757   W (ret);
19758   return ret;
19759 }
19760
19761 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19762
19763 static int
19764 api_af_packet_create (vat_main_t * vam)
19765 {
19766   unformat_input_t *i = vam->input;
19767   vl_api_af_packet_create_t *mp;
19768   u8 *host_if_name = 0;
19769   u8 hw_addr[6];
19770   u8 random_hw_addr = 1;
19771   int ret;
19772
19773   memset (hw_addr, 0, sizeof (hw_addr));
19774
19775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19776     {
19777       if (unformat (i, "name %s", &host_if_name))
19778         vec_add1 (host_if_name, 0);
19779       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19780         random_hw_addr = 0;
19781       else
19782         break;
19783     }
19784
19785   if (!vec_len (host_if_name))
19786     {
19787       errmsg ("host-interface name must be specified");
19788       return -99;
19789     }
19790
19791   if (vec_len (host_if_name) > 64)
19792     {
19793       errmsg ("host-interface name too long");
19794       return -99;
19795     }
19796
19797   M (AF_PACKET_CREATE, mp);
19798
19799   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19800   clib_memcpy (mp->hw_addr, hw_addr, 6);
19801   mp->use_random_hw_addr = random_hw_addr;
19802   vec_free (host_if_name);
19803
19804   S (mp);
19805
19806   /* *INDENT-OFF* */
19807   W2 (ret,
19808       ({
19809         if (ret == 0)
19810           fprintf (vam->ofp ? vam->ofp : stderr,
19811                    " new sw_if_index = %d\n", vam->sw_if_index);
19812       }));
19813   /* *INDENT-ON* */
19814   return ret;
19815 }
19816
19817 static int
19818 api_af_packet_delete (vat_main_t * vam)
19819 {
19820   unformat_input_t *i = vam->input;
19821   vl_api_af_packet_delete_t *mp;
19822   u8 *host_if_name = 0;
19823   int ret;
19824
19825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19826     {
19827       if (unformat (i, "name %s", &host_if_name))
19828         vec_add1 (host_if_name, 0);
19829       else
19830         break;
19831     }
19832
19833   if (!vec_len (host_if_name))
19834     {
19835       errmsg ("host-interface name must be specified");
19836       return -99;
19837     }
19838
19839   if (vec_len (host_if_name) > 64)
19840     {
19841       errmsg ("host-interface name too long");
19842       return -99;
19843     }
19844
19845   M (AF_PACKET_DELETE, mp);
19846
19847   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19848   vec_free (host_if_name);
19849
19850   S (mp);
19851   W (ret);
19852   return ret;
19853 }
19854
19855 static void vl_api_af_packet_details_t_handler
19856   (vl_api_af_packet_details_t * mp)
19857 {
19858   vat_main_t *vam = &vat_main;
19859
19860   print (vam->ofp, "%-16s %d",
19861          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19862 }
19863
19864 static void vl_api_af_packet_details_t_handler_json
19865   (vl_api_af_packet_details_t * mp)
19866 {
19867   vat_main_t *vam = &vat_main;
19868   vat_json_node_t *node = NULL;
19869
19870   if (VAT_JSON_ARRAY != vam->json_tree.type)
19871     {
19872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19873       vat_json_init_array (&vam->json_tree);
19874     }
19875   node = vat_json_array_add (&vam->json_tree);
19876
19877   vat_json_init_object (node);
19878   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19879   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19880 }
19881
19882 static int
19883 api_af_packet_dump (vat_main_t * vam)
19884 {
19885   vl_api_af_packet_dump_t *mp;
19886   vl_api_control_ping_t *mp_ping;
19887   int ret;
19888
19889   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19890   /* Get list of tap interfaces */
19891   M (AF_PACKET_DUMP, mp);
19892   S (mp);
19893
19894   /* Use a control ping for synchronization */
19895   MPING (CONTROL_PING, mp_ping);
19896   S (mp_ping);
19897
19898   W (ret);
19899   return ret;
19900 }
19901
19902 static int
19903 api_policer_add_del (vat_main_t * vam)
19904 {
19905   unformat_input_t *i = vam->input;
19906   vl_api_policer_add_del_t *mp;
19907   u8 is_add = 1;
19908   u8 *name = 0;
19909   u32 cir = 0;
19910   u32 eir = 0;
19911   u64 cb = 0;
19912   u64 eb = 0;
19913   u8 rate_type = 0;
19914   u8 round_type = 0;
19915   u8 type = 0;
19916   u8 color_aware = 0;
19917   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19918   int ret;
19919
19920   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19921   conform_action.dscp = 0;
19922   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19923   exceed_action.dscp = 0;
19924   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19925   violate_action.dscp = 0;
19926
19927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19928     {
19929       if (unformat (i, "del"))
19930         is_add = 0;
19931       else if (unformat (i, "name %s", &name))
19932         vec_add1 (name, 0);
19933       else if (unformat (i, "cir %u", &cir))
19934         ;
19935       else if (unformat (i, "eir %u", &eir))
19936         ;
19937       else if (unformat (i, "cb %u", &cb))
19938         ;
19939       else if (unformat (i, "eb %u", &eb))
19940         ;
19941       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19942                          &rate_type))
19943         ;
19944       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19945                          &round_type))
19946         ;
19947       else if (unformat (i, "type %U", unformat_policer_type, &type))
19948         ;
19949       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19950                          &conform_action))
19951         ;
19952       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19953                          &exceed_action))
19954         ;
19955       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19956                          &violate_action))
19957         ;
19958       else if (unformat (i, "color-aware"))
19959         color_aware = 1;
19960       else
19961         break;
19962     }
19963
19964   if (!vec_len (name))
19965     {
19966       errmsg ("policer name must be specified");
19967       return -99;
19968     }
19969
19970   if (vec_len (name) > 64)
19971     {
19972       errmsg ("policer name too long");
19973       return -99;
19974     }
19975
19976   M (POLICER_ADD_DEL, mp);
19977
19978   clib_memcpy (mp->name, name, vec_len (name));
19979   vec_free (name);
19980   mp->is_add = is_add;
19981   mp->cir = ntohl (cir);
19982   mp->eir = ntohl (eir);
19983   mp->cb = clib_net_to_host_u64 (cb);
19984   mp->eb = clib_net_to_host_u64 (eb);
19985   mp->rate_type = rate_type;
19986   mp->round_type = round_type;
19987   mp->type = type;
19988   mp->conform_action_type = conform_action.action_type;
19989   mp->conform_dscp = conform_action.dscp;
19990   mp->exceed_action_type = exceed_action.action_type;
19991   mp->exceed_dscp = exceed_action.dscp;
19992   mp->violate_action_type = violate_action.action_type;
19993   mp->violate_dscp = violate_action.dscp;
19994   mp->color_aware = color_aware;
19995
19996   S (mp);
19997   W (ret);
19998   return ret;
19999 }
20000
20001 static int
20002 api_policer_dump (vat_main_t * vam)
20003 {
20004   unformat_input_t *i = vam->input;
20005   vl_api_policer_dump_t *mp;
20006   vl_api_control_ping_t *mp_ping;
20007   u8 *match_name = 0;
20008   u8 match_name_valid = 0;
20009   int ret;
20010
20011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20012     {
20013       if (unformat (i, "name %s", &match_name))
20014         {
20015           vec_add1 (match_name, 0);
20016           match_name_valid = 1;
20017         }
20018       else
20019         break;
20020     }
20021
20022   M (POLICER_DUMP, mp);
20023   mp->match_name_valid = match_name_valid;
20024   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20025   vec_free (match_name);
20026   /* send it... */
20027   S (mp);
20028
20029   /* Use a control ping for synchronization */
20030   MPING (CONTROL_PING, mp_ping);
20031   S (mp_ping);
20032
20033   /* Wait for a reply... */
20034   W (ret);
20035   return ret;
20036 }
20037
20038 static int
20039 api_policer_classify_set_interface (vat_main_t * vam)
20040 {
20041   unformat_input_t *i = vam->input;
20042   vl_api_policer_classify_set_interface_t *mp;
20043   u32 sw_if_index;
20044   int sw_if_index_set;
20045   u32 ip4_table_index = ~0;
20046   u32 ip6_table_index = ~0;
20047   u32 l2_table_index = ~0;
20048   u8 is_add = 1;
20049   int ret;
20050
20051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20052     {
20053       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20054         sw_if_index_set = 1;
20055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20056         sw_if_index_set = 1;
20057       else if (unformat (i, "del"))
20058         is_add = 0;
20059       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20060         ;
20061       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20062         ;
20063       else if (unformat (i, "l2-table %d", &l2_table_index))
20064         ;
20065       else
20066         {
20067           clib_warning ("parse error '%U'", format_unformat_error, i);
20068           return -99;
20069         }
20070     }
20071
20072   if (sw_if_index_set == 0)
20073     {
20074       errmsg ("missing interface name or sw_if_index");
20075       return -99;
20076     }
20077
20078   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20079
20080   mp->sw_if_index = ntohl (sw_if_index);
20081   mp->ip4_table_index = ntohl (ip4_table_index);
20082   mp->ip6_table_index = ntohl (ip6_table_index);
20083   mp->l2_table_index = ntohl (l2_table_index);
20084   mp->is_add = is_add;
20085
20086   S (mp);
20087   W (ret);
20088   return ret;
20089 }
20090
20091 static int
20092 api_policer_classify_dump (vat_main_t * vam)
20093 {
20094   unformat_input_t *i = vam->input;
20095   vl_api_policer_classify_dump_t *mp;
20096   vl_api_control_ping_t *mp_ping;
20097   u8 type = POLICER_CLASSIFY_N_TABLES;
20098   int ret;
20099
20100   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20101     ;
20102   else
20103     {
20104       errmsg ("classify table type must be specified");
20105       return -99;
20106     }
20107
20108   if (!vam->json_output)
20109     {
20110       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20111     }
20112
20113   M (POLICER_CLASSIFY_DUMP, mp);
20114   mp->type = type;
20115   /* send it... */
20116   S (mp);
20117
20118   /* Use a control ping for synchronization */
20119   MPING (CONTROL_PING, mp_ping);
20120   S (mp_ping);
20121
20122   /* Wait for a reply... */
20123   W (ret);
20124   return ret;
20125 }
20126
20127 static int
20128 api_netmap_create (vat_main_t * vam)
20129 {
20130   unformat_input_t *i = vam->input;
20131   vl_api_netmap_create_t *mp;
20132   u8 *if_name = 0;
20133   u8 hw_addr[6];
20134   u8 random_hw_addr = 1;
20135   u8 is_pipe = 0;
20136   u8 is_master = 0;
20137   int ret;
20138
20139   memset (hw_addr, 0, sizeof (hw_addr));
20140
20141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20142     {
20143       if (unformat (i, "name %s", &if_name))
20144         vec_add1 (if_name, 0);
20145       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20146         random_hw_addr = 0;
20147       else if (unformat (i, "pipe"))
20148         is_pipe = 1;
20149       else if (unformat (i, "master"))
20150         is_master = 1;
20151       else if (unformat (i, "slave"))
20152         is_master = 0;
20153       else
20154         break;
20155     }
20156
20157   if (!vec_len (if_name))
20158     {
20159       errmsg ("interface name must be specified");
20160       return -99;
20161     }
20162
20163   if (vec_len (if_name) > 64)
20164     {
20165       errmsg ("interface name too long");
20166       return -99;
20167     }
20168
20169   M (NETMAP_CREATE, mp);
20170
20171   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20172   clib_memcpy (mp->hw_addr, hw_addr, 6);
20173   mp->use_random_hw_addr = random_hw_addr;
20174   mp->is_pipe = is_pipe;
20175   mp->is_master = is_master;
20176   vec_free (if_name);
20177
20178   S (mp);
20179   W (ret);
20180   return ret;
20181 }
20182
20183 static int
20184 api_netmap_delete (vat_main_t * vam)
20185 {
20186   unformat_input_t *i = vam->input;
20187   vl_api_netmap_delete_t *mp;
20188   u8 *if_name = 0;
20189   int ret;
20190
20191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20192     {
20193       if (unformat (i, "name %s", &if_name))
20194         vec_add1 (if_name, 0);
20195       else
20196         break;
20197     }
20198
20199   if (!vec_len (if_name))
20200     {
20201       errmsg ("interface name must be specified");
20202       return -99;
20203     }
20204
20205   if (vec_len (if_name) > 64)
20206     {
20207       errmsg ("interface name too long");
20208       return -99;
20209     }
20210
20211   M (NETMAP_DELETE, mp);
20212
20213   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20214   vec_free (if_name);
20215
20216   S (mp);
20217   W (ret);
20218   return ret;
20219 }
20220
20221 static void
20222 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20223 {
20224   if (fp->afi == IP46_TYPE_IP6)
20225     print (vam->ofp,
20226            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20227            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20228            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20229            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20230            format_ip6_address, fp->next_hop);
20231   else if (fp->afi == IP46_TYPE_IP4)
20232     print (vam->ofp,
20233            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20234            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20235            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20236            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20237            format_ip4_address, fp->next_hop);
20238 }
20239
20240 static void
20241 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20242                                  vl_api_fib_path_t * fp)
20243 {
20244   struct in_addr ip4;
20245   struct in6_addr ip6;
20246
20247   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20248   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20249   vat_json_object_add_uint (node, "is_local", fp->is_local);
20250   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20251   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20252   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20253   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20254   if (fp->afi == IP46_TYPE_IP4)
20255     {
20256       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20257       vat_json_object_add_ip4 (node, "next_hop", ip4);
20258     }
20259   else if (fp->afi == IP46_TYPE_IP6)
20260     {
20261       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20262       vat_json_object_add_ip6 (node, "next_hop", ip6);
20263     }
20264 }
20265
20266 static void
20267 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20268 {
20269   vat_main_t *vam = &vat_main;
20270   int count = ntohl (mp->mt_count);
20271   vl_api_fib_path_t *fp;
20272   i32 i;
20273
20274   print (vam->ofp, "[%d]: sw_if_index %d via:",
20275          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20276   fp = mp->mt_paths;
20277   for (i = 0; i < count; i++)
20278     {
20279       vl_api_mpls_fib_path_print (vam, fp);
20280       fp++;
20281     }
20282
20283   print (vam->ofp, "");
20284 }
20285
20286 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20287 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20288
20289 static void
20290 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20291 {
20292   vat_main_t *vam = &vat_main;
20293   vat_json_node_t *node = NULL;
20294   int count = ntohl (mp->mt_count);
20295   vl_api_fib_path_t *fp;
20296   i32 i;
20297
20298   if (VAT_JSON_ARRAY != vam->json_tree.type)
20299     {
20300       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20301       vat_json_init_array (&vam->json_tree);
20302     }
20303   node = vat_json_array_add (&vam->json_tree);
20304
20305   vat_json_init_object (node);
20306   vat_json_object_add_uint (node, "tunnel_index",
20307                             ntohl (mp->mt_tunnel_index));
20308   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20309
20310   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20311
20312   fp = mp->mt_paths;
20313   for (i = 0; i < count; i++)
20314     {
20315       vl_api_mpls_fib_path_json_print (node, fp);
20316       fp++;
20317     }
20318 }
20319
20320 static int
20321 api_mpls_tunnel_dump (vat_main_t * vam)
20322 {
20323   vl_api_mpls_tunnel_dump_t *mp;
20324   vl_api_control_ping_t *mp_ping;
20325   i32 index = -1;
20326   int ret;
20327
20328   /* Parse args required to build the message */
20329   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20330     {
20331       if (!unformat (vam->input, "tunnel_index %d", &index))
20332         {
20333           index = -1;
20334           break;
20335         }
20336     }
20337
20338   print (vam->ofp, "  tunnel_index %d", index);
20339
20340   M (MPLS_TUNNEL_DUMP, mp);
20341   mp->tunnel_index = htonl (index);
20342   S (mp);
20343
20344   /* Use a control ping for synchronization */
20345   MPING (CONTROL_PING, mp_ping);
20346   S (mp_ping);
20347
20348   W (ret);
20349   return ret;
20350 }
20351
20352 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20353 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20354
20355
20356 static void
20357 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20358 {
20359   vat_main_t *vam = &vat_main;
20360   int count = ntohl (mp->count);
20361   vl_api_fib_path_t *fp;
20362   int i;
20363
20364   print (vam->ofp,
20365          "table-id %d, label %u, ess_bit %u",
20366          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20367   fp = mp->path;
20368   for (i = 0; i < count; i++)
20369     {
20370       vl_api_mpls_fib_path_print (vam, fp);
20371       fp++;
20372     }
20373 }
20374
20375 static void vl_api_mpls_fib_details_t_handler_json
20376   (vl_api_mpls_fib_details_t * mp)
20377 {
20378   vat_main_t *vam = &vat_main;
20379   int count = ntohl (mp->count);
20380   vat_json_node_t *node = NULL;
20381   vl_api_fib_path_t *fp;
20382   int i;
20383
20384   if (VAT_JSON_ARRAY != vam->json_tree.type)
20385     {
20386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20387       vat_json_init_array (&vam->json_tree);
20388     }
20389   node = vat_json_array_add (&vam->json_tree);
20390
20391   vat_json_init_object (node);
20392   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20393   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20394   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20395   vat_json_object_add_uint (node, "path_count", count);
20396   fp = mp->path;
20397   for (i = 0; i < count; i++)
20398     {
20399       vl_api_mpls_fib_path_json_print (node, fp);
20400       fp++;
20401     }
20402 }
20403
20404 static int
20405 api_mpls_fib_dump (vat_main_t * vam)
20406 {
20407   vl_api_mpls_fib_dump_t *mp;
20408   vl_api_control_ping_t *mp_ping;
20409   int ret;
20410
20411   M (MPLS_FIB_DUMP, mp);
20412   S (mp);
20413
20414   /* Use a control ping for synchronization */
20415   MPING (CONTROL_PING, mp_ping);
20416   S (mp_ping);
20417
20418   W (ret);
20419   return ret;
20420 }
20421
20422 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20423 #define vl_api_ip_fib_details_t_print vl_noop_handler
20424
20425 static void
20426 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20427 {
20428   vat_main_t *vam = &vat_main;
20429   int count = ntohl (mp->count);
20430   vl_api_fib_path_t *fp;
20431   int i;
20432
20433   print (vam->ofp,
20434          "table-id %d, prefix %U/%d",
20435          ntohl (mp->table_id), format_ip4_address, mp->address,
20436          mp->address_length);
20437   fp = mp->path;
20438   for (i = 0; i < count; i++)
20439     {
20440       if (fp->afi == IP46_TYPE_IP6)
20441         print (vam->ofp,
20442                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20443                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20444                "next_hop_table %d",
20445                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20446                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20447                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20448       else if (fp->afi == IP46_TYPE_IP4)
20449         print (vam->ofp,
20450                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20451                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20452                "next_hop_table %d",
20453                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20454                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20455                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20456       fp++;
20457     }
20458 }
20459
20460 static void vl_api_ip_fib_details_t_handler_json
20461   (vl_api_ip_fib_details_t * mp)
20462 {
20463   vat_main_t *vam = &vat_main;
20464   int count = ntohl (mp->count);
20465   vat_json_node_t *node = NULL;
20466   struct in_addr ip4;
20467   struct in6_addr ip6;
20468   vl_api_fib_path_t *fp;
20469   int i;
20470
20471   if (VAT_JSON_ARRAY != vam->json_tree.type)
20472     {
20473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20474       vat_json_init_array (&vam->json_tree);
20475     }
20476   node = vat_json_array_add (&vam->json_tree);
20477
20478   vat_json_init_object (node);
20479   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20480   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20481   vat_json_object_add_ip4 (node, "prefix", ip4);
20482   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20483   vat_json_object_add_uint (node, "path_count", count);
20484   fp = mp->path;
20485   for (i = 0; i < count; i++)
20486     {
20487       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20488       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20489       vat_json_object_add_uint (node, "is_local", fp->is_local);
20490       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20491       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20492       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20493       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20494       if (fp->afi == IP46_TYPE_IP4)
20495         {
20496           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20497           vat_json_object_add_ip4 (node, "next_hop", ip4);
20498         }
20499       else if (fp->afi == IP46_TYPE_IP6)
20500         {
20501           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20502           vat_json_object_add_ip6 (node, "next_hop", ip6);
20503         }
20504     }
20505 }
20506
20507 static int
20508 api_ip_fib_dump (vat_main_t * vam)
20509 {
20510   vl_api_ip_fib_dump_t *mp;
20511   vl_api_control_ping_t *mp_ping;
20512   int ret;
20513
20514   M (IP_FIB_DUMP, mp);
20515   S (mp);
20516
20517   /* Use a control ping for synchronization */
20518   MPING (CONTROL_PING, mp_ping);
20519   S (mp_ping);
20520
20521   W (ret);
20522   return ret;
20523 }
20524
20525 static int
20526 api_ip_mfib_dump (vat_main_t * vam)
20527 {
20528   vl_api_ip_mfib_dump_t *mp;
20529   vl_api_control_ping_t *mp_ping;
20530   int ret;
20531
20532   M (IP_MFIB_DUMP, mp);
20533   S (mp);
20534
20535   /* Use a control ping for synchronization */
20536   MPING (CONTROL_PING, mp_ping);
20537   S (mp_ping);
20538
20539   W (ret);
20540   return ret;
20541 }
20542
20543 static void vl_api_ip_neighbor_details_t_handler
20544   (vl_api_ip_neighbor_details_t * mp)
20545 {
20546   vat_main_t *vam = &vat_main;
20547
20548   print (vam->ofp, "%c %U %U",
20549          (mp->is_static) ? 'S' : 'D',
20550          format_ethernet_address, &mp->mac_address,
20551          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20552          &mp->ip_address);
20553 }
20554
20555 static void vl_api_ip_neighbor_details_t_handler_json
20556   (vl_api_ip_neighbor_details_t * mp)
20557 {
20558
20559   vat_main_t *vam = &vat_main;
20560   vat_json_node_t *node;
20561   struct in_addr ip4;
20562   struct in6_addr ip6;
20563
20564   if (VAT_JSON_ARRAY != vam->json_tree.type)
20565     {
20566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20567       vat_json_init_array (&vam->json_tree);
20568     }
20569   node = vat_json_array_add (&vam->json_tree);
20570
20571   vat_json_init_object (node);
20572   vat_json_object_add_string_copy (node, "flag",
20573                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20574                                    "dynamic");
20575
20576   vat_json_object_add_string_copy (node, "link_layer",
20577                                    format (0, "%U", format_ethernet_address,
20578                                            &mp->mac_address));
20579
20580   if (mp->is_ipv6)
20581     {
20582       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20583       vat_json_object_add_ip6 (node, "ip_address", ip6);
20584     }
20585   else
20586     {
20587       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20588       vat_json_object_add_ip4 (node, "ip_address", ip4);
20589     }
20590 }
20591
20592 static int
20593 api_ip_neighbor_dump (vat_main_t * vam)
20594 {
20595   unformat_input_t *i = vam->input;
20596   vl_api_ip_neighbor_dump_t *mp;
20597   vl_api_control_ping_t *mp_ping;
20598   u8 is_ipv6 = 0;
20599   u32 sw_if_index = ~0;
20600   int ret;
20601
20602   /* Parse args required to build the message */
20603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20604     {
20605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20606         ;
20607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20608         ;
20609       else if (unformat (i, "ip6"))
20610         is_ipv6 = 1;
20611       else
20612         break;
20613     }
20614
20615   if (sw_if_index == ~0)
20616     {
20617       errmsg ("missing interface name or sw_if_index");
20618       return -99;
20619     }
20620
20621   M (IP_NEIGHBOR_DUMP, mp);
20622   mp->is_ipv6 = (u8) is_ipv6;
20623   mp->sw_if_index = ntohl (sw_if_index);
20624   S (mp);
20625
20626   /* Use a control ping for synchronization */
20627   MPING (CONTROL_PING, mp_ping);
20628   S (mp_ping);
20629
20630   W (ret);
20631   return ret;
20632 }
20633
20634 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20635 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20636
20637 static void
20638 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20639 {
20640   vat_main_t *vam = &vat_main;
20641   int count = ntohl (mp->count);
20642   vl_api_fib_path_t *fp;
20643   int i;
20644
20645   print (vam->ofp,
20646          "table-id %d, prefix %U/%d",
20647          ntohl (mp->table_id), format_ip6_address, mp->address,
20648          mp->address_length);
20649   fp = mp->path;
20650   for (i = 0; i < count; i++)
20651     {
20652       if (fp->afi == IP46_TYPE_IP6)
20653         print (vam->ofp,
20654                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20655                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20656                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20657                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20658                format_ip6_address, fp->next_hop);
20659       else if (fp->afi == IP46_TYPE_IP4)
20660         print (vam->ofp,
20661                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20662                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20663                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20664                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20665                format_ip4_address, fp->next_hop);
20666       fp++;
20667     }
20668 }
20669
20670 static void vl_api_ip6_fib_details_t_handler_json
20671   (vl_api_ip6_fib_details_t * mp)
20672 {
20673   vat_main_t *vam = &vat_main;
20674   int count = ntohl (mp->count);
20675   vat_json_node_t *node = NULL;
20676   struct in_addr ip4;
20677   struct in6_addr ip6;
20678   vl_api_fib_path_t *fp;
20679   int i;
20680
20681   if (VAT_JSON_ARRAY != vam->json_tree.type)
20682     {
20683       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20684       vat_json_init_array (&vam->json_tree);
20685     }
20686   node = vat_json_array_add (&vam->json_tree);
20687
20688   vat_json_init_object (node);
20689   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20690   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20691   vat_json_object_add_ip6 (node, "prefix", ip6);
20692   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20693   vat_json_object_add_uint (node, "path_count", count);
20694   fp = mp->path;
20695   for (i = 0; i < count; i++)
20696     {
20697       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20698       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20699       vat_json_object_add_uint (node, "is_local", fp->is_local);
20700       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20701       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20702       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20703       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20704       if (fp->afi == IP46_TYPE_IP4)
20705         {
20706           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20707           vat_json_object_add_ip4 (node, "next_hop", ip4);
20708         }
20709       else if (fp->afi == IP46_TYPE_IP6)
20710         {
20711           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20712           vat_json_object_add_ip6 (node, "next_hop", ip6);
20713         }
20714     }
20715 }
20716
20717 static int
20718 api_ip6_fib_dump (vat_main_t * vam)
20719 {
20720   vl_api_ip6_fib_dump_t *mp;
20721   vl_api_control_ping_t *mp_ping;
20722   int ret;
20723
20724   M (IP6_FIB_DUMP, mp);
20725   S (mp);
20726
20727   /* Use a control ping for synchronization */
20728   MPING (CONTROL_PING, mp_ping);
20729   S (mp_ping);
20730
20731   W (ret);
20732   return ret;
20733 }
20734
20735 static int
20736 api_ip6_mfib_dump (vat_main_t * vam)
20737 {
20738   vl_api_ip6_mfib_dump_t *mp;
20739   vl_api_control_ping_t *mp_ping;
20740   int ret;
20741
20742   M (IP6_MFIB_DUMP, mp);
20743   S (mp);
20744
20745   /* Use a control ping for synchronization */
20746   MPING (CONTROL_PING, mp_ping);
20747   S (mp_ping);
20748
20749   W (ret);
20750   return ret;
20751 }
20752
20753 int
20754 api_classify_table_ids (vat_main_t * vam)
20755 {
20756   vl_api_classify_table_ids_t *mp;
20757   int ret;
20758
20759   /* Construct the API message */
20760   M (CLASSIFY_TABLE_IDS, mp);
20761   mp->context = 0;
20762
20763   S (mp);
20764   W (ret);
20765   return ret;
20766 }
20767
20768 int
20769 api_classify_table_by_interface (vat_main_t * vam)
20770 {
20771   unformat_input_t *input = vam->input;
20772   vl_api_classify_table_by_interface_t *mp;
20773
20774   u32 sw_if_index = ~0;
20775   int ret;
20776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20777     {
20778       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20779         ;
20780       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20781         ;
20782       else
20783         break;
20784     }
20785   if (sw_if_index == ~0)
20786     {
20787       errmsg ("missing interface name or sw_if_index");
20788       return -99;
20789     }
20790
20791   /* Construct the API message */
20792   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20793   mp->context = 0;
20794   mp->sw_if_index = ntohl (sw_if_index);
20795
20796   S (mp);
20797   W (ret);
20798   return ret;
20799 }
20800
20801 int
20802 api_classify_table_info (vat_main_t * vam)
20803 {
20804   unformat_input_t *input = vam->input;
20805   vl_api_classify_table_info_t *mp;
20806
20807   u32 table_id = ~0;
20808   int ret;
20809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20810     {
20811       if (unformat (input, "table_id %d", &table_id))
20812         ;
20813       else
20814         break;
20815     }
20816   if (table_id == ~0)
20817     {
20818       errmsg ("missing table id");
20819       return -99;
20820     }
20821
20822   /* Construct the API message */
20823   M (CLASSIFY_TABLE_INFO, mp);
20824   mp->context = 0;
20825   mp->table_id = ntohl (table_id);
20826
20827   S (mp);
20828   W (ret);
20829   return ret;
20830 }
20831
20832 int
20833 api_classify_session_dump (vat_main_t * vam)
20834 {
20835   unformat_input_t *input = vam->input;
20836   vl_api_classify_session_dump_t *mp;
20837   vl_api_control_ping_t *mp_ping;
20838
20839   u32 table_id = ~0;
20840   int ret;
20841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20842     {
20843       if (unformat (input, "table_id %d", &table_id))
20844         ;
20845       else
20846         break;
20847     }
20848   if (table_id == ~0)
20849     {
20850       errmsg ("missing table id");
20851       return -99;
20852     }
20853
20854   /* Construct the API message */
20855   M (CLASSIFY_SESSION_DUMP, mp);
20856   mp->context = 0;
20857   mp->table_id = ntohl (table_id);
20858   S (mp);
20859
20860   /* Use a control ping for synchronization */
20861   MPING (CONTROL_PING, mp_ping);
20862   S (mp_ping);
20863
20864   W (ret);
20865   return ret;
20866 }
20867
20868 static void
20869 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20870 {
20871   vat_main_t *vam = &vat_main;
20872
20873   print (vam->ofp, "collector_address %U, collector_port %d, "
20874          "src_address %U, vrf_id %d, path_mtu %u, "
20875          "template_interval %u, udp_checksum %d",
20876          format_ip4_address, mp->collector_address,
20877          ntohs (mp->collector_port),
20878          format_ip4_address, mp->src_address,
20879          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20880          ntohl (mp->template_interval), mp->udp_checksum);
20881
20882   vam->retval = 0;
20883   vam->result_ready = 1;
20884 }
20885
20886 static void
20887   vl_api_ipfix_exporter_details_t_handler_json
20888   (vl_api_ipfix_exporter_details_t * mp)
20889 {
20890   vat_main_t *vam = &vat_main;
20891   vat_json_node_t node;
20892   struct in_addr collector_address;
20893   struct in_addr src_address;
20894
20895   vat_json_init_object (&node);
20896   clib_memcpy (&collector_address, &mp->collector_address,
20897                sizeof (collector_address));
20898   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20899   vat_json_object_add_uint (&node, "collector_port",
20900                             ntohs (mp->collector_port));
20901   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20902   vat_json_object_add_ip4 (&node, "src_address", src_address);
20903   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20904   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20905   vat_json_object_add_uint (&node, "template_interval",
20906                             ntohl (mp->template_interval));
20907   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20908
20909   vat_json_print (vam->ofp, &node);
20910   vat_json_free (&node);
20911   vam->retval = 0;
20912   vam->result_ready = 1;
20913 }
20914
20915 int
20916 api_ipfix_exporter_dump (vat_main_t * vam)
20917 {
20918   vl_api_ipfix_exporter_dump_t *mp;
20919   int ret;
20920
20921   /* Construct the API message */
20922   M (IPFIX_EXPORTER_DUMP, mp);
20923   mp->context = 0;
20924
20925   S (mp);
20926   W (ret);
20927   return ret;
20928 }
20929
20930 static int
20931 api_ipfix_classify_stream_dump (vat_main_t * vam)
20932 {
20933   vl_api_ipfix_classify_stream_dump_t *mp;
20934   int ret;
20935
20936   /* Construct the API message */
20937   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20938   mp->context = 0;
20939
20940   S (mp);
20941   W (ret);
20942   return ret;
20943   /* NOTREACHED */
20944   return 0;
20945 }
20946
20947 static void
20948   vl_api_ipfix_classify_stream_details_t_handler
20949   (vl_api_ipfix_classify_stream_details_t * mp)
20950 {
20951   vat_main_t *vam = &vat_main;
20952   print (vam->ofp, "domain_id %d, src_port %d",
20953          ntohl (mp->domain_id), ntohs (mp->src_port));
20954   vam->retval = 0;
20955   vam->result_ready = 1;
20956 }
20957
20958 static void
20959   vl_api_ipfix_classify_stream_details_t_handler_json
20960   (vl_api_ipfix_classify_stream_details_t * mp)
20961 {
20962   vat_main_t *vam = &vat_main;
20963   vat_json_node_t node;
20964
20965   vat_json_init_object (&node);
20966   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20967   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20968
20969   vat_json_print (vam->ofp, &node);
20970   vat_json_free (&node);
20971   vam->retval = 0;
20972   vam->result_ready = 1;
20973 }
20974
20975 static int
20976 api_ipfix_classify_table_dump (vat_main_t * vam)
20977 {
20978   vl_api_ipfix_classify_table_dump_t *mp;
20979   vl_api_control_ping_t *mp_ping;
20980   int ret;
20981
20982   if (!vam->json_output)
20983     {
20984       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20985              "transport_protocol");
20986     }
20987
20988   /* Construct the API message */
20989   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20990
20991   /* send it... */
20992   S (mp);
20993
20994   /* Use a control ping for synchronization */
20995   MPING (CONTROL_PING, mp_ping);
20996   S (mp_ping);
20997
20998   W (ret);
20999   return ret;
21000 }
21001
21002 static void
21003   vl_api_ipfix_classify_table_details_t_handler
21004   (vl_api_ipfix_classify_table_details_t * mp)
21005 {
21006   vat_main_t *vam = &vat_main;
21007   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21008          mp->transport_protocol);
21009 }
21010
21011 static void
21012   vl_api_ipfix_classify_table_details_t_handler_json
21013   (vl_api_ipfix_classify_table_details_t * mp)
21014 {
21015   vat_json_node_t *node = NULL;
21016   vat_main_t *vam = &vat_main;
21017
21018   if (VAT_JSON_ARRAY != vam->json_tree.type)
21019     {
21020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21021       vat_json_init_array (&vam->json_tree);
21022     }
21023
21024   node = vat_json_array_add (&vam->json_tree);
21025   vat_json_init_object (node);
21026
21027   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21028   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21029   vat_json_object_add_uint (node, "transport_protocol",
21030                             mp->transport_protocol);
21031 }
21032
21033 static int
21034 api_sw_interface_span_enable_disable (vat_main_t * vam)
21035 {
21036   unformat_input_t *i = vam->input;
21037   vl_api_sw_interface_span_enable_disable_t *mp;
21038   u32 src_sw_if_index = ~0;
21039   u32 dst_sw_if_index = ~0;
21040   u8 state = 3;
21041   int ret;
21042   u8 is_l2 = 0;
21043
21044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21045     {
21046       if (unformat
21047           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21048         ;
21049       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21050         ;
21051       else
21052         if (unformat
21053             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21054         ;
21055       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21056         ;
21057       else if (unformat (i, "disable"))
21058         state = 0;
21059       else if (unformat (i, "rx"))
21060         state = 1;
21061       else if (unformat (i, "tx"))
21062         state = 2;
21063       else if (unformat (i, "both"))
21064         state = 3;
21065       else if (unformat (i, "l2"))
21066         is_l2 = 1;
21067       else
21068         break;
21069     }
21070
21071   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21072
21073   mp->sw_if_index_from = htonl (src_sw_if_index);
21074   mp->sw_if_index_to = htonl (dst_sw_if_index);
21075   mp->state = state;
21076   mp->is_l2 = is_l2;
21077
21078   S (mp);
21079   W (ret);
21080   return ret;
21081 }
21082
21083 static void
21084 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21085                                             * mp)
21086 {
21087   vat_main_t *vam = &vat_main;
21088   u8 *sw_if_from_name = 0;
21089   u8 *sw_if_to_name = 0;
21090   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21091   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21092   char *states[] = { "none", "rx", "tx", "both" };
21093   hash_pair_t *p;
21094
21095   /* *INDENT-OFF* */
21096   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21097   ({
21098     if ((u32) p->value[0] == sw_if_index_from)
21099       {
21100         sw_if_from_name = (u8 *)(p->key);
21101         if (sw_if_to_name)
21102           break;
21103       }
21104     if ((u32) p->value[0] == sw_if_index_to)
21105       {
21106         sw_if_to_name = (u8 *)(p->key);
21107         if (sw_if_from_name)
21108           break;
21109       }
21110   }));
21111   /* *INDENT-ON* */
21112   print (vam->ofp, "%20s => %20s (%s) %s",
21113          sw_if_from_name, sw_if_to_name, states[mp->state],
21114          mp->is_l2 ? "l2" : "device");
21115 }
21116
21117 static void
21118   vl_api_sw_interface_span_details_t_handler_json
21119   (vl_api_sw_interface_span_details_t * mp)
21120 {
21121   vat_main_t *vam = &vat_main;
21122   vat_json_node_t *node = NULL;
21123   u8 *sw_if_from_name = 0;
21124   u8 *sw_if_to_name = 0;
21125   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21126   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21127   hash_pair_t *p;
21128
21129   /* *INDENT-OFF* */
21130   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21131   ({
21132     if ((u32) p->value[0] == sw_if_index_from)
21133       {
21134         sw_if_from_name = (u8 *)(p->key);
21135         if (sw_if_to_name)
21136           break;
21137       }
21138     if ((u32) p->value[0] == sw_if_index_to)
21139       {
21140         sw_if_to_name = (u8 *)(p->key);
21141         if (sw_if_from_name)
21142           break;
21143       }
21144   }));
21145   /* *INDENT-ON* */
21146
21147   if (VAT_JSON_ARRAY != vam->json_tree.type)
21148     {
21149       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21150       vat_json_init_array (&vam->json_tree);
21151     }
21152   node = vat_json_array_add (&vam->json_tree);
21153
21154   vat_json_init_object (node);
21155   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21156   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21157   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21158   if (0 != sw_if_to_name)
21159     {
21160       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21161     }
21162   vat_json_object_add_uint (node, "state", mp->state);
21163   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21164 }
21165
21166 static int
21167 api_sw_interface_span_dump (vat_main_t * vam)
21168 {
21169   unformat_input_t *input = vam->input;
21170   vl_api_sw_interface_span_dump_t *mp;
21171   vl_api_control_ping_t *mp_ping;
21172   u8 is_l2 = 0;
21173   int ret;
21174
21175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21176     {
21177       if (unformat (input, "l2"))
21178         is_l2 = 1;
21179       else
21180         break;
21181     }
21182
21183   M (SW_INTERFACE_SPAN_DUMP, mp);
21184   mp->is_l2 = is_l2;
21185   S (mp);
21186
21187   /* Use a control ping for synchronization */
21188   MPING (CONTROL_PING, mp_ping);
21189   S (mp_ping);
21190
21191   W (ret);
21192   return ret;
21193 }
21194
21195 int
21196 api_pg_create_interface (vat_main_t * vam)
21197 {
21198   unformat_input_t *input = vam->input;
21199   vl_api_pg_create_interface_t *mp;
21200
21201   u32 if_id = ~0;
21202   int ret;
21203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21204     {
21205       if (unformat (input, "if_id %d", &if_id))
21206         ;
21207       else
21208         break;
21209     }
21210   if (if_id == ~0)
21211     {
21212       errmsg ("missing pg interface index");
21213       return -99;
21214     }
21215
21216   /* Construct the API message */
21217   M (PG_CREATE_INTERFACE, mp);
21218   mp->context = 0;
21219   mp->interface_id = ntohl (if_id);
21220
21221   S (mp);
21222   W (ret);
21223   return ret;
21224 }
21225
21226 int
21227 api_pg_capture (vat_main_t * vam)
21228 {
21229   unformat_input_t *input = vam->input;
21230   vl_api_pg_capture_t *mp;
21231
21232   u32 if_id = ~0;
21233   u8 enable = 1;
21234   u32 count = 1;
21235   u8 pcap_file_set = 0;
21236   u8 *pcap_file = 0;
21237   int ret;
21238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21239     {
21240       if (unformat (input, "if_id %d", &if_id))
21241         ;
21242       else if (unformat (input, "pcap %s", &pcap_file))
21243         pcap_file_set = 1;
21244       else if (unformat (input, "count %d", &count))
21245         ;
21246       else if (unformat (input, "disable"))
21247         enable = 0;
21248       else
21249         break;
21250     }
21251   if (if_id == ~0)
21252     {
21253       errmsg ("missing pg interface index");
21254       return -99;
21255     }
21256   if (pcap_file_set > 0)
21257     {
21258       if (vec_len (pcap_file) > 255)
21259         {
21260           errmsg ("pcap file name is too long");
21261           return -99;
21262         }
21263     }
21264
21265   u32 name_len = vec_len (pcap_file);
21266   /* Construct the API message */
21267   M (PG_CAPTURE, mp);
21268   mp->context = 0;
21269   mp->interface_id = ntohl (if_id);
21270   mp->is_enabled = enable;
21271   mp->count = ntohl (count);
21272   mp->pcap_name_length = ntohl (name_len);
21273   if (pcap_file_set != 0)
21274     {
21275       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21276     }
21277   vec_free (pcap_file);
21278
21279   S (mp);
21280   W (ret);
21281   return ret;
21282 }
21283
21284 int
21285 api_pg_enable_disable (vat_main_t * vam)
21286 {
21287   unformat_input_t *input = vam->input;
21288   vl_api_pg_enable_disable_t *mp;
21289
21290   u8 enable = 1;
21291   u8 stream_name_set = 0;
21292   u8 *stream_name = 0;
21293   int ret;
21294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21295     {
21296       if (unformat (input, "stream %s", &stream_name))
21297         stream_name_set = 1;
21298       else if (unformat (input, "disable"))
21299         enable = 0;
21300       else
21301         break;
21302     }
21303
21304   if (stream_name_set > 0)
21305     {
21306       if (vec_len (stream_name) > 255)
21307         {
21308           errmsg ("stream name too long");
21309           return -99;
21310         }
21311     }
21312
21313   u32 name_len = vec_len (stream_name);
21314   /* Construct the API message */
21315   M (PG_ENABLE_DISABLE, mp);
21316   mp->context = 0;
21317   mp->is_enabled = enable;
21318   if (stream_name_set != 0)
21319     {
21320       mp->stream_name_length = ntohl (name_len);
21321       clib_memcpy (mp->stream_name, stream_name, name_len);
21322     }
21323   vec_free (stream_name);
21324
21325   S (mp);
21326   W (ret);
21327   return ret;
21328 }
21329
21330 int
21331 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21332 {
21333   unformat_input_t *input = vam->input;
21334   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21335
21336   u16 *low_ports = 0;
21337   u16 *high_ports = 0;
21338   u16 this_low;
21339   u16 this_hi;
21340   ip4_address_t ip4_addr;
21341   ip6_address_t ip6_addr;
21342   u32 length;
21343   u32 tmp, tmp2;
21344   u8 prefix_set = 0;
21345   u32 vrf_id = ~0;
21346   u8 is_add = 1;
21347   u8 is_ipv6 = 0;
21348   int ret;
21349
21350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21351     {
21352       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21353         {
21354           prefix_set = 1;
21355         }
21356       else
21357         if (unformat
21358             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21359         {
21360           prefix_set = 1;
21361           is_ipv6 = 1;
21362         }
21363       else if (unformat (input, "vrf %d", &vrf_id))
21364         ;
21365       else if (unformat (input, "del"))
21366         is_add = 0;
21367       else if (unformat (input, "port %d", &tmp))
21368         {
21369           if (tmp == 0 || tmp > 65535)
21370             {
21371               errmsg ("port %d out of range", tmp);
21372               return -99;
21373             }
21374           this_low = tmp;
21375           this_hi = this_low + 1;
21376           vec_add1 (low_ports, this_low);
21377           vec_add1 (high_ports, this_hi);
21378         }
21379       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21380         {
21381           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21382             {
21383               errmsg ("incorrect range parameters");
21384               return -99;
21385             }
21386           this_low = tmp;
21387           /* Note: in debug CLI +1 is added to high before
21388              passing to real fn that does "the work"
21389              (ip_source_and_port_range_check_add_del).
21390              This fn is a wrapper around the binary API fn a
21391              control plane will call, which expects this increment
21392              to have occurred. Hence letting the binary API control
21393              plane fn do the increment for consistency between VAT
21394              and other control planes.
21395            */
21396           this_hi = tmp2;
21397           vec_add1 (low_ports, this_low);
21398           vec_add1 (high_ports, this_hi);
21399         }
21400       else
21401         break;
21402     }
21403
21404   if (prefix_set == 0)
21405     {
21406       errmsg ("<address>/<mask> not specified");
21407       return -99;
21408     }
21409
21410   if (vrf_id == ~0)
21411     {
21412       errmsg ("VRF ID required, not specified");
21413       return -99;
21414     }
21415
21416   if (vrf_id == 0)
21417     {
21418       errmsg
21419         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21420       return -99;
21421     }
21422
21423   if (vec_len (low_ports) == 0)
21424     {
21425       errmsg ("At least one port or port range required");
21426       return -99;
21427     }
21428
21429   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21430
21431   mp->is_add = is_add;
21432
21433   if (is_ipv6)
21434     {
21435       mp->is_ipv6 = 1;
21436       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21437     }
21438   else
21439     {
21440       mp->is_ipv6 = 0;
21441       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21442     }
21443
21444   mp->mask_length = length;
21445   mp->number_of_ranges = vec_len (low_ports);
21446
21447   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21448   vec_free (low_ports);
21449
21450   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21451   vec_free (high_ports);
21452
21453   mp->vrf_id = ntohl (vrf_id);
21454
21455   S (mp);
21456   W (ret);
21457   return ret;
21458 }
21459
21460 int
21461 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21462 {
21463   unformat_input_t *input = vam->input;
21464   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21465   u32 sw_if_index = ~0;
21466   int vrf_set = 0;
21467   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21468   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21469   u8 is_add = 1;
21470   int ret;
21471
21472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21473     {
21474       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21475         ;
21476       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21477         ;
21478       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21479         vrf_set = 1;
21480       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21481         vrf_set = 1;
21482       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21483         vrf_set = 1;
21484       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21485         vrf_set = 1;
21486       else if (unformat (input, "del"))
21487         is_add = 0;
21488       else
21489         break;
21490     }
21491
21492   if (sw_if_index == ~0)
21493     {
21494       errmsg ("Interface required but not specified");
21495       return -99;
21496     }
21497
21498   if (vrf_set == 0)
21499     {
21500       errmsg ("VRF ID required but not specified");
21501       return -99;
21502     }
21503
21504   if (tcp_out_vrf_id == 0
21505       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21506     {
21507       errmsg
21508         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21509       return -99;
21510     }
21511
21512   /* Construct the API message */
21513   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21514
21515   mp->sw_if_index = ntohl (sw_if_index);
21516   mp->is_add = is_add;
21517   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21518   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21519   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21520   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21521
21522   /* send it... */
21523   S (mp);
21524
21525   /* Wait for a reply... */
21526   W (ret);
21527   return ret;
21528 }
21529
21530 static int
21531 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21532 {
21533   unformat_input_t *i = vam->input;
21534   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21535   u32 local_sa_id = 0;
21536   u32 remote_sa_id = 0;
21537   ip4_address_t src_address;
21538   ip4_address_t dst_address;
21539   u8 is_add = 1;
21540   int ret;
21541
21542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21543     {
21544       if (unformat (i, "local_sa %d", &local_sa_id))
21545         ;
21546       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21547         ;
21548       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21549         ;
21550       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21551         ;
21552       else if (unformat (i, "del"))
21553         is_add = 0;
21554       else
21555         {
21556           clib_warning ("parse error '%U'", format_unformat_error, i);
21557           return -99;
21558         }
21559     }
21560
21561   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21562
21563   mp->local_sa_id = ntohl (local_sa_id);
21564   mp->remote_sa_id = ntohl (remote_sa_id);
21565   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21566   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21567   mp->is_add = is_add;
21568
21569   S (mp);
21570   W (ret);
21571   return ret;
21572 }
21573
21574 static int
21575 api_punt (vat_main_t * vam)
21576 {
21577   unformat_input_t *i = vam->input;
21578   vl_api_punt_t *mp;
21579   u32 ipv = ~0;
21580   u32 protocol = ~0;
21581   u32 port = ~0;
21582   int is_add = 1;
21583   int ret;
21584
21585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21586     {
21587       if (unformat (i, "ip %d", &ipv))
21588         ;
21589       else if (unformat (i, "protocol %d", &protocol))
21590         ;
21591       else if (unformat (i, "port %d", &port))
21592         ;
21593       else if (unformat (i, "del"))
21594         is_add = 0;
21595       else
21596         {
21597           clib_warning ("parse error '%U'", format_unformat_error, i);
21598           return -99;
21599         }
21600     }
21601
21602   M (PUNT, mp);
21603
21604   mp->is_add = (u8) is_add;
21605   mp->ipv = (u8) ipv;
21606   mp->l4_protocol = (u8) protocol;
21607   mp->l4_port = htons ((u16) port);
21608
21609   S (mp);
21610   W (ret);
21611   return ret;
21612 }
21613
21614 static void vl_api_ipsec_gre_tunnel_details_t_handler
21615   (vl_api_ipsec_gre_tunnel_details_t * mp)
21616 {
21617   vat_main_t *vam = &vat_main;
21618
21619   print (vam->ofp, "%11d%15U%15U%14d%14d",
21620          ntohl (mp->sw_if_index),
21621          format_ip4_address, &mp->src_address,
21622          format_ip4_address, &mp->dst_address,
21623          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21624 }
21625
21626 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21627   (vl_api_ipsec_gre_tunnel_details_t * mp)
21628 {
21629   vat_main_t *vam = &vat_main;
21630   vat_json_node_t *node = NULL;
21631   struct in_addr ip4;
21632
21633   if (VAT_JSON_ARRAY != vam->json_tree.type)
21634     {
21635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21636       vat_json_init_array (&vam->json_tree);
21637     }
21638   node = vat_json_array_add (&vam->json_tree);
21639
21640   vat_json_init_object (node);
21641   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21642   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21643   vat_json_object_add_ip4 (node, "src_address", ip4);
21644   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21645   vat_json_object_add_ip4 (node, "dst_address", ip4);
21646   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21647   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21648 }
21649
21650 static int
21651 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21652 {
21653   unformat_input_t *i = vam->input;
21654   vl_api_ipsec_gre_tunnel_dump_t *mp;
21655   vl_api_control_ping_t *mp_ping;
21656   u32 sw_if_index;
21657   u8 sw_if_index_set = 0;
21658   int ret;
21659
21660   /* Parse args required to build the message */
21661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21662     {
21663       if (unformat (i, "sw_if_index %d", &sw_if_index))
21664         sw_if_index_set = 1;
21665       else
21666         break;
21667     }
21668
21669   if (sw_if_index_set == 0)
21670     {
21671       sw_if_index = ~0;
21672     }
21673
21674   if (!vam->json_output)
21675     {
21676       print (vam->ofp, "%11s%15s%15s%14s%14s",
21677              "sw_if_index", "src_address", "dst_address",
21678              "local_sa_id", "remote_sa_id");
21679     }
21680
21681   /* Get list of gre-tunnel interfaces */
21682   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21683
21684   mp->sw_if_index = htonl (sw_if_index);
21685
21686   S (mp);
21687
21688   /* Use a control ping for synchronization */
21689   MPING (CONTROL_PING, mp_ping);
21690   S (mp_ping);
21691
21692   W (ret);
21693   return ret;
21694 }
21695
21696 static int
21697 api_delete_subif (vat_main_t * vam)
21698 {
21699   unformat_input_t *i = vam->input;
21700   vl_api_delete_subif_t *mp;
21701   u32 sw_if_index = ~0;
21702   int ret;
21703
21704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21705     {
21706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21707         ;
21708       if (unformat (i, "sw_if_index %d", &sw_if_index))
21709         ;
21710       else
21711         break;
21712     }
21713
21714   if (sw_if_index == ~0)
21715     {
21716       errmsg ("missing sw_if_index");
21717       return -99;
21718     }
21719
21720   /* Construct the API message */
21721   M (DELETE_SUBIF, mp);
21722   mp->sw_if_index = ntohl (sw_if_index);
21723
21724   S (mp);
21725   W (ret);
21726   return ret;
21727 }
21728
21729 #define foreach_pbb_vtr_op      \
21730 _("disable",  L2_VTR_DISABLED)  \
21731 _("pop",  L2_VTR_POP_2)         \
21732 _("push",  L2_VTR_PUSH_2)
21733
21734 static int
21735 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21736 {
21737   unformat_input_t *i = vam->input;
21738   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21739   u32 sw_if_index = ~0, vtr_op = ~0;
21740   u16 outer_tag = ~0;
21741   u8 dmac[6], smac[6];
21742   u8 dmac_set = 0, smac_set = 0;
21743   u16 vlanid = 0;
21744   u32 sid = ~0;
21745   u32 tmp;
21746   int ret;
21747
21748   /* Shut up coverity */
21749   memset (dmac, 0, sizeof (dmac));
21750   memset (smac, 0, sizeof (smac));
21751
21752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21753     {
21754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21755         ;
21756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21757         ;
21758       else if (unformat (i, "vtr_op %d", &vtr_op))
21759         ;
21760 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21761       foreach_pbb_vtr_op
21762 #undef _
21763         else if (unformat (i, "translate_pbb_stag"))
21764         {
21765           if (unformat (i, "%d", &tmp))
21766             {
21767               vtr_op = L2_VTR_TRANSLATE_2_1;
21768               outer_tag = tmp;
21769             }
21770           else
21771             {
21772               errmsg
21773                 ("translate_pbb_stag operation requires outer tag definition");
21774               return -99;
21775             }
21776         }
21777       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21778         dmac_set++;
21779       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21780         smac_set++;
21781       else if (unformat (i, "sid %d", &sid))
21782         ;
21783       else if (unformat (i, "vlanid %d", &tmp))
21784         vlanid = tmp;
21785       else
21786         {
21787           clib_warning ("parse error '%U'", format_unformat_error, i);
21788           return -99;
21789         }
21790     }
21791
21792   if ((sw_if_index == ~0) || (vtr_op == ~0))
21793     {
21794       errmsg ("missing sw_if_index or vtr operation");
21795       return -99;
21796     }
21797   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21798       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21799     {
21800       errmsg
21801         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21802       return -99;
21803     }
21804
21805   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21806   mp->sw_if_index = ntohl (sw_if_index);
21807   mp->vtr_op = ntohl (vtr_op);
21808   mp->outer_tag = ntohs (outer_tag);
21809   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21810   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21811   mp->b_vlanid = ntohs (vlanid);
21812   mp->i_sid = ntohl (sid);
21813
21814   S (mp);
21815   W (ret);
21816   return ret;
21817 }
21818
21819 static int
21820 api_flow_classify_set_interface (vat_main_t * vam)
21821 {
21822   unformat_input_t *i = vam->input;
21823   vl_api_flow_classify_set_interface_t *mp;
21824   u32 sw_if_index;
21825   int sw_if_index_set;
21826   u32 ip4_table_index = ~0;
21827   u32 ip6_table_index = ~0;
21828   u8 is_add = 1;
21829   int ret;
21830
21831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21832     {
21833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21834         sw_if_index_set = 1;
21835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21836         sw_if_index_set = 1;
21837       else if (unformat (i, "del"))
21838         is_add = 0;
21839       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21840         ;
21841       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21842         ;
21843       else
21844         {
21845           clib_warning ("parse error '%U'", format_unformat_error, i);
21846           return -99;
21847         }
21848     }
21849
21850   if (sw_if_index_set == 0)
21851     {
21852       errmsg ("missing interface name or sw_if_index");
21853       return -99;
21854     }
21855
21856   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21857
21858   mp->sw_if_index = ntohl (sw_if_index);
21859   mp->ip4_table_index = ntohl (ip4_table_index);
21860   mp->ip6_table_index = ntohl (ip6_table_index);
21861   mp->is_add = is_add;
21862
21863   S (mp);
21864   W (ret);
21865   return ret;
21866 }
21867
21868 static int
21869 api_flow_classify_dump (vat_main_t * vam)
21870 {
21871   unformat_input_t *i = vam->input;
21872   vl_api_flow_classify_dump_t *mp;
21873   vl_api_control_ping_t *mp_ping;
21874   u8 type = FLOW_CLASSIFY_N_TABLES;
21875   int ret;
21876
21877   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21878     ;
21879   else
21880     {
21881       errmsg ("classify table type must be specified");
21882       return -99;
21883     }
21884
21885   if (!vam->json_output)
21886     {
21887       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21888     }
21889
21890   M (FLOW_CLASSIFY_DUMP, mp);
21891   mp->type = type;
21892   /* send it... */
21893   S (mp);
21894
21895   /* Use a control ping for synchronization */
21896   MPING (CONTROL_PING, mp_ping);
21897   S (mp_ping);
21898
21899   /* Wait for a reply... */
21900   W (ret);
21901   return ret;
21902 }
21903
21904 static int
21905 api_feature_enable_disable (vat_main_t * vam)
21906 {
21907   unformat_input_t *i = vam->input;
21908   vl_api_feature_enable_disable_t *mp;
21909   u8 *arc_name = 0;
21910   u8 *feature_name = 0;
21911   u32 sw_if_index = ~0;
21912   u8 enable = 1;
21913   int ret;
21914
21915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21916     {
21917       if (unformat (i, "arc_name %s", &arc_name))
21918         ;
21919       else if (unformat (i, "feature_name %s", &feature_name))
21920         ;
21921       else
21922         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21923         ;
21924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21925         ;
21926       else if (unformat (i, "disable"))
21927         enable = 0;
21928       else
21929         break;
21930     }
21931
21932   if (arc_name == 0)
21933     {
21934       errmsg ("missing arc name");
21935       return -99;
21936     }
21937   if (vec_len (arc_name) > 63)
21938     {
21939       errmsg ("arc name too long");
21940     }
21941
21942   if (feature_name == 0)
21943     {
21944       errmsg ("missing feature name");
21945       return -99;
21946     }
21947   if (vec_len (feature_name) > 63)
21948     {
21949       errmsg ("feature name too long");
21950     }
21951
21952   if (sw_if_index == ~0)
21953     {
21954       errmsg ("missing interface name or sw_if_index");
21955       return -99;
21956     }
21957
21958   /* Construct the API message */
21959   M (FEATURE_ENABLE_DISABLE, mp);
21960   mp->sw_if_index = ntohl (sw_if_index);
21961   mp->enable = enable;
21962   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21963   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21964   vec_free (arc_name);
21965   vec_free (feature_name);
21966
21967   S (mp);
21968   W (ret);
21969   return ret;
21970 }
21971
21972 static int
21973 api_sw_interface_tag_add_del (vat_main_t * vam)
21974 {
21975   unformat_input_t *i = vam->input;
21976   vl_api_sw_interface_tag_add_del_t *mp;
21977   u32 sw_if_index = ~0;
21978   u8 *tag = 0;
21979   u8 enable = 1;
21980   int ret;
21981
21982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21983     {
21984       if (unformat (i, "tag %s", &tag))
21985         ;
21986       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21987         ;
21988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21989         ;
21990       else if (unformat (i, "del"))
21991         enable = 0;
21992       else
21993         break;
21994     }
21995
21996   if (sw_if_index == ~0)
21997     {
21998       errmsg ("missing interface name or sw_if_index");
21999       return -99;
22000     }
22001
22002   if (enable && (tag == 0))
22003     {
22004       errmsg ("no tag specified");
22005       return -99;
22006     }
22007
22008   /* Construct the API message */
22009   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22010   mp->sw_if_index = ntohl (sw_if_index);
22011   mp->is_add = enable;
22012   if (enable)
22013     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22014   vec_free (tag);
22015
22016   S (mp);
22017   W (ret);
22018   return ret;
22019 }
22020
22021 static void vl_api_l2_xconnect_details_t_handler
22022   (vl_api_l2_xconnect_details_t * mp)
22023 {
22024   vat_main_t *vam = &vat_main;
22025
22026   print (vam->ofp, "%15d%15d",
22027          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22028 }
22029
22030 static void vl_api_l2_xconnect_details_t_handler_json
22031   (vl_api_l2_xconnect_details_t * mp)
22032 {
22033   vat_main_t *vam = &vat_main;
22034   vat_json_node_t *node = NULL;
22035
22036   if (VAT_JSON_ARRAY != vam->json_tree.type)
22037     {
22038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22039       vat_json_init_array (&vam->json_tree);
22040     }
22041   node = vat_json_array_add (&vam->json_tree);
22042
22043   vat_json_init_object (node);
22044   vat_json_object_add_uint (node, "rx_sw_if_index",
22045                             ntohl (mp->rx_sw_if_index));
22046   vat_json_object_add_uint (node, "tx_sw_if_index",
22047                             ntohl (mp->tx_sw_if_index));
22048 }
22049
22050 static int
22051 api_l2_xconnect_dump (vat_main_t * vam)
22052 {
22053   vl_api_l2_xconnect_dump_t *mp;
22054   vl_api_control_ping_t *mp_ping;
22055   int ret;
22056
22057   if (!vam->json_output)
22058     {
22059       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22060     }
22061
22062   M (L2_XCONNECT_DUMP, mp);
22063
22064   S (mp);
22065
22066   /* Use a control ping for synchronization */
22067   MPING (CONTROL_PING, mp_ping);
22068   S (mp_ping);
22069
22070   W (ret);
22071   return ret;
22072 }
22073
22074 static int
22075 api_hw_interface_set_mtu (vat_main_t * vam)
22076 {
22077   unformat_input_t *i = vam->input;
22078   vl_api_hw_interface_set_mtu_t *mp;
22079   u32 sw_if_index = ~0;
22080   u32 mtu = 0;
22081   int ret;
22082
22083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22084     {
22085       if (unformat (i, "mtu %d", &mtu))
22086         ;
22087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22088         ;
22089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22090         ;
22091       else
22092         break;
22093     }
22094
22095   if (sw_if_index == ~0)
22096     {
22097       errmsg ("missing interface name or sw_if_index");
22098       return -99;
22099     }
22100
22101   if (mtu == 0)
22102     {
22103       errmsg ("no mtu specified");
22104       return -99;
22105     }
22106
22107   /* Construct the API message */
22108   M (HW_INTERFACE_SET_MTU, mp);
22109   mp->sw_if_index = ntohl (sw_if_index);
22110   mp->mtu = ntohs ((u16) mtu);
22111
22112   S (mp);
22113   W (ret);
22114   return ret;
22115 }
22116
22117 static int
22118 api_p2p_ethernet_add (vat_main_t * vam)
22119 {
22120   unformat_input_t *i = vam->input;
22121   vl_api_p2p_ethernet_add_t *mp;
22122   u32 parent_if_index = ~0;
22123   u32 sub_id = ~0;
22124   u8 remote_mac[6];
22125   u8 mac_set = 0;
22126   int ret;
22127
22128   memset (remote_mac, 0, sizeof (remote_mac));
22129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22130     {
22131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22132         ;
22133       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22134         ;
22135       else
22136         if (unformat
22137             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22138         mac_set++;
22139       else if (unformat (i, "sub_id %d", &sub_id))
22140         ;
22141       else
22142         {
22143           clib_warning ("parse error '%U'", format_unformat_error, i);
22144           return -99;
22145         }
22146     }
22147
22148   if (parent_if_index == ~0)
22149     {
22150       errmsg ("missing interface name or sw_if_index");
22151       return -99;
22152     }
22153   if (mac_set == 0)
22154     {
22155       errmsg ("missing remote mac address");
22156       return -99;
22157     }
22158   if (sub_id == ~0)
22159     {
22160       errmsg ("missing sub-interface id");
22161       return -99;
22162     }
22163
22164   M (P2P_ETHERNET_ADD, mp);
22165   mp->parent_if_index = ntohl (parent_if_index);
22166   mp->subif_id = ntohl (sub_id);
22167   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22168
22169   S (mp);
22170   W (ret);
22171   return ret;
22172 }
22173
22174 static int
22175 api_p2p_ethernet_del (vat_main_t * vam)
22176 {
22177   unformat_input_t *i = vam->input;
22178   vl_api_p2p_ethernet_del_t *mp;
22179   u32 parent_if_index = ~0;
22180   u8 remote_mac[6];
22181   u8 mac_set = 0;
22182   int ret;
22183
22184   memset (remote_mac, 0, sizeof (remote_mac));
22185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22186     {
22187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22188         ;
22189       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22190         ;
22191       else
22192         if (unformat
22193             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22194         mac_set++;
22195       else
22196         {
22197           clib_warning ("parse error '%U'", format_unformat_error, i);
22198           return -99;
22199         }
22200     }
22201
22202   if (parent_if_index == ~0)
22203     {
22204       errmsg ("missing interface name or sw_if_index");
22205       return -99;
22206     }
22207   if (mac_set == 0)
22208     {
22209       errmsg ("missing remote mac address");
22210       return -99;
22211     }
22212
22213   M (P2P_ETHERNET_DEL, mp);
22214   mp->parent_if_index = ntohl (parent_if_index);
22215   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22216
22217   S (mp);
22218   W (ret);
22219   return ret;
22220 }
22221
22222 static int
22223 api_lldp_config (vat_main_t * vam)
22224 {
22225   unformat_input_t *i = vam->input;
22226   vl_api_lldp_config_t *mp;
22227   int tx_hold = 0;
22228   int tx_interval = 0;
22229   u8 *sys_name = NULL;
22230   int ret;
22231
22232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22233     {
22234       if (unformat (i, "system-name %s", &sys_name))
22235         ;
22236       else if (unformat (i, "tx-hold %d", &tx_hold))
22237         ;
22238       else if (unformat (i, "tx-interval %d", &tx_interval))
22239         ;
22240       else
22241         {
22242           clib_warning ("parse error '%U'", format_unformat_error, i);
22243           return -99;
22244         }
22245     }
22246
22247   vec_add1 (sys_name, 0);
22248
22249   M (LLDP_CONFIG, mp);
22250   mp->tx_hold = htonl (tx_hold);
22251   mp->tx_interval = htonl (tx_interval);
22252   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22253   vec_free (sys_name);
22254
22255   S (mp);
22256   W (ret);
22257   return ret;
22258 }
22259
22260 static int
22261 api_sw_interface_set_lldp (vat_main_t * vam)
22262 {
22263   unformat_input_t *i = vam->input;
22264   vl_api_sw_interface_set_lldp_t *mp;
22265   u32 sw_if_index = ~0;
22266   u32 enable = 1;
22267   u8 *port_desc = NULL, *mgmt_oid = NULL;
22268   ip4_address_t ip4_addr;
22269   ip6_address_t ip6_addr;
22270   int ret;
22271
22272   memset (&ip4_addr, 0, sizeof (ip4_addr));
22273   memset (&ip6_addr, 0, sizeof (ip6_addr));
22274
22275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22276     {
22277       if (unformat (i, "disable"))
22278         enable = 0;
22279       else
22280         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22281         ;
22282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22283         ;
22284       else if (unformat (i, "port-desc %s", &port_desc))
22285         ;
22286       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22287         ;
22288       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22289         ;
22290       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22291         ;
22292       else
22293         break;
22294     }
22295
22296   if (sw_if_index == ~0)
22297     {
22298       errmsg ("missing interface name or sw_if_index");
22299       return -99;
22300     }
22301
22302   /* Construct the API message */
22303   vec_add1 (port_desc, 0);
22304   vec_add1 (mgmt_oid, 0);
22305   M (SW_INTERFACE_SET_LLDP, mp);
22306   mp->sw_if_index = ntohl (sw_if_index);
22307   mp->enable = enable;
22308   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22309   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22310   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22311   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22312   vec_free (port_desc);
22313   vec_free (mgmt_oid);
22314
22315   S (mp);
22316   W (ret);
22317   return ret;
22318 }
22319
22320 static int
22321 api_tcp_configure_src_addresses (vat_main_t * vam)
22322 {
22323   vl_api_tcp_configure_src_addresses_t *mp;
22324   unformat_input_t *i = vam->input;
22325   ip4_address_t v4first, v4last;
22326   ip6_address_t v6first, v6last;
22327   u8 range_set = 0;
22328   u32 vrf_id = 0;
22329   int ret;
22330
22331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22332     {
22333       if (unformat (i, "%U - %U",
22334                     unformat_ip4_address, &v4first,
22335                     unformat_ip4_address, &v4last))
22336         {
22337           if (range_set)
22338             {
22339               errmsg ("one range per message (range already set)");
22340               return -99;
22341             }
22342           range_set = 1;
22343         }
22344       else if (unformat (i, "%U - %U",
22345                          unformat_ip6_address, &v6first,
22346                          unformat_ip6_address, &v6last))
22347         {
22348           if (range_set)
22349             {
22350               errmsg ("one range per message (range already set)");
22351               return -99;
22352             }
22353           range_set = 2;
22354         }
22355       else if (unformat (i, "vrf %d", &vrf_id))
22356         ;
22357       else
22358         break;
22359     }
22360
22361   if (range_set == 0)
22362     {
22363       errmsg ("address range not set");
22364       return -99;
22365     }
22366
22367   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22368   mp->vrf_id = ntohl (vrf_id);
22369   /* ipv6? */
22370   if (range_set == 2)
22371     {
22372       mp->is_ipv6 = 1;
22373       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22374       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22375     }
22376   else
22377     {
22378       mp->is_ipv6 = 0;
22379       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22380       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22381     }
22382   S (mp);
22383   W (ret);
22384   return ret;
22385 }
22386
22387 static void vl_api_app_namespace_add_del_reply_t_handler
22388   (vl_api_app_namespace_add_del_reply_t * mp)
22389 {
22390   vat_main_t *vam = &vat_main;
22391   i32 retval = ntohl (mp->retval);
22392   if (vam->async_mode)
22393     {
22394       vam->async_errors += (retval < 0);
22395     }
22396   else
22397     {
22398       vam->retval = retval;
22399       if (retval == 0)
22400         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22401       vam->result_ready = 1;
22402     }
22403 }
22404
22405 static void vl_api_app_namespace_add_del_reply_t_handler_json
22406   (vl_api_app_namespace_add_del_reply_t * mp)
22407 {
22408   vat_main_t *vam = &vat_main;
22409   vat_json_node_t node;
22410
22411   vat_json_init_object (&node);
22412   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22413   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22414
22415   vat_json_print (vam->ofp, &node);
22416   vat_json_free (&node);
22417
22418   vam->retval = ntohl (mp->retval);
22419   vam->result_ready = 1;
22420 }
22421
22422 static int
22423 api_app_namespace_add_del (vat_main_t * vam)
22424 {
22425   vl_api_app_namespace_add_del_t *mp;
22426   unformat_input_t *i = vam->input;
22427   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22428   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22429   u64 secret;
22430   int ret;
22431
22432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22433     {
22434       if (unformat (i, "id %_%v%_", &ns_id))
22435         ;
22436       else if (unformat (i, "secret %lu", &secret))
22437         secret_set = 1;
22438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22439         sw_if_index_set = 1;
22440       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22441         ;
22442       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22443         ;
22444       else
22445         break;
22446     }
22447   if (!ns_id || !secret_set || !sw_if_index_set)
22448     {
22449       errmsg ("namespace id, secret and sw_if_index must be set");
22450       return -99;
22451     }
22452   if (vec_len (ns_id) > 64)
22453     {
22454       errmsg ("namespace id too long");
22455       return -99;
22456     }
22457   M (APP_NAMESPACE_ADD_DEL, mp);
22458
22459   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22460   mp->namespace_id_len = vec_len (ns_id);
22461   mp->secret = clib_host_to_net_u64 (secret);
22462   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22463   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22464   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22465   vec_free (ns_id);
22466   S (mp);
22467   W (ret);
22468   return ret;
22469 }
22470
22471 static int
22472 api_sock_init_shm (vat_main_t * vam)
22473 {
22474 #if VPP_API_TEST_BUILTIN == 0
22475   unformat_input_t *i = vam->input;
22476   vl_api_shm_elem_config_t *config = 0;
22477   u64 size = 64 << 20;
22478   int rv;
22479
22480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22481     {
22482       if (unformat (i, "size %U", unformat_memory_size, &size))
22483         ;
22484       else
22485         break;
22486     }
22487
22488   /*
22489    * Canned custom ring allocator config.
22490    * Should probably parse all of this
22491    */
22492   vec_validate (config, 6);
22493   config[0].type = VL_API_VLIB_RING;
22494   config[0].size = 256;
22495   config[0].count = 32;
22496
22497   config[1].type = VL_API_VLIB_RING;
22498   config[1].size = 1024;
22499   config[1].count = 16;
22500
22501   config[2].type = VL_API_VLIB_RING;
22502   config[2].size = 4096;
22503   config[2].count = 2;
22504
22505   config[3].type = VL_API_CLIENT_RING;
22506   config[3].size = 256;
22507   config[3].count = 32;
22508
22509   config[4].type = VL_API_CLIENT_RING;
22510   config[4].size = 1024;
22511   config[4].count = 16;
22512
22513   config[5].type = VL_API_CLIENT_RING;
22514   config[5].size = 4096;
22515   config[5].count = 2;
22516
22517   config[6].type = VL_API_QUEUE;
22518   config[6].count = 128;
22519   config[6].size = sizeof (uword);
22520
22521   rv = vl_socket_client_init_shm (config);
22522   if (!rv)
22523     vam->client_index_invalid = 1;
22524   return rv;
22525 #else
22526   return -99;
22527 #endif
22528 }
22529
22530 static int
22531 api_dns_enable_disable (vat_main_t * vam)
22532 {
22533   unformat_input_t *line_input = vam->input;
22534   vl_api_dns_enable_disable_t *mp;
22535   u8 enable_disable = 1;
22536   int ret;
22537
22538   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22539     {
22540       if (unformat (line_input, "disable"))
22541         enable_disable = 0;
22542       if (unformat (line_input, "enable"))
22543         enable_disable = 1;
22544       else
22545         break;
22546     }
22547
22548   /* Construct the API message */
22549   M (DNS_ENABLE_DISABLE, mp);
22550   mp->enable = enable_disable;
22551
22552   /* send it... */
22553   S (mp);
22554   /* Wait for the reply */
22555   W (ret);
22556   return ret;
22557 }
22558
22559 static int
22560 api_dns_resolve_name (vat_main_t * vam)
22561 {
22562   unformat_input_t *line_input = vam->input;
22563   vl_api_dns_resolve_name_t *mp;
22564   u8 *name = 0;
22565   int ret;
22566
22567   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22568     {
22569       if (unformat (line_input, "%s", &name))
22570         ;
22571       else
22572         break;
22573     }
22574
22575   if (vec_len (name) > 127)
22576     {
22577       errmsg ("name too long");
22578       return -99;
22579     }
22580
22581   /* Construct the API message */
22582   M (DNS_RESOLVE_NAME, mp);
22583   memcpy (mp->name, name, vec_len (name));
22584   vec_free (name);
22585
22586   /* send it... */
22587   S (mp);
22588   /* Wait for the reply */
22589   W (ret);
22590   return ret;
22591 }
22592
22593 static int
22594 api_dns_resolve_ip (vat_main_t * vam)
22595 {
22596   unformat_input_t *line_input = vam->input;
22597   vl_api_dns_resolve_ip_t *mp;
22598   int is_ip6 = -1;
22599   ip4_address_t addr4;
22600   ip6_address_t addr6;
22601   int ret;
22602
22603   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22604     {
22605       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22606         is_ip6 = 1;
22607       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22608         is_ip6 = 0;
22609       else
22610         break;
22611     }
22612
22613   if (is_ip6 == -1)
22614     {
22615       errmsg ("missing address");
22616       return -99;
22617     }
22618
22619   /* Construct the API message */
22620   M (DNS_RESOLVE_IP, mp);
22621   mp->is_ip6 = is_ip6;
22622   if (is_ip6)
22623     memcpy (mp->address, &addr6, sizeof (addr6));
22624   else
22625     memcpy (mp->address, &addr4, sizeof (addr4));
22626
22627   /* send it... */
22628   S (mp);
22629   /* Wait for the reply */
22630   W (ret);
22631   return ret;
22632 }
22633
22634 static int
22635 api_dns_name_server_add_del (vat_main_t * vam)
22636 {
22637   unformat_input_t *i = vam->input;
22638   vl_api_dns_name_server_add_del_t *mp;
22639   u8 is_add = 1;
22640   ip6_address_t ip6_server;
22641   ip4_address_t ip4_server;
22642   int ip6_set = 0;
22643   int ip4_set = 0;
22644   int ret = 0;
22645
22646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22647     {
22648       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22649         ip6_set = 1;
22650       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22651         ip4_set = 1;
22652       else if (unformat (i, "del"))
22653         is_add = 0;
22654       else
22655         {
22656           clib_warning ("parse error '%U'", format_unformat_error, i);
22657           return -99;
22658         }
22659     }
22660
22661   if (ip4_set && ip6_set)
22662     {
22663       errmsg ("Only one server address allowed per message");
22664       return -99;
22665     }
22666   if ((ip4_set + ip6_set) == 0)
22667     {
22668       errmsg ("Server address required");
22669       return -99;
22670     }
22671
22672   /* Construct the API message */
22673   M (DNS_NAME_SERVER_ADD_DEL, mp);
22674
22675   if (ip6_set)
22676     {
22677       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22678       mp->is_ip6 = 1;
22679     }
22680   else
22681     {
22682       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22683       mp->is_ip6 = 0;
22684     }
22685
22686   mp->is_add = is_add;
22687
22688   /* send it... */
22689   S (mp);
22690
22691   /* Wait for a reply, return good/bad news  */
22692   W (ret);
22693   return ret;
22694 }
22695
22696 static void
22697 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22698 {
22699   vat_main_t *vam = &vat_main;
22700
22701   if (mp->is_ip4)
22702     {
22703       print (vam->ofp,
22704              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22705              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22706              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22707              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22708              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22709              clib_net_to_host_u32 (mp->action_index), mp->tag);
22710     }
22711   else
22712     {
22713       print (vam->ofp,
22714              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22715              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22716              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22717              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22718              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22719              clib_net_to_host_u32 (mp->action_index), mp->tag);
22720     }
22721 }
22722
22723 static void
22724 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22725                                              mp)
22726 {
22727   vat_main_t *vam = &vat_main;
22728   vat_json_node_t *node = NULL;
22729   struct in6_addr ip6;
22730   struct in_addr ip4;
22731
22732   if (VAT_JSON_ARRAY != vam->json_tree.type)
22733     {
22734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22735       vat_json_init_array (&vam->json_tree);
22736     }
22737   node = vat_json_array_add (&vam->json_tree);
22738   vat_json_init_object (node);
22739
22740   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22741   vat_json_object_add_uint (node, "appns_index",
22742                             clib_net_to_host_u32 (mp->appns_index));
22743   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22744   vat_json_object_add_uint (node, "scope", mp->scope);
22745   vat_json_object_add_uint (node, "action_index",
22746                             clib_net_to_host_u32 (mp->action_index));
22747   vat_json_object_add_uint (node, "lcl_port",
22748                             clib_net_to_host_u16 (mp->lcl_port));
22749   vat_json_object_add_uint (node, "rmt_port",
22750                             clib_net_to_host_u16 (mp->rmt_port));
22751   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22752   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22753   vat_json_object_add_string_copy (node, "tag", mp->tag);
22754   if (mp->is_ip4)
22755     {
22756       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22757       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22758       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22759       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22760     }
22761   else
22762     {
22763       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22764       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22765       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22766       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22767     }
22768 }
22769
22770 static int
22771 api_session_rule_add_del (vat_main_t * vam)
22772 {
22773   vl_api_session_rule_add_del_t *mp;
22774   unformat_input_t *i = vam->input;
22775   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22776   u32 appns_index = 0, scope = 0;
22777   ip4_address_t lcl_ip4, rmt_ip4;
22778   ip6_address_t lcl_ip6, rmt_ip6;
22779   u8 is_ip4 = 1, conn_set = 0;
22780   u8 is_add = 1, *tag = 0;
22781   int ret;
22782
22783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22784     {
22785       if (unformat (i, "del"))
22786         is_add = 0;
22787       else if (unformat (i, "add"))
22788         ;
22789       else if (unformat (i, "proto tcp"))
22790         proto = 0;
22791       else if (unformat (i, "proto udp"))
22792         proto = 1;
22793       else if (unformat (i, "appns %d", &appns_index))
22794         ;
22795       else if (unformat (i, "scope %d", &scope))
22796         ;
22797       else if (unformat (i, "tag %_%v%_", &tag))
22798         ;
22799       else
22800         if (unformat
22801             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22802              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22803              &rmt_port))
22804         {
22805           is_ip4 = 1;
22806           conn_set = 1;
22807         }
22808       else
22809         if (unformat
22810             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22811              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22812              &rmt_port))
22813         {
22814           is_ip4 = 0;
22815           conn_set = 1;
22816         }
22817       else if (unformat (i, "action %d", &action))
22818         ;
22819       else
22820         break;
22821     }
22822   if (proto == ~0 || !conn_set || action == ~0)
22823     {
22824       errmsg ("transport proto, connection and action must be set");
22825       return -99;
22826     }
22827
22828   if (scope > 3)
22829     {
22830       errmsg ("scope should be 0-3");
22831       return -99;
22832     }
22833
22834   M (SESSION_RULE_ADD_DEL, mp);
22835
22836   mp->is_ip4 = is_ip4;
22837   mp->transport_proto = proto;
22838   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22839   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22840   mp->lcl_plen = lcl_plen;
22841   mp->rmt_plen = rmt_plen;
22842   mp->action_index = clib_host_to_net_u32 (action);
22843   mp->appns_index = clib_host_to_net_u32 (appns_index);
22844   mp->scope = scope;
22845   mp->is_add = is_add;
22846   if (is_ip4)
22847     {
22848       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22849       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22850     }
22851   else
22852     {
22853       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22854       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22855     }
22856   if (tag)
22857     {
22858       clib_memcpy (mp->tag, tag, vec_len (tag));
22859       vec_free (tag);
22860     }
22861
22862   S (mp);
22863   W (ret);
22864   return ret;
22865 }
22866
22867 static int
22868 api_session_rules_dump (vat_main_t * vam)
22869 {
22870   vl_api_session_rules_dump_t *mp;
22871   vl_api_control_ping_t *mp_ping;
22872   int ret;
22873
22874   if (!vam->json_output)
22875     {
22876       print (vam->ofp, "%=20s", "Session Rules");
22877     }
22878
22879   M (SESSION_RULES_DUMP, mp);
22880   /* send it... */
22881   S (mp);
22882
22883   /* Use a control ping for synchronization */
22884   MPING (CONTROL_PING, mp_ping);
22885   S (mp_ping);
22886
22887   /* Wait for a reply... */
22888   W (ret);
22889   return ret;
22890 }
22891
22892 static int
22893 api_ip_container_proxy_add_del (vat_main_t * vam)
22894 {
22895   vl_api_ip_container_proxy_add_del_t *mp;
22896   unformat_input_t *i = vam->input;
22897   u32 plen = ~0, sw_if_index = ~0;
22898   ip4_address_t ip4;
22899   ip6_address_t ip6;
22900   u8 is_ip4 = 1;
22901   u8 is_add = 1;
22902   int ret;
22903
22904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22905     {
22906       if (unformat (i, "del"))
22907         is_add = 0;
22908       else if (unformat (i, "add"))
22909         ;
22910       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22911         {
22912           is_ip4 = 1;
22913           plen = 32;
22914         }
22915       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22916         {
22917           is_ip4 = 0;
22918           plen = 128;
22919         }
22920       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22921         ;
22922       else
22923         break;
22924     }
22925   if (sw_if_index == ~0 || plen == ~0)
22926     {
22927       errmsg ("address and sw_if_index must be set");
22928       return -99;
22929     }
22930
22931   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22932
22933   mp->is_ip4 = is_ip4;
22934   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22935   mp->plen = plen;
22936   mp->is_add = is_add;
22937   if (is_ip4)
22938     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22939   else
22940     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22941
22942   S (mp);
22943   W (ret);
22944   return ret;
22945 }
22946
22947 static int
22948 api_qos_record_enable_disable (vat_main_t * vam)
22949 {
22950   unformat_input_t *i = vam->input;
22951   vl_api_qos_record_enable_disable_t *mp;
22952   u32 sw_if_index, qs = 0xff;
22953   u8 sw_if_index_set = 0;
22954   u8 enable = 1;
22955   int ret;
22956
22957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22958     {
22959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22960         sw_if_index_set = 1;
22961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22962         sw_if_index_set = 1;
22963       else if (unformat (i, "%U", unformat_qos_source, &qs))
22964         ;
22965       else if (unformat (i, "disable"))
22966         enable = 0;
22967       else
22968         {
22969           clib_warning ("parse error '%U'", format_unformat_error, i);
22970           return -99;
22971         }
22972     }
22973
22974   if (sw_if_index_set == 0)
22975     {
22976       errmsg ("missing interface name or sw_if_index");
22977       return -99;
22978     }
22979   if (qs == 0xff)
22980     {
22981       errmsg ("input location must be specified");
22982       return -99;
22983     }
22984
22985   M (QOS_RECORD_ENABLE_DISABLE, mp);
22986
22987   mp->sw_if_index = ntohl (sw_if_index);
22988   mp->input_source = qs;
22989   mp->enable = enable;
22990
22991   S (mp);
22992   W (ret);
22993   return ret;
22994 }
22995
22996
22997 static int
22998 q_or_quit (vat_main_t * vam)
22999 {
23000 #if VPP_API_TEST_BUILTIN == 0
23001   longjmp (vam->jump_buf, 1);
23002 #endif
23003   return 0;                     /* not so much */
23004 }
23005
23006 static int
23007 q (vat_main_t * vam)
23008 {
23009   return q_or_quit (vam);
23010 }
23011
23012 static int
23013 quit (vat_main_t * vam)
23014 {
23015   return q_or_quit (vam);
23016 }
23017
23018 static int
23019 comment (vat_main_t * vam)
23020 {
23021   return 0;
23022 }
23023
23024 static int
23025 statseg (vat_main_t * vam)
23026 {
23027   ssvm_private_t *ssvmp = &vam->stat_segment;
23028   ssvm_shared_header_t *shared_header = ssvmp->sh;
23029   vlib_counter_t **counters;
23030   u64 thread0_index1_packets;
23031   u64 thread0_index1_bytes;
23032   f64 vector_rate, input_rate;
23033   uword *p;
23034
23035   uword *counter_vector_by_name;
23036   if (vam->stat_segment_lockp == 0)
23037     {
23038       errmsg ("Stat segment not mapped...");
23039       return -99;
23040     }
23041
23042   /* look up "/if/rx for sw_if_index 1 as a test */
23043
23044   clib_spinlock_lock (vam->stat_segment_lockp);
23045
23046   counter_vector_by_name = (uword *) shared_header->opaque[1];
23047
23048   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23049   if (p == 0)
23050     {
23051       clib_spinlock_unlock (vam->stat_segment_lockp);
23052       errmsg ("/if/tx not found?");
23053       return -99;
23054     }
23055
23056   /* Fish per-thread vector of combined counters from shared memory */
23057   counters = (vlib_counter_t **) p[0];
23058
23059   if (vec_len (counters[0]) < 2)
23060     {
23061       clib_spinlock_unlock (vam->stat_segment_lockp);
23062       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23063       return -99;
23064     }
23065
23066   /* Read thread 0 sw_if_index 1 counter */
23067   thread0_index1_packets = counters[0][1].packets;
23068   thread0_index1_bytes = counters[0][1].bytes;
23069
23070   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23071   if (p == 0)
23072     {
23073       clib_spinlock_unlock (vam->stat_segment_lockp);
23074       errmsg ("vector_rate not found?");
23075       return -99;
23076     }
23077
23078   vector_rate = *(f64 *) (p[0]);
23079   p = hash_get_mem (counter_vector_by_name, "input_rate");
23080   if (p == 0)
23081     {
23082       clib_spinlock_unlock (vam->stat_segment_lockp);
23083       errmsg ("input_rate not found?");
23084       return -99;
23085     }
23086   input_rate = *(f64 *) (p[0]);
23087
23088   clib_spinlock_unlock (vam->stat_segment_lockp);
23089
23090   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23091          vector_rate, input_rate);
23092   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23093          thread0_index1_packets, thread0_index1_bytes);
23094
23095   return 0;
23096 }
23097
23098 static int
23099 cmd_cmp (void *a1, void *a2)
23100 {
23101   u8 **c1 = a1;
23102   u8 **c2 = a2;
23103
23104   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23105 }
23106
23107 static int
23108 help (vat_main_t * vam)
23109 {
23110   u8 **cmds = 0;
23111   u8 *name = 0;
23112   hash_pair_t *p;
23113   unformat_input_t *i = vam->input;
23114   int j;
23115
23116   if (unformat (i, "%s", &name))
23117     {
23118       uword *hs;
23119
23120       vec_add1 (name, 0);
23121
23122       hs = hash_get_mem (vam->help_by_name, name);
23123       if (hs)
23124         print (vam->ofp, "usage: %s %s", name, hs[0]);
23125       else
23126         print (vam->ofp, "No such msg / command '%s'", name);
23127       vec_free (name);
23128       return 0;
23129     }
23130
23131   print (vam->ofp, "Help is available for the following:");
23132
23133     /* *INDENT-OFF* */
23134     hash_foreach_pair (p, vam->function_by_name,
23135     ({
23136       vec_add1 (cmds, (u8 *)(p->key));
23137     }));
23138     /* *INDENT-ON* */
23139
23140   vec_sort_with_function (cmds, cmd_cmp);
23141
23142   for (j = 0; j < vec_len (cmds); j++)
23143     print (vam->ofp, "%s", cmds[j]);
23144
23145   vec_free (cmds);
23146   return 0;
23147 }
23148
23149 static int
23150 set (vat_main_t * vam)
23151 {
23152   u8 *name = 0, *value = 0;
23153   unformat_input_t *i = vam->input;
23154
23155   if (unformat (i, "%s", &name))
23156     {
23157       /* The input buffer is a vector, not a string. */
23158       value = vec_dup (i->buffer);
23159       vec_delete (value, i->index, 0);
23160       /* Almost certainly has a trailing newline */
23161       if (value[vec_len (value) - 1] == '\n')
23162         value[vec_len (value) - 1] = 0;
23163       /* Make sure it's a proper string, one way or the other */
23164       vec_add1 (value, 0);
23165       (void) clib_macro_set_value (&vam->macro_main,
23166                                    (char *) name, (char *) value);
23167     }
23168   else
23169     errmsg ("usage: set <name> <value>");
23170
23171   vec_free (name);
23172   vec_free (value);
23173   return 0;
23174 }
23175
23176 static int
23177 unset (vat_main_t * vam)
23178 {
23179   u8 *name = 0;
23180
23181   if (unformat (vam->input, "%s", &name))
23182     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23183       errmsg ("unset: %s wasn't set", name);
23184   vec_free (name);
23185   return 0;
23186 }
23187
23188 typedef struct
23189 {
23190   u8 *name;
23191   u8 *value;
23192 } macro_sort_t;
23193
23194
23195 static int
23196 macro_sort_cmp (void *a1, void *a2)
23197 {
23198   macro_sort_t *s1 = a1;
23199   macro_sort_t *s2 = a2;
23200
23201   return strcmp ((char *) (s1->name), (char *) (s2->name));
23202 }
23203
23204 static int
23205 dump_macro_table (vat_main_t * vam)
23206 {
23207   macro_sort_t *sort_me = 0, *sm;
23208   int i;
23209   hash_pair_t *p;
23210
23211     /* *INDENT-OFF* */
23212     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23213     ({
23214       vec_add2 (sort_me, sm, 1);
23215       sm->name = (u8 *)(p->key);
23216       sm->value = (u8 *) (p->value[0]);
23217     }));
23218     /* *INDENT-ON* */
23219
23220   vec_sort_with_function (sort_me, macro_sort_cmp);
23221
23222   if (vec_len (sort_me))
23223     print (vam->ofp, "%-15s%s", "Name", "Value");
23224   else
23225     print (vam->ofp, "The macro table is empty...");
23226
23227   for (i = 0; i < vec_len (sort_me); i++)
23228     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23229   return 0;
23230 }
23231
23232 static int
23233 dump_node_table (vat_main_t * vam)
23234 {
23235   int i, j;
23236   vlib_node_t *node, *next_node;
23237
23238   if (vec_len (vam->graph_nodes) == 0)
23239     {
23240       print (vam->ofp, "Node table empty, issue get_node_graph...");
23241       return 0;
23242     }
23243
23244   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23245     {
23246       node = vam->graph_nodes[0][i];
23247       print (vam->ofp, "[%d] %s", i, node->name);
23248       for (j = 0; j < vec_len (node->next_nodes); j++)
23249         {
23250           if (node->next_nodes[j] != ~0)
23251             {
23252               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23253               print (vam->ofp, "  [%d] %s", j, next_node->name);
23254             }
23255         }
23256     }
23257   return 0;
23258 }
23259
23260 static int
23261 value_sort_cmp (void *a1, void *a2)
23262 {
23263   name_sort_t *n1 = a1;
23264   name_sort_t *n2 = a2;
23265
23266   if (n1->value < n2->value)
23267     return -1;
23268   if (n1->value > n2->value)
23269     return 1;
23270   return 0;
23271 }
23272
23273
23274 static int
23275 dump_msg_api_table (vat_main_t * vam)
23276 {
23277   api_main_t *am = &api_main;
23278   name_sort_t *nses = 0, *ns;
23279   hash_pair_t *hp;
23280   int i;
23281
23282   /* *INDENT-OFF* */
23283   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23284   ({
23285     vec_add2 (nses, ns, 1);
23286     ns->name = (u8 *)(hp->key);
23287     ns->value = (u32) hp->value[0];
23288   }));
23289   /* *INDENT-ON* */
23290
23291   vec_sort_with_function (nses, value_sort_cmp);
23292
23293   for (i = 0; i < vec_len (nses); i++)
23294     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23295   vec_free (nses);
23296   return 0;
23297 }
23298
23299 static int
23300 get_msg_id (vat_main_t * vam)
23301 {
23302   u8 *name_and_crc;
23303   u32 message_index;
23304
23305   if (unformat (vam->input, "%s", &name_and_crc))
23306     {
23307       message_index = vl_msg_api_get_msg_index (name_and_crc);
23308       if (message_index == ~0)
23309         {
23310           print (vam->ofp, " '%s' not found", name_and_crc);
23311           return 0;
23312         }
23313       print (vam->ofp, " '%s' has message index %d",
23314              name_and_crc, message_index);
23315       return 0;
23316     }
23317   errmsg ("name_and_crc required...");
23318   return 0;
23319 }
23320
23321 static int
23322 search_node_table (vat_main_t * vam)
23323 {
23324   unformat_input_t *line_input = vam->input;
23325   u8 *node_to_find;
23326   int j;
23327   vlib_node_t *node, *next_node;
23328   uword *p;
23329
23330   if (vam->graph_node_index_by_name == 0)
23331     {
23332       print (vam->ofp, "Node table empty, issue get_node_graph...");
23333       return 0;
23334     }
23335
23336   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23337     {
23338       if (unformat (line_input, "%s", &node_to_find))
23339         {
23340           vec_add1 (node_to_find, 0);
23341           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23342           if (p == 0)
23343             {
23344               print (vam->ofp, "%s not found...", node_to_find);
23345               goto out;
23346             }
23347           node = vam->graph_nodes[0][p[0]];
23348           print (vam->ofp, "[%d] %s", p[0], node->name);
23349           for (j = 0; j < vec_len (node->next_nodes); j++)
23350             {
23351               if (node->next_nodes[j] != ~0)
23352                 {
23353                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23354                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23355                 }
23356             }
23357         }
23358
23359       else
23360         {
23361           clib_warning ("parse error '%U'", format_unformat_error,
23362                         line_input);
23363           return -99;
23364         }
23365
23366     out:
23367       vec_free (node_to_find);
23368
23369     }
23370
23371   return 0;
23372 }
23373
23374
23375 static int
23376 script (vat_main_t * vam)
23377 {
23378 #if (VPP_API_TEST_BUILTIN==0)
23379   u8 *s = 0;
23380   char *save_current_file;
23381   unformat_input_t save_input;
23382   jmp_buf save_jump_buf;
23383   u32 save_line_number;
23384
23385   FILE *new_fp, *save_ifp;
23386
23387   if (unformat (vam->input, "%s", &s))
23388     {
23389       new_fp = fopen ((char *) s, "r");
23390       if (new_fp == 0)
23391         {
23392           errmsg ("Couldn't open script file %s", s);
23393           vec_free (s);
23394           return -99;
23395         }
23396     }
23397   else
23398     {
23399       errmsg ("Missing script name");
23400       return -99;
23401     }
23402
23403   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23404   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23405   save_ifp = vam->ifp;
23406   save_line_number = vam->input_line_number;
23407   save_current_file = (char *) vam->current_file;
23408
23409   vam->input_line_number = 0;
23410   vam->ifp = new_fp;
23411   vam->current_file = s;
23412   do_one_file (vam);
23413
23414   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23415   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23416   vam->ifp = save_ifp;
23417   vam->input_line_number = save_line_number;
23418   vam->current_file = (u8 *) save_current_file;
23419   vec_free (s);
23420
23421   return 0;
23422 #else
23423   clib_warning ("use the exec command...");
23424   return -99;
23425 #endif
23426 }
23427
23428 static int
23429 echo (vat_main_t * vam)
23430 {
23431   print (vam->ofp, "%v", vam->input->buffer);
23432   return 0;
23433 }
23434
23435 /* List of API message constructors, CLI names map to api_xxx */
23436 #define foreach_vpe_api_msg                                             \
23437 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23438 _(sw_interface_dump,"")                                                 \
23439 _(sw_interface_set_flags,                                               \
23440   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23441 _(sw_interface_add_del_address,                                         \
23442   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23443 _(sw_interface_set_rx_mode,                                             \
23444   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23445 _(sw_interface_set_rx_placement,                                        \
23446   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23447 _(sw_interface_set_table,                                               \
23448   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23449 _(sw_interface_set_mpls_enable,                                         \
23450   "<intfc> | sw_if_index [disable | dis]")                              \
23451 _(sw_interface_set_vpath,                                               \
23452   "<intfc> | sw_if_index <id> enable | disable")                        \
23453 _(sw_interface_set_vxlan_bypass,                                        \
23454   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23455 _(sw_interface_set_geneve_bypass,                                       \
23456   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23457 _(sw_interface_set_l2_xconnect,                                         \
23458   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23459   "enable | disable")                                                   \
23460 _(sw_interface_set_l2_bridge,                                           \
23461   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23462   "[shg <split-horizon-group>] [bvi]\n"                                 \
23463   "enable | disable")                                                   \
23464 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23465 _(bridge_domain_add_del,                                                \
23466   "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") \
23467 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23468 _(l2fib_add_del,                                                        \
23469   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23470 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23471 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23472 _(l2_flags,                                                             \
23473   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23474 _(bridge_flags,                                                         \
23475   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23476 _(tap_connect,                                                          \
23477   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23478 _(tap_modify,                                                           \
23479   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23480 _(tap_delete,                                                           \
23481   "<vpp-if-name> | sw_if_index <id>")                                   \
23482 _(sw_interface_tap_dump, "")                                            \
23483 _(tap_create_v2,                                                        \
23484   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23485 _(tap_delete_v2,                                                        \
23486   "<vpp-if-name> | sw_if_index <id>")                                   \
23487 _(sw_interface_tap_v2_dump, "")                                         \
23488 _(bond_create,                                                          \
23489   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23490   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23491 _(bond_delete,                                                          \
23492   "<vpp-if-name> | sw_if_index <id>")                                   \
23493 _(bond_enslave,                                                         \
23494   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23495 _(bond_detach_slave,                                                    \
23496   "sw_if_index <n>")                                                    \
23497 _(sw_interface_bond_dump, "")                                           \
23498 _(sw_interface_slave_dump,                                              \
23499   "<vpp-if-name> | sw_if_index <id>")                                   \
23500 _(ip_table_add_del,                                                     \
23501   "table <n> [ipv6] [add | del]\n")                                     \
23502 _(ip_add_del_route,                                                     \
23503   "<addr>/<mask> via <addr | via-label <n>> [table-id <n>]\n"           \
23504   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
23505   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23506   "[multipath] [count <n>]")                                            \
23507 _(ip_mroute_add_del,                                                    \
23508   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23509   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23510 _(mpls_table_add_del,                                                   \
23511   "table <n> [add | del]\n")                                            \
23512 _(mpls_route_add_del,                                                   \
23513   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23514   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23515   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23516   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23517   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23518 _(mpls_ip_bind_unbind,                                                  \
23519   "<label> <addr/len>")                                                 \
23520 _(mpls_tunnel_add_del,                                                  \
23521   " via <addr> [table-id <n>]\n"                                        \
23522   "sw_if_index <id>] [l2]  [del]")                                      \
23523 _(sr_mpls_policy_add,                                                   \
23524   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23525 _(sr_mpls_policy_del,                                                   \
23526   "bsid <id>")                                                          \
23527 _(bier_table_add_del,                                                   \
23528   "<label> <sub-domain> <set> <bsl> [del]")                             \
23529 _(bier_route_add_del,                                                   \
23530   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23531   "[<intfc> | sw_if_index <id>]"                                        \
23532   "[weight <n>] [del] [multipath]")                                     \
23533 _(proxy_arp_add_del,                                                    \
23534   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23535 _(proxy_arp_intfc_enable_disable,                                       \
23536   "<intfc> | sw_if_index <id> enable | disable")                        \
23537 _(sw_interface_set_unnumbered,                                          \
23538   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23539 _(ip_neighbor_add_del,                                                  \
23540   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23541   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23542 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23543 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23544   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23545   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23546   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23547 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23548 _(reset_fib, "vrf <n> [ipv6]")                                          \
23549 _(dhcp_proxy_config,                                                    \
23550   "svr <v46-address> src <v46-address>\n"                               \
23551    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23552 _(dhcp_proxy_set_vss,                                                   \
23553   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23554 _(dhcp_proxy_dump, "ip6")                                               \
23555 _(dhcp_client_config,                                                   \
23556   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23557 _(set_ip_flow_hash,                                                     \
23558   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23559 _(sw_interface_ip6_enable_disable,                                      \
23560   "<intfc> | sw_if_index <id> enable | disable")                        \
23561 _(sw_interface_ip6_set_link_local_address,                              \
23562   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23563 _(ip6nd_proxy_add_del,                                                  \
23564   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23565 _(ip6nd_proxy_dump, "")                                                 \
23566 _(sw_interface_ip6nd_ra_prefix,                                         \
23567   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23568   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23569   "[nolink] [isno]")                                                    \
23570 _(sw_interface_ip6nd_ra_config,                                         \
23571   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23572   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23573   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23574 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23575 _(l2_patch_add_del,                                                     \
23576   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23577   "enable | disable")                                                   \
23578 _(sr_localsid_add_del,                                                  \
23579   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23580   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23581 _(classify_add_del_table,                                               \
23582   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23583   " [del] [del-chain] mask <mask-value>\n"                              \
23584   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23585   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23586 _(classify_add_del_session,                                             \
23587   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23588   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23589   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23590   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23591 _(classify_set_interface_ip_table,                                      \
23592   "<intfc> | sw_if_index <nn> table <nn>")                              \
23593 _(classify_set_interface_l2_tables,                                     \
23594   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23595   "  [other-table <nn>]")                                               \
23596 _(get_node_index, "node <node-name")                                    \
23597 _(add_node_next, "node <node-name> next <next-node-name>")              \
23598 _(l2tpv3_create_tunnel,                                                 \
23599   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23600   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23601   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23602 _(l2tpv3_set_tunnel_cookies,                                            \
23603   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23604   "[new_remote_cookie <nn>]\n")                                         \
23605 _(l2tpv3_interface_enable_disable,                                      \
23606   "<intfc> | sw_if_index <nn> enable | disable")                        \
23607 _(l2tpv3_set_lookup_key,                                                \
23608   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23609 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23610 _(vxlan_offload_rx,                                                     \
23611   "hw { <interface name> | hw_if_index <nn>} "                          \
23612   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23613 _(vxlan_add_del_tunnel,                                                 \
23614   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23615   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23616   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23617 _(geneve_add_del_tunnel,                                                \
23618   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23619   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23620   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23621 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23622 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23623 _(gre_add_del_tunnel,                                                   \
23624   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23625   "[teb | erspan <session-id>] [del]")                                  \
23626 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23627 _(l2_fib_clear_table, "")                                               \
23628 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23629 _(l2_interface_vlan_tag_rewrite,                                        \
23630   "<intfc> | sw_if_index <nn> \n"                                       \
23631   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23632   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23633 _(create_vhost_user_if,                                                 \
23634         "socket <filename> [server] [renumber <dev_instance>] "         \
23635         "[mac <mac_address>]")                                          \
23636 _(modify_vhost_user_if,                                                 \
23637         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23638         "[server] [renumber <dev_instance>]")                           \
23639 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23640 _(sw_interface_vhost_user_dump, "")                                     \
23641 _(show_version, "")                                                     \
23642 _(vxlan_gpe_add_del_tunnel,                                             \
23643   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23644   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23645   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23646   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23647 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23648 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23649 _(interface_name_renumber,                                              \
23650   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23651 _(input_acl_set_interface,                                              \
23652   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23653   "  [l2-table <nn>] [del]")                                            \
23654 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23655 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23656   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23657 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23658 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23659 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23660 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23661 _(ip_dump, "ipv4 | ipv6")                                               \
23662 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23663 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23664   "  spid_id <n> ")                                                     \
23665 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23666   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23667   "  integ_alg <alg> integ_key <hex>")                                  \
23668 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23669   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23670   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23671   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23672 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23673 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23674   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23675   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23676   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23677   "  [instance <n>]")     \
23678 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23679 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23680   "  <alg> <hex>\n")                                                    \
23681 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23682 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23683 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23684   "(auth_data 0x<data> | auth_data <data>)")                            \
23685 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23686   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23687 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23688   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23689   "(local|remote)")                                                     \
23690 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23691 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23692 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23693 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23694 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23695 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23696 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23697 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23698 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23699 _(delete_loopback,"sw_if_index <nn>")                                   \
23700 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23701 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23702 _(want_interface_events,  "enable|disable")                             \
23703 _(want_stats,"enable|disable")                                          \
23704 _(get_first_msg_id, "client <name>")                                    \
23705 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23706 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23707   "fib-id <nn> [ip4][ip6][default]")                                    \
23708 _(get_node_graph, " ")                                                  \
23709 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23710 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23711 _(ioam_disable, "")                                                     \
23712 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23713                             " sw_if_index <sw_if_index> p <priority> "  \
23714                             "w <weight>] [del]")                        \
23715 _(one_add_del_locator, "locator-set <locator_name> "                    \
23716                         "iface <intf> | sw_if_index <sw_if_index> "     \
23717                         "p <priority> w <weight> [del]")                \
23718 _(one_add_del_local_eid,"vni <vni> eid "                                \
23719                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23720                          "locator-set <locator_name> [del]"             \
23721                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23722 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23723 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23724 _(one_enable_disable, "enable|disable")                                 \
23725 _(one_map_register_enable_disable, "enable|disable")                    \
23726 _(one_map_register_fallback_threshold, "<value>")                       \
23727 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23728 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23729                                "[seid <seid>] "                         \
23730                                "rloc <locator> p <prio> "               \
23731                                "w <weight> [rloc <loc> ... ] "          \
23732                                "action <action> [del-all]")             \
23733 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23734                           "<local-eid>")                                \
23735 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23736 _(one_use_petr, "ip-address> | disable")                                \
23737 _(one_map_request_mode, "src-dst|dst-only")                             \
23738 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23739 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23740 _(one_locator_set_dump, "[local | remote]")                             \
23741 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23742 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23743                        "[local] | [remote]")                            \
23744 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23745 _(one_ndp_bd_get, "")                                                   \
23746 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23747 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23748 _(one_l2_arp_bd_get, "")                                                \
23749 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23750 _(one_stats_enable_disable, "enable|disalbe")                           \
23751 _(show_one_stats_enable_disable, "")                                    \
23752 _(one_eid_table_vni_dump, "")                                           \
23753 _(one_eid_table_map_dump, "l2|l3")                                      \
23754 _(one_map_resolver_dump, "")                                            \
23755 _(one_map_server_dump, "")                                              \
23756 _(one_adjacencies_get, "vni <vni>")                                     \
23757 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23758 _(show_one_rloc_probe_state, "")                                        \
23759 _(show_one_map_register_state, "")                                      \
23760 _(show_one_status, "")                                                  \
23761 _(one_stats_dump, "")                                                   \
23762 _(one_stats_flush, "")                                                  \
23763 _(one_get_map_request_itr_rlocs, "")                                    \
23764 _(one_map_register_set_ttl, "<ttl>")                                    \
23765 _(one_set_transport_protocol, "udp|api")                                \
23766 _(one_get_transport_protocol, "")                                       \
23767 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23768 _(one_show_xtr_mode, "")                                                \
23769 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23770 _(one_show_pitr_mode, "")                                               \
23771 _(one_enable_disable_petr_mode, "enable|disable")                       \
23772 _(one_show_petr_mode, "")                                               \
23773 _(show_one_nsh_mapping, "")                                             \
23774 _(show_one_pitr, "")                                                    \
23775 _(show_one_use_petr, "")                                                \
23776 _(show_one_map_request_mode, "")                                        \
23777 _(show_one_map_register_ttl, "")                                        \
23778 _(show_one_map_register_fallback_threshold, "")                         \
23779 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23780                             " sw_if_index <sw_if_index> p <priority> "  \
23781                             "w <weight>] [del]")                        \
23782 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23783                         "iface <intf> | sw_if_index <sw_if_index> "     \
23784                         "p <priority> w <weight> [del]")                \
23785 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23786                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23787                          "locator-set <locator_name> [del]"             \
23788                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23789 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23790 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23791 _(lisp_enable_disable, "enable|disable")                                \
23792 _(lisp_map_register_enable_disable, "enable|disable")                   \
23793 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23794 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23795                                "[seid <seid>] "                         \
23796                                "rloc <locator> p <prio> "               \
23797                                "w <weight> [rloc <loc> ... ] "          \
23798                                "action <action> [del-all]")             \
23799 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23800                           "<local-eid>")                                \
23801 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23802 _(lisp_use_petr, "<ip-address> | disable")                              \
23803 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23804 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23805 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23806 _(lisp_locator_set_dump, "[local | remote]")                            \
23807 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23808 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23809                        "[local] | [remote]")                            \
23810 _(lisp_eid_table_vni_dump, "")                                          \
23811 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23812 _(lisp_map_resolver_dump, "")                                           \
23813 _(lisp_map_server_dump, "")                                             \
23814 _(lisp_adjacencies_get, "vni <vni>")                                    \
23815 _(gpe_fwd_entry_vnis_get, "")                                           \
23816 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23817 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23818                                 "[table <table-id>]")                   \
23819 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23820 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23821 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23822 _(gpe_get_encap_mode, "")                                               \
23823 _(lisp_gpe_add_del_iface, "up|down")                                    \
23824 _(lisp_gpe_enable_disable, "enable|disable")                            \
23825 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23826   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23827 _(show_lisp_rloc_probe_state, "")                                       \
23828 _(show_lisp_map_register_state, "")                                     \
23829 _(show_lisp_status, "")                                                 \
23830 _(lisp_get_map_request_itr_rlocs, "")                                   \
23831 _(show_lisp_pitr, "")                                                   \
23832 _(show_lisp_use_petr, "")                                               \
23833 _(show_lisp_map_request_mode, "")                                       \
23834 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23835 _(af_packet_delete, "name <host interface name>")                       \
23836 _(af_packet_dump, "")                                                   \
23837 _(policer_add_del, "name <policer name> <params> [del]")                \
23838 _(policer_dump, "[name <policer name>]")                                \
23839 _(policer_classify_set_interface,                                       \
23840   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23841   "  [l2-table <nn>] [del]")                                            \
23842 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23843 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23844     "[master|slave]")                                                   \
23845 _(netmap_delete, "name <interface name>")                               \
23846 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23847 _(mpls_fib_dump, "")                                                    \
23848 _(classify_table_ids, "")                                               \
23849 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23850 _(classify_table_info, "table_id <nn>")                                 \
23851 _(classify_session_dump, "table_id <nn>")                               \
23852 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23853     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23854     "[template_interval <nn>] [udp_checksum]")                          \
23855 _(ipfix_exporter_dump, "")                                              \
23856 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23857 _(ipfix_classify_stream_dump, "")                                       \
23858 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23859 _(ipfix_classify_table_dump, "")                                        \
23860 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23861 _(sw_interface_span_dump, "[l2]")                                           \
23862 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23863 _(pg_create_interface, "if_id <nn>")                                    \
23864 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23865 _(pg_enable_disable, "[stream <id>] disable")                           \
23866 _(ip_source_and_port_range_check_add_del,                               \
23867   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23868 _(ip_source_and_port_range_check_interface_add_del,                     \
23869   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23870   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23871 _(ipsec_gre_add_del_tunnel,                                             \
23872   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23873 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23874 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23875 _(l2_interface_pbb_tag_rewrite,                                         \
23876   "<intfc> | sw_if_index <nn> \n"                                       \
23877   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23878   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23879 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23880 _(flow_classify_set_interface,                                          \
23881   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23882 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23883 _(ip_fib_dump, "")                                                      \
23884 _(ip_mfib_dump, "")                                                     \
23885 _(ip6_fib_dump, "")                                                     \
23886 _(ip6_mfib_dump, "")                                                    \
23887 _(feature_enable_disable, "arc_name <arc_name> "                        \
23888   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23889 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23890 "[disable]")                                                            \
23891 _(l2_xconnect_dump, "")                                                 \
23892 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23893 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23894 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23895 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23896 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23897 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23898 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23899   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23900 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23901 _(sock_init_shm, "size <nnn>")                                          \
23902 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23903 _(dns_enable_disable, "[enable][disable]")                              \
23904 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23905 _(dns_resolve_name, "<hostname>")                                       \
23906 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23907 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23908 _(dns_resolve_name, "<hostname>")                                       \
23909 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23910   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23911 _(session_rules_dump, "")                                               \
23912 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23913 _(output_acl_set_interface,                                             \
23914   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23915   "  [l2-table <nn>] [del]")                                            \
23916 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23917
23918 /* List of command functions, CLI names map directly to functions */
23919 #define foreach_cli_function                                    \
23920 _(comment, "usage: comment <ignore-rest-of-line>")              \
23921 _(dump_interface_table, "usage: dump_interface_table")          \
23922 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23923 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23924 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23925 _(dump_stats_table, "usage: dump_stats_table")                  \
23926 _(dump_macro_table, "usage: dump_macro_table ")                 \
23927 _(dump_node_table, "usage: dump_node_table")                    \
23928 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23929 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23930 _(echo, "usage: echo <message>")                                \
23931 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23932 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23933 _(help, "usage: help")                                          \
23934 _(q, "usage: quit")                                             \
23935 _(quit, "usage: quit")                                          \
23936 _(search_node_table, "usage: search_node_table <name>...")      \
23937 _(set, "usage: set <variable-name> <value>")                    \
23938 _(script, "usage: script <file-name>")                          \
23939 _(statseg, "usage: statseg");                                   \
23940 _(unset, "usage: unset <variable-name>")
23941
23942 #define _(N,n)                                  \
23943     static void vl_api_##n##_t_handler_uni      \
23944     (vl_api_##n##_t * mp)                       \
23945     {                                           \
23946         vat_main_t * vam = &vat_main;           \
23947         if (vam->json_output) {                 \
23948             vl_api_##n##_t_handler_json(mp);    \
23949         } else {                                \
23950             vl_api_##n##_t_handler(mp);         \
23951         }                                       \
23952     }
23953 foreach_vpe_api_reply_msg;
23954 #if VPP_API_TEST_BUILTIN == 0
23955 foreach_standalone_reply_msg;
23956 #endif
23957 #undef _
23958
23959 void
23960 vat_api_hookup (vat_main_t * vam)
23961 {
23962 #define _(N,n)                                                  \
23963     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23964                            vl_api_##n##_t_handler_uni,          \
23965                            vl_noop_handler,                     \
23966                            vl_api_##n##_t_endian,               \
23967                            vl_api_##n##_t_print,                \
23968                            sizeof(vl_api_##n##_t), 1);
23969   foreach_vpe_api_reply_msg;
23970 #if VPP_API_TEST_BUILTIN == 0
23971   foreach_standalone_reply_msg;
23972 #endif
23973 #undef _
23974
23975 #if (VPP_API_TEST_BUILTIN==0)
23976   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
23977
23978   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
23979
23980   vam->function_by_name = hash_create_string (0, sizeof (uword));
23981
23982   vam->help_by_name = hash_create_string (0, sizeof (uword));
23983 #endif
23984
23985   /* API messages we can send */
23986 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
23987   foreach_vpe_api_msg;
23988 #undef _
23989
23990   /* Help strings */
23991 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
23992   foreach_vpe_api_msg;
23993 #undef _
23994
23995   /* CLI functions */
23996 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
23997   foreach_cli_function;
23998 #undef _
23999
24000   /* Help strings */
24001 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24002   foreach_cli_function;
24003 #undef _
24004 }
24005
24006 #if VPP_API_TEST_BUILTIN
24007 static clib_error_t *
24008 vat_api_hookup_shim (vlib_main_t * vm)
24009 {
24010   vat_api_hookup (&vat_main);
24011   return 0;
24012 }
24013
24014 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24015 #endif
24016
24017 /*
24018  * fd.io coding-style-patch-verification: ON
24019  *
24020  * Local Variables:
24021  * eval: (c-set-style "gnu")
24022  * End:
24023  */