L2 BD: introduce a BD interface on which to send UU packets
[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   vl_api_l2_port_type_t port_type;
7119   u32 rx_sw_if_index;
7120   u8 rx_sw_if_index_set = 0;
7121   u32 bd_id;
7122   u8 bd_id_set = 0;
7123   u32 shg = 0;
7124   u8 enable = 1;
7125   int ret;
7126
7127   port_type = L2_API_PORT_TYPE_NORMAL;
7128
7129   /* Parse args required to build the message */
7130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7131     {
7132       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7133         rx_sw_if_index_set = 1;
7134       else if (unformat (i, "bd_id %d", &bd_id))
7135         bd_id_set = 1;
7136       else
7137         if (unformat
7138             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7139         rx_sw_if_index_set = 1;
7140       else if (unformat (i, "shg %d", &shg))
7141         ;
7142       else if (unformat (i, "bvi"))
7143         port_type = L2_API_PORT_TYPE_BVI;
7144       else if (unformat (i, "uu-fwd"))
7145         port_type = L2_API_PORT_TYPE_UU_FWD;
7146       else if (unformat (i, "enable"))
7147         enable = 1;
7148       else if (unformat (i, "disable"))
7149         enable = 0;
7150       else
7151         break;
7152     }
7153
7154   if (rx_sw_if_index_set == 0)
7155     {
7156       errmsg ("missing rx interface name or sw_if_index");
7157       return -99;
7158     }
7159
7160   if (enable && (bd_id_set == 0))
7161     {
7162       errmsg ("missing bridge domain");
7163       return -99;
7164     }
7165
7166   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7167
7168   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7169   mp->bd_id = ntohl (bd_id);
7170   mp->shg = (u8) shg;
7171   mp->port_type = ntohl (port_type);
7172   mp->enable = enable;
7173
7174   S (mp);
7175   W (ret);
7176   return ret;
7177 }
7178
7179 static int
7180 api_bridge_domain_dump (vat_main_t * vam)
7181 {
7182   unformat_input_t *i = vam->input;
7183   vl_api_bridge_domain_dump_t *mp;
7184   vl_api_control_ping_t *mp_ping;
7185   u32 bd_id = ~0;
7186   int ret;
7187
7188   /* Parse args required to build the message */
7189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190     {
7191       if (unformat (i, "bd_id %d", &bd_id))
7192         ;
7193       else
7194         break;
7195     }
7196
7197   M (BRIDGE_DOMAIN_DUMP, mp);
7198   mp->bd_id = ntohl (bd_id);
7199   S (mp);
7200
7201   /* Use a control ping for synchronization */
7202   MPING (CONTROL_PING, mp_ping);
7203   S (mp_ping);
7204
7205   W (ret);
7206   return ret;
7207 }
7208
7209 static int
7210 api_bridge_domain_add_del (vat_main_t * vam)
7211 {
7212   unformat_input_t *i = vam->input;
7213   vl_api_bridge_domain_add_del_t *mp;
7214   u32 bd_id = ~0;
7215   u8 is_add = 1;
7216   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7217   u8 *bd_tag = NULL;
7218   u32 mac_age = 0;
7219   int ret;
7220
7221   /* Parse args required to build the message */
7222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223     {
7224       if (unformat (i, "bd_id %d", &bd_id))
7225         ;
7226       else if (unformat (i, "flood %d", &flood))
7227         ;
7228       else if (unformat (i, "uu-flood %d", &uu_flood))
7229         ;
7230       else if (unformat (i, "forward %d", &forward))
7231         ;
7232       else if (unformat (i, "learn %d", &learn))
7233         ;
7234       else if (unformat (i, "arp-term %d", &arp_term))
7235         ;
7236       else if (unformat (i, "mac-age %d", &mac_age))
7237         ;
7238       else if (unformat (i, "bd-tag %s", &bd_tag))
7239         ;
7240       else if (unformat (i, "del"))
7241         {
7242           is_add = 0;
7243           flood = uu_flood = forward = learn = 0;
7244         }
7245       else
7246         break;
7247     }
7248
7249   if (bd_id == ~0)
7250     {
7251       errmsg ("missing bridge domain");
7252       ret = -99;
7253       goto done;
7254     }
7255
7256   if (mac_age > 255)
7257     {
7258       errmsg ("mac age must be less than 256 ");
7259       ret = -99;
7260       goto done;
7261     }
7262
7263   if ((bd_tag) && (vec_len (bd_tag) > 63))
7264     {
7265       errmsg ("bd-tag cannot be longer than 63");
7266       ret = -99;
7267       goto done;
7268     }
7269
7270   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7271
7272   mp->bd_id = ntohl (bd_id);
7273   mp->flood = flood;
7274   mp->uu_flood = uu_flood;
7275   mp->forward = forward;
7276   mp->learn = learn;
7277   mp->arp_term = arp_term;
7278   mp->is_add = is_add;
7279   mp->mac_age = (u8) mac_age;
7280   if (bd_tag)
7281     {
7282       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7283       mp->bd_tag[vec_len (bd_tag)] = 0;
7284     }
7285   S (mp);
7286   W (ret);
7287
7288 done:
7289   vec_free (bd_tag);
7290   return ret;
7291 }
7292
7293 static int
7294 api_l2fib_flush_bd (vat_main_t * vam)
7295 {
7296   unformat_input_t *i = vam->input;
7297   vl_api_l2fib_flush_bd_t *mp;
7298   u32 bd_id = ~0;
7299   int ret;
7300
7301   /* Parse args required to build the message */
7302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7303     {
7304       if (unformat (i, "bd_id %d", &bd_id));
7305       else
7306         break;
7307     }
7308
7309   if (bd_id == ~0)
7310     {
7311       errmsg ("missing bridge domain");
7312       return -99;
7313     }
7314
7315   M (L2FIB_FLUSH_BD, mp);
7316
7317   mp->bd_id = htonl (bd_id);
7318
7319   S (mp);
7320   W (ret);
7321   return ret;
7322 }
7323
7324 static int
7325 api_l2fib_flush_int (vat_main_t * vam)
7326 {
7327   unformat_input_t *i = vam->input;
7328   vl_api_l2fib_flush_int_t *mp;
7329   u32 sw_if_index = ~0;
7330   int ret;
7331
7332   /* Parse args required to build the message */
7333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7334     {
7335       if (unformat (i, "sw_if_index %d", &sw_if_index));
7336       else
7337         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7338       else
7339         break;
7340     }
7341
7342   if (sw_if_index == ~0)
7343     {
7344       errmsg ("missing interface name or sw_if_index");
7345       return -99;
7346     }
7347
7348   M (L2FIB_FLUSH_INT, mp);
7349
7350   mp->sw_if_index = ntohl (sw_if_index);
7351
7352   S (mp);
7353   W (ret);
7354   return ret;
7355 }
7356
7357 static int
7358 api_l2fib_add_del (vat_main_t * vam)
7359 {
7360   unformat_input_t *i = vam->input;
7361   vl_api_l2fib_add_del_t *mp;
7362   f64 timeout;
7363   u8 mac[6] = { 0 };
7364   u8 mac_set = 0;
7365   u32 bd_id;
7366   u8 bd_id_set = 0;
7367   u32 sw_if_index = 0;
7368   u8 sw_if_index_set = 0;
7369   u8 is_add = 1;
7370   u8 static_mac = 0;
7371   u8 filter_mac = 0;
7372   u8 bvi_mac = 0;
7373   int count = 1;
7374   f64 before = 0;
7375   int j;
7376
7377   /* Parse args required to build the message */
7378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7379     {
7380       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7381         mac_set = 1;
7382       else if (unformat (i, "bd_id %d", &bd_id))
7383         bd_id_set = 1;
7384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7385         sw_if_index_set = 1;
7386       else if (unformat (i, "sw_if"))
7387         {
7388           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7389             {
7390               if (unformat
7391                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7392                 sw_if_index_set = 1;
7393             }
7394           else
7395             break;
7396         }
7397       else if (unformat (i, "static"))
7398         static_mac = 1;
7399       else if (unformat (i, "filter"))
7400         {
7401           filter_mac = 1;
7402           static_mac = 1;
7403         }
7404       else if (unformat (i, "bvi"))
7405         {
7406           bvi_mac = 1;
7407           static_mac = 1;
7408         }
7409       else if (unformat (i, "del"))
7410         is_add = 0;
7411       else if (unformat (i, "count %d", &count))
7412         ;
7413       else
7414         break;
7415     }
7416
7417   if (mac_set == 0)
7418     {
7419       errmsg ("missing mac address");
7420       return -99;
7421     }
7422
7423   if (bd_id_set == 0)
7424     {
7425       errmsg ("missing bridge domain");
7426       return -99;
7427     }
7428
7429   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7430     {
7431       errmsg ("missing interface name or sw_if_index");
7432       return -99;
7433     }
7434
7435   if (count > 1)
7436     {
7437       /* Turn on async mode */
7438       vam->async_mode = 1;
7439       vam->async_errors = 0;
7440       before = vat_time_now (vam);
7441     }
7442
7443   for (j = 0; j < count; j++)
7444     {
7445       M (L2FIB_ADD_DEL, mp);
7446
7447       clib_memcpy (mp->mac, mac, 6);
7448       mp->bd_id = ntohl (bd_id);
7449       mp->is_add = is_add;
7450       mp->sw_if_index = ntohl (sw_if_index);
7451
7452       if (is_add)
7453         {
7454           mp->static_mac = static_mac;
7455           mp->filter_mac = filter_mac;
7456           mp->bvi_mac = bvi_mac;
7457         }
7458       increment_mac_address (mac);
7459       /* send it... */
7460       S (mp);
7461     }
7462
7463   if (count > 1)
7464     {
7465       vl_api_control_ping_t *mp_ping;
7466       f64 after;
7467
7468       /* Shut off async mode */
7469       vam->async_mode = 0;
7470
7471       MPING (CONTROL_PING, mp_ping);
7472       S (mp_ping);
7473
7474       timeout = vat_time_now (vam) + 1.0;
7475       while (vat_time_now (vam) < timeout)
7476         if (vam->result_ready == 1)
7477           goto out;
7478       vam->retval = -99;
7479
7480     out:
7481       if (vam->retval == -99)
7482         errmsg ("timeout");
7483
7484       if (vam->async_errors > 0)
7485         {
7486           errmsg ("%d asynchronous errors", vam->async_errors);
7487           vam->retval = -98;
7488         }
7489       vam->async_errors = 0;
7490       after = vat_time_now (vam);
7491
7492       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7493              count, after - before, count / (after - before));
7494     }
7495   else
7496     {
7497       int ret;
7498
7499       /* Wait for a reply... */
7500       W (ret);
7501       return ret;
7502     }
7503   /* Return the good/bad news */
7504   return (vam->retval);
7505 }
7506
7507 static int
7508 api_bridge_domain_set_mac_age (vat_main_t * vam)
7509 {
7510   unformat_input_t *i = vam->input;
7511   vl_api_bridge_domain_set_mac_age_t *mp;
7512   u32 bd_id = ~0;
7513   u32 mac_age = 0;
7514   int ret;
7515
7516   /* Parse args required to build the message */
7517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (i, "bd_id %d", &bd_id));
7520       else if (unformat (i, "mac-age %d", &mac_age));
7521       else
7522         break;
7523     }
7524
7525   if (bd_id == ~0)
7526     {
7527       errmsg ("missing bridge domain");
7528       return -99;
7529     }
7530
7531   if (mac_age > 255)
7532     {
7533       errmsg ("mac age must be less than 256 ");
7534       return -99;
7535     }
7536
7537   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7538
7539   mp->bd_id = htonl (bd_id);
7540   mp->mac_age = (u8) mac_age;
7541
7542   S (mp);
7543   W (ret);
7544   return ret;
7545 }
7546
7547 static int
7548 api_l2_flags (vat_main_t * vam)
7549 {
7550   unformat_input_t *i = vam->input;
7551   vl_api_l2_flags_t *mp;
7552   u32 sw_if_index;
7553   u32 flags = 0;
7554   u8 sw_if_index_set = 0;
7555   u8 is_set = 0;
7556   int ret;
7557
7558   /* Parse args required to build the message */
7559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7560     {
7561       if (unformat (i, "sw_if_index %d", &sw_if_index))
7562         sw_if_index_set = 1;
7563       else if (unformat (i, "sw_if"))
7564         {
7565           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7566             {
7567               if (unformat
7568                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7569                 sw_if_index_set = 1;
7570             }
7571           else
7572             break;
7573         }
7574       else if (unformat (i, "learn"))
7575         flags |= L2_LEARN;
7576       else if (unformat (i, "forward"))
7577         flags |= L2_FWD;
7578       else if (unformat (i, "flood"))
7579         flags |= L2_FLOOD;
7580       else if (unformat (i, "uu-flood"))
7581         flags |= L2_UU_FLOOD;
7582       else if (unformat (i, "arp-term"))
7583         flags |= L2_ARP_TERM;
7584       else if (unformat (i, "off"))
7585         is_set = 0;
7586       else if (unformat (i, "disable"))
7587         is_set = 0;
7588       else
7589         break;
7590     }
7591
7592   if (sw_if_index_set == 0)
7593     {
7594       errmsg ("missing interface name or sw_if_index");
7595       return -99;
7596     }
7597
7598   M (L2_FLAGS, mp);
7599
7600   mp->sw_if_index = ntohl (sw_if_index);
7601   mp->feature_bitmap = ntohl (flags);
7602   mp->is_set = is_set;
7603
7604   S (mp);
7605   W (ret);
7606   return ret;
7607 }
7608
7609 static int
7610 api_bridge_flags (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_bridge_flags_t *mp;
7614   u32 bd_id;
7615   u8 bd_id_set = 0;
7616   u8 is_set = 1;
7617   bd_flags_t flags = 0;
7618   int ret;
7619
7620   /* Parse args required to build the message */
7621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7622     {
7623       if (unformat (i, "bd_id %d", &bd_id))
7624         bd_id_set = 1;
7625       else if (unformat (i, "learn"))
7626         flags |= BRIDGE_API_FLAG_LEARN;
7627       else if (unformat (i, "forward"))
7628         flags |= BRIDGE_API_FLAG_FWD;
7629       else if (unformat (i, "flood"))
7630         flags |= BRIDGE_API_FLAG_FLOOD;
7631       else if (unformat (i, "uu-flood"))
7632         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7633       else if (unformat (i, "arp-term"))
7634         flags |= BRIDGE_API_FLAG_ARP_TERM;
7635       else if (unformat (i, "off"))
7636         is_set = 0;
7637       else if (unformat (i, "disable"))
7638         is_set = 0;
7639       else
7640         break;
7641     }
7642
7643   if (bd_id_set == 0)
7644     {
7645       errmsg ("missing bridge domain");
7646       return -99;
7647     }
7648
7649   M (BRIDGE_FLAGS, mp);
7650
7651   mp->bd_id = ntohl (bd_id);
7652   mp->flags = ntohl (flags);
7653   mp->is_set = is_set;
7654
7655   S (mp);
7656   W (ret);
7657   return ret;
7658 }
7659
7660 static int
7661 api_bd_ip_mac_add_del (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_bd_ip_mac_add_del_t *mp;
7665   u32 bd_id;
7666   u8 is_ipv6 = 0;
7667   u8 is_add = 1;
7668   u8 bd_id_set = 0;
7669   u8 ip_set = 0;
7670   u8 mac_set = 0;
7671   ip4_address_t v4addr;
7672   ip6_address_t v6addr;
7673   u8 macaddr[6];
7674   int ret;
7675
7676
7677   /* Parse args required to build the message */
7678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7679     {
7680       if (unformat (i, "bd_id %d", &bd_id))
7681         {
7682           bd_id_set++;
7683         }
7684       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7685         {
7686           ip_set++;
7687         }
7688       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7689         {
7690           ip_set++;
7691           is_ipv6++;
7692         }
7693       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7694         {
7695           mac_set++;
7696         }
7697       else if (unformat (i, "del"))
7698         is_add = 0;
7699       else
7700         break;
7701     }
7702
7703   if (bd_id_set == 0)
7704     {
7705       errmsg ("missing bridge domain");
7706       return -99;
7707     }
7708   else if (ip_set == 0)
7709     {
7710       errmsg ("missing IP address");
7711       return -99;
7712     }
7713   else if (mac_set == 0)
7714     {
7715       errmsg ("missing MAC address");
7716       return -99;
7717     }
7718
7719   M (BD_IP_MAC_ADD_DEL, mp);
7720
7721   mp->bd_id = ntohl (bd_id);
7722   mp->is_ipv6 = is_ipv6;
7723   mp->is_add = is_add;
7724   if (is_ipv6)
7725     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7726   else
7727     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7728   clib_memcpy (mp->mac_address, macaddr, 6);
7729   S (mp);
7730   W (ret);
7731   return ret;
7732 }
7733
7734 static void vl_api_bd_ip_mac_details_t_handler
7735   (vl_api_bd_ip_mac_details_t * mp)
7736 {
7737   vat_main_t *vam = &vat_main;
7738   u8 *ip = 0;
7739
7740   if (!mp->is_ipv6)
7741     ip =
7742       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7743   else
7744     ip =
7745       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7746
7747   print (vam->ofp,
7748          "\n%-5d %-7s %-20U %-30s",
7749          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7750          format_ethernet_address, mp->mac_address, ip);
7751
7752   vec_free (ip);
7753 }
7754
7755 static void vl_api_bd_ip_mac_details_t_handler_json
7756   (vl_api_bd_ip_mac_details_t * mp)
7757 {
7758   vat_main_t *vam = &vat_main;
7759   vat_json_node_t *node = NULL;
7760
7761   if (VAT_JSON_ARRAY != vam->json_tree.type)
7762     {
7763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7764       vat_json_init_array (&vam->json_tree);
7765     }
7766   node = vat_json_array_add (&vam->json_tree);
7767
7768   vat_json_init_object (node);
7769   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7770   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7771   vat_json_object_add_string_copy (node, "mac_address",
7772                                    format (0, "%U", format_ethernet_address,
7773                                            &mp->mac_address));
7774   u8 *ip = 0;
7775
7776   if (!mp->is_ipv6)
7777     ip =
7778       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7779   else
7780     ip =
7781       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7782   vat_json_object_add_string_copy (node, "ip_address", ip);
7783   vec_free (ip);
7784 }
7785
7786 static int
7787 api_bd_ip_mac_dump (vat_main_t * vam)
7788 {
7789   unformat_input_t *i = vam->input;
7790   vl_api_bd_ip_mac_dump_t *mp;
7791   vl_api_control_ping_t *mp_ping;
7792   int ret;
7793   u32 bd_id;
7794   u8 bd_id_set = 0;
7795
7796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7797     {
7798       if (unformat (i, "bd_id %d", &bd_id))
7799         {
7800           bd_id_set++;
7801         }
7802       else
7803         break;
7804     }
7805
7806   print (vam->ofp,
7807          "\n%-5s %-7s %-20s %-30s",
7808          "bd_id", "is_ipv6", "mac_address", "ip_address");
7809
7810   /* Dump Bridge Domain Ip to Mac entries */
7811   M (BD_IP_MAC_DUMP, mp);
7812
7813   if (bd_id_set)
7814     mp->bd_id = htonl (bd_id);
7815   else
7816     mp->bd_id = ~0;
7817
7818   S (mp);
7819
7820   /* Use a control ping for synchronization */
7821   MPING (CONTROL_PING, mp_ping);
7822   S (mp_ping);
7823
7824   W (ret);
7825   return ret;
7826 }
7827
7828 static int
7829 api_tap_connect (vat_main_t * vam)
7830 {
7831   unformat_input_t *i = vam->input;
7832   vl_api_tap_connect_t *mp;
7833   u8 mac_address[6];
7834   u8 random_mac = 1;
7835   u8 name_set = 0;
7836   u8 *tap_name;
7837   u8 *tag = 0;
7838   ip4_address_t ip4_address;
7839   u32 ip4_mask_width;
7840   int ip4_address_set = 0;
7841   ip6_address_t ip6_address;
7842   u32 ip6_mask_width;
7843   int ip6_address_set = 0;
7844   int ret;
7845
7846   memset (mac_address, 0, sizeof (mac_address));
7847
7848   /* Parse args required to build the message */
7849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7850     {
7851       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7852         {
7853           random_mac = 0;
7854         }
7855       else if (unformat (i, "random-mac"))
7856         random_mac = 1;
7857       else if (unformat (i, "tapname %s", &tap_name))
7858         name_set = 1;
7859       else if (unformat (i, "tag %s", &tag))
7860         ;
7861       else if (unformat (i, "address %U/%d",
7862                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7863         ip4_address_set = 1;
7864       else if (unformat (i, "address %U/%d",
7865                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7866         ip6_address_set = 1;
7867       else
7868         break;
7869     }
7870
7871   if (name_set == 0)
7872     {
7873       errmsg ("missing tap name");
7874       return -99;
7875     }
7876   if (vec_len (tap_name) > 63)
7877     {
7878       errmsg ("tap name too long");
7879       return -99;
7880     }
7881   vec_add1 (tap_name, 0);
7882
7883   if (vec_len (tag) > 63)
7884     {
7885       errmsg ("tag too long");
7886       return -99;
7887     }
7888
7889   /* Construct the API message */
7890   M (TAP_CONNECT, mp);
7891
7892   mp->use_random_mac = random_mac;
7893   clib_memcpy (mp->mac_address, mac_address, 6);
7894   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7895   if (tag)
7896     clib_memcpy (mp->tag, tag, vec_len (tag));
7897
7898   if (ip4_address_set)
7899     {
7900       mp->ip4_address_set = 1;
7901       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7902       mp->ip4_mask_width = ip4_mask_width;
7903     }
7904   if (ip6_address_set)
7905     {
7906       mp->ip6_address_set = 1;
7907       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7908       mp->ip6_mask_width = ip6_mask_width;
7909     }
7910
7911   vec_free (tap_name);
7912   vec_free (tag);
7913
7914   /* send it... */
7915   S (mp);
7916
7917   /* Wait for a reply... */
7918   W (ret);
7919   return ret;
7920 }
7921
7922 static int
7923 api_tap_modify (vat_main_t * vam)
7924 {
7925   unformat_input_t *i = vam->input;
7926   vl_api_tap_modify_t *mp;
7927   u8 mac_address[6];
7928   u8 random_mac = 1;
7929   u8 name_set = 0;
7930   u8 *tap_name;
7931   u32 sw_if_index = ~0;
7932   u8 sw_if_index_set = 0;
7933   int ret;
7934
7935   memset (mac_address, 0, sizeof (mac_address));
7936
7937   /* Parse args required to build the message */
7938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7939     {
7940       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7941         sw_if_index_set = 1;
7942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7943         sw_if_index_set = 1;
7944       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7945         {
7946           random_mac = 0;
7947         }
7948       else if (unformat (i, "random-mac"))
7949         random_mac = 1;
7950       else if (unformat (i, "tapname %s", &tap_name))
7951         name_set = 1;
7952       else
7953         break;
7954     }
7955
7956   if (sw_if_index_set == 0)
7957     {
7958       errmsg ("missing vpp interface name");
7959       return -99;
7960     }
7961   if (name_set == 0)
7962     {
7963       errmsg ("missing tap name");
7964       return -99;
7965     }
7966   if (vec_len (tap_name) > 63)
7967     {
7968       errmsg ("tap name too long");
7969     }
7970   vec_add1 (tap_name, 0);
7971
7972   /* Construct the API message */
7973   M (TAP_MODIFY, mp);
7974
7975   mp->use_random_mac = random_mac;
7976   mp->sw_if_index = ntohl (sw_if_index);
7977   clib_memcpy (mp->mac_address, mac_address, 6);
7978   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7979   vec_free (tap_name);
7980
7981   /* send it... */
7982   S (mp);
7983
7984   /* Wait for a reply... */
7985   W (ret);
7986   return ret;
7987 }
7988
7989 static int
7990 api_tap_delete (vat_main_t * vam)
7991 {
7992   unformat_input_t *i = vam->input;
7993   vl_api_tap_delete_t *mp;
7994   u32 sw_if_index = ~0;
7995   u8 sw_if_index_set = 0;
7996   int ret;
7997
7998   /* Parse args required to build the message */
7999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8000     {
8001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8002         sw_if_index_set = 1;
8003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8004         sw_if_index_set = 1;
8005       else
8006         break;
8007     }
8008
8009   if (sw_if_index_set == 0)
8010     {
8011       errmsg ("missing vpp interface name");
8012       return -99;
8013     }
8014
8015   /* Construct the API message */
8016   M (TAP_DELETE, mp);
8017
8018   mp->sw_if_index = ntohl (sw_if_index);
8019
8020   /* send it... */
8021   S (mp);
8022
8023   /* Wait for a reply... */
8024   W (ret);
8025   return ret;
8026 }
8027
8028 static int
8029 api_tap_create_v2 (vat_main_t * vam)
8030 {
8031   unformat_input_t *i = vam->input;
8032   vl_api_tap_create_v2_t *mp;
8033   u8 mac_address[6];
8034   u8 random_mac = 1;
8035   u32 id = ~0;
8036   u8 *host_if_name = 0;
8037   u8 *host_ns = 0;
8038   u8 host_mac_addr[6];
8039   u8 host_mac_addr_set = 0;
8040   u8 *host_bridge = 0;
8041   ip4_address_t host_ip4_addr;
8042   ip4_address_t host_ip4_gw;
8043   u8 host_ip4_gw_set = 0;
8044   u32 host_ip4_prefix_len = 0;
8045   ip6_address_t host_ip6_addr;
8046   ip6_address_t host_ip6_gw;
8047   u8 host_ip6_gw_set = 0;
8048   u32 host_ip6_prefix_len = 0;
8049   int ret;
8050   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8051
8052   memset (mac_address, 0, sizeof (mac_address));
8053
8054   /* Parse args required to build the message */
8055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8056     {
8057       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8058         {
8059           random_mac = 0;
8060         }
8061       else if (unformat (i, "id %u", &id))
8062         ;
8063       else if (unformat (i, "host-if-name %s", &host_if_name))
8064         ;
8065       else if (unformat (i, "host-ns %s", &host_ns))
8066         ;
8067       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8068                          host_mac_addr))
8069         host_mac_addr_set = 1;
8070       else if (unformat (i, "host-bridge %s", &host_bridge))
8071         ;
8072       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8073                          &host_ip4_addr, &host_ip4_prefix_len))
8074         ;
8075       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8076                          &host_ip6_addr, &host_ip6_prefix_len))
8077         ;
8078       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8079                          &host_ip4_gw))
8080         host_ip4_gw_set = 1;
8081       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8082                          &host_ip6_gw))
8083         host_ip6_gw_set = 1;
8084       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8085         ;
8086       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8087         ;
8088       else
8089         break;
8090     }
8091
8092   if (vec_len (host_if_name) > 63)
8093     {
8094       errmsg ("tap name too long. ");
8095       return -99;
8096     }
8097   if (vec_len (host_ns) > 63)
8098     {
8099       errmsg ("host name space too long. ");
8100       return -99;
8101     }
8102   if (vec_len (host_bridge) > 63)
8103     {
8104       errmsg ("host bridge name too long. ");
8105       return -99;
8106     }
8107   if (host_ip4_prefix_len > 32)
8108     {
8109       errmsg ("host ip4 prefix length not valid. ");
8110       return -99;
8111     }
8112   if (host_ip6_prefix_len > 128)
8113     {
8114       errmsg ("host ip6 prefix length not valid. ");
8115       return -99;
8116     }
8117   if (!is_pow2 (rx_ring_sz))
8118     {
8119       errmsg ("rx ring size must be power of 2. ");
8120       return -99;
8121     }
8122   if (rx_ring_sz > 32768)
8123     {
8124       errmsg ("rx ring size must be 32768 or lower. ");
8125       return -99;
8126     }
8127   if (!is_pow2 (tx_ring_sz))
8128     {
8129       errmsg ("tx ring size must be power of 2. ");
8130       return -99;
8131     }
8132   if (tx_ring_sz > 32768)
8133     {
8134       errmsg ("tx ring size must be 32768 or lower. ");
8135       return -99;
8136     }
8137
8138   /* Construct the API message */
8139   M (TAP_CREATE_V2, mp);
8140
8141   mp->use_random_mac = random_mac;
8142
8143   mp->id = ntohl (id);
8144   mp->host_namespace_set = host_ns != 0;
8145   mp->host_bridge_set = host_bridge != 0;
8146   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8147   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8148   mp->rx_ring_sz = ntohs (rx_ring_sz);
8149   mp->tx_ring_sz = ntohs (tx_ring_sz);
8150
8151   if (random_mac == 0)
8152     clib_memcpy (mp->mac_address, mac_address, 6);
8153   if (host_mac_addr_set)
8154     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8155   if (host_if_name)
8156     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8157   if (host_ns)
8158     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8159   if (host_bridge)
8160     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8161   if (host_ip4_prefix_len)
8162     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8163   if (host_ip4_prefix_len)
8164     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8165   if (host_ip4_gw_set)
8166     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8167   if (host_ip6_gw_set)
8168     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8169
8170   vec_free (host_ns);
8171   vec_free (host_if_name);
8172   vec_free (host_bridge);
8173
8174   /* send it... */
8175   S (mp);
8176
8177   /* Wait for a reply... */
8178   W (ret);
8179   return ret;
8180 }
8181
8182 static int
8183 api_tap_delete_v2 (vat_main_t * vam)
8184 {
8185   unformat_input_t *i = vam->input;
8186   vl_api_tap_delete_v2_t *mp;
8187   u32 sw_if_index = ~0;
8188   u8 sw_if_index_set = 0;
8189   int ret;
8190
8191   /* Parse args required to build the message */
8192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8193     {
8194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8195         sw_if_index_set = 1;
8196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8197         sw_if_index_set = 1;
8198       else
8199         break;
8200     }
8201
8202   if (sw_if_index_set == 0)
8203     {
8204       errmsg ("missing vpp interface name. ");
8205       return -99;
8206     }
8207
8208   /* Construct the API message */
8209   M (TAP_DELETE_V2, mp);
8210
8211   mp->sw_if_index = ntohl (sw_if_index);
8212
8213   /* send it... */
8214   S (mp);
8215
8216   /* Wait for a reply... */
8217   W (ret);
8218   return ret;
8219 }
8220
8221 static int
8222 api_bond_create (vat_main_t * vam)
8223 {
8224   unformat_input_t *i = vam->input;
8225   vl_api_bond_create_t *mp;
8226   u8 mac_address[6];
8227   u8 custom_mac = 0;
8228   int ret;
8229   u8 mode;
8230   u8 lb;
8231   u8 mode_is_set = 0;
8232
8233   memset (mac_address, 0, sizeof (mac_address));
8234   lb = BOND_LB_L2;
8235
8236   /* Parse args required to build the message */
8237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8238     {
8239       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8240         mode_is_set = 1;
8241       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8242                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8243         ;
8244       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8245                          mac_address))
8246         custom_mac = 1;
8247       else
8248         break;
8249     }
8250
8251   if (mode_is_set == 0)
8252     {
8253       errmsg ("Missing bond mode. ");
8254       return -99;
8255     }
8256
8257   /* Construct the API message */
8258   M (BOND_CREATE, mp);
8259
8260   mp->use_custom_mac = custom_mac;
8261
8262   mp->mode = mode;
8263   mp->lb = lb;
8264
8265   if (custom_mac)
8266     clib_memcpy (mp->mac_address, mac_address, 6);
8267
8268   /* send it... */
8269   S (mp);
8270
8271   /* Wait for a reply... */
8272   W (ret);
8273   return ret;
8274 }
8275
8276 static int
8277 api_bond_delete (vat_main_t * vam)
8278 {
8279   unformat_input_t *i = vam->input;
8280   vl_api_bond_delete_t *mp;
8281   u32 sw_if_index = ~0;
8282   u8 sw_if_index_set = 0;
8283   int ret;
8284
8285   /* Parse args required to build the message */
8286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8287     {
8288       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8289         sw_if_index_set = 1;
8290       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8291         sw_if_index_set = 1;
8292       else
8293         break;
8294     }
8295
8296   if (sw_if_index_set == 0)
8297     {
8298       errmsg ("missing vpp interface name. ");
8299       return -99;
8300     }
8301
8302   /* Construct the API message */
8303   M (BOND_DELETE, mp);
8304
8305   mp->sw_if_index = ntohl (sw_if_index);
8306
8307   /* send it... */
8308   S (mp);
8309
8310   /* Wait for a reply... */
8311   W (ret);
8312   return ret;
8313 }
8314
8315 static int
8316 api_bond_enslave (vat_main_t * vam)
8317 {
8318   unformat_input_t *i = vam->input;
8319   vl_api_bond_enslave_t *mp;
8320   u32 bond_sw_if_index;
8321   int ret;
8322   u8 is_passive;
8323   u8 is_long_timeout;
8324   u32 bond_sw_if_index_is_set = 0;
8325   u32 sw_if_index;
8326   u8 sw_if_index_is_set = 0;
8327
8328   /* Parse args required to build the message */
8329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8330     {
8331       if (unformat (i, "sw_if_index %d", &sw_if_index))
8332         sw_if_index_is_set = 1;
8333       else if (unformat (i, "bond %u", &bond_sw_if_index))
8334         bond_sw_if_index_is_set = 1;
8335       else if (unformat (i, "passive %d", &is_passive))
8336         ;
8337       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8338         ;
8339       else
8340         break;
8341     }
8342
8343   if (bond_sw_if_index_is_set == 0)
8344     {
8345       errmsg ("Missing bond sw_if_index. ");
8346       return -99;
8347     }
8348   if (sw_if_index_is_set == 0)
8349     {
8350       errmsg ("Missing slave sw_if_index. ");
8351       return -99;
8352     }
8353
8354   /* Construct the API message */
8355   M (BOND_ENSLAVE, mp);
8356
8357   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8358   mp->sw_if_index = ntohl (sw_if_index);
8359   mp->is_long_timeout = is_long_timeout;
8360   mp->is_passive = is_passive;
8361
8362   /* send it... */
8363   S (mp);
8364
8365   /* Wait for a reply... */
8366   W (ret);
8367   return ret;
8368 }
8369
8370 static int
8371 api_bond_detach_slave (vat_main_t * vam)
8372 {
8373   unformat_input_t *i = vam->input;
8374   vl_api_bond_detach_slave_t *mp;
8375   u32 sw_if_index = ~0;
8376   u8 sw_if_index_set = 0;
8377   int ret;
8378
8379   /* Parse args required to build the message */
8380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8381     {
8382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8383         sw_if_index_set = 1;
8384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8385         sw_if_index_set = 1;
8386       else
8387         break;
8388     }
8389
8390   if (sw_if_index_set == 0)
8391     {
8392       errmsg ("missing vpp interface name. ");
8393       return -99;
8394     }
8395
8396   /* Construct the API message */
8397   M (BOND_DETACH_SLAVE, mp);
8398
8399   mp->sw_if_index = ntohl (sw_if_index);
8400
8401   /* send it... */
8402   S (mp);
8403
8404   /* Wait for a reply... */
8405   W (ret);
8406   return ret;
8407 }
8408
8409 static int
8410 api_ip_table_add_del (vat_main_t * vam)
8411 {
8412   unformat_input_t *i = vam->input;
8413   vl_api_ip_table_add_del_t *mp;
8414   u32 table_id = ~0;
8415   u8 is_ipv6 = 0;
8416   u8 is_add = 1;
8417   int ret = 0;
8418
8419   /* Parse args required to build the message */
8420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8421     {
8422       if (unformat (i, "ipv6"))
8423         is_ipv6 = 1;
8424       else if (unformat (i, "del"))
8425         is_add = 0;
8426       else if (unformat (i, "add"))
8427         is_add = 1;
8428       else if (unformat (i, "table %d", &table_id))
8429         ;
8430       else
8431         {
8432           clib_warning ("parse error '%U'", format_unformat_error, i);
8433           return -99;
8434         }
8435     }
8436
8437   if (~0 == table_id)
8438     {
8439       errmsg ("missing table-ID");
8440       return -99;
8441     }
8442
8443   /* Construct the API message */
8444   M (IP_TABLE_ADD_DEL, mp);
8445
8446   mp->table_id = ntohl (table_id);
8447   mp->is_ipv6 = is_ipv6;
8448   mp->is_add = is_add;
8449
8450   /* send it... */
8451   S (mp);
8452
8453   /* Wait for a reply... */
8454   W (ret);
8455
8456   return ret;
8457 }
8458
8459 static int
8460 api_ip_add_del_route (vat_main_t * vam)
8461 {
8462   unformat_input_t *i = vam->input;
8463   vl_api_ip_add_del_route_t *mp;
8464   u32 sw_if_index = ~0, vrf_id = 0;
8465   u8 is_ipv6 = 0;
8466   u8 is_local = 0, is_drop = 0;
8467   u8 is_unreach = 0, is_prohibit = 0;
8468   u8 is_add = 1;
8469   u32 next_hop_weight = 1;
8470   u8 is_multipath = 0;
8471   u8 address_set = 0;
8472   u8 address_length_set = 0;
8473   u32 next_hop_table_id = 0;
8474   u32 resolve_attempts = 0;
8475   u32 dst_address_length = 0;
8476   u8 next_hop_set = 0;
8477   ip4_address_t v4_dst_address, v4_next_hop_address;
8478   ip6_address_t v6_dst_address, v6_next_hop_address;
8479   int count = 1;
8480   int j;
8481   f64 before = 0;
8482   u32 random_add_del = 0;
8483   u32 *random_vector = 0;
8484   uword *random_hash;
8485   u32 random_seed = 0xdeaddabe;
8486   u32 classify_table_index = ~0;
8487   u8 is_classify = 0;
8488   u8 resolve_host = 0, resolve_attached = 0;
8489   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8490   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8491   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8492
8493   memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8494   memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8495   /* Parse args required to build the message */
8496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8497     {
8498       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8499         ;
8500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8501         ;
8502       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8503         {
8504           address_set = 1;
8505           is_ipv6 = 0;
8506         }
8507       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8508         {
8509           address_set = 1;
8510           is_ipv6 = 1;
8511         }
8512       else if (unformat (i, "/%d", &dst_address_length))
8513         {
8514           address_length_set = 1;
8515         }
8516
8517       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8518                                          &v4_next_hop_address))
8519         {
8520           next_hop_set = 1;
8521         }
8522       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8523                                          &v6_next_hop_address))
8524         {
8525           next_hop_set = 1;
8526         }
8527       else
8528         if (unformat
8529             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8530         {
8531           next_hop_set = 1;
8532         }
8533       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8534         {
8535           next_hop_set = 1;
8536         }
8537       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8538         ;
8539       else if (unformat (i, "weight %d", &next_hop_weight))
8540         ;
8541       else if (unformat (i, "drop"))
8542         {
8543           is_drop = 1;
8544         }
8545       else if (unformat (i, "null-send-unreach"))
8546         {
8547           is_unreach = 1;
8548         }
8549       else if (unformat (i, "null-send-prohibit"))
8550         {
8551           is_prohibit = 1;
8552         }
8553       else if (unformat (i, "local"))
8554         {
8555           is_local = 1;
8556         }
8557       else if (unformat (i, "classify %d", &classify_table_index))
8558         {
8559           is_classify = 1;
8560         }
8561       else if (unformat (i, "del"))
8562         is_add = 0;
8563       else if (unformat (i, "add"))
8564         is_add = 1;
8565       else if (unformat (i, "resolve-via-host"))
8566         resolve_host = 1;
8567       else if (unformat (i, "resolve-via-attached"))
8568         resolve_attached = 1;
8569       else if (unformat (i, "multipath"))
8570         is_multipath = 1;
8571       else if (unformat (i, "vrf %d", &vrf_id))
8572         ;
8573       else if (unformat (i, "count %d", &count))
8574         ;
8575       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8576         ;
8577       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8578         ;
8579       else if (unformat (i, "out-label %d", &next_hop_out_label))
8580         {
8581           vl_api_fib_mpls_label_t fib_label = {
8582             .label = ntohl (next_hop_out_label),
8583             .ttl = 64,
8584             .exp = 0,
8585           };
8586           vec_add1 (next_hop_out_label_stack, fib_label);
8587         }
8588       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8589         ;
8590       else if (unformat (i, "random"))
8591         random_add_del = 1;
8592       else if (unformat (i, "seed %d", &random_seed))
8593         ;
8594       else
8595         {
8596           clib_warning ("parse error '%U'", format_unformat_error, i);
8597           return -99;
8598         }
8599     }
8600
8601   if (!next_hop_set && !is_drop && !is_local &&
8602       !is_classify && !is_unreach && !is_prohibit &&
8603       MPLS_LABEL_INVALID == next_hop_via_label)
8604     {
8605       errmsg
8606         ("next hop / local / drop / unreach / prohibit / classify not set");
8607       return -99;
8608     }
8609
8610   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8611     {
8612       errmsg ("next hop and next-hop via label set");
8613       return -99;
8614     }
8615   if (address_set == 0)
8616     {
8617       errmsg ("missing addresses");
8618       return -99;
8619     }
8620
8621   if (address_length_set == 0)
8622     {
8623       errmsg ("missing address length");
8624       return -99;
8625     }
8626
8627   /* Generate a pile of unique, random routes */
8628   if (random_add_del)
8629     {
8630       u32 this_random_address;
8631       random_hash = hash_create (count, sizeof (uword));
8632
8633       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8634       for (j = 0; j <= count; j++)
8635         {
8636           do
8637             {
8638               this_random_address = random_u32 (&random_seed);
8639               this_random_address =
8640                 clib_host_to_net_u32 (this_random_address);
8641             }
8642           while (hash_get (random_hash, this_random_address));
8643           vec_add1 (random_vector, this_random_address);
8644           hash_set (random_hash, this_random_address, 1);
8645         }
8646       hash_free (random_hash);
8647       v4_dst_address.as_u32 = random_vector[0];
8648     }
8649
8650   if (count > 1)
8651     {
8652       /* Turn on async mode */
8653       vam->async_mode = 1;
8654       vam->async_errors = 0;
8655       before = vat_time_now (vam);
8656     }
8657
8658   for (j = 0; j < count; j++)
8659     {
8660       /* Construct the API message */
8661       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8662           vec_len (next_hop_out_label_stack));
8663
8664       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8665       mp->table_id = ntohl (vrf_id);
8666
8667       mp->is_add = is_add;
8668       mp->is_drop = is_drop;
8669       mp->is_unreach = is_unreach;
8670       mp->is_prohibit = is_prohibit;
8671       mp->is_ipv6 = is_ipv6;
8672       mp->is_local = is_local;
8673       mp->is_classify = is_classify;
8674       mp->is_multipath = is_multipath;
8675       mp->is_resolve_host = resolve_host;
8676       mp->is_resolve_attached = resolve_attached;
8677       mp->next_hop_weight = next_hop_weight;
8678       mp->dst_address_length = dst_address_length;
8679       mp->next_hop_table_id = ntohl (next_hop_table_id);
8680       mp->classify_table_index = ntohl (classify_table_index);
8681       mp->next_hop_via_label = ntohl (next_hop_via_label);
8682       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8683       if (0 != mp->next_hop_n_out_labels)
8684         {
8685           memcpy (mp->next_hop_out_label_stack,
8686                   next_hop_out_label_stack,
8687                   (vec_len (next_hop_out_label_stack) *
8688                    sizeof (vl_api_fib_mpls_label_t)));
8689           vec_free (next_hop_out_label_stack);
8690         }
8691
8692       if (is_ipv6)
8693         {
8694           clib_memcpy (mp->dst_address, &v6_dst_address,
8695                        sizeof (v6_dst_address));
8696           if (next_hop_set)
8697             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8698                          sizeof (v6_next_hop_address));
8699           increment_v6_address (&v6_dst_address);
8700         }
8701       else
8702         {
8703           clib_memcpy (mp->dst_address, &v4_dst_address,
8704                        sizeof (v4_dst_address));
8705           if (next_hop_set)
8706             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8707                          sizeof (v4_next_hop_address));
8708           if (random_add_del)
8709             v4_dst_address.as_u32 = random_vector[j + 1];
8710           else
8711             increment_v4_address (&v4_dst_address);
8712         }
8713       /* send it... */
8714       S (mp);
8715       /* If we receive SIGTERM, stop now... */
8716       if (vam->do_exit)
8717         break;
8718     }
8719
8720   /* When testing multiple add/del ops, use a control-ping to sync */
8721   if (count > 1)
8722     {
8723       vl_api_control_ping_t *mp_ping;
8724       f64 after;
8725       f64 timeout;
8726
8727       /* Shut off async mode */
8728       vam->async_mode = 0;
8729
8730       MPING (CONTROL_PING, mp_ping);
8731       S (mp_ping);
8732
8733       timeout = vat_time_now (vam) + 1.0;
8734       while (vat_time_now (vam) < timeout)
8735         if (vam->result_ready == 1)
8736           goto out;
8737       vam->retval = -99;
8738
8739     out:
8740       if (vam->retval == -99)
8741         errmsg ("timeout");
8742
8743       if (vam->async_errors > 0)
8744         {
8745           errmsg ("%d asynchronous errors", vam->async_errors);
8746           vam->retval = -98;
8747         }
8748       vam->async_errors = 0;
8749       after = vat_time_now (vam);
8750
8751       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8752       if (j > 0)
8753         count = j;
8754
8755       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8756              count, after - before, count / (after - before));
8757     }
8758   else
8759     {
8760       int ret;
8761
8762       /* Wait for a reply... */
8763       W (ret);
8764       return ret;
8765     }
8766
8767   /* Return the good/bad news */
8768   return (vam->retval);
8769 }
8770
8771 static int
8772 api_ip_mroute_add_del (vat_main_t * vam)
8773 {
8774   unformat_input_t *i = vam->input;
8775   vl_api_ip_mroute_add_del_t *mp;
8776   u32 sw_if_index = ~0, vrf_id = 0;
8777   u8 is_ipv6 = 0;
8778   u8 is_local = 0;
8779   u8 is_add = 1;
8780   u8 address_set = 0;
8781   u32 grp_address_length = 0;
8782   ip4_address_t v4_grp_address, v4_src_address;
8783   ip6_address_t v6_grp_address, v6_src_address;
8784   mfib_itf_flags_t iflags = 0;
8785   mfib_entry_flags_t eflags = 0;
8786   int ret;
8787
8788   /* Parse args required to build the message */
8789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8790     {
8791       if (unformat (i, "sw_if_index %d", &sw_if_index))
8792         ;
8793       else if (unformat (i, "%U %U",
8794                          unformat_ip4_address, &v4_src_address,
8795                          unformat_ip4_address, &v4_grp_address))
8796         {
8797           grp_address_length = 64;
8798           address_set = 1;
8799           is_ipv6 = 0;
8800         }
8801       else if (unformat (i, "%U %U",
8802                          unformat_ip6_address, &v6_src_address,
8803                          unformat_ip6_address, &v6_grp_address))
8804         {
8805           grp_address_length = 256;
8806           address_set = 1;
8807           is_ipv6 = 1;
8808         }
8809       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8810         {
8811           memset (&v4_src_address, 0, sizeof (v4_src_address));
8812           grp_address_length = 32;
8813           address_set = 1;
8814           is_ipv6 = 0;
8815         }
8816       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8817         {
8818           memset (&v6_src_address, 0, sizeof (v6_src_address));
8819           grp_address_length = 128;
8820           address_set = 1;
8821           is_ipv6 = 1;
8822         }
8823       else if (unformat (i, "/%d", &grp_address_length))
8824         ;
8825       else if (unformat (i, "local"))
8826         {
8827           is_local = 1;
8828         }
8829       else if (unformat (i, "del"))
8830         is_add = 0;
8831       else if (unformat (i, "add"))
8832         is_add = 1;
8833       else if (unformat (i, "vrf %d", &vrf_id))
8834         ;
8835       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8836         ;
8837       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8838         ;
8839       else
8840         {
8841           clib_warning ("parse error '%U'", format_unformat_error, i);
8842           return -99;
8843         }
8844     }
8845
8846   if (address_set == 0)
8847     {
8848       errmsg ("missing addresses\n");
8849       return -99;
8850     }
8851
8852   /* Construct the API message */
8853   M (IP_MROUTE_ADD_DEL, mp);
8854
8855   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8856   mp->table_id = ntohl (vrf_id);
8857
8858   mp->is_add = is_add;
8859   mp->is_ipv6 = is_ipv6;
8860   mp->is_local = is_local;
8861   mp->itf_flags = ntohl (iflags);
8862   mp->entry_flags = ntohl (eflags);
8863   mp->grp_address_length = grp_address_length;
8864   mp->grp_address_length = ntohs (mp->grp_address_length);
8865
8866   if (is_ipv6)
8867     {
8868       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8869       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8870     }
8871   else
8872     {
8873       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8874       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8875
8876     }
8877
8878   /* send it... */
8879   S (mp);
8880   /* Wait for a reply... */
8881   W (ret);
8882   return ret;
8883 }
8884
8885 static int
8886 api_mpls_table_add_del (vat_main_t * vam)
8887 {
8888   unformat_input_t *i = vam->input;
8889   vl_api_mpls_table_add_del_t *mp;
8890   u32 table_id = ~0;
8891   u8 is_add = 1;
8892   int ret = 0;
8893
8894   /* Parse args required to build the message */
8895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8896     {
8897       if (unformat (i, "table %d", &table_id))
8898         ;
8899       else if (unformat (i, "del"))
8900         is_add = 0;
8901       else if (unformat (i, "add"))
8902         is_add = 1;
8903       else
8904         {
8905           clib_warning ("parse error '%U'", format_unformat_error, i);
8906           return -99;
8907         }
8908     }
8909
8910   if (~0 == table_id)
8911     {
8912       errmsg ("missing table-ID");
8913       return -99;
8914     }
8915
8916   /* Construct the API message */
8917   M (MPLS_TABLE_ADD_DEL, mp);
8918
8919   mp->mt_table_id = ntohl (table_id);
8920   mp->mt_is_add = is_add;
8921
8922   /* send it... */
8923   S (mp);
8924
8925   /* Wait for a reply... */
8926   W (ret);
8927
8928   return ret;
8929 }
8930
8931 static int
8932 api_mpls_route_add_del (vat_main_t * vam)
8933 {
8934   unformat_input_t *i = vam->input;
8935   vl_api_mpls_route_add_del_t *mp;
8936   u32 sw_if_index = ~0, table_id = 0;
8937   u8 is_add = 1;
8938   u32 next_hop_weight = 1;
8939   u8 is_multipath = 0;
8940   u32 next_hop_table_id = 0;
8941   u8 next_hop_set = 0;
8942   ip4_address_t v4_next_hop_address = {
8943     .as_u32 = 0,
8944   };
8945   ip6_address_t v6_next_hop_address = { {0} };
8946   int count = 1;
8947   int j;
8948   f64 before = 0;
8949   u32 classify_table_index = ~0;
8950   u8 is_classify = 0;
8951   u8 resolve_host = 0, resolve_attached = 0;
8952   u8 is_interface_rx = 0;
8953   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8954   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8955   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8956   mpls_label_t local_label = MPLS_LABEL_INVALID;
8957   u8 is_eos = 0;
8958   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
8959
8960   /* Parse args required to build the message */
8961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8962     {
8963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8964         ;
8965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8966         ;
8967       else if (unformat (i, "%d", &local_label))
8968         ;
8969       else if (unformat (i, "eos"))
8970         is_eos = 1;
8971       else if (unformat (i, "non-eos"))
8972         is_eos = 0;
8973       else if (unformat (i, "via %U", unformat_ip4_address,
8974                          &v4_next_hop_address))
8975         {
8976           next_hop_set = 1;
8977           next_hop_proto = DPO_PROTO_IP4;
8978         }
8979       else if (unformat (i, "via %U", unformat_ip6_address,
8980                          &v6_next_hop_address))
8981         {
8982           next_hop_set = 1;
8983           next_hop_proto = DPO_PROTO_IP6;
8984         }
8985       else if (unformat (i, "weight %d", &next_hop_weight))
8986         ;
8987       else if (unformat (i, "classify %d", &classify_table_index))
8988         {
8989           is_classify = 1;
8990         }
8991       else if (unformat (i, "del"))
8992         is_add = 0;
8993       else if (unformat (i, "add"))
8994         is_add = 1;
8995       else if (unformat (i, "resolve-via-host"))
8996         resolve_host = 1;
8997       else if (unformat (i, "resolve-via-attached"))
8998         resolve_attached = 1;
8999       else if (unformat (i, "multipath"))
9000         is_multipath = 1;
9001       else if (unformat (i, "count %d", &count))
9002         ;
9003       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9004         {
9005           next_hop_set = 1;
9006           next_hop_proto = DPO_PROTO_IP4;
9007         }
9008       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9009         {
9010           next_hop_set = 1;
9011           next_hop_proto = DPO_PROTO_IP6;
9012         }
9013       else
9014         if (unformat
9015             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9016              &sw_if_index))
9017         {
9018           next_hop_set = 1;
9019           next_hop_proto = DPO_PROTO_ETHERNET;
9020           is_interface_rx = 1;
9021         }
9022       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9023         {
9024           next_hop_set = 1;
9025           next_hop_proto = DPO_PROTO_ETHERNET;
9026           is_interface_rx = 1;
9027         }
9028       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9029         next_hop_set = 1;
9030       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9031         next_hop_set = 1;
9032       else if (unformat (i, "out-label %d", &next_hop_out_label))
9033         {
9034           vl_api_fib_mpls_label_t fib_label = {
9035             .label = ntohl (next_hop_out_label),
9036             .ttl = 64,
9037             .exp = 0,
9038           };
9039           vec_add1 (next_hop_out_label_stack, fib_label);
9040         }
9041       else
9042         {
9043           clib_warning ("parse error '%U'", format_unformat_error, i);
9044           return -99;
9045         }
9046     }
9047
9048   if (!next_hop_set && !is_classify)
9049     {
9050       errmsg ("next hop / classify not set");
9051       return -99;
9052     }
9053
9054   if (MPLS_LABEL_INVALID == local_label)
9055     {
9056       errmsg ("missing label");
9057       return -99;
9058     }
9059
9060   if (count > 1)
9061     {
9062       /* Turn on async mode */
9063       vam->async_mode = 1;
9064       vam->async_errors = 0;
9065       before = vat_time_now (vam);
9066     }
9067
9068   for (j = 0; j < count; j++)
9069     {
9070       /* Construct the API message */
9071       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9072           vec_len (next_hop_out_label_stack));
9073
9074       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9075       mp->mr_table_id = ntohl (table_id);
9076
9077       mp->mr_is_add = is_add;
9078       mp->mr_next_hop_proto = next_hop_proto;
9079       mp->mr_is_classify = is_classify;
9080       mp->mr_is_multipath = is_multipath;
9081       mp->mr_is_resolve_host = resolve_host;
9082       mp->mr_is_resolve_attached = resolve_attached;
9083       mp->mr_is_interface_rx = is_interface_rx;
9084       mp->mr_next_hop_weight = next_hop_weight;
9085       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9086       mp->mr_classify_table_index = ntohl (classify_table_index);
9087       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9088       mp->mr_label = ntohl (local_label);
9089       mp->mr_eos = is_eos;
9090
9091       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9092       if (0 != mp->mr_next_hop_n_out_labels)
9093         {
9094           memcpy (mp->mr_next_hop_out_label_stack,
9095                   next_hop_out_label_stack,
9096                   vec_len (next_hop_out_label_stack) *
9097                   sizeof (vl_api_fib_mpls_label_t));
9098           vec_free (next_hop_out_label_stack);
9099         }
9100
9101       if (next_hop_set)
9102         {
9103           if (DPO_PROTO_IP4 == next_hop_proto)
9104             {
9105               clib_memcpy (mp->mr_next_hop,
9106                            &v4_next_hop_address,
9107                            sizeof (v4_next_hop_address));
9108             }
9109           else if (DPO_PROTO_IP6 == next_hop_proto)
9110
9111             {
9112               clib_memcpy (mp->mr_next_hop,
9113                            &v6_next_hop_address,
9114                            sizeof (v6_next_hop_address));
9115             }
9116         }
9117       local_label++;
9118
9119       /* send it... */
9120       S (mp);
9121       /* If we receive SIGTERM, stop now... */
9122       if (vam->do_exit)
9123         break;
9124     }
9125
9126   /* When testing multiple add/del ops, use a control-ping to sync */
9127   if (count > 1)
9128     {
9129       vl_api_control_ping_t *mp_ping;
9130       f64 after;
9131       f64 timeout;
9132
9133       /* Shut off async mode */
9134       vam->async_mode = 0;
9135
9136       MPING (CONTROL_PING, mp_ping);
9137       S (mp_ping);
9138
9139       timeout = vat_time_now (vam) + 1.0;
9140       while (vat_time_now (vam) < timeout)
9141         if (vam->result_ready == 1)
9142           goto out;
9143       vam->retval = -99;
9144
9145     out:
9146       if (vam->retval == -99)
9147         errmsg ("timeout");
9148
9149       if (vam->async_errors > 0)
9150         {
9151           errmsg ("%d asynchronous errors", vam->async_errors);
9152           vam->retval = -98;
9153         }
9154       vam->async_errors = 0;
9155       after = vat_time_now (vam);
9156
9157       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9158       if (j > 0)
9159         count = j;
9160
9161       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9162              count, after - before, count / (after - before));
9163     }
9164   else
9165     {
9166       int ret;
9167
9168       /* Wait for a reply... */
9169       W (ret);
9170       return ret;
9171     }
9172
9173   /* Return the good/bad news */
9174   return (vam->retval);
9175 }
9176
9177 static int
9178 api_mpls_ip_bind_unbind (vat_main_t * vam)
9179 {
9180   unformat_input_t *i = vam->input;
9181   vl_api_mpls_ip_bind_unbind_t *mp;
9182   u32 ip_table_id = 0;
9183   u8 is_bind = 1;
9184   u8 is_ip4 = 1;
9185   ip4_address_t v4_address;
9186   ip6_address_t v6_address;
9187   u32 address_length;
9188   u8 address_set = 0;
9189   mpls_label_t local_label = MPLS_LABEL_INVALID;
9190   int ret;
9191
9192   /* Parse args required to build the message */
9193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9194     {
9195       if (unformat (i, "%U/%d", unformat_ip4_address,
9196                     &v4_address, &address_length))
9197         {
9198           is_ip4 = 1;
9199           address_set = 1;
9200         }
9201       else if (unformat (i, "%U/%d", unformat_ip6_address,
9202                          &v6_address, &address_length))
9203         {
9204           is_ip4 = 0;
9205           address_set = 1;
9206         }
9207       else if (unformat (i, "%d", &local_label))
9208         ;
9209       else if (unformat (i, "table-id %d", &ip_table_id))
9210         ;
9211       else if (unformat (i, "unbind"))
9212         is_bind = 0;
9213       else if (unformat (i, "bind"))
9214         is_bind = 1;
9215       else
9216         {
9217           clib_warning ("parse error '%U'", format_unformat_error, i);
9218           return -99;
9219         }
9220     }
9221
9222   if (!address_set)
9223     {
9224       errmsg ("IP addres not set");
9225       return -99;
9226     }
9227
9228   if (MPLS_LABEL_INVALID == local_label)
9229     {
9230       errmsg ("missing label");
9231       return -99;
9232     }
9233
9234   /* Construct the API message */
9235   M (MPLS_IP_BIND_UNBIND, mp);
9236
9237   mp->mb_is_bind = is_bind;
9238   mp->mb_is_ip4 = is_ip4;
9239   mp->mb_ip_table_id = ntohl (ip_table_id);
9240   mp->mb_mpls_table_id = 0;
9241   mp->mb_label = ntohl (local_label);
9242   mp->mb_address_length = address_length;
9243
9244   if (is_ip4)
9245     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9246   else
9247     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9248
9249   /* send it... */
9250   S (mp);
9251
9252   /* Wait for a reply... */
9253   W (ret);
9254   return ret;
9255 }
9256
9257 static int
9258 api_sr_mpls_policy_add (vat_main_t * vam)
9259 {
9260   unformat_input_t *i = vam->input;
9261   vl_api_sr_mpls_policy_add_t *mp;
9262   u32 bsid = 0;
9263   u32 weight = 1;
9264   u8 type = 0;
9265   u8 n_segments = 0;
9266   u32 sid;
9267   u32 *segments = NULL;
9268   int ret;
9269
9270   /* Parse args required to build the message */
9271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9272     {
9273       if (unformat (i, "bsid %d", &bsid))
9274         ;
9275       else if (unformat (i, "weight %d", &weight))
9276         ;
9277       else if (unformat (i, "spray"))
9278         type = 1;
9279       else if (unformat (i, "next %d", &sid))
9280         {
9281           n_segments += 1;
9282           vec_add1 (segments, htonl (sid));
9283         }
9284       else
9285         {
9286           clib_warning ("parse error '%U'", format_unformat_error, i);
9287           return -99;
9288         }
9289     }
9290
9291   if (bsid == 0)
9292     {
9293       errmsg ("bsid not set");
9294       return -99;
9295     }
9296
9297   if (n_segments == 0)
9298     {
9299       errmsg ("no sid in segment stack");
9300       return -99;
9301     }
9302
9303   /* Construct the API message */
9304   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9305
9306   mp->bsid = htonl (bsid);
9307   mp->weight = htonl (weight);
9308   mp->type = type;
9309   mp->n_segments = n_segments;
9310   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9311   vec_free (segments);
9312
9313   /* send it... */
9314   S (mp);
9315
9316   /* Wait for a reply... */
9317   W (ret);
9318   return ret;
9319 }
9320
9321 static int
9322 api_sr_mpls_policy_del (vat_main_t * vam)
9323 {
9324   unformat_input_t *i = vam->input;
9325   vl_api_sr_mpls_policy_del_t *mp;
9326   u32 bsid = 0;
9327   int ret;
9328
9329   /* Parse args required to build the message */
9330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9331     {
9332       if (unformat (i, "bsid %d", &bsid))
9333         ;
9334       else
9335         {
9336           clib_warning ("parse error '%U'", format_unformat_error, i);
9337           return -99;
9338         }
9339     }
9340
9341   if (bsid == 0)
9342     {
9343       errmsg ("bsid not set");
9344       return -99;
9345     }
9346
9347   /* Construct the API message */
9348   M (SR_MPLS_POLICY_DEL, mp);
9349
9350   mp->bsid = htonl (bsid);
9351
9352   /* send it... */
9353   S (mp);
9354
9355   /* Wait for a reply... */
9356   W (ret);
9357   return ret;
9358 }
9359
9360 static int
9361 api_bier_table_add_del (vat_main_t * vam)
9362 {
9363   unformat_input_t *i = vam->input;
9364   vl_api_bier_table_add_del_t *mp;
9365   u8 is_add = 1;
9366   u32 set = 0, sub_domain = 0, hdr_len = 3;
9367   mpls_label_t local_label = MPLS_LABEL_INVALID;
9368   int ret;
9369
9370   /* Parse args required to build the message */
9371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9372     {
9373       if (unformat (i, "sub-domain %d", &sub_domain))
9374         ;
9375       else if (unformat (i, "set %d", &set))
9376         ;
9377       else if (unformat (i, "label %d", &local_label))
9378         ;
9379       else if (unformat (i, "hdr-len %d", &hdr_len))
9380         ;
9381       else if (unformat (i, "add"))
9382         is_add = 1;
9383       else if (unformat (i, "del"))
9384         is_add = 0;
9385       else
9386         {
9387           clib_warning ("parse error '%U'", format_unformat_error, i);
9388           return -99;
9389         }
9390     }
9391
9392   if (MPLS_LABEL_INVALID == local_label)
9393     {
9394       errmsg ("missing label\n");
9395       return -99;
9396     }
9397
9398   /* Construct the API message */
9399   M (BIER_TABLE_ADD_DEL, mp);
9400
9401   mp->bt_is_add = is_add;
9402   mp->bt_label = ntohl (local_label);
9403   mp->bt_tbl_id.bt_set = set;
9404   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9405   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9406
9407   /* send it... */
9408   S (mp);
9409
9410   /* Wait for a reply... */
9411   W (ret);
9412
9413   return (ret);
9414 }
9415
9416 static int
9417 api_bier_route_add_del (vat_main_t * vam)
9418 {
9419   unformat_input_t *i = vam->input;
9420   vl_api_bier_route_add_del_t *mp;
9421   u8 is_add = 1;
9422   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9423   ip4_address_t v4_next_hop_address;
9424   ip6_address_t v6_next_hop_address;
9425   u8 next_hop_set = 0;
9426   u8 next_hop_proto_is_ip4 = 1;
9427   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9428   int ret;
9429
9430   /* Parse args required to build the message */
9431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9432     {
9433       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9434         {
9435           next_hop_proto_is_ip4 = 1;
9436           next_hop_set = 1;
9437         }
9438       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9439         {
9440           next_hop_proto_is_ip4 = 0;
9441           next_hop_set = 1;
9442         }
9443       if (unformat (i, "sub-domain %d", &sub_domain))
9444         ;
9445       else if (unformat (i, "set %d", &set))
9446         ;
9447       else if (unformat (i, "hdr-len %d", &hdr_len))
9448         ;
9449       else if (unformat (i, "bp %d", &bp))
9450         ;
9451       else if (unformat (i, "add"))
9452         is_add = 1;
9453       else if (unformat (i, "del"))
9454         is_add = 0;
9455       else if (unformat (i, "out-label %d", &next_hop_out_label))
9456         ;
9457       else
9458         {
9459           clib_warning ("parse error '%U'", format_unformat_error, i);
9460           return -99;
9461         }
9462     }
9463
9464   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9465     {
9466       errmsg ("next hop / label set\n");
9467       return -99;
9468     }
9469   if (0 == bp)
9470     {
9471       errmsg ("bit=position not set\n");
9472       return -99;
9473     }
9474
9475   /* Construct the API message */
9476   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9477
9478   mp->br_is_add = is_add;
9479   mp->br_tbl_id.bt_set = set;
9480   mp->br_tbl_id.bt_sub_domain = sub_domain;
9481   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9482   mp->br_bp = ntohs (bp);
9483   mp->br_n_paths = 1;
9484   mp->br_paths[0].n_labels = 1;
9485   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9486   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9487
9488   if (next_hop_proto_is_ip4)
9489     {
9490       clib_memcpy (mp->br_paths[0].next_hop,
9491                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9492     }
9493   else
9494     {
9495       clib_memcpy (mp->br_paths[0].next_hop,
9496                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9497     }
9498
9499   /* send it... */
9500   S (mp);
9501
9502   /* Wait for a reply... */
9503   W (ret);
9504
9505   return (ret);
9506 }
9507
9508 static int
9509 api_proxy_arp_add_del (vat_main_t * vam)
9510 {
9511   unformat_input_t *i = vam->input;
9512   vl_api_proxy_arp_add_del_t *mp;
9513   u32 vrf_id = 0;
9514   u8 is_add = 1;
9515   ip4_address_t lo, hi;
9516   u8 range_set = 0;
9517   int ret;
9518
9519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9520     {
9521       if (unformat (i, "vrf %d", &vrf_id))
9522         ;
9523       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9524                          unformat_ip4_address, &hi))
9525         range_set = 1;
9526       else if (unformat (i, "del"))
9527         is_add = 0;
9528       else
9529         {
9530           clib_warning ("parse error '%U'", format_unformat_error, i);
9531           return -99;
9532         }
9533     }
9534
9535   if (range_set == 0)
9536     {
9537       errmsg ("address range not set");
9538       return -99;
9539     }
9540
9541   M (PROXY_ARP_ADD_DEL, mp);
9542
9543   mp->proxy.vrf_id = ntohl (vrf_id);
9544   mp->is_add = is_add;
9545   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9546   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9547
9548   S (mp);
9549   W (ret);
9550   return ret;
9551 }
9552
9553 static int
9554 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9555 {
9556   unformat_input_t *i = vam->input;
9557   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9558   u32 sw_if_index;
9559   u8 enable = 1;
9560   u8 sw_if_index_set = 0;
9561   int ret;
9562
9563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9564     {
9565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9566         sw_if_index_set = 1;
9567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9568         sw_if_index_set = 1;
9569       else if (unformat (i, "enable"))
9570         enable = 1;
9571       else if (unformat (i, "disable"))
9572         enable = 0;
9573       else
9574         {
9575           clib_warning ("parse error '%U'", format_unformat_error, i);
9576           return -99;
9577         }
9578     }
9579
9580   if (sw_if_index_set == 0)
9581     {
9582       errmsg ("missing interface name or sw_if_index");
9583       return -99;
9584     }
9585
9586   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9587
9588   mp->sw_if_index = ntohl (sw_if_index);
9589   mp->enable_disable = enable;
9590
9591   S (mp);
9592   W (ret);
9593   return ret;
9594 }
9595
9596 static int
9597 api_mpls_tunnel_add_del (vat_main_t * vam)
9598 {
9599   unformat_input_t *i = vam->input;
9600   vl_api_mpls_tunnel_add_del_t *mp;
9601
9602   u8 is_add = 1;
9603   u8 l2_only = 0;
9604   u32 sw_if_index = ~0;
9605   u32 next_hop_sw_if_index = ~0;
9606   u32 next_hop_proto_is_ip4 = 1;
9607
9608   u32 next_hop_table_id = 0;
9609   ip4_address_t v4_next_hop_address = {
9610     .as_u32 = 0,
9611   };
9612   ip6_address_t v6_next_hop_address = { {0} };
9613   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9614   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9615   int ret;
9616
9617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9618     {
9619       if (unformat (i, "add"))
9620         is_add = 1;
9621       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9622         is_add = 0;
9623       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9624         ;
9625       else if (unformat (i, "via %U",
9626                          unformat_ip4_address, &v4_next_hop_address))
9627         {
9628           next_hop_proto_is_ip4 = 1;
9629         }
9630       else if (unformat (i, "via %U",
9631                          unformat_ip6_address, &v6_next_hop_address))
9632         {
9633           next_hop_proto_is_ip4 = 0;
9634         }
9635       else if (unformat (i, "via-label %d", &next_hop_via_label))
9636         ;
9637       else if (unformat (i, "l2-only"))
9638         l2_only = 1;
9639       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9640         ;
9641       else if (unformat (i, "out-label %d", &next_hop_out_label))
9642         vec_add1 (labels, ntohl (next_hop_out_label));
9643       else
9644         {
9645           clib_warning ("parse error '%U'", format_unformat_error, i);
9646           return -99;
9647         }
9648     }
9649
9650   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9651
9652   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9653   mp->mt_sw_if_index = ntohl (sw_if_index);
9654   mp->mt_is_add = is_add;
9655   mp->mt_l2_only = l2_only;
9656   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9657   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9658   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9659
9660   mp->mt_next_hop_n_out_labels = vec_len (labels);
9661
9662   if (0 != mp->mt_next_hop_n_out_labels)
9663     {
9664       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9665                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9666       vec_free (labels);
9667     }
9668
9669   if (next_hop_proto_is_ip4)
9670     {
9671       clib_memcpy (mp->mt_next_hop,
9672                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9673     }
9674   else
9675     {
9676       clib_memcpy (mp->mt_next_hop,
9677                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9678     }
9679
9680   S (mp);
9681   W (ret);
9682   return ret;
9683 }
9684
9685 static int
9686 api_sw_interface_set_unnumbered (vat_main_t * vam)
9687 {
9688   unformat_input_t *i = vam->input;
9689   vl_api_sw_interface_set_unnumbered_t *mp;
9690   u32 sw_if_index;
9691   u32 unnum_sw_index = ~0;
9692   u8 is_add = 1;
9693   u8 sw_if_index_set = 0;
9694   int ret;
9695
9696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9697     {
9698       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9699         sw_if_index_set = 1;
9700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9701         sw_if_index_set = 1;
9702       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9703         ;
9704       else if (unformat (i, "del"))
9705         is_add = 0;
9706       else
9707         {
9708           clib_warning ("parse error '%U'", format_unformat_error, i);
9709           return -99;
9710         }
9711     }
9712
9713   if (sw_if_index_set == 0)
9714     {
9715       errmsg ("missing interface name or sw_if_index");
9716       return -99;
9717     }
9718
9719   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9720
9721   mp->sw_if_index = ntohl (sw_if_index);
9722   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9723   mp->is_add = is_add;
9724
9725   S (mp);
9726   W (ret);
9727   return ret;
9728 }
9729
9730 static int
9731 api_ip_neighbor_add_del (vat_main_t * vam)
9732 {
9733   unformat_input_t *i = vam->input;
9734   vl_api_ip_neighbor_add_del_t *mp;
9735   u32 sw_if_index;
9736   u8 sw_if_index_set = 0;
9737   u8 is_add = 1;
9738   u8 is_static = 0;
9739   u8 is_no_fib_entry = 0;
9740   u8 mac_address[6];
9741   u8 mac_set = 0;
9742   u8 v4_address_set = 0;
9743   u8 v6_address_set = 0;
9744   ip4_address_t v4address;
9745   ip6_address_t v6address;
9746   int ret;
9747
9748   memset (mac_address, 0, sizeof (mac_address));
9749
9750   /* Parse args required to build the message */
9751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9754         {
9755           mac_set = 1;
9756         }
9757       else if (unformat (i, "del"))
9758         is_add = 0;
9759       else
9760         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9761         sw_if_index_set = 1;
9762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9763         sw_if_index_set = 1;
9764       else if (unformat (i, "is_static"))
9765         is_static = 1;
9766       else if (unformat (i, "no-fib-entry"))
9767         is_no_fib_entry = 1;
9768       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9769         v4_address_set = 1;
9770       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9771         v6_address_set = 1;
9772       else
9773         {
9774           clib_warning ("parse error '%U'", format_unformat_error, i);
9775           return -99;
9776         }
9777     }
9778
9779   if (sw_if_index_set == 0)
9780     {
9781       errmsg ("missing interface name or sw_if_index");
9782       return -99;
9783     }
9784   if (v4_address_set && v6_address_set)
9785     {
9786       errmsg ("both v4 and v6 addresses set");
9787       return -99;
9788     }
9789   if (!v4_address_set && !v6_address_set)
9790     {
9791       errmsg ("no address set");
9792       return -99;
9793     }
9794
9795   /* Construct the API message */
9796   M (IP_NEIGHBOR_ADD_DEL, mp);
9797
9798   mp->sw_if_index = ntohl (sw_if_index);
9799   mp->is_add = is_add;
9800   mp->is_static = is_static;
9801   mp->is_no_adj_fib = is_no_fib_entry;
9802   if (mac_set)
9803     clib_memcpy (mp->mac_address, mac_address, 6);
9804   if (v6_address_set)
9805     {
9806       mp->is_ipv6 = 1;
9807       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9808     }
9809   else
9810     {
9811       /* mp->is_ipv6 = 0; via memset in M macro above */
9812       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9813     }
9814
9815   /* send it... */
9816   S (mp);
9817
9818   /* Wait for a reply, return good/bad news  */
9819   W (ret);
9820   return ret;
9821 }
9822
9823 static int
9824 api_create_vlan_subif (vat_main_t * vam)
9825 {
9826   unformat_input_t *i = vam->input;
9827   vl_api_create_vlan_subif_t *mp;
9828   u32 sw_if_index;
9829   u8 sw_if_index_set = 0;
9830   u32 vlan_id;
9831   u8 vlan_id_set = 0;
9832   int ret;
9833
9834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9835     {
9836       if (unformat (i, "sw_if_index %d", &sw_if_index))
9837         sw_if_index_set = 1;
9838       else
9839         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9840         sw_if_index_set = 1;
9841       else if (unformat (i, "vlan %d", &vlan_id))
9842         vlan_id_set = 1;
9843       else
9844         {
9845           clib_warning ("parse error '%U'", format_unformat_error, i);
9846           return -99;
9847         }
9848     }
9849
9850   if (sw_if_index_set == 0)
9851     {
9852       errmsg ("missing interface name or sw_if_index");
9853       return -99;
9854     }
9855
9856   if (vlan_id_set == 0)
9857     {
9858       errmsg ("missing vlan_id");
9859       return -99;
9860     }
9861   M (CREATE_VLAN_SUBIF, mp);
9862
9863   mp->sw_if_index = ntohl (sw_if_index);
9864   mp->vlan_id = ntohl (vlan_id);
9865
9866   S (mp);
9867   W (ret);
9868   return ret;
9869 }
9870
9871 #define foreach_create_subif_bit                \
9872 _(no_tags)                                      \
9873 _(one_tag)                                      \
9874 _(two_tags)                                     \
9875 _(dot1ad)                                       \
9876 _(exact_match)                                  \
9877 _(default_sub)                                  \
9878 _(outer_vlan_id_any)                            \
9879 _(inner_vlan_id_any)
9880
9881 static int
9882 api_create_subif (vat_main_t * vam)
9883 {
9884   unformat_input_t *i = vam->input;
9885   vl_api_create_subif_t *mp;
9886   u32 sw_if_index;
9887   u8 sw_if_index_set = 0;
9888   u32 sub_id;
9889   u8 sub_id_set = 0;
9890   u32 no_tags = 0;
9891   u32 one_tag = 0;
9892   u32 two_tags = 0;
9893   u32 dot1ad = 0;
9894   u32 exact_match = 0;
9895   u32 default_sub = 0;
9896   u32 outer_vlan_id_any = 0;
9897   u32 inner_vlan_id_any = 0;
9898   u32 tmp;
9899   u16 outer_vlan_id = 0;
9900   u16 inner_vlan_id = 0;
9901   int ret;
9902
9903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9904     {
9905       if (unformat (i, "sw_if_index %d", &sw_if_index))
9906         sw_if_index_set = 1;
9907       else
9908         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9909         sw_if_index_set = 1;
9910       else if (unformat (i, "sub_id %d", &sub_id))
9911         sub_id_set = 1;
9912       else if (unformat (i, "outer_vlan_id %d", &tmp))
9913         outer_vlan_id = tmp;
9914       else if (unformat (i, "inner_vlan_id %d", &tmp))
9915         inner_vlan_id = tmp;
9916
9917 #define _(a) else if (unformat (i, #a)) a = 1 ;
9918       foreach_create_subif_bit
9919 #undef _
9920         else
9921         {
9922           clib_warning ("parse error '%U'", format_unformat_error, i);
9923           return -99;
9924         }
9925     }
9926
9927   if (sw_if_index_set == 0)
9928     {
9929       errmsg ("missing interface name or sw_if_index");
9930       return -99;
9931     }
9932
9933   if (sub_id_set == 0)
9934     {
9935       errmsg ("missing sub_id");
9936       return -99;
9937     }
9938   M (CREATE_SUBIF, mp);
9939
9940   mp->sw_if_index = ntohl (sw_if_index);
9941   mp->sub_id = ntohl (sub_id);
9942
9943 #define _(a) mp->a = a;
9944   foreach_create_subif_bit;
9945 #undef _
9946
9947   mp->outer_vlan_id = ntohs (outer_vlan_id);
9948   mp->inner_vlan_id = ntohs (inner_vlan_id);
9949
9950   S (mp);
9951   W (ret);
9952   return ret;
9953 }
9954
9955 static int
9956 api_oam_add_del (vat_main_t * vam)
9957 {
9958   unformat_input_t *i = vam->input;
9959   vl_api_oam_add_del_t *mp;
9960   u32 vrf_id = 0;
9961   u8 is_add = 1;
9962   ip4_address_t src, dst;
9963   u8 src_set = 0;
9964   u8 dst_set = 0;
9965   int ret;
9966
9967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9968     {
9969       if (unformat (i, "vrf %d", &vrf_id))
9970         ;
9971       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9972         src_set = 1;
9973       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9974         dst_set = 1;
9975       else if (unformat (i, "del"))
9976         is_add = 0;
9977       else
9978         {
9979           clib_warning ("parse error '%U'", format_unformat_error, i);
9980           return -99;
9981         }
9982     }
9983
9984   if (src_set == 0)
9985     {
9986       errmsg ("missing src addr");
9987       return -99;
9988     }
9989
9990   if (dst_set == 0)
9991     {
9992       errmsg ("missing dst addr");
9993       return -99;
9994     }
9995
9996   M (OAM_ADD_DEL, mp);
9997
9998   mp->vrf_id = ntohl (vrf_id);
9999   mp->is_add = is_add;
10000   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10001   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10002
10003   S (mp);
10004   W (ret);
10005   return ret;
10006 }
10007
10008 static int
10009 api_reset_fib (vat_main_t * vam)
10010 {
10011   unformat_input_t *i = vam->input;
10012   vl_api_reset_fib_t *mp;
10013   u32 vrf_id = 0;
10014   u8 is_ipv6 = 0;
10015   u8 vrf_id_set = 0;
10016
10017   int ret;
10018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10019     {
10020       if (unformat (i, "vrf %d", &vrf_id))
10021         vrf_id_set = 1;
10022       else if (unformat (i, "ipv6"))
10023         is_ipv6 = 1;
10024       else
10025         {
10026           clib_warning ("parse error '%U'", format_unformat_error, i);
10027           return -99;
10028         }
10029     }
10030
10031   if (vrf_id_set == 0)
10032     {
10033       errmsg ("missing vrf id");
10034       return -99;
10035     }
10036
10037   M (RESET_FIB, mp);
10038
10039   mp->vrf_id = ntohl (vrf_id);
10040   mp->is_ipv6 = is_ipv6;
10041
10042   S (mp);
10043   W (ret);
10044   return ret;
10045 }
10046
10047 static int
10048 api_dhcp_proxy_config (vat_main_t * vam)
10049 {
10050   unformat_input_t *i = vam->input;
10051   vl_api_dhcp_proxy_config_t *mp;
10052   u32 rx_vrf_id = 0;
10053   u32 server_vrf_id = 0;
10054   u8 is_add = 1;
10055   u8 v4_address_set = 0;
10056   u8 v6_address_set = 0;
10057   ip4_address_t v4address;
10058   ip6_address_t v6address;
10059   u8 v4_src_address_set = 0;
10060   u8 v6_src_address_set = 0;
10061   ip4_address_t v4srcaddress;
10062   ip6_address_t v6srcaddress;
10063   int ret;
10064
10065   /* Parse args required to build the message */
10066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10067     {
10068       if (unformat (i, "del"))
10069         is_add = 0;
10070       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10071         ;
10072       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10073         ;
10074       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10075         v4_address_set = 1;
10076       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10077         v6_address_set = 1;
10078       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10079         v4_src_address_set = 1;
10080       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10081         v6_src_address_set = 1;
10082       else
10083         break;
10084     }
10085
10086   if (v4_address_set && v6_address_set)
10087     {
10088       errmsg ("both v4 and v6 server addresses set");
10089       return -99;
10090     }
10091   if (!v4_address_set && !v6_address_set)
10092     {
10093       errmsg ("no server addresses set");
10094       return -99;
10095     }
10096
10097   if (v4_src_address_set && v6_src_address_set)
10098     {
10099       errmsg ("both v4 and v6  src addresses set");
10100       return -99;
10101     }
10102   if (!v4_src_address_set && !v6_src_address_set)
10103     {
10104       errmsg ("no src addresses set");
10105       return -99;
10106     }
10107
10108   if (!(v4_src_address_set && v4_address_set) &&
10109       !(v6_src_address_set && v6_address_set))
10110     {
10111       errmsg ("no matching server and src addresses set");
10112       return -99;
10113     }
10114
10115   /* Construct the API message */
10116   M (DHCP_PROXY_CONFIG, mp);
10117
10118   mp->is_add = is_add;
10119   mp->rx_vrf_id = ntohl (rx_vrf_id);
10120   mp->server_vrf_id = ntohl (server_vrf_id);
10121   if (v6_address_set)
10122     {
10123       mp->is_ipv6 = 1;
10124       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10125       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10126     }
10127   else
10128     {
10129       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10130       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10131     }
10132
10133   /* send it... */
10134   S (mp);
10135
10136   /* Wait for a reply, return good/bad news  */
10137   W (ret);
10138   return ret;
10139 }
10140
10141 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10142 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10143
10144 static void
10145 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10146 {
10147   vat_main_t *vam = &vat_main;
10148   u32 i, count = mp->count;
10149   vl_api_dhcp_server_t *s;
10150
10151   if (mp->is_ipv6)
10152     print (vam->ofp,
10153            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10154            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10155            ntohl (mp->rx_vrf_id),
10156            format_ip6_address, mp->dhcp_src_address,
10157            mp->vss_type, mp->vss_vpn_ascii_id,
10158            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10159   else
10160     print (vam->ofp,
10161            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10162            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10163            ntohl (mp->rx_vrf_id),
10164            format_ip4_address, mp->dhcp_src_address,
10165            mp->vss_type, mp->vss_vpn_ascii_id,
10166            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10167
10168   for (i = 0; i < count; i++)
10169     {
10170       s = &mp->servers[i];
10171
10172       if (mp->is_ipv6)
10173         print (vam->ofp,
10174                " Server Table-ID %d, Server Address %U",
10175                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10176       else
10177         print (vam->ofp,
10178                " Server Table-ID %d, Server Address %U",
10179                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10180     }
10181 }
10182
10183 static void vl_api_dhcp_proxy_details_t_handler_json
10184   (vl_api_dhcp_proxy_details_t * mp)
10185 {
10186   vat_main_t *vam = &vat_main;
10187   vat_json_node_t *node = NULL;
10188   u32 i, count = mp->count;
10189   struct in_addr ip4;
10190   struct in6_addr ip6;
10191   vl_api_dhcp_server_t *s;
10192
10193   if (VAT_JSON_ARRAY != vam->json_tree.type)
10194     {
10195       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10196       vat_json_init_array (&vam->json_tree);
10197     }
10198   node = vat_json_array_add (&vam->json_tree);
10199
10200   vat_json_init_object (node);
10201   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10202   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10203                              sizeof (mp->vss_type));
10204   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10205                                    mp->vss_vpn_ascii_id);
10206   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10207   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10208
10209   if (mp->is_ipv6)
10210     {
10211       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10212       vat_json_object_add_ip6 (node, "src_address", ip6);
10213     }
10214   else
10215     {
10216       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10217       vat_json_object_add_ip4 (node, "src_address", ip4);
10218     }
10219
10220   for (i = 0; i < count; i++)
10221     {
10222       s = &mp->servers[i];
10223
10224       vat_json_object_add_uint (node, "server-table-id",
10225                                 ntohl (s->server_vrf_id));
10226
10227       if (mp->is_ipv6)
10228         {
10229           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10230           vat_json_object_add_ip4 (node, "src_address", ip4);
10231         }
10232       else
10233         {
10234           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10235           vat_json_object_add_ip6 (node, "server_address", ip6);
10236         }
10237     }
10238 }
10239
10240 static int
10241 api_dhcp_proxy_dump (vat_main_t * vam)
10242 {
10243   unformat_input_t *i = vam->input;
10244   vl_api_control_ping_t *mp_ping;
10245   vl_api_dhcp_proxy_dump_t *mp;
10246   u8 is_ipv6 = 0;
10247   int ret;
10248
10249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10250     {
10251       if (unformat (i, "ipv6"))
10252         is_ipv6 = 1;
10253       else
10254         {
10255           clib_warning ("parse error '%U'", format_unformat_error, i);
10256           return -99;
10257         }
10258     }
10259
10260   M (DHCP_PROXY_DUMP, mp);
10261
10262   mp->is_ip6 = is_ipv6;
10263   S (mp);
10264
10265   /* Use a control ping for synchronization */
10266   MPING (CONTROL_PING, mp_ping);
10267   S (mp_ping);
10268
10269   W (ret);
10270   return ret;
10271 }
10272
10273 static int
10274 api_dhcp_proxy_set_vss (vat_main_t * vam)
10275 {
10276   unformat_input_t *i = vam->input;
10277   vl_api_dhcp_proxy_set_vss_t *mp;
10278   u8 is_ipv6 = 0;
10279   u8 is_add = 1;
10280   u32 tbl_id = ~0;
10281   u8 vss_type = VSS_TYPE_DEFAULT;
10282   u8 *vpn_ascii_id = 0;
10283   u32 oui = 0;
10284   u32 fib_id = 0;
10285   int ret;
10286
10287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10288     {
10289       if (unformat (i, "tbl_id %d", &tbl_id))
10290         ;
10291       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10292         vss_type = VSS_TYPE_ASCII;
10293       else if (unformat (i, "fib_id %d", &fib_id))
10294         vss_type = VSS_TYPE_VPN_ID;
10295       else if (unformat (i, "oui %d", &oui))
10296         vss_type = VSS_TYPE_VPN_ID;
10297       else if (unformat (i, "ipv6"))
10298         is_ipv6 = 1;
10299       else if (unformat (i, "del"))
10300         is_add = 0;
10301       else
10302         break;
10303     }
10304
10305   if (tbl_id == ~0)
10306     {
10307       errmsg ("missing tbl_id ");
10308       vec_free (vpn_ascii_id);
10309       return -99;
10310     }
10311
10312   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10313     {
10314       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10315       vec_free (vpn_ascii_id);
10316       return -99;
10317     }
10318
10319   M (DHCP_PROXY_SET_VSS, mp);
10320   mp->tbl_id = ntohl (tbl_id);
10321   mp->vss_type = vss_type;
10322   if (vpn_ascii_id)
10323     {
10324       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10325       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10326     }
10327   mp->vpn_index = ntohl (fib_id);
10328   mp->oui = ntohl (oui);
10329   mp->is_ipv6 = is_ipv6;
10330   mp->is_add = is_add;
10331
10332   S (mp);
10333   W (ret);
10334
10335   vec_free (vpn_ascii_id);
10336   return ret;
10337 }
10338
10339 static int
10340 api_dhcp_client_config (vat_main_t * vam)
10341 {
10342   unformat_input_t *i = vam->input;
10343   vl_api_dhcp_client_config_t *mp;
10344   u32 sw_if_index;
10345   u8 sw_if_index_set = 0;
10346   u8 is_add = 1;
10347   u8 *hostname = 0;
10348   u8 disable_event = 0;
10349   int ret;
10350
10351   /* Parse args required to build the message */
10352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10353     {
10354       if (unformat (i, "del"))
10355         is_add = 0;
10356       else
10357         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10358         sw_if_index_set = 1;
10359       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10360         sw_if_index_set = 1;
10361       else if (unformat (i, "hostname %s", &hostname))
10362         ;
10363       else if (unformat (i, "disable_event"))
10364         disable_event = 1;
10365       else
10366         break;
10367     }
10368
10369   if (sw_if_index_set == 0)
10370     {
10371       errmsg ("missing interface name or sw_if_index");
10372       return -99;
10373     }
10374
10375   if (vec_len (hostname) > 63)
10376     {
10377       errmsg ("hostname too long");
10378     }
10379   vec_add1 (hostname, 0);
10380
10381   /* Construct the API message */
10382   M (DHCP_CLIENT_CONFIG, mp);
10383
10384   mp->is_add = is_add;
10385   mp->client.sw_if_index = htonl (sw_if_index);
10386   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10387   vec_free (hostname);
10388   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10389   mp->client.pid = htonl (getpid ());
10390
10391   /* send it... */
10392   S (mp);
10393
10394   /* Wait for a reply, return good/bad news  */
10395   W (ret);
10396   return ret;
10397 }
10398
10399 static int
10400 api_set_ip_flow_hash (vat_main_t * vam)
10401 {
10402   unformat_input_t *i = vam->input;
10403   vl_api_set_ip_flow_hash_t *mp;
10404   u32 vrf_id = 0;
10405   u8 is_ipv6 = 0;
10406   u8 vrf_id_set = 0;
10407   u8 src = 0;
10408   u8 dst = 0;
10409   u8 sport = 0;
10410   u8 dport = 0;
10411   u8 proto = 0;
10412   u8 reverse = 0;
10413   int ret;
10414
10415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10416     {
10417       if (unformat (i, "vrf %d", &vrf_id))
10418         vrf_id_set = 1;
10419       else if (unformat (i, "ipv6"))
10420         is_ipv6 = 1;
10421       else if (unformat (i, "src"))
10422         src = 1;
10423       else if (unformat (i, "dst"))
10424         dst = 1;
10425       else if (unformat (i, "sport"))
10426         sport = 1;
10427       else if (unformat (i, "dport"))
10428         dport = 1;
10429       else if (unformat (i, "proto"))
10430         proto = 1;
10431       else if (unformat (i, "reverse"))
10432         reverse = 1;
10433
10434       else
10435         {
10436           clib_warning ("parse error '%U'", format_unformat_error, i);
10437           return -99;
10438         }
10439     }
10440
10441   if (vrf_id_set == 0)
10442     {
10443       errmsg ("missing vrf id");
10444       return -99;
10445     }
10446
10447   M (SET_IP_FLOW_HASH, mp);
10448   mp->src = src;
10449   mp->dst = dst;
10450   mp->sport = sport;
10451   mp->dport = dport;
10452   mp->proto = proto;
10453   mp->reverse = reverse;
10454   mp->vrf_id = ntohl (vrf_id);
10455   mp->is_ipv6 = is_ipv6;
10456
10457   S (mp);
10458   W (ret);
10459   return ret;
10460 }
10461
10462 static int
10463 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10464 {
10465   unformat_input_t *i = vam->input;
10466   vl_api_sw_interface_ip6_enable_disable_t *mp;
10467   u32 sw_if_index;
10468   u8 sw_if_index_set = 0;
10469   u8 enable = 0;
10470   int ret;
10471
10472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10473     {
10474       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10475         sw_if_index_set = 1;
10476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10477         sw_if_index_set = 1;
10478       else if (unformat (i, "enable"))
10479         enable = 1;
10480       else if (unformat (i, "disable"))
10481         enable = 0;
10482       else
10483         {
10484           clib_warning ("parse error '%U'", format_unformat_error, i);
10485           return -99;
10486         }
10487     }
10488
10489   if (sw_if_index_set == 0)
10490     {
10491       errmsg ("missing interface name or sw_if_index");
10492       return -99;
10493     }
10494
10495   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10496
10497   mp->sw_if_index = ntohl (sw_if_index);
10498   mp->enable = enable;
10499
10500   S (mp);
10501   W (ret);
10502   return ret;
10503 }
10504
10505 static int
10506 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10507 {
10508   unformat_input_t *i = vam->input;
10509   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10510   u32 sw_if_index;
10511   u8 sw_if_index_set = 0;
10512   u8 v6_address_set = 0;
10513   ip6_address_t v6address;
10514   int ret;
10515
10516   /* Parse args required to build the message */
10517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10518     {
10519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10520         sw_if_index_set = 1;
10521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10522         sw_if_index_set = 1;
10523       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10524         v6_address_set = 1;
10525       else
10526         break;
10527     }
10528
10529   if (sw_if_index_set == 0)
10530     {
10531       errmsg ("missing interface name or sw_if_index");
10532       return -99;
10533     }
10534   if (!v6_address_set)
10535     {
10536       errmsg ("no address set");
10537       return -99;
10538     }
10539
10540   /* Construct the API message */
10541   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10542
10543   mp->sw_if_index = ntohl (sw_if_index);
10544   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10545
10546   /* send it... */
10547   S (mp);
10548
10549   /* Wait for a reply, return good/bad news  */
10550   W (ret);
10551   return ret;
10552 }
10553
10554 static int
10555 api_ip6nd_proxy_add_del (vat_main_t * vam)
10556 {
10557   unformat_input_t *i = vam->input;
10558   vl_api_ip6nd_proxy_add_del_t *mp;
10559   u32 sw_if_index = ~0;
10560   u8 v6_address_set = 0;
10561   ip6_address_t v6address;
10562   u8 is_del = 0;
10563   int ret;
10564
10565   /* Parse args required to build the message */
10566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10567     {
10568       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10569         ;
10570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10571         ;
10572       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10573         v6_address_set = 1;
10574       if (unformat (i, "del"))
10575         is_del = 1;
10576       else
10577         {
10578           clib_warning ("parse error '%U'", format_unformat_error, i);
10579           return -99;
10580         }
10581     }
10582
10583   if (sw_if_index == ~0)
10584     {
10585       errmsg ("missing interface name or sw_if_index");
10586       return -99;
10587     }
10588   if (!v6_address_set)
10589     {
10590       errmsg ("no address set");
10591       return -99;
10592     }
10593
10594   /* Construct the API message */
10595   M (IP6ND_PROXY_ADD_DEL, mp);
10596
10597   mp->is_del = is_del;
10598   mp->sw_if_index = ntohl (sw_if_index);
10599   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10600
10601   /* send it... */
10602   S (mp);
10603
10604   /* Wait for a reply, return good/bad news  */
10605   W (ret);
10606   return ret;
10607 }
10608
10609 static int
10610 api_ip6nd_proxy_dump (vat_main_t * vam)
10611 {
10612   vl_api_ip6nd_proxy_dump_t *mp;
10613   vl_api_control_ping_t *mp_ping;
10614   int ret;
10615
10616   M (IP6ND_PROXY_DUMP, mp);
10617
10618   S (mp);
10619
10620   /* Use a control ping for synchronization */
10621   MPING (CONTROL_PING, mp_ping);
10622   S (mp_ping);
10623
10624   W (ret);
10625   return ret;
10626 }
10627
10628 static void vl_api_ip6nd_proxy_details_t_handler
10629   (vl_api_ip6nd_proxy_details_t * mp)
10630 {
10631   vat_main_t *vam = &vat_main;
10632
10633   print (vam->ofp, "host %U sw_if_index %d",
10634          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10635 }
10636
10637 static void vl_api_ip6nd_proxy_details_t_handler_json
10638   (vl_api_ip6nd_proxy_details_t * mp)
10639 {
10640   vat_main_t *vam = &vat_main;
10641   struct in6_addr ip6;
10642   vat_json_node_t *node = NULL;
10643
10644   if (VAT_JSON_ARRAY != vam->json_tree.type)
10645     {
10646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10647       vat_json_init_array (&vam->json_tree);
10648     }
10649   node = vat_json_array_add (&vam->json_tree);
10650
10651   vat_json_init_object (node);
10652   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10653
10654   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10655   vat_json_object_add_ip6 (node, "host", ip6);
10656 }
10657
10658 static int
10659 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10660 {
10661   unformat_input_t *i = vam->input;
10662   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10663   u32 sw_if_index;
10664   u8 sw_if_index_set = 0;
10665   u32 address_length = 0;
10666   u8 v6_address_set = 0;
10667   ip6_address_t v6address;
10668   u8 use_default = 0;
10669   u8 no_advertise = 0;
10670   u8 off_link = 0;
10671   u8 no_autoconfig = 0;
10672   u8 no_onlink = 0;
10673   u8 is_no = 0;
10674   u32 val_lifetime = 0;
10675   u32 pref_lifetime = 0;
10676   int ret;
10677
10678   /* Parse args required to build the message */
10679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10682         sw_if_index_set = 1;
10683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10684         sw_if_index_set = 1;
10685       else if (unformat (i, "%U/%d",
10686                          unformat_ip6_address, &v6address, &address_length))
10687         v6_address_set = 1;
10688       else if (unformat (i, "val_life %d", &val_lifetime))
10689         ;
10690       else if (unformat (i, "pref_life %d", &pref_lifetime))
10691         ;
10692       else if (unformat (i, "def"))
10693         use_default = 1;
10694       else if (unformat (i, "noadv"))
10695         no_advertise = 1;
10696       else if (unformat (i, "offl"))
10697         off_link = 1;
10698       else if (unformat (i, "noauto"))
10699         no_autoconfig = 1;
10700       else if (unformat (i, "nolink"))
10701         no_onlink = 1;
10702       else if (unformat (i, "isno"))
10703         is_no = 1;
10704       else
10705         {
10706           clib_warning ("parse error '%U'", format_unformat_error, i);
10707           return -99;
10708         }
10709     }
10710
10711   if (sw_if_index_set == 0)
10712     {
10713       errmsg ("missing interface name or sw_if_index");
10714       return -99;
10715     }
10716   if (!v6_address_set)
10717     {
10718       errmsg ("no address set");
10719       return -99;
10720     }
10721
10722   /* Construct the API message */
10723   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10724
10725   mp->sw_if_index = ntohl (sw_if_index);
10726   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10727   mp->address_length = address_length;
10728   mp->use_default = use_default;
10729   mp->no_advertise = no_advertise;
10730   mp->off_link = off_link;
10731   mp->no_autoconfig = no_autoconfig;
10732   mp->no_onlink = no_onlink;
10733   mp->is_no = is_no;
10734   mp->val_lifetime = ntohl (val_lifetime);
10735   mp->pref_lifetime = ntohl (pref_lifetime);
10736
10737   /* send it... */
10738   S (mp);
10739
10740   /* Wait for a reply, return good/bad news  */
10741   W (ret);
10742   return ret;
10743 }
10744
10745 static int
10746 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10747 {
10748   unformat_input_t *i = vam->input;
10749   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10750   u32 sw_if_index;
10751   u8 sw_if_index_set = 0;
10752   u8 suppress = 0;
10753   u8 managed = 0;
10754   u8 other = 0;
10755   u8 ll_option = 0;
10756   u8 send_unicast = 0;
10757   u8 cease = 0;
10758   u8 is_no = 0;
10759   u8 default_router = 0;
10760   u32 max_interval = 0;
10761   u32 min_interval = 0;
10762   u32 lifetime = 0;
10763   u32 initial_count = 0;
10764   u32 initial_interval = 0;
10765   int ret;
10766
10767
10768   /* Parse args required to build the message */
10769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10772         sw_if_index_set = 1;
10773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10774         sw_if_index_set = 1;
10775       else if (unformat (i, "maxint %d", &max_interval))
10776         ;
10777       else if (unformat (i, "minint %d", &min_interval))
10778         ;
10779       else if (unformat (i, "life %d", &lifetime))
10780         ;
10781       else if (unformat (i, "count %d", &initial_count))
10782         ;
10783       else if (unformat (i, "interval %d", &initial_interval))
10784         ;
10785       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10786         suppress = 1;
10787       else if (unformat (i, "managed"))
10788         managed = 1;
10789       else if (unformat (i, "other"))
10790         other = 1;
10791       else if (unformat (i, "ll"))
10792         ll_option = 1;
10793       else if (unformat (i, "send"))
10794         send_unicast = 1;
10795       else if (unformat (i, "cease"))
10796         cease = 1;
10797       else if (unformat (i, "isno"))
10798         is_no = 1;
10799       else if (unformat (i, "def"))
10800         default_router = 1;
10801       else
10802         {
10803           clib_warning ("parse error '%U'", format_unformat_error, i);
10804           return -99;
10805         }
10806     }
10807
10808   if (sw_if_index_set == 0)
10809     {
10810       errmsg ("missing interface name or sw_if_index");
10811       return -99;
10812     }
10813
10814   /* Construct the API message */
10815   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10816
10817   mp->sw_if_index = ntohl (sw_if_index);
10818   mp->max_interval = ntohl (max_interval);
10819   mp->min_interval = ntohl (min_interval);
10820   mp->lifetime = ntohl (lifetime);
10821   mp->initial_count = ntohl (initial_count);
10822   mp->initial_interval = ntohl (initial_interval);
10823   mp->suppress = suppress;
10824   mp->managed = managed;
10825   mp->other = other;
10826   mp->ll_option = ll_option;
10827   mp->send_unicast = send_unicast;
10828   mp->cease = cease;
10829   mp->is_no = is_no;
10830   mp->default_router = default_router;
10831
10832   /* send it... */
10833   S (mp);
10834
10835   /* Wait for a reply, return good/bad news  */
10836   W (ret);
10837   return ret;
10838 }
10839
10840 static int
10841 api_set_arp_neighbor_limit (vat_main_t * vam)
10842 {
10843   unformat_input_t *i = vam->input;
10844   vl_api_set_arp_neighbor_limit_t *mp;
10845   u32 arp_nbr_limit;
10846   u8 limit_set = 0;
10847   u8 is_ipv6 = 0;
10848   int ret;
10849
10850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10853         limit_set = 1;
10854       else if (unformat (i, "ipv6"))
10855         is_ipv6 = 1;
10856       else
10857         {
10858           clib_warning ("parse error '%U'", format_unformat_error, i);
10859           return -99;
10860         }
10861     }
10862
10863   if (limit_set == 0)
10864     {
10865       errmsg ("missing limit value");
10866       return -99;
10867     }
10868
10869   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10870
10871   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10872   mp->is_ipv6 = is_ipv6;
10873
10874   S (mp);
10875   W (ret);
10876   return ret;
10877 }
10878
10879 static int
10880 api_l2_patch_add_del (vat_main_t * vam)
10881 {
10882   unformat_input_t *i = vam->input;
10883   vl_api_l2_patch_add_del_t *mp;
10884   u32 rx_sw_if_index;
10885   u8 rx_sw_if_index_set = 0;
10886   u32 tx_sw_if_index;
10887   u8 tx_sw_if_index_set = 0;
10888   u8 is_add = 1;
10889   int ret;
10890
10891   /* Parse args required to build the message */
10892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10893     {
10894       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10895         rx_sw_if_index_set = 1;
10896       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10897         tx_sw_if_index_set = 1;
10898       else if (unformat (i, "rx"))
10899         {
10900           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10901             {
10902               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10903                             &rx_sw_if_index))
10904                 rx_sw_if_index_set = 1;
10905             }
10906           else
10907             break;
10908         }
10909       else if (unformat (i, "tx"))
10910         {
10911           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10912             {
10913               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10914                             &tx_sw_if_index))
10915                 tx_sw_if_index_set = 1;
10916             }
10917           else
10918             break;
10919         }
10920       else if (unformat (i, "del"))
10921         is_add = 0;
10922       else
10923         break;
10924     }
10925
10926   if (rx_sw_if_index_set == 0)
10927     {
10928       errmsg ("missing rx interface name or rx_sw_if_index");
10929       return -99;
10930     }
10931
10932   if (tx_sw_if_index_set == 0)
10933     {
10934       errmsg ("missing tx interface name or tx_sw_if_index");
10935       return -99;
10936     }
10937
10938   M (L2_PATCH_ADD_DEL, mp);
10939
10940   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10941   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10942   mp->is_add = is_add;
10943
10944   S (mp);
10945   W (ret);
10946   return ret;
10947 }
10948
10949 u8 is_del;
10950 u8 localsid_addr[16];
10951 u8 end_psp;
10952 u8 behavior;
10953 u32 sw_if_index;
10954 u32 vlan_index;
10955 u32 fib_table;
10956 u8 nh_addr[16];
10957
10958 static int
10959 api_sr_localsid_add_del (vat_main_t * vam)
10960 {
10961   unformat_input_t *i = vam->input;
10962   vl_api_sr_localsid_add_del_t *mp;
10963
10964   u8 is_del;
10965   ip6_address_t localsid;
10966   u8 end_psp = 0;
10967   u8 behavior = ~0;
10968   u32 sw_if_index;
10969   u32 fib_table = ~(u32) 0;
10970   ip6_address_t nh_addr6;
10971   ip4_address_t nh_addr4;
10972   memset (&nh_addr6, 0, sizeof (ip6_address_t));
10973   memset (&nh_addr4, 0, sizeof (ip4_address_t));
10974
10975   bool nexthop_set = 0;
10976
10977   int ret;
10978
10979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10980     {
10981       if (unformat (i, "del"))
10982         is_del = 1;
10983       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10984       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
10985         nexthop_set = 1;
10986       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
10987         nexthop_set = 1;
10988       else if (unformat (i, "behavior %u", &behavior));
10989       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10990       else if (unformat (i, "fib-table %u", &fib_table));
10991       else if (unformat (i, "end.psp %u", &behavior));
10992       else
10993         break;
10994     }
10995
10996   M (SR_LOCALSID_ADD_DEL, mp);
10997
10998   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
10999   if (nexthop_set)
11000     {
11001       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11002       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11003     }
11004   mp->behavior = behavior;
11005   mp->sw_if_index = ntohl (sw_if_index);
11006   mp->fib_table = ntohl (fib_table);
11007   mp->end_psp = end_psp;
11008   mp->is_del = is_del;
11009
11010   S (mp);
11011   W (ret);
11012   return ret;
11013 }
11014
11015 static int
11016 api_ioam_enable (vat_main_t * vam)
11017 {
11018   unformat_input_t *input = vam->input;
11019   vl_api_ioam_enable_t *mp;
11020   u32 id = 0;
11021   int has_trace_option = 0;
11022   int has_pot_option = 0;
11023   int has_seqno_option = 0;
11024   int has_analyse_option = 0;
11025   int ret;
11026
11027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (input, "trace"))
11030         has_trace_option = 1;
11031       else if (unformat (input, "pot"))
11032         has_pot_option = 1;
11033       else if (unformat (input, "seqno"))
11034         has_seqno_option = 1;
11035       else if (unformat (input, "analyse"))
11036         has_analyse_option = 1;
11037       else
11038         break;
11039     }
11040   M (IOAM_ENABLE, mp);
11041   mp->id = htons (id);
11042   mp->seqno = has_seqno_option;
11043   mp->analyse = has_analyse_option;
11044   mp->pot_enable = has_pot_option;
11045   mp->trace_enable = has_trace_option;
11046
11047   S (mp);
11048   W (ret);
11049   return ret;
11050 }
11051
11052
11053 static int
11054 api_ioam_disable (vat_main_t * vam)
11055 {
11056   vl_api_ioam_disable_t *mp;
11057   int ret;
11058
11059   M (IOAM_DISABLE, mp);
11060   S (mp);
11061   W (ret);
11062   return ret;
11063 }
11064
11065 #define foreach_tcp_proto_field                 \
11066 _(src_port)                                     \
11067 _(dst_port)
11068
11069 #define foreach_udp_proto_field                 \
11070 _(src_port)                                     \
11071 _(dst_port)
11072
11073 #define foreach_ip4_proto_field                 \
11074 _(src_address)                                  \
11075 _(dst_address)                                  \
11076 _(tos)                                          \
11077 _(length)                                       \
11078 _(fragment_id)                                  \
11079 _(ttl)                                          \
11080 _(protocol)                                     \
11081 _(checksum)
11082
11083 typedef struct
11084 {
11085   u16 src_port, dst_port;
11086 } tcpudp_header_t;
11087
11088 #if VPP_API_TEST_BUILTIN == 0
11089 uword
11090 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11091 {
11092   u8 **maskp = va_arg (*args, u8 **);
11093   u8 *mask = 0;
11094   u8 found_something = 0;
11095   tcp_header_t *tcp;
11096
11097 #define _(a) u8 a=0;
11098   foreach_tcp_proto_field;
11099 #undef _
11100
11101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (0);
11104 #define _(a) else if (unformat (input, #a)) a=1;
11105       foreach_tcp_proto_field
11106 #undef _
11107         else
11108         break;
11109     }
11110
11111 #define _(a) found_something += a;
11112   foreach_tcp_proto_field;
11113 #undef _
11114
11115   if (found_something == 0)
11116     return 0;
11117
11118   vec_validate (mask, sizeof (*tcp) - 1);
11119
11120   tcp = (tcp_header_t *) mask;
11121
11122 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11123   foreach_tcp_proto_field;
11124 #undef _
11125
11126   *maskp = mask;
11127   return 1;
11128 }
11129
11130 uword
11131 unformat_udp_mask (unformat_input_t * input, va_list * args)
11132 {
11133   u8 **maskp = va_arg (*args, u8 **);
11134   u8 *mask = 0;
11135   u8 found_something = 0;
11136   udp_header_t *udp;
11137
11138 #define _(a) u8 a=0;
11139   foreach_udp_proto_field;
11140 #undef _
11141
11142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11143     {
11144       if (0);
11145 #define _(a) else if (unformat (input, #a)) a=1;
11146       foreach_udp_proto_field
11147 #undef _
11148         else
11149         break;
11150     }
11151
11152 #define _(a) found_something += a;
11153   foreach_udp_proto_field;
11154 #undef _
11155
11156   if (found_something == 0)
11157     return 0;
11158
11159   vec_validate (mask, sizeof (*udp) - 1);
11160
11161   udp = (udp_header_t *) mask;
11162
11163 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11164   foreach_udp_proto_field;
11165 #undef _
11166
11167   *maskp = mask;
11168   return 1;
11169 }
11170
11171 uword
11172 unformat_l4_mask (unformat_input_t * input, va_list * args)
11173 {
11174   u8 **maskp = va_arg (*args, u8 **);
11175   u16 src_port = 0, dst_port = 0;
11176   tcpudp_header_t *tcpudp;
11177
11178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11179     {
11180       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11181         return 1;
11182       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11183         return 1;
11184       else if (unformat (input, "src_port"))
11185         src_port = 0xFFFF;
11186       else if (unformat (input, "dst_port"))
11187         dst_port = 0xFFFF;
11188       else
11189         return 0;
11190     }
11191
11192   if (!src_port && !dst_port)
11193     return 0;
11194
11195   u8 *mask = 0;
11196   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11197
11198   tcpudp = (tcpudp_header_t *) mask;
11199   tcpudp->src_port = src_port;
11200   tcpudp->dst_port = dst_port;
11201
11202   *maskp = mask;
11203
11204   return 1;
11205 }
11206
11207 uword
11208 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11209 {
11210   u8 **maskp = va_arg (*args, u8 **);
11211   u8 *mask = 0;
11212   u8 found_something = 0;
11213   ip4_header_t *ip;
11214
11215 #define _(a) u8 a=0;
11216   foreach_ip4_proto_field;
11217 #undef _
11218   u8 version = 0;
11219   u8 hdr_length = 0;
11220
11221
11222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (input, "version"))
11225         version = 1;
11226       else if (unformat (input, "hdr_length"))
11227         hdr_length = 1;
11228       else if (unformat (input, "src"))
11229         src_address = 1;
11230       else if (unformat (input, "dst"))
11231         dst_address = 1;
11232       else if (unformat (input, "proto"))
11233         protocol = 1;
11234
11235 #define _(a) else if (unformat (input, #a)) a=1;
11236       foreach_ip4_proto_field
11237 #undef _
11238         else
11239         break;
11240     }
11241
11242 #define _(a) found_something += a;
11243   foreach_ip4_proto_field;
11244 #undef _
11245
11246   if (found_something == 0)
11247     return 0;
11248
11249   vec_validate (mask, sizeof (*ip) - 1);
11250
11251   ip = (ip4_header_t *) mask;
11252
11253 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11254   foreach_ip4_proto_field;
11255 #undef _
11256
11257   ip->ip_version_and_header_length = 0;
11258
11259   if (version)
11260     ip->ip_version_and_header_length |= 0xF0;
11261
11262   if (hdr_length)
11263     ip->ip_version_and_header_length |= 0x0F;
11264
11265   *maskp = mask;
11266   return 1;
11267 }
11268
11269 #define foreach_ip6_proto_field                 \
11270 _(src_address)                                  \
11271 _(dst_address)                                  \
11272 _(payload_length)                               \
11273 _(hop_limit)                                    \
11274 _(protocol)
11275
11276 uword
11277 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11278 {
11279   u8 **maskp = va_arg (*args, u8 **);
11280   u8 *mask = 0;
11281   u8 found_something = 0;
11282   ip6_header_t *ip;
11283   u32 ip_version_traffic_class_and_flow_label;
11284
11285 #define _(a) u8 a=0;
11286   foreach_ip6_proto_field;
11287 #undef _
11288   u8 version = 0;
11289   u8 traffic_class = 0;
11290   u8 flow_label = 0;
11291
11292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11293     {
11294       if (unformat (input, "version"))
11295         version = 1;
11296       else if (unformat (input, "traffic-class"))
11297         traffic_class = 1;
11298       else if (unformat (input, "flow-label"))
11299         flow_label = 1;
11300       else if (unformat (input, "src"))
11301         src_address = 1;
11302       else if (unformat (input, "dst"))
11303         dst_address = 1;
11304       else if (unformat (input, "proto"))
11305         protocol = 1;
11306
11307 #define _(a) else if (unformat (input, #a)) a=1;
11308       foreach_ip6_proto_field
11309 #undef _
11310         else
11311         break;
11312     }
11313
11314 #define _(a) found_something += a;
11315   foreach_ip6_proto_field;
11316 #undef _
11317
11318   if (found_something == 0)
11319     return 0;
11320
11321   vec_validate (mask, sizeof (*ip) - 1);
11322
11323   ip = (ip6_header_t *) mask;
11324
11325 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11326   foreach_ip6_proto_field;
11327 #undef _
11328
11329   ip_version_traffic_class_and_flow_label = 0;
11330
11331   if (version)
11332     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11333
11334   if (traffic_class)
11335     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11336
11337   if (flow_label)
11338     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11339
11340   ip->ip_version_traffic_class_and_flow_label =
11341     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11342
11343   *maskp = mask;
11344   return 1;
11345 }
11346
11347 uword
11348 unformat_l3_mask (unformat_input_t * input, va_list * args)
11349 {
11350   u8 **maskp = va_arg (*args, u8 **);
11351
11352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11353     {
11354       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11355         return 1;
11356       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11357         return 1;
11358       else
11359         break;
11360     }
11361   return 0;
11362 }
11363
11364 uword
11365 unformat_l2_mask (unformat_input_t * input, va_list * args)
11366 {
11367   u8 **maskp = va_arg (*args, u8 **);
11368   u8 *mask = 0;
11369   u8 src = 0;
11370   u8 dst = 0;
11371   u8 proto = 0;
11372   u8 tag1 = 0;
11373   u8 tag2 = 0;
11374   u8 ignore_tag1 = 0;
11375   u8 ignore_tag2 = 0;
11376   u8 cos1 = 0;
11377   u8 cos2 = 0;
11378   u8 dot1q = 0;
11379   u8 dot1ad = 0;
11380   int len = 14;
11381
11382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11383     {
11384       if (unformat (input, "src"))
11385         src = 1;
11386       else if (unformat (input, "dst"))
11387         dst = 1;
11388       else if (unformat (input, "proto"))
11389         proto = 1;
11390       else if (unformat (input, "tag1"))
11391         tag1 = 1;
11392       else if (unformat (input, "tag2"))
11393         tag2 = 1;
11394       else if (unformat (input, "ignore-tag1"))
11395         ignore_tag1 = 1;
11396       else if (unformat (input, "ignore-tag2"))
11397         ignore_tag2 = 1;
11398       else if (unformat (input, "cos1"))
11399         cos1 = 1;
11400       else if (unformat (input, "cos2"))
11401         cos2 = 1;
11402       else if (unformat (input, "dot1q"))
11403         dot1q = 1;
11404       else if (unformat (input, "dot1ad"))
11405         dot1ad = 1;
11406       else
11407         break;
11408     }
11409   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11410        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11411     return 0;
11412
11413   if (tag1 || ignore_tag1 || cos1 || dot1q)
11414     len = 18;
11415   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11416     len = 22;
11417
11418   vec_validate (mask, len - 1);
11419
11420   if (dst)
11421     memset (mask, 0xff, 6);
11422
11423   if (src)
11424     memset (mask + 6, 0xff, 6);
11425
11426   if (tag2 || dot1ad)
11427     {
11428       /* inner vlan tag */
11429       if (tag2)
11430         {
11431           mask[19] = 0xff;
11432           mask[18] = 0x0f;
11433         }
11434       if (cos2)
11435         mask[18] |= 0xe0;
11436       if (proto)
11437         mask[21] = mask[20] = 0xff;
11438       if (tag1)
11439         {
11440           mask[15] = 0xff;
11441           mask[14] = 0x0f;
11442         }
11443       if (cos1)
11444         mask[14] |= 0xe0;
11445       *maskp = mask;
11446       return 1;
11447     }
11448   if (tag1 | dot1q)
11449     {
11450       if (tag1)
11451         {
11452           mask[15] = 0xff;
11453           mask[14] = 0x0f;
11454         }
11455       if (cos1)
11456         mask[14] |= 0xe0;
11457       if (proto)
11458         mask[16] = mask[17] = 0xff;
11459
11460       *maskp = mask;
11461       return 1;
11462     }
11463   if (cos2)
11464     mask[18] |= 0xe0;
11465   if (cos1)
11466     mask[14] |= 0xe0;
11467   if (proto)
11468     mask[12] = mask[13] = 0xff;
11469
11470   *maskp = mask;
11471   return 1;
11472 }
11473
11474 uword
11475 unformat_classify_mask (unformat_input_t * input, va_list * args)
11476 {
11477   u8 **maskp = va_arg (*args, u8 **);
11478   u32 *skipp = va_arg (*args, u32 *);
11479   u32 *matchp = va_arg (*args, u32 *);
11480   u32 match;
11481   u8 *mask = 0;
11482   u8 *l2 = 0;
11483   u8 *l3 = 0;
11484   u8 *l4 = 0;
11485   int i;
11486
11487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11488     {
11489       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11490         ;
11491       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11492         ;
11493       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11494         ;
11495       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11496         ;
11497       else
11498         break;
11499     }
11500
11501   if (l4 && !l3)
11502     {
11503       vec_free (mask);
11504       vec_free (l2);
11505       vec_free (l4);
11506       return 0;
11507     }
11508
11509   if (mask || l2 || l3 || l4)
11510     {
11511       if (l2 || l3 || l4)
11512         {
11513           /* "With a free Ethernet header in every package" */
11514           if (l2 == 0)
11515             vec_validate (l2, 13);
11516           mask = l2;
11517           if (vec_len (l3))
11518             {
11519               vec_append (mask, l3);
11520               vec_free (l3);
11521             }
11522           if (vec_len (l4))
11523             {
11524               vec_append (mask, l4);
11525               vec_free (l4);
11526             }
11527         }
11528
11529       /* Scan forward looking for the first significant mask octet */
11530       for (i = 0; i < vec_len (mask); i++)
11531         if (mask[i])
11532           break;
11533
11534       /* compute (skip, match) params */
11535       *skipp = i / sizeof (u32x4);
11536       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11537
11538       /* Pad mask to an even multiple of the vector size */
11539       while (vec_len (mask) % sizeof (u32x4))
11540         vec_add1 (mask, 0);
11541
11542       match = vec_len (mask) / sizeof (u32x4);
11543
11544       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11545         {
11546           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11547           if (*tmp || *(tmp + 1))
11548             break;
11549           match--;
11550         }
11551       if (match == 0)
11552         clib_warning ("BUG: match 0");
11553
11554       _vec_len (mask) = match * sizeof (u32x4);
11555
11556       *matchp = match;
11557       *maskp = mask;
11558
11559       return 1;
11560     }
11561
11562   return 0;
11563 }
11564 #endif /* VPP_API_TEST_BUILTIN */
11565
11566 #define foreach_l2_next                         \
11567 _(drop, DROP)                                   \
11568 _(ethernet, ETHERNET_INPUT)                     \
11569 _(ip4, IP4_INPUT)                               \
11570 _(ip6, IP6_INPUT)
11571
11572 uword
11573 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11574 {
11575   u32 *miss_next_indexp = va_arg (*args, u32 *);
11576   u32 next_index = 0;
11577   u32 tmp;
11578
11579 #define _(n,N) \
11580   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11581   foreach_l2_next;
11582 #undef _
11583
11584   if (unformat (input, "%d", &tmp))
11585     {
11586       next_index = tmp;
11587       goto out;
11588     }
11589
11590   return 0;
11591
11592 out:
11593   *miss_next_indexp = next_index;
11594   return 1;
11595 }
11596
11597 #define foreach_ip_next                         \
11598 _(drop, DROP)                                   \
11599 _(local, LOCAL)                                 \
11600 _(rewrite, REWRITE)
11601
11602 uword
11603 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11604 {
11605   u32 *miss_next_indexp = va_arg (*args, u32 *);
11606   u32 next_index = 0;
11607   u32 tmp;
11608
11609 #define _(n,N) \
11610   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11611   foreach_ip_next;
11612 #undef _
11613
11614   if (unformat (input, "%d", &tmp))
11615     {
11616       next_index = tmp;
11617       goto out;
11618     }
11619
11620   return 0;
11621
11622 out:
11623   *miss_next_indexp = next_index;
11624   return 1;
11625 }
11626
11627 #define foreach_acl_next                        \
11628 _(deny, DENY)
11629
11630 uword
11631 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11632 {
11633   u32 *miss_next_indexp = va_arg (*args, u32 *);
11634   u32 next_index = 0;
11635   u32 tmp;
11636
11637 #define _(n,N) \
11638   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11639   foreach_acl_next;
11640 #undef _
11641
11642   if (unformat (input, "permit"))
11643     {
11644       next_index = ~0;
11645       goto out;
11646     }
11647   else if (unformat (input, "%d", &tmp))
11648     {
11649       next_index = tmp;
11650       goto out;
11651     }
11652
11653   return 0;
11654
11655 out:
11656   *miss_next_indexp = next_index;
11657   return 1;
11658 }
11659
11660 uword
11661 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11662 {
11663   u32 *r = va_arg (*args, u32 *);
11664
11665   if (unformat (input, "conform-color"))
11666     *r = POLICE_CONFORM;
11667   else if (unformat (input, "exceed-color"))
11668     *r = POLICE_EXCEED;
11669   else
11670     return 0;
11671
11672   return 1;
11673 }
11674
11675 static int
11676 api_classify_add_del_table (vat_main_t * vam)
11677 {
11678   unformat_input_t *i = vam->input;
11679   vl_api_classify_add_del_table_t *mp;
11680
11681   u32 nbuckets = 2;
11682   u32 skip = ~0;
11683   u32 match = ~0;
11684   int is_add = 1;
11685   int del_chain = 0;
11686   u32 table_index = ~0;
11687   u32 next_table_index = ~0;
11688   u32 miss_next_index = ~0;
11689   u32 memory_size = 32 << 20;
11690   u8 *mask = 0;
11691   u32 current_data_flag = 0;
11692   int current_data_offset = 0;
11693   int ret;
11694
11695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (i, "del"))
11698         is_add = 0;
11699       else if (unformat (i, "del-chain"))
11700         {
11701           is_add = 0;
11702           del_chain = 1;
11703         }
11704       else if (unformat (i, "buckets %d", &nbuckets))
11705         ;
11706       else if (unformat (i, "memory_size %d", &memory_size))
11707         ;
11708       else if (unformat (i, "skip %d", &skip))
11709         ;
11710       else if (unformat (i, "match %d", &match))
11711         ;
11712       else if (unformat (i, "table %d", &table_index))
11713         ;
11714       else if (unformat (i, "mask %U", unformat_classify_mask,
11715                          &mask, &skip, &match))
11716         ;
11717       else if (unformat (i, "next-table %d", &next_table_index))
11718         ;
11719       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11720                          &miss_next_index))
11721         ;
11722       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11723                          &miss_next_index))
11724         ;
11725       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11726                          &miss_next_index))
11727         ;
11728       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11729         ;
11730       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11731         ;
11732       else
11733         break;
11734     }
11735
11736   if (is_add && mask == 0)
11737     {
11738       errmsg ("Mask required");
11739       return -99;
11740     }
11741
11742   if (is_add && skip == ~0)
11743     {
11744       errmsg ("skip count required");
11745       return -99;
11746     }
11747
11748   if (is_add && match == ~0)
11749     {
11750       errmsg ("match count required");
11751       return -99;
11752     }
11753
11754   if (!is_add && table_index == ~0)
11755     {
11756       errmsg ("table index required for delete");
11757       return -99;
11758     }
11759
11760   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11761
11762   mp->is_add = is_add;
11763   mp->del_chain = del_chain;
11764   mp->table_index = ntohl (table_index);
11765   mp->nbuckets = ntohl (nbuckets);
11766   mp->memory_size = ntohl (memory_size);
11767   mp->skip_n_vectors = ntohl (skip);
11768   mp->match_n_vectors = ntohl (match);
11769   mp->next_table_index = ntohl (next_table_index);
11770   mp->miss_next_index = ntohl (miss_next_index);
11771   mp->current_data_flag = ntohl (current_data_flag);
11772   mp->current_data_offset = ntohl (current_data_offset);
11773   mp->mask_len = ntohl (vec_len (mask));
11774   clib_memcpy (mp->mask, mask, vec_len (mask));
11775
11776   vec_free (mask);
11777
11778   S (mp);
11779   W (ret);
11780   return ret;
11781 }
11782
11783 #if VPP_API_TEST_BUILTIN == 0
11784 uword
11785 unformat_l4_match (unformat_input_t * input, va_list * args)
11786 {
11787   u8 **matchp = va_arg (*args, u8 **);
11788
11789   u8 *proto_header = 0;
11790   int src_port = 0;
11791   int dst_port = 0;
11792
11793   tcpudp_header_t h;
11794
11795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11796     {
11797       if (unformat (input, "src_port %d", &src_port))
11798         ;
11799       else if (unformat (input, "dst_port %d", &dst_port))
11800         ;
11801       else
11802         return 0;
11803     }
11804
11805   h.src_port = clib_host_to_net_u16 (src_port);
11806   h.dst_port = clib_host_to_net_u16 (dst_port);
11807   vec_validate (proto_header, sizeof (h) - 1);
11808   memcpy (proto_header, &h, sizeof (h));
11809
11810   *matchp = proto_header;
11811
11812   return 1;
11813 }
11814
11815 uword
11816 unformat_ip4_match (unformat_input_t * input, va_list * args)
11817 {
11818   u8 **matchp = va_arg (*args, u8 **);
11819   u8 *match = 0;
11820   ip4_header_t *ip;
11821   int version = 0;
11822   u32 version_val;
11823   int hdr_length = 0;
11824   u32 hdr_length_val;
11825   int src = 0, dst = 0;
11826   ip4_address_t src_val, dst_val;
11827   int proto = 0;
11828   u32 proto_val;
11829   int tos = 0;
11830   u32 tos_val;
11831   int length = 0;
11832   u32 length_val;
11833   int fragment_id = 0;
11834   u32 fragment_id_val;
11835   int ttl = 0;
11836   int ttl_val;
11837   int checksum = 0;
11838   u32 checksum_val;
11839
11840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11841     {
11842       if (unformat (input, "version %d", &version_val))
11843         version = 1;
11844       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11845         hdr_length = 1;
11846       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11847         src = 1;
11848       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11849         dst = 1;
11850       else if (unformat (input, "proto %d", &proto_val))
11851         proto = 1;
11852       else if (unformat (input, "tos %d", &tos_val))
11853         tos = 1;
11854       else if (unformat (input, "length %d", &length_val))
11855         length = 1;
11856       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11857         fragment_id = 1;
11858       else if (unformat (input, "ttl %d", &ttl_val))
11859         ttl = 1;
11860       else if (unformat (input, "checksum %d", &checksum_val))
11861         checksum = 1;
11862       else
11863         break;
11864     }
11865
11866   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11867       + ttl + checksum == 0)
11868     return 0;
11869
11870   /*
11871    * Aligned because we use the real comparison functions
11872    */
11873   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11874
11875   ip = (ip4_header_t *) match;
11876
11877   /* These are realistically matched in practice */
11878   if (src)
11879     ip->src_address.as_u32 = src_val.as_u32;
11880
11881   if (dst)
11882     ip->dst_address.as_u32 = dst_val.as_u32;
11883
11884   if (proto)
11885     ip->protocol = proto_val;
11886
11887
11888   /* These are not, but they're included for completeness */
11889   if (version)
11890     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11891
11892   if (hdr_length)
11893     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11894
11895   if (tos)
11896     ip->tos = tos_val;
11897
11898   if (length)
11899     ip->length = clib_host_to_net_u16 (length_val);
11900
11901   if (ttl)
11902     ip->ttl = ttl_val;
11903
11904   if (checksum)
11905     ip->checksum = clib_host_to_net_u16 (checksum_val);
11906
11907   *matchp = match;
11908   return 1;
11909 }
11910
11911 uword
11912 unformat_ip6_match (unformat_input_t * input, va_list * args)
11913 {
11914   u8 **matchp = va_arg (*args, u8 **);
11915   u8 *match = 0;
11916   ip6_header_t *ip;
11917   int version = 0;
11918   u32 version_val;
11919   u8 traffic_class = 0;
11920   u32 traffic_class_val = 0;
11921   u8 flow_label = 0;
11922   u8 flow_label_val;
11923   int src = 0, dst = 0;
11924   ip6_address_t src_val, dst_val;
11925   int proto = 0;
11926   u32 proto_val;
11927   int payload_length = 0;
11928   u32 payload_length_val;
11929   int hop_limit = 0;
11930   int hop_limit_val;
11931   u32 ip_version_traffic_class_and_flow_label;
11932
11933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11934     {
11935       if (unformat (input, "version %d", &version_val))
11936         version = 1;
11937       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11938         traffic_class = 1;
11939       else if (unformat (input, "flow_label %d", &flow_label_val))
11940         flow_label = 1;
11941       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11942         src = 1;
11943       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11944         dst = 1;
11945       else if (unformat (input, "proto %d", &proto_val))
11946         proto = 1;
11947       else if (unformat (input, "payload_length %d", &payload_length_val))
11948         payload_length = 1;
11949       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11950         hop_limit = 1;
11951       else
11952         break;
11953     }
11954
11955   if (version + traffic_class + flow_label + src + dst + proto +
11956       payload_length + hop_limit == 0)
11957     return 0;
11958
11959   /*
11960    * Aligned because we use the real comparison functions
11961    */
11962   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11963
11964   ip = (ip6_header_t *) match;
11965
11966   if (src)
11967     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11968
11969   if (dst)
11970     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11971
11972   if (proto)
11973     ip->protocol = proto_val;
11974
11975   ip_version_traffic_class_and_flow_label = 0;
11976
11977   if (version)
11978     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11979
11980   if (traffic_class)
11981     ip_version_traffic_class_and_flow_label |=
11982       (traffic_class_val & 0xFF) << 20;
11983
11984   if (flow_label)
11985     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11986
11987   ip->ip_version_traffic_class_and_flow_label =
11988     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11989
11990   if (payload_length)
11991     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11992
11993   if (hop_limit)
11994     ip->hop_limit = hop_limit_val;
11995
11996   *matchp = match;
11997   return 1;
11998 }
11999
12000 uword
12001 unformat_l3_match (unformat_input_t * input, va_list * args)
12002 {
12003   u8 **matchp = va_arg (*args, u8 **);
12004
12005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12006     {
12007       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12008         return 1;
12009       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12010         return 1;
12011       else
12012         break;
12013     }
12014   return 0;
12015 }
12016
12017 uword
12018 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12019 {
12020   u8 *tagp = va_arg (*args, u8 *);
12021   u32 tag;
12022
12023   if (unformat (input, "%d", &tag))
12024     {
12025       tagp[0] = (tag >> 8) & 0x0F;
12026       tagp[1] = tag & 0xFF;
12027       return 1;
12028     }
12029
12030   return 0;
12031 }
12032
12033 uword
12034 unformat_l2_match (unformat_input_t * input, va_list * args)
12035 {
12036   u8 **matchp = va_arg (*args, u8 **);
12037   u8 *match = 0;
12038   u8 src = 0;
12039   u8 src_val[6];
12040   u8 dst = 0;
12041   u8 dst_val[6];
12042   u8 proto = 0;
12043   u16 proto_val;
12044   u8 tag1 = 0;
12045   u8 tag1_val[2];
12046   u8 tag2 = 0;
12047   u8 tag2_val[2];
12048   int len = 14;
12049   u8 ignore_tag1 = 0;
12050   u8 ignore_tag2 = 0;
12051   u8 cos1 = 0;
12052   u8 cos2 = 0;
12053   u32 cos1_val = 0;
12054   u32 cos2_val = 0;
12055
12056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12057     {
12058       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12059         src = 1;
12060       else
12061         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12062         dst = 1;
12063       else if (unformat (input, "proto %U",
12064                          unformat_ethernet_type_host_byte_order, &proto_val))
12065         proto = 1;
12066       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12067         tag1 = 1;
12068       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12069         tag2 = 1;
12070       else if (unformat (input, "ignore-tag1"))
12071         ignore_tag1 = 1;
12072       else if (unformat (input, "ignore-tag2"))
12073         ignore_tag2 = 1;
12074       else if (unformat (input, "cos1 %d", &cos1_val))
12075         cos1 = 1;
12076       else if (unformat (input, "cos2 %d", &cos2_val))
12077         cos2 = 1;
12078       else
12079         break;
12080     }
12081   if ((src + dst + proto + tag1 + tag2 +
12082        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12083     return 0;
12084
12085   if (tag1 || ignore_tag1 || cos1)
12086     len = 18;
12087   if (tag2 || ignore_tag2 || cos2)
12088     len = 22;
12089
12090   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12091
12092   if (dst)
12093     clib_memcpy (match, dst_val, 6);
12094
12095   if (src)
12096     clib_memcpy (match + 6, src_val, 6);
12097
12098   if (tag2)
12099     {
12100       /* inner vlan tag */
12101       match[19] = tag2_val[1];
12102       match[18] = tag2_val[0];
12103       if (cos2)
12104         match[18] |= (cos2_val & 0x7) << 5;
12105       if (proto)
12106         {
12107           match[21] = proto_val & 0xff;
12108           match[20] = proto_val >> 8;
12109         }
12110       if (tag1)
12111         {
12112           match[15] = tag1_val[1];
12113           match[14] = tag1_val[0];
12114         }
12115       if (cos1)
12116         match[14] |= (cos1_val & 0x7) << 5;
12117       *matchp = match;
12118       return 1;
12119     }
12120   if (tag1)
12121     {
12122       match[15] = tag1_val[1];
12123       match[14] = tag1_val[0];
12124       if (proto)
12125         {
12126           match[17] = proto_val & 0xff;
12127           match[16] = proto_val >> 8;
12128         }
12129       if (cos1)
12130         match[14] |= (cos1_val & 0x7) << 5;
12131
12132       *matchp = match;
12133       return 1;
12134     }
12135   if (cos2)
12136     match[18] |= (cos2_val & 0x7) << 5;
12137   if (cos1)
12138     match[14] |= (cos1_val & 0x7) << 5;
12139   if (proto)
12140     {
12141       match[13] = proto_val & 0xff;
12142       match[12] = proto_val >> 8;
12143     }
12144
12145   *matchp = match;
12146   return 1;
12147 }
12148
12149 uword
12150 unformat_qos_source (unformat_input_t * input, va_list * args)
12151 {
12152   int *qs = va_arg (*args, int *);
12153
12154   if (unformat (input, "ip"))
12155     *qs = QOS_SOURCE_IP;
12156   else if (unformat (input, "mpls"))
12157     *qs = QOS_SOURCE_MPLS;
12158   else if (unformat (input, "ext"))
12159     *qs = QOS_SOURCE_EXT;
12160   else if (unformat (input, "vlan"))
12161     *qs = QOS_SOURCE_VLAN;
12162   else
12163     return 0;
12164
12165   return 1;
12166 }
12167 #endif
12168
12169 uword
12170 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12171 {
12172   u8 **matchp = va_arg (*args, u8 **);
12173   u32 skip_n_vectors = va_arg (*args, u32);
12174   u32 match_n_vectors = va_arg (*args, u32);
12175
12176   u8 *match = 0;
12177   u8 *l2 = 0;
12178   u8 *l3 = 0;
12179   u8 *l4 = 0;
12180
12181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12182     {
12183       if (unformat (input, "hex %U", unformat_hex_string, &match))
12184         ;
12185       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12186         ;
12187       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12188         ;
12189       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12190         ;
12191       else
12192         break;
12193     }
12194
12195   if (l4 && !l3)
12196     {
12197       vec_free (match);
12198       vec_free (l2);
12199       vec_free (l4);
12200       return 0;
12201     }
12202
12203   if (match || l2 || l3 || l4)
12204     {
12205       if (l2 || l3 || l4)
12206         {
12207           /* "Win a free Ethernet header in every packet" */
12208           if (l2 == 0)
12209             vec_validate_aligned (l2, 13, sizeof (u32x4));
12210           match = l2;
12211           if (vec_len (l3))
12212             {
12213               vec_append_aligned (match, l3, sizeof (u32x4));
12214               vec_free (l3);
12215             }
12216           if (vec_len (l4))
12217             {
12218               vec_append_aligned (match, l4, sizeof (u32x4));
12219               vec_free (l4);
12220             }
12221         }
12222
12223       /* Make sure the vector is big enough even if key is all 0's */
12224       vec_validate_aligned
12225         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12226          sizeof (u32x4));
12227
12228       /* Set size, include skipped vectors */
12229       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12230
12231       *matchp = match;
12232
12233       return 1;
12234     }
12235
12236   return 0;
12237 }
12238
12239 static int
12240 api_classify_add_del_session (vat_main_t * vam)
12241 {
12242   unformat_input_t *i = vam->input;
12243   vl_api_classify_add_del_session_t *mp;
12244   int is_add = 1;
12245   u32 table_index = ~0;
12246   u32 hit_next_index = ~0;
12247   u32 opaque_index = ~0;
12248   u8 *match = 0;
12249   i32 advance = 0;
12250   u32 skip_n_vectors = 0;
12251   u32 match_n_vectors = 0;
12252   u32 action = 0;
12253   u32 metadata = 0;
12254   int ret;
12255
12256   /*
12257    * Warning: you have to supply skip_n and match_n
12258    * because the API client cant simply look at the classify
12259    * table object.
12260    */
12261
12262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12263     {
12264       if (unformat (i, "del"))
12265         is_add = 0;
12266       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12267                          &hit_next_index))
12268         ;
12269       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12270                          &hit_next_index))
12271         ;
12272       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12273                          &hit_next_index))
12274         ;
12275       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12276         ;
12277       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12278         ;
12279       else if (unformat (i, "opaque-index %d", &opaque_index))
12280         ;
12281       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12282         ;
12283       else if (unformat (i, "match_n %d", &match_n_vectors))
12284         ;
12285       else if (unformat (i, "match %U", api_unformat_classify_match,
12286                          &match, skip_n_vectors, match_n_vectors))
12287         ;
12288       else if (unformat (i, "advance %d", &advance))
12289         ;
12290       else if (unformat (i, "table-index %d", &table_index))
12291         ;
12292       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12293         action = 1;
12294       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12295         action = 2;
12296       else if (unformat (i, "action %d", &action))
12297         ;
12298       else if (unformat (i, "metadata %d", &metadata))
12299         ;
12300       else
12301         break;
12302     }
12303
12304   if (table_index == ~0)
12305     {
12306       errmsg ("Table index required");
12307       return -99;
12308     }
12309
12310   if (is_add && match == 0)
12311     {
12312       errmsg ("Match value required");
12313       return -99;
12314     }
12315
12316   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12317
12318   mp->is_add = is_add;
12319   mp->table_index = ntohl (table_index);
12320   mp->hit_next_index = ntohl (hit_next_index);
12321   mp->opaque_index = ntohl (opaque_index);
12322   mp->advance = ntohl (advance);
12323   mp->action = action;
12324   mp->metadata = ntohl (metadata);
12325   mp->match_len = ntohl (vec_len (match));
12326   clib_memcpy (mp->match, match, vec_len (match));
12327   vec_free (match);
12328
12329   S (mp);
12330   W (ret);
12331   return ret;
12332 }
12333
12334 static int
12335 api_classify_set_interface_ip_table (vat_main_t * vam)
12336 {
12337   unformat_input_t *i = vam->input;
12338   vl_api_classify_set_interface_ip_table_t *mp;
12339   u32 sw_if_index;
12340   int sw_if_index_set;
12341   u32 table_index = ~0;
12342   u8 is_ipv6 = 0;
12343   int ret;
12344
12345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12346     {
12347       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12348         sw_if_index_set = 1;
12349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12350         sw_if_index_set = 1;
12351       else if (unformat (i, "table %d", &table_index))
12352         ;
12353       else
12354         {
12355           clib_warning ("parse error '%U'", format_unformat_error, i);
12356           return -99;
12357         }
12358     }
12359
12360   if (sw_if_index_set == 0)
12361     {
12362       errmsg ("missing interface name or sw_if_index");
12363       return -99;
12364     }
12365
12366
12367   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12368
12369   mp->sw_if_index = ntohl (sw_if_index);
12370   mp->table_index = ntohl (table_index);
12371   mp->is_ipv6 = is_ipv6;
12372
12373   S (mp);
12374   W (ret);
12375   return ret;
12376 }
12377
12378 static int
12379 api_classify_set_interface_l2_tables (vat_main_t * vam)
12380 {
12381   unformat_input_t *i = vam->input;
12382   vl_api_classify_set_interface_l2_tables_t *mp;
12383   u32 sw_if_index;
12384   int sw_if_index_set;
12385   u32 ip4_table_index = ~0;
12386   u32 ip6_table_index = ~0;
12387   u32 other_table_index = ~0;
12388   u32 is_input = 1;
12389   int ret;
12390
12391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12392     {
12393       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12394         sw_if_index_set = 1;
12395       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12396         sw_if_index_set = 1;
12397       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12398         ;
12399       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12400         ;
12401       else if (unformat (i, "other-table %d", &other_table_index))
12402         ;
12403       else if (unformat (i, "is-input %d", &is_input))
12404         ;
12405       else
12406         {
12407           clib_warning ("parse error '%U'", format_unformat_error, i);
12408           return -99;
12409         }
12410     }
12411
12412   if (sw_if_index_set == 0)
12413     {
12414       errmsg ("missing interface name or sw_if_index");
12415       return -99;
12416     }
12417
12418
12419   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12420
12421   mp->sw_if_index = ntohl (sw_if_index);
12422   mp->ip4_table_index = ntohl (ip4_table_index);
12423   mp->ip6_table_index = ntohl (ip6_table_index);
12424   mp->other_table_index = ntohl (other_table_index);
12425   mp->is_input = (u8) is_input;
12426
12427   S (mp);
12428   W (ret);
12429   return ret;
12430 }
12431
12432 static int
12433 api_set_ipfix_exporter (vat_main_t * vam)
12434 {
12435   unformat_input_t *i = vam->input;
12436   vl_api_set_ipfix_exporter_t *mp;
12437   ip4_address_t collector_address;
12438   u8 collector_address_set = 0;
12439   u32 collector_port = ~0;
12440   ip4_address_t src_address;
12441   u8 src_address_set = 0;
12442   u32 vrf_id = ~0;
12443   u32 path_mtu = ~0;
12444   u32 template_interval = ~0;
12445   u8 udp_checksum = 0;
12446   int ret;
12447
12448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12449     {
12450       if (unformat (i, "collector_address %U", unformat_ip4_address,
12451                     &collector_address))
12452         collector_address_set = 1;
12453       else if (unformat (i, "collector_port %d", &collector_port))
12454         ;
12455       else if (unformat (i, "src_address %U", unformat_ip4_address,
12456                          &src_address))
12457         src_address_set = 1;
12458       else if (unformat (i, "vrf_id %d", &vrf_id))
12459         ;
12460       else if (unformat (i, "path_mtu %d", &path_mtu))
12461         ;
12462       else if (unformat (i, "template_interval %d", &template_interval))
12463         ;
12464       else if (unformat (i, "udp_checksum"))
12465         udp_checksum = 1;
12466       else
12467         break;
12468     }
12469
12470   if (collector_address_set == 0)
12471     {
12472       errmsg ("collector_address required");
12473       return -99;
12474     }
12475
12476   if (src_address_set == 0)
12477     {
12478       errmsg ("src_address required");
12479       return -99;
12480     }
12481
12482   M (SET_IPFIX_EXPORTER, mp);
12483
12484   memcpy (mp->collector_address, collector_address.data,
12485           sizeof (collector_address.data));
12486   mp->collector_port = htons ((u16) collector_port);
12487   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12488   mp->vrf_id = htonl (vrf_id);
12489   mp->path_mtu = htonl (path_mtu);
12490   mp->template_interval = htonl (template_interval);
12491   mp->udp_checksum = udp_checksum;
12492
12493   S (mp);
12494   W (ret);
12495   return ret;
12496 }
12497
12498 static int
12499 api_set_ipfix_classify_stream (vat_main_t * vam)
12500 {
12501   unformat_input_t *i = vam->input;
12502   vl_api_set_ipfix_classify_stream_t *mp;
12503   u32 domain_id = 0;
12504   u32 src_port = UDP_DST_PORT_ipfix;
12505   int ret;
12506
12507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12508     {
12509       if (unformat (i, "domain %d", &domain_id))
12510         ;
12511       else if (unformat (i, "src_port %d", &src_port))
12512         ;
12513       else
12514         {
12515           errmsg ("unknown input `%U'", format_unformat_error, i);
12516           return -99;
12517         }
12518     }
12519
12520   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12521
12522   mp->domain_id = htonl (domain_id);
12523   mp->src_port = htons ((u16) src_port);
12524
12525   S (mp);
12526   W (ret);
12527   return ret;
12528 }
12529
12530 static int
12531 api_ipfix_classify_table_add_del (vat_main_t * vam)
12532 {
12533   unformat_input_t *i = vam->input;
12534   vl_api_ipfix_classify_table_add_del_t *mp;
12535   int is_add = -1;
12536   u32 classify_table_index = ~0;
12537   u8 ip_version = 0;
12538   u8 transport_protocol = 255;
12539   int ret;
12540
12541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12542     {
12543       if (unformat (i, "add"))
12544         is_add = 1;
12545       else if (unformat (i, "del"))
12546         is_add = 0;
12547       else if (unformat (i, "table %d", &classify_table_index))
12548         ;
12549       else if (unformat (i, "ip4"))
12550         ip_version = 4;
12551       else if (unformat (i, "ip6"))
12552         ip_version = 6;
12553       else if (unformat (i, "tcp"))
12554         transport_protocol = 6;
12555       else if (unformat (i, "udp"))
12556         transport_protocol = 17;
12557       else
12558         {
12559           errmsg ("unknown input `%U'", format_unformat_error, i);
12560           return -99;
12561         }
12562     }
12563
12564   if (is_add == -1)
12565     {
12566       errmsg ("expecting: add|del");
12567       return -99;
12568     }
12569   if (classify_table_index == ~0)
12570     {
12571       errmsg ("classifier table not specified");
12572       return -99;
12573     }
12574   if (ip_version == 0)
12575     {
12576       errmsg ("IP version not specified");
12577       return -99;
12578     }
12579
12580   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12581
12582   mp->is_add = is_add;
12583   mp->table_id = htonl (classify_table_index);
12584   mp->ip_version = ip_version;
12585   mp->transport_protocol = transport_protocol;
12586
12587   S (mp);
12588   W (ret);
12589   return ret;
12590 }
12591
12592 static int
12593 api_get_node_index (vat_main_t * vam)
12594 {
12595   unformat_input_t *i = vam->input;
12596   vl_api_get_node_index_t *mp;
12597   u8 *name = 0;
12598   int ret;
12599
12600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12601     {
12602       if (unformat (i, "node %s", &name))
12603         ;
12604       else
12605         break;
12606     }
12607   if (name == 0)
12608     {
12609       errmsg ("node name required");
12610       return -99;
12611     }
12612   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12613     {
12614       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12615       return -99;
12616     }
12617
12618   M (GET_NODE_INDEX, mp);
12619   clib_memcpy (mp->node_name, name, vec_len (name));
12620   vec_free (name);
12621
12622   S (mp);
12623   W (ret);
12624   return ret;
12625 }
12626
12627 static int
12628 api_get_next_index (vat_main_t * vam)
12629 {
12630   unformat_input_t *i = vam->input;
12631   vl_api_get_next_index_t *mp;
12632   u8 *node_name = 0, *next_node_name = 0;
12633   int ret;
12634
12635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12636     {
12637       if (unformat (i, "node-name %s", &node_name))
12638         ;
12639       else if (unformat (i, "next-node-name %s", &next_node_name))
12640         break;
12641     }
12642
12643   if (node_name == 0)
12644     {
12645       errmsg ("node name required");
12646       return -99;
12647     }
12648   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12649     {
12650       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12651       return -99;
12652     }
12653
12654   if (next_node_name == 0)
12655     {
12656       errmsg ("next node name required");
12657       return -99;
12658     }
12659   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12660     {
12661       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12662       return -99;
12663     }
12664
12665   M (GET_NEXT_INDEX, mp);
12666   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12667   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12668   vec_free (node_name);
12669   vec_free (next_node_name);
12670
12671   S (mp);
12672   W (ret);
12673   return ret;
12674 }
12675
12676 static int
12677 api_add_node_next (vat_main_t * vam)
12678 {
12679   unformat_input_t *i = vam->input;
12680   vl_api_add_node_next_t *mp;
12681   u8 *name = 0;
12682   u8 *next = 0;
12683   int ret;
12684
12685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12686     {
12687       if (unformat (i, "node %s", &name))
12688         ;
12689       else if (unformat (i, "next %s", &next))
12690         ;
12691       else
12692         break;
12693     }
12694   if (name == 0)
12695     {
12696       errmsg ("node name required");
12697       return -99;
12698     }
12699   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12700     {
12701       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12702       return -99;
12703     }
12704   if (next == 0)
12705     {
12706       errmsg ("next node required");
12707       return -99;
12708     }
12709   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12710     {
12711       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12712       return -99;
12713     }
12714
12715   M (ADD_NODE_NEXT, mp);
12716   clib_memcpy (mp->node_name, name, vec_len (name));
12717   clib_memcpy (mp->next_name, next, vec_len (next));
12718   vec_free (name);
12719   vec_free (next);
12720
12721   S (mp);
12722   W (ret);
12723   return ret;
12724 }
12725
12726 static int
12727 api_l2tpv3_create_tunnel (vat_main_t * vam)
12728 {
12729   unformat_input_t *i = vam->input;
12730   ip6_address_t client_address, our_address;
12731   int client_address_set = 0;
12732   int our_address_set = 0;
12733   u32 local_session_id = 0;
12734   u32 remote_session_id = 0;
12735   u64 local_cookie = 0;
12736   u64 remote_cookie = 0;
12737   u8 l2_sublayer_present = 0;
12738   vl_api_l2tpv3_create_tunnel_t *mp;
12739   int ret;
12740
12741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12742     {
12743       if (unformat (i, "client_address %U", unformat_ip6_address,
12744                     &client_address))
12745         client_address_set = 1;
12746       else if (unformat (i, "our_address %U", unformat_ip6_address,
12747                          &our_address))
12748         our_address_set = 1;
12749       else if (unformat (i, "local_session_id %d", &local_session_id))
12750         ;
12751       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12752         ;
12753       else if (unformat (i, "local_cookie %lld", &local_cookie))
12754         ;
12755       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12756         ;
12757       else if (unformat (i, "l2-sublayer-present"))
12758         l2_sublayer_present = 1;
12759       else
12760         break;
12761     }
12762
12763   if (client_address_set == 0)
12764     {
12765       errmsg ("client_address required");
12766       return -99;
12767     }
12768
12769   if (our_address_set == 0)
12770     {
12771       errmsg ("our_address required");
12772       return -99;
12773     }
12774
12775   M (L2TPV3_CREATE_TUNNEL, mp);
12776
12777   clib_memcpy (mp->client_address, client_address.as_u8,
12778                sizeof (mp->client_address));
12779
12780   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12781
12782   mp->local_session_id = ntohl (local_session_id);
12783   mp->remote_session_id = ntohl (remote_session_id);
12784   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12785   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12786   mp->l2_sublayer_present = l2_sublayer_present;
12787   mp->is_ipv6 = 1;
12788
12789   S (mp);
12790   W (ret);
12791   return ret;
12792 }
12793
12794 static int
12795 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12796 {
12797   unformat_input_t *i = vam->input;
12798   u32 sw_if_index;
12799   u8 sw_if_index_set = 0;
12800   u64 new_local_cookie = 0;
12801   u64 new_remote_cookie = 0;
12802   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12803   int ret;
12804
12805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12806     {
12807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12808         sw_if_index_set = 1;
12809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12810         sw_if_index_set = 1;
12811       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12812         ;
12813       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12814         ;
12815       else
12816         break;
12817     }
12818
12819   if (sw_if_index_set == 0)
12820     {
12821       errmsg ("missing interface name or sw_if_index");
12822       return -99;
12823     }
12824
12825   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12826
12827   mp->sw_if_index = ntohl (sw_if_index);
12828   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12829   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12830
12831   S (mp);
12832   W (ret);
12833   return ret;
12834 }
12835
12836 static int
12837 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12838 {
12839   unformat_input_t *i = vam->input;
12840   vl_api_l2tpv3_interface_enable_disable_t *mp;
12841   u32 sw_if_index;
12842   u8 sw_if_index_set = 0;
12843   u8 enable_disable = 1;
12844   int ret;
12845
12846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12847     {
12848       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12849         sw_if_index_set = 1;
12850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12851         sw_if_index_set = 1;
12852       else if (unformat (i, "enable"))
12853         enable_disable = 1;
12854       else if (unformat (i, "disable"))
12855         enable_disable = 0;
12856       else
12857         break;
12858     }
12859
12860   if (sw_if_index_set == 0)
12861     {
12862       errmsg ("missing interface name or sw_if_index");
12863       return -99;
12864     }
12865
12866   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12867
12868   mp->sw_if_index = ntohl (sw_if_index);
12869   mp->enable_disable = enable_disable;
12870
12871   S (mp);
12872   W (ret);
12873   return ret;
12874 }
12875
12876 static int
12877 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12878 {
12879   unformat_input_t *i = vam->input;
12880   vl_api_l2tpv3_set_lookup_key_t *mp;
12881   u8 key = ~0;
12882   int ret;
12883
12884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12885     {
12886       if (unformat (i, "lookup_v6_src"))
12887         key = L2T_LOOKUP_SRC_ADDRESS;
12888       else if (unformat (i, "lookup_v6_dst"))
12889         key = L2T_LOOKUP_DST_ADDRESS;
12890       else if (unformat (i, "lookup_session_id"))
12891         key = L2T_LOOKUP_SESSION_ID;
12892       else
12893         break;
12894     }
12895
12896   if (key == (u8) ~ 0)
12897     {
12898       errmsg ("l2tp session lookup key unset");
12899       return -99;
12900     }
12901
12902   M (L2TPV3_SET_LOOKUP_KEY, mp);
12903
12904   mp->key = key;
12905
12906   S (mp);
12907   W (ret);
12908   return ret;
12909 }
12910
12911 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12912   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12913 {
12914   vat_main_t *vam = &vat_main;
12915
12916   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12917          format_ip6_address, mp->our_address,
12918          format_ip6_address, mp->client_address,
12919          clib_net_to_host_u32 (mp->sw_if_index));
12920
12921   print (vam->ofp,
12922          "   local cookies %016llx %016llx remote cookie %016llx",
12923          clib_net_to_host_u64 (mp->local_cookie[0]),
12924          clib_net_to_host_u64 (mp->local_cookie[1]),
12925          clib_net_to_host_u64 (mp->remote_cookie));
12926
12927   print (vam->ofp, "   local session-id %d remote session-id %d",
12928          clib_net_to_host_u32 (mp->local_session_id),
12929          clib_net_to_host_u32 (mp->remote_session_id));
12930
12931   print (vam->ofp, "   l2 specific sublayer %s\n",
12932          mp->l2_sublayer_present ? "preset" : "absent");
12933
12934 }
12935
12936 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12937   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12938 {
12939   vat_main_t *vam = &vat_main;
12940   vat_json_node_t *node = NULL;
12941   struct in6_addr addr;
12942
12943   if (VAT_JSON_ARRAY != vam->json_tree.type)
12944     {
12945       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12946       vat_json_init_array (&vam->json_tree);
12947     }
12948   node = vat_json_array_add (&vam->json_tree);
12949
12950   vat_json_init_object (node);
12951
12952   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12953   vat_json_object_add_ip6 (node, "our_address", addr);
12954   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12955   vat_json_object_add_ip6 (node, "client_address", addr);
12956
12957   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12958   vat_json_init_array (lc);
12959   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12960   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12961   vat_json_object_add_uint (node, "remote_cookie",
12962                             clib_net_to_host_u64 (mp->remote_cookie));
12963
12964   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12965   vat_json_object_add_uint (node, "local_session_id",
12966                             clib_net_to_host_u32 (mp->local_session_id));
12967   vat_json_object_add_uint (node, "remote_session_id",
12968                             clib_net_to_host_u32 (mp->remote_session_id));
12969   vat_json_object_add_string_copy (node, "l2_sublayer",
12970                                    mp->l2_sublayer_present ? (u8 *) "present"
12971                                    : (u8 *) "absent");
12972 }
12973
12974 static int
12975 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12976 {
12977   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12978   vl_api_control_ping_t *mp_ping;
12979   int ret;
12980
12981   /* Get list of l2tpv3-tunnel interfaces */
12982   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12983   S (mp);
12984
12985   /* Use a control ping for synchronization */
12986   MPING (CONTROL_PING, mp_ping);
12987   S (mp_ping);
12988
12989   W (ret);
12990   return ret;
12991 }
12992
12993
12994 static void vl_api_sw_interface_tap_details_t_handler
12995   (vl_api_sw_interface_tap_details_t * mp)
12996 {
12997   vat_main_t *vam = &vat_main;
12998
12999   print (vam->ofp, "%-16s %d",
13000          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13001 }
13002
13003 static void vl_api_sw_interface_tap_details_t_handler_json
13004   (vl_api_sw_interface_tap_details_t * mp)
13005 {
13006   vat_main_t *vam = &vat_main;
13007   vat_json_node_t *node = NULL;
13008
13009   if (VAT_JSON_ARRAY != vam->json_tree.type)
13010     {
13011       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13012       vat_json_init_array (&vam->json_tree);
13013     }
13014   node = vat_json_array_add (&vam->json_tree);
13015
13016   vat_json_init_object (node);
13017   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13018   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13019 }
13020
13021 static int
13022 api_sw_interface_tap_dump (vat_main_t * vam)
13023 {
13024   vl_api_sw_interface_tap_dump_t *mp;
13025   vl_api_control_ping_t *mp_ping;
13026   int ret;
13027
13028   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13029   /* Get list of tap interfaces */
13030   M (SW_INTERFACE_TAP_DUMP, mp);
13031   S (mp);
13032
13033   /* Use a control ping for synchronization */
13034   MPING (CONTROL_PING, mp_ping);
13035   S (mp_ping);
13036
13037   W (ret);
13038   return ret;
13039 }
13040
13041 static void vl_api_sw_interface_tap_v2_details_t_handler
13042   (vl_api_sw_interface_tap_v2_details_t * mp)
13043 {
13044   vat_main_t *vam = &vat_main;
13045
13046   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13047                     mp->host_ip4_prefix_len);
13048   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13049                     mp->host_ip6_prefix_len);
13050
13051   print (vam->ofp,
13052          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13053          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13054          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13055          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13056          mp->host_bridge, ip4, ip6);
13057
13058   vec_free (ip4);
13059   vec_free (ip6);
13060 }
13061
13062 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13063   (vl_api_sw_interface_tap_v2_details_t * mp)
13064 {
13065   vat_main_t *vam = &vat_main;
13066   vat_json_node_t *node = NULL;
13067
13068   if (VAT_JSON_ARRAY != vam->json_tree.type)
13069     {
13070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13071       vat_json_init_array (&vam->json_tree);
13072     }
13073   node = vat_json_array_add (&vam->json_tree);
13074
13075   vat_json_init_object (node);
13076   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13077   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13078   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13079   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13080   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13081   vat_json_object_add_string_copy (node, "host_mac_addr",
13082                                    format (0, "%U", format_ethernet_address,
13083                                            &mp->host_mac_addr));
13084   vat_json_object_add_string_copy (node, "host_namespace",
13085                                    mp->host_namespace);
13086   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13087   vat_json_object_add_string_copy (node, "host_ip4_addr",
13088                                    format (0, "%U/%d", format_ip4_address,
13089                                            mp->host_ip4_addr,
13090                                            mp->host_ip4_prefix_len));
13091   vat_json_object_add_string_copy (node, "host_ip6_addr",
13092                                    format (0, "%U/%d", format_ip6_address,
13093                                            mp->host_ip6_addr,
13094                                            mp->host_ip6_prefix_len));
13095
13096 }
13097
13098 static int
13099 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13100 {
13101   vl_api_sw_interface_tap_v2_dump_t *mp;
13102   vl_api_control_ping_t *mp_ping;
13103   int ret;
13104
13105   print (vam->ofp,
13106          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13107          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13108          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13109          "host_ip6_addr");
13110
13111   /* Get list of tap interfaces */
13112   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13113   S (mp);
13114
13115   /* Use a control ping for synchronization */
13116   MPING (CONTROL_PING, mp_ping);
13117   S (mp_ping);
13118
13119   W (ret);
13120   return ret;
13121 }
13122
13123 static int
13124 api_vxlan_offload_rx (vat_main_t * vam)
13125 {
13126   unformat_input_t *line_input = vam->input;
13127   vl_api_vxlan_offload_rx_t *mp;
13128   u32 hw_if_index = ~0, rx_if_index = ~0;
13129   u8 is_add = 1;
13130   int ret;
13131
13132   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13133     {
13134       if (unformat (line_input, "del"))
13135         is_add = 0;
13136       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13137                          &hw_if_index))
13138         ;
13139       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13140         ;
13141       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13142                          &rx_if_index))
13143         ;
13144       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13145         ;
13146       else
13147         {
13148           errmsg ("parse error '%U'", format_unformat_error, line_input);
13149           return -99;
13150         }
13151     }
13152
13153   if (hw_if_index == ~0)
13154     {
13155       errmsg ("no hw interface");
13156       return -99;
13157     }
13158
13159   if (rx_if_index == ~0)
13160     {
13161       errmsg ("no rx tunnel");
13162       return -99;
13163     }
13164
13165   M (VXLAN_OFFLOAD_RX, mp);
13166
13167   mp->hw_if_index = ntohl (hw_if_index);
13168   mp->sw_if_index = ntohl (rx_if_index);
13169   mp->enable = is_add;
13170
13171   S (mp);
13172   W (ret);
13173   return ret;
13174 }
13175
13176 static uword unformat_vxlan_decap_next
13177   (unformat_input_t * input, va_list * args)
13178 {
13179   u32 *result = va_arg (*args, u32 *);
13180   u32 tmp;
13181
13182   if (unformat (input, "l2"))
13183     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13184   else if (unformat (input, "%d", &tmp))
13185     *result = tmp;
13186   else
13187     return 0;
13188   return 1;
13189 }
13190
13191 static int
13192 api_vxlan_add_del_tunnel (vat_main_t * vam)
13193 {
13194   unformat_input_t *line_input = vam->input;
13195   vl_api_vxlan_add_del_tunnel_t *mp;
13196   ip46_address_t src, dst;
13197   u8 is_add = 1;
13198   u8 ipv4_set = 0, ipv6_set = 0;
13199   u8 src_set = 0;
13200   u8 dst_set = 0;
13201   u8 grp_set = 0;
13202   u32 instance = ~0;
13203   u32 mcast_sw_if_index = ~0;
13204   u32 encap_vrf_id = 0;
13205   u32 decap_next_index = ~0;
13206   u32 vni = 0;
13207   int ret;
13208
13209   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13210   memset (&src, 0, sizeof src);
13211   memset (&dst, 0, sizeof dst);
13212
13213   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13214     {
13215       if (unformat (line_input, "del"))
13216         is_add = 0;
13217       else if (unformat (line_input, "instance %d", &instance))
13218         ;
13219       else
13220         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13221         {
13222           ipv4_set = 1;
13223           src_set = 1;
13224         }
13225       else
13226         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13227         {
13228           ipv4_set = 1;
13229           dst_set = 1;
13230         }
13231       else
13232         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13233         {
13234           ipv6_set = 1;
13235           src_set = 1;
13236         }
13237       else
13238         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13239         {
13240           ipv6_set = 1;
13241           dst_set = 1;
13242         }
13243       else if (unformat (line_input, "group %U %U",
13244                          unformat_ip4_address, &dst.ip4,
13245                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13246         {
13247           grp_set = dst_set = 1;
13248           ipv4_set = 1;
13249         }
13250       else if (unformat (line_input, "group %U",
13251                          unformat_ip4_address, &dst.ip4))
13252         {
13253           grp_set = dst_set = 1;
13254           ipv4_set = 1;
13255         }
13256       else if (unformat (line_input, "group %U %U",
13257                          unformat_ip6_address, &dst.ip6,
13258                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13259         {
13260           grp_set = dst_set = 1;
13261           ipv6_set = 1;
13262         }
13263       else if (unformat (line_input, "group %U",
13264                          unformat_ip6_address, &dst.ip6))
13265         {
13266           grp_set = dst_set = 1;
13267           ipv6_set = 1;
13268         }
13269       else
13270         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13271         ;
13272       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13273         ;
13274       else if (unformat (line_input, "decap-next %U",
13275                          unformat_vxlan_decap_next, &decap_next_index))
13276         ;
13277       else if (unformat (line_input, "vni %d", &vni))
13278         ;
13279       else
13280         {
13281           errmsg ("parse error '%U'", format_unformat_error, line_input);
13282           return -99;
13283         }
13284     }
13285
13286   if (src_set == 0)
13287     {
13288       errmsg ("tunnel src address not specified");
13289       return -99;
13290     }
13291   if (dst_set == 0)
13292     {
13293       errmsg ("tunnel dst address not specified");
13294       return -99;
13295     }
13296
13297   if (grp_set && !ip46_address_is_multicast (&dst))
13298     {
13299       errmsg ("tunnel group address not multicast");
13300       return -99;
13301     }
13302   if (grp_set && mcast_sw_if_index == ~0)
13303     {
13304       errmsg ("tunnel nonexistent multicast device");
13305       return -99;
13306     }
13307   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13308     {
13309       errmsg ("tunnel dst address must be unicast");
13310       return -99;
13311     }
13312
13313
13314   if (ipv4_set && ipv6_set)
13315     {
13316       errmsg ("both IPv4 and IPv6 addresses specified");
13317       return -99;
13318     }
13319
13320   if ((vni == 0) || (vni >> 24))
13321     {
13322       errmsg ("vni not specified or out of range");
13323       return -99;
13324     }
13325
13326   M (VXLAN_ADD_DEL_TUNNEL, mp);
13327
13328   if (ipv6_set)
13329     {
13330       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13331       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13332     }
13333   else
13334     {
13335       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13336       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13337     }
13338
13339   mp->instance = htonl (instance);
13340   mp->encap_vrf_id = ntohl (encap_vrf_id);
13341   mp->decap_next_index = ntohl (decap_next_index);
13342   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13343   mp->vni = ntohl (vni);
13344   mp->is_add = is_add;
13345   mp->is_ipv6 = ipv6_set;
13346
13347   S (mp);
13348   W (ret);
13349   return ret;
13350 }
13351
13352 static void vl_api_vxlan_tunnel_details_t_handler
13353   (vl_api_vxlan_tunnel_details_t * mp)
13354 {
13355   vat_main_t *vam = &vat_main;
13356   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13357   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13358
13359   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13360          ntohl (mp->sw_if_index),
13361          ntohl (mp->instance),
13362          format_ip46_address, &src, IP46_TYPE_ANY,
13363          format_ip46_address, &dst, IP46_TYPE_ANY,
13364          ntohl (mp->encap_vrf_id),
13365          ntohl (mp->decap_next_index), ntohl (mp->vni),
13366          ntohl (mp->mcast_sw_if_index));
13367 }
13368
13369 static void vl_api_vxlan_tunnel_details_t_handler_json
13370   (vl_api_vxlan_tunnel_details_t * mp)
13371 {
13372   vat_main_t *vam = &vat_main;
13373   vat_json_node_t *node = NULL;
13374
13375   if (VAT_JSON_ARRAY != vam->json_tree.type)
13376     {
13377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13378       vat_json_init_array (&vam->json_tree);
13379     }
13380   node = vat_json_array_add (&vam->json_tree);
13381
13382   vat_json_init_object (node);
13383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13384
13385   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13386
13387   if (mp->is_ipv6)
13388     {
13389       struct in6_addr ip6;
13390
13391       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13392       vat_json_object_add_ip6 (node, "src_address", ip6);
13393       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13394       vat_json_object_add_ip6 (node, "dst_address", ip6);
13395     }
13396   else
13397     {
13398       struct in_addr ip4;
13399
13400       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13401       vat_json_object_add_ip4 (node, "src_address", ip4);
13402       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13403       vat_json_object_add_ip4 (node, "dst_address", ip4);
13404     }
13405   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13406   vat_json_object_add_uint (node, "decap_next_index",
13407                             ntohl (mp->decap_next_index));
13408   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13409   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13410   vat_json_object_add_uint (node, "mcast_sw_if_index",
13411                             ntohl (mp->mcast_sw_if_index));
13412 }
13413
13414 static int
13415 api_vxlan_tunnel_dump (vat_main_t * vam)
13416 {
13417   unformat_input_t *i = vam->input;
13418   vl_api_vxlan_tunnel_dump_t *mp;
13419   vl_api_control_ping_t *mp_ping;
13420   u32 sw_if_index;
13421   u8 sw_if_index_set = 0;
13422   int ret;
13423
13424   /* Parse args required to build the message */
13425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13426     {
13427       if (unformat (i, "sw_if_index %d", &sw_if_index))
13428         sw_if_index_set = 1;
13429       else
13430         break;
13431     }
13432
13433   if (sw_if_index_set == 0)
13434     {
13435       sw_if_index = ~0;
13436     }
13437
13438   if (!vam->json_output)
13439     {
13440       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13441              "sw_if_index", "instance", "src_address", "dst_address",
13442              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13443     }
13444
13445   /* Get list of vxlan-tunnel interfaces */
13446   M (VXLAN_TUNNEL_DUMP, mp);
13447
13448   mp->sw_if_index = htonl (sw_if_index);
13449
13450   S (mp);
13451
13452   /* Use a control ping for synchronization */
13453   MPING (CONTROL_PING, mp_ping);
13454   S (mp_ping);
13455
13456   W (ret);
13457   return ret;
13458 }
13459
13460 static uword unformat_geneve_decap_next
13461   (unformat_input_t * input, va_list * args)
13462 {
13463   u32 *result = va_arg (*args, u32 *);
13464   u32 tmp;
13465
13466   if (unformat (input, "l2"))
13467     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13468   else if (unformat (input, "%d", &tmp))
13469     *result = tmp;
13470   else
13471     return 0;
13472   return 1;
13473 }
13474
13475 static int
13476 api_geneve_add_del_tunnel (vat_main_t * vam)
13477 {
13478   unformat_input_t *line_input = vam->input;
13479   vl_api_geneve_add_del_tunnel_t *mp;
13480   ip46_address_t src, dst;
13481   u8 is_add = 1;
13482   u8 ipv4_set = 0, ipv6_set = 0;
13483   u8 src_set = 0;
13484   u8 dst_set = 0;
13485   u8 grp_set = 0;
13486   u32 mcast_sw_if_index = ~0;
13487   u32 encap_vrf_id = 0;
13488   u32 decap_next_index = ~0;
13489   u32 vni = 0;
13490   int ret;
13491
13492   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13493   memset (&src, 0, sizeof src);
13494   memset (&dst, 0, sizeof dst);
13495
13496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13497     {
13498       if (unformat (line_input, "del"))
13499         is_add = 0;
13500       else
13501         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13502         {
13503           ipv4_set = 1;
13504           src_set = 1;
13505         }
13506       else
13507         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13508         {
13509           ipv4_set = 1;
13510           dst_set = 1;
13511         }
13512       else
13513         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13514         {
13515           ipv6_set = 1;
13516           src_set = 1;
13517         }
13518       else
13519         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13520         {
13521           ipv6_set = 1;
13522           dst_set = 1;
13523         }
13524       else if (unformat (line_input, "group %U %U",
13525                          unformat_ip4_address, &dst.ip4,
13526                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13527         {
13528           grp_set = dst_set = 1;
13529           ipv4_set = 1;
13530         }
13531       else if (unformat (line_input, "group %U",
13532                          unformat_ip4_address, &dst.ip4))
13533         {
13534           grp_set = dst_set = 1;
13535           ipv4_set = 1;
13536         }
13537       else if (unformat (line_input, "group %U %U",
13538                          unformat_ip6_address, &dst.ip6,
13539                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13540         {
13541           grp_set = dst_set = 1;
13542           ipv6_set = 1;
13543         }
13544       else if (unformat (line_input, "group %U",
13545                          unformat_ip6_address, &dst.ip6))
13546         {
13547           grp_set = dst_set = 1;
13548           ipv6_set = 1;
13549         }
13550       else
13551         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13552         ;
13553       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13554         ;
13555       else if (unformat (line_input, "decap-next %U",
13556                          unformat_geneve_decap_next, &decap_next_index))
13557         ;
13558       else if (unformat (line_input, "vni %d", &vni))
13559         ;
13560       else
13561         {
13562           errmsg ("parse error '%U'", format_unformat_error, line_input);
13563           return -99;
13564         }
13565     }
13566
13567   if (src_set == 0)
13568     {
13569       errmsg ("tunnel src address not specified");
13570       return -99;
13571     }
13572   if (dst_set == 0)
13573     {
13574       errmsg ("tunnel dst address not specified");
13575       return -99;
13576     }
13577
13578   if (grp_set && !ip46_address_is_multicast (&dst))
13579     {
13580       errmsg ("tunnel group address not multicast");
13581       return -99;
13582     }
13583   if (grp_set && mcast_sw_if_index == ~0)
13584     {
13585       errmsg ("tunnel nonexistent multicast device");
13586       return -99;
13587     }
13588   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13589     {
13590       errmsg ("tunnel dst address must be unicast");
13591       return -99;
13592     }
13593
13594
13595   if (ipv4_set && ipv6_set)
13596     {
13597       errmsg ("both IPv4 and IPv6 addresses specified");
13598       return -99;
13599     }
13600
13601   if ((vni == 0) || (vni >> 24))
13602     {
13603       errmsg ("vni not specified or out of range");
13604       return -99;
13605     }
13606
13607   M (GENEVE_ADD_DEL_TUNNEL, mp);
13608
13609   if (ipv6_set)
13610     {
13611       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13612       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13613     }
13614   else
13615     {
13616       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13617       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13618     }
13619   mp->encap_vrf_id = ntohl (encap_vrf_id);
13620   mp->decap_next_index = ntohl (decap_next_index);
13621   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13622   mp->vni = ntohl (vni);
13623   mp->is_add = is_add;
13624   mp->is_ipv6 = ipv6_set;
13625
13626   S (mp);
13627   W (ret);
13628   return ret;
13629 }
13630
13631 static void vl_api_geneve_tunnel_details_t_handler
13632   (vl_api_geneve_tunnel_details_t * mp)
13633 {
13634   vat_main_t *vam = &vat_main;
13635   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13636   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13637
13638   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13639          ntohl (mp->sw_if_index),
13640          format_ip46_address, &src, IP46_TYPE_ANY,
13641          format_ip46_address, &dst, IP46_TYPE_ANY,
13642          ntohl (mp->encap_vrf_id),
13643          ntohl (mp->decap_next_index), ntohl (mp->vni),
13644          ntohl (mp->mcast_sw_if_index));
13645 }
13646
13647 static void vl_api_geneve_tunnel_details_t_handler_json
13648   (vl_api_geneve_tunnel_details_t * mp)
13649 {
13650   vat_main_t *vam = &vat_main;
13651   vat_json_node_t *node = NULL;
13652
13653   if (VAT_JSON_ARRAY != vam->json_tree.type)
13654     {
13655       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13656       vat_json_init_array (&vam->json_tree);
13657     }
13658   node = vat_json_array_add (&vam->json_tree);
13659
13660   vat_json_init_object (node);
13661   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13662   if (mp->is_ipv6)
13663     {
13664       struct in6_addr ip6;
13665
13666       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13667       vat_json_object_add_ip6 (node, "src_address", ip6);
13668       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13669       vat_json_object_add_ip6 (node, "dst_address", ip6);
13670     }
13671   else
13672     {
13673       struct in_addr ip4;
13674
13675       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13676       vat_json_object_add_ip4 (node, "src_address", ip4);
13677       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13678       vat_json_object_add_ip4 (node, "dst_address", ip4);
13679     }
13680   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13681   vat_json_object_add_uint (node, "decap_next_index",
13682                             ntohl (mp->decap_next_index));
13683   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13684   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13685   vat_json_object_add_uint (node, "mcast_sw_if_index",
13686                             ntohl (mp->mcast_sw_if_index));
13687 }
13688
13689 static int
13690 api_geneve_tunnel_dump (vat_main_t * vam)
13691 {
13692   unformat_input_t *i = vam->input;
13693   vl_api_geneve_tunnel_dump_t *mp;
13694   vl_api_control_ping_t *mp_ping;
13695   u32 sw_if_index;
13696   u8 sw_if_index_set = 0;
13697   int ret;
13698
13699   /* Parse args required to build the message */
13700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13701     {
13702       if (unformat (i, "sw_if_index %d", &sw_if_index))
13703         sw_if_index_set = 1;
13704       else
13705         break;
13706     }
13707
13708   if (sw_if_index_set == 0)
13709     {
13710       sw_if_index = ~0;
13711     }
13712
13713   if (!vam->json_output)
13714     {
13715       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13716              "sw_if_index", "local_address", "remote_address",
13717              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13718     }
13719
13720   /* Get list of geneve-tunnel interfaces */
13721   M (GENEVE_TUNNEL_DUMP, mp);
13722
13723   mp->sw_if_index = htonl (sw_if_index);
13724
13725   S (mp);
13726
13727   /* Use a control ping for synchronization */
13728   M (CONTROL_PING, mp_ping);
13729   S (mp_ping);
13730
13731   W (ret);
13732   return ret;
13733 }
13734
13735 static int
13736 api_gre_add_del_tunnel (vat_main_t * vam)
13737 {
13738   unformat_input_t *line_input = vam->input;
13739   vl_api_gre_add_del_tunnel_t *mp;
13740   ip4_address_t src4, dst4;
13741   ip6_address_t src6, dst6;
13742   u8 is_add = 1;
13743   u8 ipv4_set = 0;
13744   u8 ipv6_set = 0;
13745   u8 t_type = GRE_TUNNEL_TYPE_L3;
13746   u8 src_set = 0;
13747   u8 dst_set = 0;
13748   u32 outer_fib_id = 0;
13749   u32 session_id = 0;
13750   u32 instance = ~0;
13751   int ret;
13752
13753   memset (&src4, 0, sizeof src4);
13754   memset (&dst4, 0, sizeof dst4);
13755   memset (&src6, 0, sizeof src6);
13756   memset (&dst6, 0, sizeof dst6);
13757
13758   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13759     {
13760       if (unformat (line_input, "del"))
13761         is_add = 0;
13762       else if (unformat (line_input, "instance %d", &instance))
13763         ;
13764       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13765         {
13766           src_set = 1;
13767           ipv4_set = 1;
13768         }
13769       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13770         {
13771           dst_set = 1;
13772           ipv4_set = 1;
13773         }
13774       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13775         {
13776           src_set = 1;
13777           ipv6_set = 1;
13778         }
13779       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13780         {
13781           dst_set = 1;
13782           ipv6_set = 1;
13783         }
13784       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13785         ;
13786       else if (unformat (line_input, "teb"))
13787         t_type = GRE_TUNNEL_TYPE_TEB;
13788       else if (unformat (line_input, "erspan %d", &session_id))
13789         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13790       else
13791         {
13792           errmsg ("parse error '%U'", format_unformat_error, line_input);
13793           return -99;
13794         }
13795     }
13796
13797   if (src_set == 0)
13798     {
13799       errmsg ("tunnel src address not specified");
13800       return -99;
13801     }
13802   if (dst_set == 0)
13803     {
13804       errmsg ("tunnel dst address not specified");
13805       return -99;
13806     }
13807   if (ipv4_set && ipv6_set)
13808     {
13809       errmsg ("both IPv4 and IPv6 addresses specified");
13810       return -99;
13811     }
13812
13813
13814   M (GRE_ADD_DEL_TUNNEL, mp);
13815
13816   if (ipv4_set)
13817     {
13818       clib_memcpy (&mp->src_address, &src4, 4);
13819       clib_memcpy (&mp->dst_address, &dst4, 4);
13820     }
13821   else
13822     {
13823       clib_memcpy (&mp->src_address, &src6, 16);
13824       clib_memcpy (&mp->dst_address, &dst6, 16);
13825     }
13826   mp->instance = htonl (instance);
13827   mp->outer_fib_id = htonl (outer_fib_id);
13828   mp->is_add = is_add;
13829   mp->session_id = htons ((u16) session_id);
13830   mp->tunnel_type = t_type;
13831   mp->is_ipv6 = ipv6_set;
13832
13833   S (mp);
13834   W (ret);
13835   return ret;
13836 }
13837
13838 static void vl_api_gre_tunnel_details_t_handler
13839   (vl_api_gre_tunnel_details_t * mp)
13840 {
13841   vat_main_t *vam = &vat_main;
13842   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13843   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13844
13845   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13846          ntohl (mp->sw_if_index),
13847          ntohl (mp->instance),
13848          format_ip46_address, &src, IP46_TYPE_ANY,
13849          format_ip46_address, &dst, IP46_TYPE_ANY,
13850          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
13851 }
13852
13853 static void vl_api_gre_tunnel_details_t_handler_json
13854   (vl_api_gre_tunnel_details_t * mp)
13855 {
13856   vat_main_t *vam = &vat_main;
13857   vat_json_node_t *node = NULL;
13858   struct in_addr ip4;
13859   struct in6_addr ip6;
13860
13861   if (VAT_JSON_ARRAY != vam->json_tree.type)
13862     {
13863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13864       vat_json_init_array (&vam->json_tree);
13865     }
13866   node = vat_json_array_add (&vam->json_tree);
13867
13868   vat_json_init_object (node);
13869   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13870   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13871   if (!mp->is_ipv6)
13872     {
13873       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
13874       vat_json_object_add_ip4 (node, "src_address", ip4);
13875       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
13876       vat_json_object_add_ip4 (node, "dst_address", ip4);
13877     }
13878   else
13879     {
13880       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
13881       vat_json_object_add_ip6 (node, "src_address", ip6);
13882       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
13883       vat_json_object_add_ip6 (node, "dst_address", ip6);
13884     }
13885   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
13886   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
13887   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
13888   vat_json_object_add_uint (node, "session_id", mp->session_id);
13889 }
13890
13891 static int
13892 api_gre_tunnel_dump (vat_main_t * vam)
13893 {
13894   unformat_input_t *i = vam->input;
13895   vl_api_gre_tunnel_dump_t *mp;
13896   vl_api_control_ping_t *mp_ping;
13897   u32 sw_if_index;
13898   u8 sw_if_index_set = 0;
13899   int ret;
13900
13901   /* Parse args required to build the message */
13902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13903     {
13904       if (unformat (i, "sw_if_index %d", &sw_if_index))
13905         sw_if_index_set = 1;
13906       else
13907         break;
13908     }
13909
13910   if (sw_if_index_set == 0)
13911     {
13912       sw_if_index = ~0;
13913     }
13914
13915   if (!vam->json_output)
13916     {
13917       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
13918              "sw_if_index", "instance", "src_address", "dst_address",
13919              "tunnel_type", "outer_fib_id", "session_id");
13920     }
13921
13922   /* Get list of gre-tunnel interfaces */
13923   M (GRE_TUNNEL_DUMP, mp);
13924
13925   mp->sw_if_index = htonl (sw_if_index);
13926
13927   S (mp);
13928
13929   /* Use a control ping for synchronization */
13930   MPING (CONTROL_PING, mp_ping);
13931   S (mp_ping);
13932
13933   W (ret);
13934   return ret;
13935 }
13936
13937 static int
13938 api_l2_fib_clear_table (vat_main_t * vam)
13939 {
13940 //  unformat_input_t * i = vam->input;
13941   vl_api_l2_fib_clear_table_t *mp;
13942   int ret;
13943
13944   M (L2_FIB_CLEAR_TABLE, mp);
13945
13946   S (mp);
13947   W (ret);
13948   return ret;
13949 }
13950
13951 static int
13952 api_l2_interface_efp_filter (vat_main_t * vam)
13953 {
13954   unformat_input_t *i = vam->input;
13955   vl_api_l2_interface_efp_filter_t *mp;
13956   u32 sw_if_index;
13957   u8 enable = 1;
13958   u8 sw_if_index_set = 0;
13959   int ret;
13960
13961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13962     {
13963       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13964         sw_if_index_set = 1;
13965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13966         sw_if_index_set = 1;
13967       else if (unformat (i, "enable"))
13968         enable = 1;
13969       else if (unformat (i, "disable"))
13970         enable = 0;
13971       else
13972         {
13973           clib_warning ("parse error '%U'", format_unformat_error, i);
13974           return -99;
13975         }
13976     }
13977
13978   if (sw_if_index_set == 0)
13979     {
13980       errmsg ("missing sw_if_index");
13981       return -99;
13982     }
13983
13984   M (L2_INTERFACE_EFP_FILTER, mp);
13985
13986   mp->sw_if_index = ntohl (sw_if_index);
13987   mp->enable_disable = enable;
13988
13989   S (mp);
13990   W (ret);
13991   return ret;
13992 }
13993
13994 #define foreach_vtr_op                          \
13995 _("disable",  L2_VTR_DISABLED)                  \
13996 _("push-1",  L2_VTR_PUSH_1)                     \
13997 _("push-2",  L2_VTR_PUSH_2)                     \
13998 _("pop-1",  L2_VTR_POP_1)                       \
13999 _("pop-2",  L2_VTR_POP_2)                       \
14000 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14001 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14002 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14003 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14004
14005 static int
14006 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14007 {
14008   unformat_input_t *i = vam->input;
14009   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14010   u32 sw_if_index;
14011   u8 sw_if_index_set = 0;
14012   u8 vtr_op_set = 0;
14013   u32 vtr_op = 0;
14014   u32 push_dot1q = 1;
14015   u32 tag1 = ~0;
14016   u32 tag2 = ~0;
14017   int ret;
14018
14019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14020     {
14021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14022         sw_if_index_set = 1;
14023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14024         sw_if_index_set = 1;
14025       else if (unformat (i, "vtr_op %d", &vtr_op))
14026         vtr_op_set = 1;
14027 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14028       foreach_vtr_op
14029 #undef _
14030         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14031         ;
14032       else if (unformat (i, "tag1 %d", &tag1))
14033         ;
14034       else if (unformat (i, "tag2 %d", &tag2))
14035         ;
14036       else
14037         {
14038           clib_warning ("parse error '%U'", format_unformat_error, i);
14039           return -99;
14040         }
14041     }
14042
14043   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14044     {
14045       errmsg ("missing vtr operation or sw_if_index");
14046       return -99;
14047     }
14048
14049   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14050   mp->sw_if_index = ntohl (sw_if_index);
14051   mp->vtr_op = ntohl (vtr_op);
14052   mp->push_dot1q = ntohl (push_dot1q);
14053   mp->tag1 = ntohl (tag1);
14054   mp->tag2 = ntohl (tag2);
14055
14056   S (mp);
14057   W (ret);
14058   return ret;
14059 }
14060
14061 static int
14062 api_create_vhost_user_if (vat_main_t * vam)
14063 {
14064   unformat_input_t *i = vam->input;
14065   vl_api_create_vhost_user_if_t *mp;
14066   u8 *file_name;
14067   u8 is_server = 0;
14068   u8 file_name_set = 0;
14069   u32 custom_dev_instance = ~0;
14070   u8 hwaddr[6];
14071   u8 use_custom_mac = 0;
14072   u8 disable_mrg_rxbuf = 0;
14073   u8 disable_indirect_desc = 0;
14074   u8 *tag = 0;
14075   int ret;
14076
14077   /* Shut up coverity */
14078   memset (hwaddr, 0, sizeof (hwaddr));
14079
14080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (i, "socket %s", &file_name))
14083         {
14084           file_name_set = 1;
14085         }
14086       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14087         ;
14088       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14089         use_custom_mac = 1;
14090       else if (unformat (i, "server"))
14091         is_server = 1;
14092       else if (unformat (i, "disable_mrg_rxbuf"))
14093         disable_mrg_rxbuf = 1;
14094       else if (unformat (i, "disable_indirect_desc"))
14095         disable_indirect_desc = 1;
14096       else if (unformat (i, "tag %s", &tag))
14097         ;
14098       else
14099         break;
14100     }
14101
14102   if (file_name_set == 0)
14103     {
14104       errmsg ("missing socket file name");
14105       return -99;
14106     }
14107
14108   if (vec_len (file_name) > 255)
14109     {
14110       errmsg ("socket file name too long");
14111       return -99;
14112     }
14113   vec_add1 (file_name, 0);
14114
14115   M (CREATE_VHOST_USER_IF, mp);
14116
14117   mp->is_server = is_server;
14118   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14119   mp->disable_indirect_desc = disable_indirect_desc;
14120   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14121   vec_free (file_name);
14122   if (custom_dev_instance != ~0)
14123     {
14124       mp->renumber = 1;
14125       mp->custom_dev_instance = ntohl (custom_dev_instance);
14126     }
14127
14128   mp->use_custom_mac = use_custom_mac;
14129   clib_memcpy (mp->mac_address, hwaddr, 6);
14130   if (tag)
14131     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14132   vec_free (tag);
14133
14134   S (mp);
14135   W (ret);
14136   return ret;
14137 }
14138
14139 static int
14140 api_modify_vhost_user_if (vat_main_t * vam)
14141 {
14142   unformat_input_t *i = vam->input;
14143   vl_api_modify_vhost_user_if_t *mp;
14144   u8 *file_name;
14145   u8 is_server = 0;
14146   u8 file_name_set = 0;
14147   u32 custom_dev_instance = ~0;
14148   u8 sw_if_index_set = 0;
14149   u32 sw_if_index = (u32) ~ 0;
14150   int ret;
14151
14152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14153     {
14154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14155         sw_if_index_set = 1;
14156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14157         sw_if_index_set = 1;
14158       else if (unformat (i, "socket %s", &file_name))
14159         {
14160           file_name_set = 1;
14161         }
14162       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14163         ;
14164       else if (unformat (i, "server"))
14165         is_server = 1;
14166       else
14167         break;
14168     }
14169
14170   if (sw_if_index_set == 0)
14171     {
14172       errmsg ("missing sw_if_index or interface name");
14173       return -99;
14174     }
14175
14176   if (file_name_set == 0)
14177     {
14178       errmsg ("missing socket file name");
14179       return -99;
14180     }
14181
14182   if (vec_len (file_name) > 255)
14183     {
14184       errmsg ("socket file name too long");
14185       return -99;
14186     }
14187   vec_add1 (file_name, 0);
14188
14189   M (MODIFY_VHOST_USER_IF, mp);
14190
14191   mp->sw_if_index = ntohl (sw_if_index);
14192   mp->is_server = is_server;
14193   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14194   vec_free (file_name);
14195   if (custom_dev_instance != ~0)
14196     {
14197       mp->renumber = 1;
14198       mp->custom_dev_instance = ntohl (custom_dev_instance);
14199     }
14200
14201   S (mp);
14202   W (ret);
14203   return ret;
14204 }
14205
14206 static int
14207 api_delete_vhost_user_if (vat_main_t * vam)
14208 {
14209   unformat_input_t *i = vam->input;
14210   vl_api_delete_vhost_user_if_t *mp;
14211   u32 sw_if_index = ~0;
14212   u8 sw_if_index_set = 0;
14213   int ret;
14214
14215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14216     {
14217       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14218         sw_if_index_set = 1;
14219       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14220         sw_if_index_set = 1;
14221       else
14222         break;
14223     }
14224
14225   if (sw_if_index_set == 0)
14226     {
14227       errmsg ("missing sw_if_index or interface name");
14228       return -99;
14229     }
14230
14231
14232   M (DELETE_VHOST_USER_IF, mp);
14233
14234   mp->sw_if_index = ntohl (sw_if_index);
14235
14236   S (mp);
14237   W (ret);
14238   return ret;
14239 }
14240
14241 static void vl_api_sw_interface_vhost_user_details_t_handler
14242   (vl_api_sw_interface_vhost_user_details_t * mp)
14243 {
14244   vat_main_t *vam = &vat_main;
14245
14246   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14247          (char *) mp->interface_name,
14248          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14249          clib_net_to_host_u64 (mp->features), mp->is_server,
14250          ntohl (mp->num_regions), (char *) mp->sock_filename);
14251   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14252 }
14253
14254 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14255   (vl_api_sw_interface_vhost_user_details_t * mp)
14256 {
14257   vat_main_t *vam = &vat_main;
14258   vat_json_node_t *node = NULL;
14259
14260   if (VAT_JSON_ARRAY != vam->json_tree.type)
14261     {
14262       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14263       vat_json_init_array (&vam->json_tree);
14264     }
14265   node = vat_json_array_add (&vam->json_tree);
14266
14267   vat_json_init_object (node);
14268   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14269   vat_json_object_add_string_copy (node, "interface_name",
14270                                    mp->interface_name);
14271   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14272                             ntohl (mp->virtio_net_hdr_sz));
14273   vat_json_object_add_uint (node, "features",
14274                             clib_net_to_host_u64 (mp->features));
14275   vat_json_object_add_uint (node, "is_server", mp->is_server);
14276   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14277   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14278   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14279 }
14280
14281 static int
14282 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14283 {
14284   vl_api_sw_interface_vhost_user_dump_t *mp;
14285   vl_api_control_ping_t *mp_ping;
14286   int ret;
14287   print (vam->ofp,
14288          "Interface name            idx hdr_sz features server regions filename");
14289
14290   /* Get list of vhost-user interfaces */
14291   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14292   S (mp);
14293
14294   /* Use a control ping for synchronization */
14295   MPING (CONTROL_PING, mp_ping);
14296   S (mp_ping);
14297
14298   W (ret);
14299   return ret;
14300 }
14301
14302 static int
14303 api_show_version (vat_main_t * vam)
14304 {
14305   vl_api_show_version_t *mp;
14306   int ret;
14307
14308   M (SHOW_VERSION, mp);
14309
14310   S (mp);
14311   W (ret);
14312   return ret;
14313 }
14314
14315
14316 static int
14317 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14318 {
14319   unformat_input_t *line_input = vam->input;
14320   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14321   ip4_address_t local4, remote4;
14322   ip6_address_t local6, remote6;
14323   u8 is_add = 1;
14324   u8 ipv4_set = 0, ipv6_set = 0;
14325   u8 local_set = 0;
14326   u8 remote_set = 0;
14327   u8 grp_set = 0;
14328   u32 mcast_sw_if_index = ~0;
14329   u32 encap_vrf_id = 0;
14330   u32 decap_vrf_id = 0;
14331   u8 protocol = ~0;
14332   u32 vni;
14333   u8 vni_set = 0;
14334   int ret;
14335
14336   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14337   memset (&local4, 0, sizeof local4);
14338   memset (&remote4, 0, sizeof remote4);
14339   memset (&local6, 0, sizeof local6);
14340   memset (&remote6, 0, sizeof remote6);
14341
14342   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14343     {
14344       if (unformat (line_input, "del"))
14345         is_add = 0;
14346       else if (unformat (line_input, "local %U",
14347                          unformat_ip4_address, &local4))
14348         {
14349           local_set = 1;
14350           ipv4_set = 1;
14351         }
14352       else if (unformat (line_input, "remote %U",
14353                          unformat_ip4_address, &remote4))
14354         {
14355           remote_set = 1;
14356           ipv4_set = 1;
14357         }
14358       else if (unformat (line_input, "local %U",
14359                          unformat_ip6_address, &local6))
14360         {
14361           local_set = 1;
14362           ipv6_set = 1;
14363         }
14364       else if (unformat (line_input, "remote %U",
14365                          unformat_ip6_address, &remote6))
14366         {
14367           remote_set = 1;
14368           ipv6_set = 1;
14369         }
14370       else if (unformat (line_input, "group %U %U",
14371                          unformat_ip4_address, &remote4,
14372                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14373         {
14374           grp_set = remote_set = 1;
14375           ipv4_set = 1;
14376         }
14377       else if (unformat (line_input, "group %U",
14378                          unformat_ip4_address, &remote4))
14379         {
14380           grp_set = remote_set = 1;
14381           ipv4_set = 1;
14382         }
14383       else if (unformat (line_input, "group %U %U",
14384                          unformat_ip6_address, &remote6,
14385                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14386         {
14387           grp_set = remote_set = 1;
14388           ipv6_set = 1;
14389         }
14390       else if (unformat (line_input, "group %U",
14391                          unformat_ip6_address, &remote6))
14392         {
14393           grp_set = remote_set = 1;
14394           ipv6_set = 1;
14395         }
14396       else
14397         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14398         ;
14399       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14400         ;
14401       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14402         ;
14403       else if (unformat (line_input, "vni %d", &vni))
14404         vni_set = 1;
14405       else if (unformat (line_input, "next-ip4"))
14406         protocol = 1;
14407       else if (unformat (line_input, "next-ip6"))
14408         protocol = 2;
14409       else if (unformat (line_input, "next-ethernet"))
14410         protocol = 3;
14411       else if (unformat (line_input, "next-nsh"))
14412         protocol = 4;
14413       else
14414         {
14415           errmsg ("parse error '%U'", format_unformat_error, line_input);
14416           return -99;
14417         }
14418     }
14419
14420   if (local_set == 0)
14421     {
14422       errmsg ("tunnel local address not specified");
14423       return -99;
14424     }
14425   if (remote_set == 0)
14426     {
14427       errmsg ("tunnel remote address not specified");
14428       return -99;
14429     }
14430   if (grp_set && mcast_sw_if_index == ~0)
14431     {
14432       errmsg ("tunnel nonexistent multicast device");
14433       return -99;
14434     }
14435   if (ipv4_set && ipv6_set)
14436     {
14437       errmsg ("both IPv4 and IPv6 addresses specified");
14438       return -99;
14439     }
14440
14441   if (vni_set == 0)
14442     {
14443       errmsg ("vni not specified");
14444       return -99;
14445     }
14446
14447   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14448
14449
14450   if (ipv6_set)
14451     {
14452       clib_memcpy (&mp->local, &local6, sizeof (local6));
14453       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14454     }
14455   else
14456     {
14457       clib_memcpy (&mp->local, &local4, sizeof (local4));
14458       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14459     }
14460
14461   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14462   mp->encap_vrf_id = ntohl (encap_vrf_id);
14463   mp->decap_vrf_id = ntohl (decap_vrf_id);
14464   mp->protocol = protocol;
14465   mp->vni = ntohl (vni);
14466   mp->is_add = is_add;
14467   mp->is_ipv6 = ipv6_set;
14468
14469   S (mp);
14470   W (ret);
14471   return ret;
14472 }
14473
14474 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14475   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14476 {
14477   vat_main_t *vam = &vat_main;
14478   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14479   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14480
14481   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14482          ntohl (mp->sw_if_index),
14483          format_ip46_address, &local, IP46_TYPE_ANY,
14484          format_ip46_address, &remote, IP46_TYPE_ANY,
14485          ntohl (mp->vni), mp->protocol,
14486          ntohl (mp->mcast_sw_if_index),
14487          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14488 }
14489
14490
14491 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14492   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14493 {
14494   vat_main_t *vam = &vat_main;
14495   vat_json_node_t *node = NULL;
14496   struct in_addr ip4;
14497   struct in6_addr ip6;
14498
14499   if (VAT_JSON_ARRAY != vam->json_tree.type)
14500     {
14501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14502       vat_json_init_array (&vam->json_tree);
14503     }
14504   node = vat_json_array_add (&vam->json_tree);
14505
14506   vat_json_init_object (node);
14507   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14508   if (mp->is_ipv6)
14509     {
14510       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14511       vat_json_object_add_ip6 (node, "local", ip6);
14512       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14513       vat_json_object_add_ip6 (node, "remote", ip6);
14514     }
14515   else
14516     {
14517       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14518       vat_json_object_add_ip4 (node, "local", ip4);
14519       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14520       vat_json_object_add_ip4 (node, "remote", ip4);
14521     }
14522   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14523   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14524   vat_json_object_add_uint (node, "mcast_sw_if_index",
14525                             ntohl (mp->mcast_sw_if_index));
14526   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14527   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14528   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14529 }
14530
14531 static int
14532 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14533 {
14534   unformat_input_t *i = vam->input;
14535   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14536   vl_api_control_ping_t *mp_ping;
14537   u32 sw_if_index;
14538   u8 sw_if_index_set = 0;
14539   int ret;
14540
14541   /* Parse args required to build the message */
14542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14543     {
14544       if (unformat (i, "sw_if_index %d", &sw_if_index))
14545         sw_if_index_set = 1;
14546       else
14547         break;
14548     }
14549
14550   if (sw_if_index_set == 0)
14551     {
14552       sw_if_index = ~0;
14553     }
14554
14555   if (!vam->json_output)
14556     {
14557       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14558              "sw_if_index", "local", "remote", "vni",
14559              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14560     }
14561
14562   /* Get list of vxlan-tunnel interfaces */
14563   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14564
14565   mp->sw_if_index = htonl (sw_if_index);
14566
14567   S (mp);
14568
14569   /* Use a control ping for synchronization */
14570   MPING (CONTROL_PING, mp_ping);
14571   S (mp_ping);
14572
14573   W (ret);
14574   return ret;
14575 }
14576
14577 static void vl_api_l2_fib_table_details_t_handler
14578   (vl_api_l2_fib_table_details_t * mp)
14579 {
14580   vat_main_t *vam = &vat_main;
14581
14582   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14583          "       %d       %d     %d",
14584          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14585          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14586          mp->bvi_mac);
14587 }
14588
14589 static void vl_api_l2_fib_table_details_t_handler_json
14590   (vl_api_l2_fib_table_details_t * mp)
14591 {
14592   vat_main_t *vam = &vat_main;
14593   vat_json_node_t *node = NULL;
14594
14595   if (VAT_JSON_ARRAY != vam->json_tree.type)
14596     {
14597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14598       vat_json_init_array (&vam->json_tree);
14599     }
14600   node = vat_json_array_add (&vam->json_tree);
14601
14602   vat_json_init_object (node);
14603   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14604   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14605   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14606   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14607   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14608   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14609 }
14610
14611 static int
14612 api_l2_fib_table_dump (vat_main_t * vam)
14613 {
14614   unformat_input_t *i = vam->input;
14615   vl_api_l2_fib_table_dump_t *mp;
14616   vl_api_control_ping_t *mp_ping;
14617   u32 bd_id;
14618   u8 bd_id_set = 0;
14619   int ret;
14620
14621   /* Parse args required to build the message */
14622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14623     {
14624       if (unformat (i, "bd_id %d", &bd_id))
14625         bd_id_set = 1;
14626       else
14627         break;
14628     }
14629
14630   if (bd_id_set == 0)
14631     {
14632       errmsg ("missing bridge domain");
14633       return -99;
14634     }
14635
14636   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14637
14638   /* Get list of l2 fib entries */
14639   M (L2_FIB_TABLE_DUMP, mp);
14640
14641   mp->bd_id = ntohl (bd_id);
14642   S (mp);
14643
14644   /* Use a control ping for synchronization */
14645   MPING (CONTROL_PING, mp_ping);
14646   S (mp_ping);
14647
14648   W (ret);
14649   return ret;
14650 }
14651
14652
14653 static int
14654 api_interface_name_renumber (vat_main_t * vam)
14655 {
14656   unformat_input_t *line_input = vam->input;
14657   vl_api_interface_name_renumber_t *mp;
14658   u32 sw_if_index = ~0;
14659   u32 new_show_dev_instance = ~0;
14660   int ret;
14661
14662   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14665                     &sw_if_index))
14666         ;
14667       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14668         ;
14669       else if (unformat (line_input, "new_show_dev_instance %d",
14670                          &new_show_dev_instance))
14671         ;
14672       else
14673         break;
14674     }
14675
14676   if (sw_if_index == ~0)
14677     {
14678       errmsg ("missing interface name or sw_if_index");
14679       return -99;
14680     }
14681
14682   if (new_show_dev_instance == ~0)
14683     {
14684       errmsg ("missing new_show_dev_instance");
14685       return -99;
14686     }
14687
14688   M (INTERFACE_NAME_RENUMBER, mp);
14689
14690   mp->sw_if_index = ntohl (sw_if_index);
14691   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14692
14693   S (mp);
14694   W (ret);
14695   return ret;
14696 }
14697
14698 static int
14699 api_ip_probe_neighbor (vat_main_t * vam)
14700 {
14701   unformat_input_t *i = vam->input;
14702   vl_api_ip_probe_neighbor_t *mp;
14703   u8 int_set = 0;
14704   u8 adr_set = 0;
14705   u8 is_ipv6 = 0;
14706   u8 dst_adr[16];
14707   u32 sw_if_index;
14708   int ret;
14709
14710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14711     {
14712       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14713         int_set = 1;
14714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14715         int_set = 1;
14716       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14717         adr_set = 1;
14718       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14719         {
14720           adr_set = 1;
14721           is_ipv6 = 1;
14722         }
14723       else
14724         break;
14725     }
14726
14727   if (int_set == 0)
14728     {
14729       errmsg ("missing interface");
14730       return -99;
14731     }
14732
14733   if (adr_set == 0)
14734     {
14735       errmsg ("missing addresses");
14736       return -99;
14737     }
14738
14739   M (IP_PROBE_NEIGHBOR, mp);
14740
14741   mp->sw_if_index = ntohl (sw_if_index);
14742   mp->is_ipv6 = is_ipv6;
14743   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14744
14745   S (mp);
14746   W (ret);
14747   return ret;
14748 }
14749
14750 static int
14751 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14752 {
14753   unformat_input_t *i = vam->input;
14754   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14755   u8 mode = IP_SCAN_V46_NEIGHBORS;
14756   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14757   int ret;
14758
14759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14760     {
14761       if (unformat (i, "ip4"))
14762         mode = IP_SCAN_V4_NEIGHBORS;
14763       else if (unformat (i, "ip6"))
14764         mode = IP_SCAN_V6_NEIGHBORS;
14765       if (unformat (i, "both"))
14766         mode = IP_SCAN_V46_NEIGHBORS;
14767       else if (unformat (i, "disable"))
14768         mode = IP_SCAN_DISABLED;
14769       else if (unformat (i, "interval %d", &interval))
14770         ;
14771       else if (unformat (i, "max-time %d", &time))
14772         ;
14773       else if (unformat (i, "max-update %d", &update))
14774         ;
14775       else if (unformat (i, "delay %d", &delay))
14776         ;
14777       else if (unformat (i, "stale %d", &stale))
14778         ;
14779       else
14780         break;
14781     }
14782
14783   if (interval > 255)
14784     {
14785       errmsg ("interval cannot exceed 255 minutes.");
14786       return -99;
14787     }
14788   if (time > 255)
14789     {
14790       errmsg ("max-time cannot exceed 255 usec.");
14791       return -99;
14792     }
14793   if (update > 255)
14794     {
14795       errmsg ("max-update cannot exceed 255.");
14796       return -99;
14797     }
14798   if (delay > 255)
14799     {
14800       errmsg ("delay cannot exceed 255 msec.");
14801       return -99;
14802     }
14803   if (stale > 255)
14804     {
14805       errmsg ("stale cannot exceed 255 minutes.");
14806       return -99;
14807     }
14808
14809   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14810   mp->mode = mode;
14811   mp->scan_interval = interval;
14812   mp->max_proc_time = time;
14813   mp->max_update = update;
14814   mp->scan_int_delay = delay;
14815   mp->stale_threshold = stale;
14816
14817   S (mp);
14818   W (ret);
14819   return ret;
14820 }
14821
14822 static int
14823 api_want_ip4_arp_events (vat_main_t * vam)
14824 {
14825   unformat_input_t *line_input = vam->input;
14826   vl_api_want_ip4_arp_events_t *mp;
14827   ip4_address_t address;
14828   int address_set = 0;
14829   u32 enable_disable = 1;
14830   int ret;
14831
14832   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14833     {
14834       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14835         address_set = 1;
14836       else if (unformat (line_input, "del"))
14837         enable_disable = 0;
14838       else
14839         break;
14840     }
14841
14842   if (address_set == 0)
14843     {
14844       errmsg ("missing addresses");
14845       return -99;
14846     }
14847
14848   M (WANT_IP4_ARP_EVENTS, mp);
14849   mp->enable_disable = enable_disable;
14850   mp->pid = htonl (getpid ());
14851   mp->address = address.as_u32;
14852
14853   S (mp);
14854   W (ret);
14855   return ret;
14856 }
14857
14858 static int
14859 api_want_ip6_nd_events (vat_main_t * vam)
14860 {
14861   unformat_input_t *line_input = vam->input;
14862   vl_api_want_ip6_nd_events_t *mp;
14863   ip6_address_t address;
14864   int address_set = 0;
14865   u32 enable_disable = 1;
14866   int ret;
14867
14868   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14869     {
14870       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
14871         address_set = 1;
14872       else if (unformat (line_input, "del"))
14873         enable_disable = 0;
14874       else
14875         break;
14876     }
14877
14878   if (address_set == 0)
14879     {
14880       errmsg ("missing addresses");
14881       return -99;
14882     }
14883
14884   M (WANT_IP6_ND_EVENTS, mp);
14885   mp->enable_disable = enable_disable;
14886   mp->pid = htonl (getpid ());
14887   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
14888
14889   S (mp);
14890   W (ret);
14891   return ret;
14892 }
14893
14894 static int
14895 api_want_l2_macs_events (vat_main_t * vam)
14896 {
14897   unformat_input_t *line_input = vam->input;
14898   vl_api_want_l2_macs_events_t *mp;
14899   u8 enable_disable = 1;
14900   u32 scan_delay = 0;
14901   u32 max_macs_in_event = 0;
14902   u32 learn_limit = 0;
14903   int ret;
14904
14905   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14906     {
14907       if (unformat (line_input, "learn-limit %d", &learn_limit))
14908         ;
14909       else if (unformat (line_input, "scan-delay %d", &scan_delay))
14910         ;
14911       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
14912         ;
14913       else if (unformat (line_input, "disable"))
14914         enable_disable = 0;
14915       else
14916         break;
14917     }
14918
14919   M (WANT_L2_MACS_EVENTS, mp);
14920   mp->enable_disable = enable_disable;
14921   mp->pid = htonl (getpid ());
14922   mp->learn_limit = htonl (learn_limit);
14923   mp->scan_delay = (u8) scan_delay;
14924   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
14925   S (mp);
14926   W (ret);
14927   return ret;
14928 }
14929
14930 static int
14931 api_input_acl_set_interface (vat_main_t * vam)
14932 {
14933   unformat_input_t *i = vam->input;
14934   vl_api_input_acl_set_interface_t *mp;
14935   u32 sw_if_index;
14936   int sw_if_index_set;
14937   u32 ip4_table_index = ~0;
14938   u32 ip6_table_index = ~0;
14939   u32 l2_table_index = ~0;
14940   u8 is_add = 1;
14941   int ret;
14942
14943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14944     {
14945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14946         sw_if_index_set = 1;
14947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14948         sw_if_index_set = 1;
14949       else if (unformat (i, "del"))
14950         is_add = 0;
14951       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14952         ;
14953       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14954         ;
14955       else if (unformat (i, "l2-table %d", &l2_table_index))
14956         ;
14957       else
14958         {
14959           clib_warning ("parse error '%U'", format_unformat_error, i);
14960           return -99;
14961         }
14962     }
14963
14964   if (sw_if_index_set == 0)
14965     {
14966       errmsg ("missing interface name or sw_if_index");
14967       return -99;
14968     }
14969
14970   M (INPUT_ACL_SET_INTERFACE, mp);
14971
14972   mp->sw_if_index = ntohl (sw_if_index);
14973   mp->ip4_table_index = ntohl (ip4_table_index);
14974   mp->ip6_table_index = ntohl (ip6_table_index);
14975   mp->l2_table_index = ntohl (l2_table_index);
14976   mp->is_add = is_add;
14977
14978   S (mp);
14979   W (ret);
14980   return ret;
14981 }
14982
14983 static int
14984 api_output_acl_set_interface (vat_main_t * vam)
14985 {
14986   unformat_input_t *i = vam->input;
14987   vl_api_output_acl_set_interface_t *mp;
14988   u32 sw_if_index;
14989   int sw_if_index_set;
14990   u32 ip4_table_index = ~0;
14991   u32 ip6_table_index = ~0;
14992   u32 l2_table_index = ~0;
14993   u8 is_add = 1;
14994   int ret;
14995
14996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14997     {
14998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14999         sw_if_index_set = 1;
15000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15001         sw_if_index_set = 1;
15002       else if (unformat (i, "del"))
15003         is_add = 0;
15004       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15005         ;
15006       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15007         ;
15008       else if (unformat (i, "l2-table %d", &l2_table_index))
15009         ;
15010       else
15011         {
15012           clib_warning ("parse error '%U'", format_unformat_error, i);
15013           return -99;
15014         }
15015     }
15016
15017   if (sw_if_index_set == 0)
15018     {
15019       errmsg ("missing interface name or sw_if_index");
15020       return -99;
15021     }
15022
15023   M (OUTPUT_ACL_SET_INTERFACE, mp);
15024
15025   mp->sw_if_index = ntohl (sw_if_index);
15026   mp->ip4_table_index = ntohl (ip4_table_index);
15027   mp->ip6_table_index = ntohl (ip6_table_index);
15028   mp->l2_table_index = ntohl (l2_table_index);
15029   mp->is_add = is_add;
15030
15031   S (mp);
15032   W (ret);
15033   return ret;
15034 }
15035
15036 static int
15037 api_ip_address_dump (vat_main_t * vam)
15038 {
15039   unformat_input_t *i = vam->input;
15040   vl_api_ip_address_dump_t *mp;
15041   vl_api_control_ping_t *mp_ping;
15042   u32 sw_if_index = ~0;
15043   u8 sw_if_index_set = 0;
15044   u8 ipv4_set = 0;
15045   u8 ipv6_set = 0;
15046   int ret;
15047
15048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15049     {
15050       if (unformat (i, "sw_if_index %d", &sw_if_index))
15051         sw_if_index_set = 1;
15052       else
15053         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15054         sw_if_index_set = 1;
15055       else if (unformat (i, "ipv4"))
15056         ipv4_set = 1;
15057       else if (unformat (i, "ipv6"))
15058         ipv6_set = 1;
15059       else
15060         break;
15061     }
15062
15063   if (ipv4_set && ipv6_set)
15064     {
15065       errmsg ("ipv4 and ipv6 flags cannot be both set");
15066       return -99;
15067     }
15068
15069   if ((!ipv4_set) && (!ipv6_set))
15070     {
15071       errmsg ("no ipv4 nor ipv6 flag set");
15072       return -99;
15073     }
15074
15075   if (sw_if_index_set == 0)
15076     {
15077       errmsg ("missing interface name or sw_if_index");
15078       return -99;
15079     }
15080
15081   vam->current_sw_if_index = sw_if_index;
15082   vam->is_ipv6 = ipv6_set;
15083
15084   M (IP_ADDRESS_DUMP, mp);
15085   mp->sw_if_index = ntohl (sw_if_index);
15086   mp->is_ipv6 = ipv6_set;
15087   S (mp);
15088
15089   /* Use a control ping for synchronization */
15090   MPING (CONTROL_PING, mp_ping);
15091   S (mp_ping);
15092
15093   W (ret);
15094   return ret;
15095 }
15096
15097 static int
15098 api_ip_dump (vat_main_t * vam)
15099 {
15100   vl_api_ip_dump_t *mp;
15101   vl_api_control_ping_t *mp_ping;
15102   unformat_input_t *in = vam->input;
15103   int ipv4_set = 0;
15104   int ipv6_set = 0;
15105   int is_ipv6;
15106   int i;
15107   int ret;
15108
15109   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15110     {
15111       if (unformat (in, "ipv4"))
15112         ipv4_set = 1;
15113       else if (unformat (in, "ipv6"))
15114         ipv6_set = 1;
15115       else
15116         break;
15117     }
15118
15119   if (ipv4_set && ipv6_set)
15120     {
15121       errmsg ("ipv4 and ipv6 flags cannot be both set");
15122       return -99;
15123     }
15124
15125   if ((!ipv4_set) && (!ipv6_set))
15126     {
15127       errmsg ("no ipv4 nor ipv6 flag set");
15128       return -99;
15129     }
15130
15131   is_ipv6 = ipv6_set;
15132   vam->is_ipv6 = is_ipv6;
15133
15134   /* free old data */
15135   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15136     {
15137       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15138     }
15139   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15140
15141   M (IP_DUMP, mp);
15142   mp->is_ipv6 = ipv6_set;
15143   S (mp);
15144
15145   /* Use a control ping for synchronization */
15146   MPING (CONTROL_PING, mp_ping);
15147   S (mp_ping);
15148
15149   W (ret);
15150   return ret;
15151 }
15152
15153 static int
15154 api_ipsec_spd_add_del (vat_main_t * vam)
15155 {
15156   unformat_input_t *i = vam->input;
15157   vl_api_ipsec_spd_add_del_t *mp;
15158   u32 spd_id = ~0;
15159   u8 is_add = 1;
15160   int ret;
15161
15162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15163     {
15164       if (unformat (i, "spd_id %d", &spd_id))
15165         ;
15166       else if (unformat (i, "del"))
15167         is_add = 0;
15168       else
15169         {
15170           clib_warning ("parse error '%U'", format_unformat_error, i);
15171           return -99;
15172         }
15173     }
15174   if (spd_id == ~0)
15175     {
15176       errmsg ("spd_id must be set");
15177       return -99;
15178     }
15179
15180   M (IPSEC_SPD_ADD_DEL, mp);
15181
15182   mp->spd_id = ntohl (spd_id);
15183   mp->is_add = is_add;
15184
15185   S (mp);
15186   W (ret);
15187   return ret;
15188 }
15189
15190 static int
15191 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15192 {
15193   unformat_input_t *i = vam->input;
15194   vl_api_ipsec_interface_add_del_spd_t *mp;
15195   u32 sw_if_index;
15196   u8 sw_if_index_set = 0;
15197   u32 spd_id = (u32) ~ 0;
15198   u8 is_add = 1;
15199   int ret;
15200
15201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15202     {
15203       if (unformat (i, "del"))
15204         is_add = 0;
15205       else if (unformat (i, "spd_id %d", &spd_id))
15206         ;
15207       else
15208         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15209         sw_if_index_set = 1;
15210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15211         sw_if_index_set = 1;
15212       else
15213         {
15214           clib_warning ("parse error '%U'", format_unformat_error, i);
15215           return -99;
15216         }
15217
15218     }
15219
15220   if (spd_id == (u32) ~ 0)
15221     {
15222       errmsg ("spd_id must be set");
15223       return -99;
15224     }
15225
15226   if (sw_if_index_set == 0)
15227     {
15228       errmsg ("missing interface name or sw_if_index");
15229       return -99;
15230     }
15231
15232   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15233
15234   mp->spd_id = ntohl (spd_id);
15235   mp->sw_if_index = ntohl (sw_if_index);
15236   mp->is_add = is_add;
15237
15238   S (mp);
15239   W (ret);
15240   return ret;
15241 }
15242
15243 static int
15244 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15245 {
15246   unformat_input_t *i = vam->input;
15247   vl_api_ipsec_spd_add_del_entry_t *mp;
15248   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15249   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15250   i32 priority = 0;
15251   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15252   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15253   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15254   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15255   int ret;
15256
15257   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15258   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15259   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15260   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15261   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15262   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15263
15264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15265     {
15266       if (unformat (i, "del"))
15267         is_add = 0;
15268       if (unformat (i, "outbound"))
15269         is_outbound = 1;
15270       if (unformat (i, "inbound"))
15271         is_outbound = 0;
15272       else if (unformat (i, "spd_id %d", &spd_id))
15273         ;
15274       else if (unformat (i, "sa_id %d", &sa_id))
15275         ;
15276       else if (unformat (i, "priority %d", &priority))
15277         ;
15278       else if (unformat (i, "protocol %d", &protocol))
15279         ;
15280       else if (unformat (i, "lport_start %d", &lport_start))
15281         ;
15282       else if (unformat (i, "lport_stop %d", &lport_stop))
15283         ;
15284       else if (unformat (i, "rport_start %d", &rport_start))
15285         ;
15286       else if (unformat (i, "rport_stop %d", &rport_stop))
15287         ;
15288       else
15289         if (unformat
15290             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15291         {
15292           is_ipv6 = 0;
15293           is_ip_any = 0;
15294         }
15295       else
15296         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15297         {
15298           is_ipv6 = 0;
15299           is_ip_any = 0;
15300         }
15301       else
15302         if (unformat
15303             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15304         {
15305           is_ipv6 = 0;
15306           is_ip_any = 0;
15307         }
15308       else
15309         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15310         {
15311           is_ipv6 = 0;
15312           is_ip_any = 0;
15313         }
15314       else
15315         if (unformat
15316             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15317         {
15318           is_ipv6 = 1;
15319           is_ip_any = 0;
15320         }
15321       else
15322         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15323         {
15324           is_ipv6 = 1;
15325           is_ip_any = 0;
15326         }
15327       else
15328         if (unformat
15329             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15330         {
15331           is_ipv6 = 1;
15332           is_ip_any = 0;
15333         }
15334       else
15335         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15336         {
15337           is_ipv6 = 1;
15338           is_ip_any = 0;
15339         }
15340       else
15341         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15342         {
15343           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15344             {
15345               clib_warning ("unsupported action: 'resolve'");
15346               return -99;
15347             }
15348         }
15349       else
15350         {
15351           clib_warning ("parse error '%U'", format_unformat_error, i);
15352           return -99;
15353         }
15354
15355     }
15356
15357   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15358
15359   mp->spd_id = ntohl (spd_id);
15360   mp->priority = ntohl (priority);
15361   mp->is_outbound = is_outbound;
15362
15363   mp->is_ipv6 = is_ipv6;
15364   if (is_ipv6 || is_ip_any)
15365     {
15366       clib_memcpy (mp->remote_address_start, &raddr6_start,
15367                    sizeof (ip6_address_t));
15368       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15369                    sizeof (ip6_address_t));
15370       clib_memcpy (mp->local_address_start, &laddr6_start,
15371                    sizeof (ip6_address_t));
15372       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15373                    sizeof (ip6_address_t));
15374     }
15375   else
15376     {
15377       clib_memcpy (mp->remote_address_start, &raddr4_start,
15378                    sizeof (ip4_address_t));
15379       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15380                    sizeof (ip4_address_t));
15381       clib_memcpy (mp->local_address_start, &laddr4_start,
15382                    sizeof (ip4_address_t));
15383       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15384                    sizeof (ip4_address_t));
15385     }
15386   mp->protocol = (u8) protocol;
15387   mp->local_port_start = ntohs ((u16) lport_start);
15388   mp->local_port_stop = ntohs ((u16) lport_stop);
15389   mp->remote_port_start = ntohs ((u16) rport_start);
15390   mp->remote_port_stop = ntohs ((u16) rport_stop);
15391   mp->policy = (u8) policy;
15392   mp->sa_id = ntohl (sa_id);
15393   mp->is_add = is_add;
15394   mp->is_ip_any = is_ip_any;
15395   S (mp);
15396   W (ret);
15397   return ret;
15398 }
15399
15400 static int
15401 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15402 {
15403   unformat_input_t *i = vam->input;
15404   vl_api_ipsec_sad_add_del_entry_t *mp;
15405   u32 sad_id = 0, spi = 0;
15406   u8 *ck = 0, *ik = 0;
15407   u8 is_add = 1;
15408
15409   u8 protocol = IPSEC_PROTOCOL_AH;
15410   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15411   u32 crypto_alg = 0, integ_alg = 0;
15412   ip4_address_t tun_src4;
15413   ip4_address_t tun_dst4;
15414   ip6_address_t tun_src6;
15415   ip6_address_t tun_dst6;
15416   int ret;
15417
15418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15419     {
15420       if (unformat (i, "del"))
15421         is_add = 0;
15422       else if (unformat (i, "sad_id %d", &sad_id))
15423         ;
15424       else if (unformat (i, "spi %d", &spi))
15425         ;
15426       else if (unformat (i, "esp"))
15427         protocol = IPSEC_PROTOCOL_ESP;
15428       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15429         {
15430           is_tunnel = 1;
15431           is_tunnel_ipv6 = 0;
15432         }
15433       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15434         {
15435           is_tunnel = 1;
15436           is_tunnel_ipv6 = 0;
15437         }
15438       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15439         {
15440           is_tunnel = 1;
15441           is_tunnel_ipv6 = 1;
15442         }
15443       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15444         {
15445           is_tunnel = 1;
15446           is_tunnel_ipv6 = 1;
15447         }
15448       else
15449         if (unformat
15450             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15451         {
15452           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15453             {
15454               clib_warning ("unsupported crypto-alg: '%U'",
15455                             format_ipsec_crypto_alg, crypto_alg);
15456               return -99;
15457             }
15458         }
15459       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15460         ;
15461       else
15462         if (unformat
15463             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15464         {
15465           if (integ_alg >= IPSEC_INTEG_N_ALG)
15466             {
15467               clib_warning ("unsupported integ-alg: '%U'",
15468                             format_ipsec_integ_alg, integ_alg);
15469               return -99;
15470             }
15471         }
15472       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15473         ;
15474       else
15475         {
15476           clib_warning ("parse error '%U'", format_unformat_error, i);
15477           return -99;
15478         }
15479
15480     }
15481
15482   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15483
15484   mp->sad_id = ntohl (sad_id);
15485   mp->is_add = is_add;
15486   mp->protocol = protocol;
15487   mp->spi = ntohl (spi);
15488   mp->is_tunnel = is_tunnel;
15489   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15490   mp->crypto_algorithm = crypto_alg;
15491   mp->integrity_algorithm = integ_alg;
15492   mp->crypto_key_length = vec_len (ck);
15493   mp->integrity_key_length = vec_len (ik);
15494
15495   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15496     mp->crypto_key_length = sizeof (mp->crypto_key);
15497
15498   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15499     mp->integrity_key_length = sizeof (mp->integrity_key);
15500
15501   if (ck)
15502     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15503   if (ik)
15504     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15505
15506   if (is_tunnel)
15507     {
15508       if (is_tunnel_ipv6)
15509         {
15510           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15511                        sizeof (ip6_address_t));
15512           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15513                        sizeof (ip6_address_t));
15514         }
15515       else
15516         {
15517           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15518                        sizeof (ip4_address_t));
15519           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15520                        sizeof (ip4_address_t));
15521         }
15522     }
15523
15524   S (mp);
15525   W (ret);
15526   return ret;
15527 }
15528
15529 static int
15530 api_ipsec_sa_set_key (vat_main_t * vam)
15531 {
15532   unformat_input_t *i = vam->input;
15533   vl_api_ipsec_sa_set_key_t *mp;
15534   u32 sa_id;
15535   u8 *ck = 0, *ik = 0;
15536   int ret;
15537
15538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15539     {
15540       if (unformat (i, "sa_id %d", &sa_id))
15541         ;
15542       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15543         ;
15544       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15545         ;
15546       else
15547         {
15548           clib_warning ("parse error '%U'", format_unformat_error, i);
15549           return -99;
15550         }
15551     }
15552
15553   M (IPSEC_SA_SET_KEY, mp);
15554
15555   mp->sa_id = ntohl (sa_id);
15556   mp->crypto_key_length = vec_len (ck);
15557   mp->integrity_key_length = vec_len (ik);
15558
15559   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15560     mp->crypto_key_length = sizeof (mp->crypto_key);
15561
15562   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15563     mp->integrity_key_length = sizeof (mp->integrity_key);
15564
15565   if (ck)
15566     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15567   if (ik)
15568     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15569
15570   S (mp);
15571   W (ret);
15572   return ret;
15573 }
15574
15575 static int
15576 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15577 {
15578   unformat_input_t *i = vam->input;
15579   vl_api_ipsec_tunnel_if_add_del_t *mp;
15580   u32 local_spi = 0, remote_spi = 0;
15581   u32 crypto_alg = 0, integ_alg = 0;
15582   u8 *lck = NULL, *rck = NULL;
15583   u8 *lik = NULL, *rik = NULL;
15584   ip4_address_t local_ip = { {0} };
15585   ip4_address_t remote_ip = { {0} };
15586   u8 is_add = 1;
15587   u8 esn = 0;
15588   u8 anti_replay = 0;
15589   u8 renumber = 0;
15590   u32 instance = ~0;
15591   int ret;
15592
15593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15594     {
15595       if (unformat (i, "del"))
15596         is_add = 0;
15597       else if (unformat (i, "esn"))
15598         esn = 1;
15599       else if (unformat (i, "anti_replay"))
15600         anti_replay = 1;
15601       else if (unformat (i, "local_spi %d", &local_spi))
15602         ;
15603       else if (unformat (i, "remote_spi %d", &remote_spi))
15604         ;
15605       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15606         ;
15607       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15608         ;
15609       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15610         ;
15611       else
15612         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15613         ;
15614       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15615         ;
15616       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15617         ;
15618       else
15619         if (unformat
15620             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15621         {
15622           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15623             {
15624               errmsg ("unsupported crypto-alg: '%U'\n",
15625                       format_ipsec_crypto_alg, crypto_alg);
15626               return -99;
15627             }
15628         }
15629       else
15630         if (unformat
15631             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15632         {
15633           if (integ_alg >= IPSEC_INTEG_N_ALG)
15634             {
15635               errmsg ("unsupported integ-alg: '%U'\n",
15636                       format_ipsec_integ_alg, integ_alg);
15637               return -99;
15638             }
15639         }
15640       else if (unformat (i, "instance %u", &instance))
15641         renumber = 1;
15642       else
15643         {
15644           errmsg ("parse error '%U'\n", format_unformat_error, i);
15645           return -99;
15646         }
15647     }
15648
15649   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15650
15651   mp->is_add = is_add;
15652   mp->esn = esn;
15653   mp->anti_replay = anti_replay;
15654
15655   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15656   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15657
15658   mp->local_spi = htonl (local_spi);
15659   mp->remote_spi = htonl (remote_spi);
15660   mp->crypto_alg = (u8) crypto_alg;
15661
15662   mp->local_crypto_key_len = 0;
15663   if (lck)
15664     {
15665       mp->local_crypto_key_len = vec_len (lck);
15666       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15667         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15668       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15669     }
15670
15671   mp->remote_crypto_key_len = 0;
15672   if (rck)
15673     {
15674       mp->remote_crypto_key_len = vec_len (rck);
15675       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15676         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15677       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15678     }
15679
15680   mp->integ_alg = (u8) integ_alg;
15681
15682   mp->local_integ_key_len = 0;
15683   if (lik)
15684     {
15685       mp->local_integ_key_len = vec_len (lik);
15686       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15687         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15688       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15689     }
15690
15691   mp->remote_integ_key_len = 0;
15692   if (rik)
15693     {
15694       mp->remote_integ_key_len = vec_len (rik);
15695       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15696         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15697       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15698     }
15699
15700   if (renumber)
15701     {
15702       mp->renumber = renumber;
15703       mp->show_instance = ntohl (instance);
15704     }
15705
15706   S (mp);
15707   W (ret);
15708   return ret;
15709 }
15710
15711 static void
15712 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15713 {
15714   vat_main_t *vam = &vat_main;
15715
15716   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15717          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15718          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15719          "tunnel_src_addr %U tunnel_dst_addr %U "
15720          "salt %u seq_outbound %lu last_seq_inbound %lu "
15721          "replay_window %lu total_data_size %lu\n",
15722          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15723          mp->protocol,
15724          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15725          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15726          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15727          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15728          mp->tunnel_src_addr,
15729          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15730          mp->tunnel_dst_addr,
15731          ntohl (mp->salt),
15732          clib_net_to_host_u64 (mp->seq_outbound),
15733          clib_net_to_host_u64 (mp->last_seq_inbound),
15734          clib_net_to_host_u64 (mp->replay_window),
15735          clib_net_to_host_u64 (mp->total_data_size));
15736 }
15737
15738 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15739 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15740
15741 static void vl_api_ipsec_sa_details_t_handler_json
15742   (vl_api_ipsec_sa_details_t * mp)
15743 {
15744   vat_main_t *vam = &vat_main;
15745   vat_json_node_t *node = NULL;
15746   struct in_addr src_ip4, dst_ip4;
15747   struct in6_addr src_ip6, dst_ip6;
15748
15749   if (VAT_JSON_ARRAY != vam->json_tree.type)
15750     {
15751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15752       vat_json_init_array (&vam->json_tree);
15753     }
15754   node = vat_json_array_add (&vam->json_tree);
15755
15756   vat_json_init_object (node);
15757   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15758   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15759   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15760   vat_json_object_add_uint (node, "proto", mp->protocol);
15761   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15762   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15763   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15764   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15765   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15766   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15767   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15768                              mp->crypto_key_len);
15769   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15770                              mp->integ_key_len);
15771   if (mp->is_tunnel_ip6)
15772     {
15773       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15774       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15775       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15776       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15777     }
15778   else
15779     {
15780       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15781       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15782       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15783       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15784     }
15785   vat_json_object_add_uint (node, "replay_window",
15786                             clib_net_to_host_u64 (mp->replay_window));
15787   vat_json_object_add_uint (node, "total_data_size",
15788                             clib_net_to_host_u64 (mp->total_data_size));
15789
15790 }
15791
15792 static int
15793 api_ipsec_sa_dump (vat_main_t * vam)
15794 {
15795   unformat_input_t *i = vam->input;
15796   vl_api_ipsec_sa_dump_t *mp;
15797   vl_api_control_ping_t *mp_ping;
15798   u32 sa_id = ~0;
15799   int ret;
15800
15801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15802     {
15803       if (unformat (i, "sa_id %d", &sa_id))
15804         ;
15805       else
15806         {
15807           clib_warning ("parse error '%U'", format_unformat_error, i);
15808           return -99;
15809         }
15810     }
15811
15812   M (IPSEC_SA_DUMP, mp);
15813
15814   mp->sa_id = ntohl (sa_id);
15815
15816   S (mp);
15817
15818   /* Use a control ping for synchronization */
15819   M (CONTROL_PING, mp_ping);
15820   S (mp_ping);
15821
15822   W (ret);
15823   return ret;
15824 }
15825
15826 static int
15827 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15828 {
15829   unformat_input_t *i = vam->input;
15830   vl_api_ipsec_tunnel_if_set_key_t *mp;
15831   u32 sw_if_index = ~0;
15832   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15833   u8 *key = 0;
15834   u32 alg = ~0;
15835   int ret;
15836
15837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15838     {
15839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15840         ;
15841       else
15842         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15843         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15844       else
15845         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15846         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
15847       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
15848         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
15849       else
15850         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
15851         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
15852       else if (unformat (i, "%U", unformat_hex_string, &key))
15853         ;
15854       else
15855         {
15856           clib_warning ("parse error '%U'", format_unformat_error, i);
15857           return -99;
15858         }
15859     }
15860
15861   if (sw_if_index == ~0)
15862     {
15863       errmsg ("interface must be specified");
15864       return -99;
15865     }
15866
15867   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
15868     {
15869       errmsg ("key type must be specified");
15870       return -99;
15871     }
15872
15873   if (alg == ~0)
15874     {
15875       errmsg ("algorithm must be specified");
15876       return -99;
15877     }
15878
15879   if (vec_len (key) == 0)
15880     {
15881       errmsg ("key must be specified");
15882       return -99;
15883     }
15884
15885   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
15886
15887   mp->sw_if_index = htonl (sw_if_index);
15888   mp->alg = alg;
15889   mp->key_type = key_type;
15890   mp->key_len = vec_len (key);
15891   clib_memcpy (mp->key, key, vec_len (key));
15892
15893   S (mp);
15894   W (ret);
15895
15896   return ret;
15897 }
15898
15899 static int
15900 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
15901 {
15902   unformat_input_t *i = vam->input;
15903   vl_api_ipsec_tunnel_if_set_sa_t *mp;
15904   u32 sw_if_index = ~0;
15905   u32 sa_id = ~0;
15906   u8 is_outbound = (u8) ~ 0;
15907   int ret;
15908
15909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15910     {
15911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15912         ;
15913       else if (unformat (i, "sa_id %d", &sa_id))
15914         ;
15915       else if (unformat (i, "outbound"))
15916         is_outbound = 1;
15917       else if (unformat (i, "inbound"))
15918         is_outbound = 0;
15919       else
15920         {
15921           clib_warning ("parse error '%U'", format_unformat_error, i);
15922           return -99;
15923         }
15924     }
15925
15926   if (sw_if_index == ~0)
15927     {
15928       errmsg ("interface must be specified");
15929       return -99;
15930     }
15931
15932   if (sa_id == ~0)
15933     {
15934       errmsg ("SA ID must be specified");
15935       return -99;
15936     }
15937
15938   M (IPSEC_TUNNEL_IF_SET_SA, mp);
15939
15940   mp->sw_if_index = htonl (sw_if_index);
15941   mp->sa_id = htonl (sa_id);
15942   mp->is_outbound = is_outbound;
15943
15944   S (mp);
15945   W (ret);
15946
15947   return ret;
15948 }
15949
15950 static int
15951 api_ikev2_profile_add_del (vat_main_t * vam)
15952 {
15953   unformat_input_t *i = vam->input;
15954   vl_api_ikev2_profile_add_del_t *mp;
15955   u8 is_add = 1;
15956   u8 *name = 0;
15957   int ret;
15958
15959   const char *valid_chars = "a-zA-Z0-9_";
15960
15961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15962     {
15963       if (unformat (i, "del"))
15964         is_add = 0;
15965       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15966         vec_add1 (name, 0);
15967       else
15968         {
15969           errmsg ("parse error '%U'", format_unformat_error, i);
15970           return -99;
15971         }
15972     }
15973
15974   if (!vec_len (name))
15975     {
15976       errmsg ("profile name must be specified");
15977       return -99;
15978     }
15979
15980   if (vec_len (name) > 64)
15981     {
15982       errmsg ("profile name too long");
15983       return -99;
15984     }
15985
15986   M (IKEV2_PROFILE_ADD_DEL, mp);
15987
15988   clib_memcpy (mp->name, name, vec_len (name));
15989   mp->is_add = is_add;
15990   vec_free (name);
15991
15992   S (mp);
15993   W (ret);
15994   return ret;
15995 }
15996
15997 static int
15998 api_ikev2_profile_set_auth (vat_main_t * vam)
15999 {
16000   unformat_input_t *i = vam->input;
16001   vl_api_ikev2_profile_set_auth_t *mp;
16002   u8 *name = 0;
16003   u8 *data = 0;
16004   u32 auth_method = 0;
16005   u8 is_hex = 0;
16006   int ret;
16007
16008   const char *valid_chars = "a-zA-Z0-9_";
16009
16010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16011     {
16012       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16013         vec_add1 (name, 0);
16014       else if (unformat (i, "auth_method %U",
16015                          unformat_ikev2_auth_method, &auth_method))
16016         ;
16017       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16018         is_hex = 1;
16019       else if (unformat (i, "auth_data %v", &data))
16020         ;
16021       else
16022         {
16023           errmsg ("parse error '%U'", format_unformat_error, i);
16024           return -99;
16025         }
16026     }
16027
16028   if (!vec_len (name))
16029     {
16030       errmsg ("profile name must be specified");
16031       return -99;
16032     }
16033
16034   if (vec_len (name) > 64)
16035     {
16036       errmsg ("profile name too long");
16037       return -99;
16038     }
16039
16040   if (!vec_len (data))
16041     {
16042       errmsg ("auth_data must be specified");
16043       return -99;
16044     }
16045
16046   if (!auth_method)
16047     {
16048       errmsg ("auth_method must be specified");
16049       return -99;
16050     }
16051
16052   M (IKEV2_PROFILE_SET_AUTH, mp);
16053
16054   mp->is_hex = is_hex;
16055   mp->auth_method = (u8) auth_method;
16056   mp->data_len = vec_len (data);
16057   clib_memcpy (mp->name, name, vec_len (name));
16058   clib_memcpy (mp->data, data, vec_len (data));
16059   vec_free (name);
16060   vec_free (data);
16061
16062   S (mp);
16063   W (ret);
16064   return ret;
16065 }
16066
16067 static int
16068 api_ikev2_profile_set_id (vat_main_t * vam)
16069 {
16070   unformat_input_t *i = vam->input;
16071   vl_api_ikev2_profile_set_id_t *mp;
16072   u8 *name = 0;
16073   u8 *data = 0;
16074   u8 is_local = 0;
16075   u32 id_type = 0;
16076   ip4_address_t ip4;
16077   int ret;
16078
16079   const char *valid_chars = "a-zA-Z0-9_";
16080
16081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16082     {
16083       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16084         vec_add1 (name, 0);
16085       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16086         ;
16087       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16088         {
16089           data = vec_new (u8, 4);
16090           clib_memcpy (data, ip4.as_u8, 4);
16091         }
16092       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16093         ;
16094       else if (unformat (i, "id_data %v", &data))
16095         ;
16096       else if (unformat (i, "local"))
16097         is_local = 1;
16098       else if (unformat (i, "remote"))
16099         is_local = 0;
16100       else
16101         {
16102           errmsg ("parse error '%U'", format_unformat_error, i);
16103           return -99;
16104         }
16105     }
16106
16107   if (!vec_len (name))
16108     {
16109       errmsg ("profile name must be specified");
16110       return -99;
16111     }
16112
16113   if (vec_len (name) > 64)
16114     {
16115       errmsg ("profile name too long");
16116       return -99;
16117     }
16118
16119   if (!vec_len (data))
16120     {
16121       errmsg ("id_data must be specified");
16122       return -99;
16123     }
16124
16125   if (!id_type)
16126     {
16127       errmsg ("id_type must be specified");
16128       return -99;
16129     }
16130
16131   M (IKEV2_PROFILE_SET_ID, mp);
16132
16133   mp->is_local = is_local;
16134   mp->id_type = (u8) id_type;
16135   mp->data_len = vec_len (data);
16136   clib_memcpy (mp->name, name, vec_len (name));
16137   clib_memcpy (mp->data, data, vec_len (data));
16138   vec_free (name);
16139   vec_free (data);
16140
16141   S (mp);
16142   W (ret);
16143   return ret;
16144 }
16145
16146 static int
16147 api_ikev2_profile_set_ts (vat_main_t * vam)
16148 {
16149   unformat_input_t *i = vam->input;
16150   vl_api_ikev2_profile_set_ts_t *mp;
16151   u8 *name = 0;
16152   u8 is_local = 0;
16153   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16154   ip4_address_t start_addr, end_addr;
16155
16156   const char *valid_chars = "a-zA-Z0-9_";
16157   int ret;
16158
16159   start_addr.as_u32 = 0;
16160   end_addr.as_u32 = (u32) ~ 0;
16161
16162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16163     {
16164       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16165         vec_add1 (name, 0);
16166       else if (unformat (i, "protocol %d", &proto))
16167         ;
16168       else if (unformat (i, "start_port %d", &start_port))
16169         ;
16170       else if (unformat (i, "end_port %d", &end_port))
16171         ;
16172       else
16173         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16174         ;
16175       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16176         ;
16177       else if (unformat (i, "local"))
16178         is_local = 1;
16179       else if (unformat (i, "remote"))
16180         is_local = 0;
16181       else
16182         {
16183           errmsg ("parse error '%U'", format_unformat_error, i);
16184           return -99;
16185         }
16186     }
16187
16188   if (!vec_len (name))
16189     {
16190       errmsg ("profile name must be specified");
16191       return -99;
16192     }
16193
16194   if (vec_len (name) > 64)
16195     {
16196       errmsg ("profile name too long");
16197       return -99;
16198     }
16199
16200   M (IKEV2_PROFILE_SET_TS, mp);
16201
16202   mp->is_local = is_local;
16203   mp->proto = (u8) proto;
16204   mp->start_port = (u16) start_port;
16205   mp->end_port = (u16) end_port;
16206   mp->start_addr = start_addr.as_u32;
16207   mp->end_addr = end_addr.as_u32;
16208   clib_memcpy (mp->name, name, vec_len (name));
16209   vec_free (name);
16210
16211   S (mp);
16212   W (ret);
16213   return ret;
16214 }
16215
16216 static int
16217 api_ikev2_set_local_key (vat_main_t * vam)
16218 {
16219   unformat_input_t *i = vam->input;
16220   vl_api_ikev2_set_local_key_t *mp;
16221   u8 *file = 0;
16222   int ret;
16223
16224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16225     {
16226       if (unformat (i, "file %v", &file))
16227         vec_add1 (file, 0);
16228       else
16229         {
16230           errmsg ("parse error '%U'", format_unformat_error, i);
16231           return -99;
16232         }
16233     }
16234
16235   if (!vec_len (file))
16236     {
16237       errmsg ("RSA key file must be specified");
16238       return -99;
16239     }
16240
16241   if (vec_len (file) > 256)
16242     {
16243       errmsg ("file name too long");
16244       return -99;
16245     }
16246
16247   M (IKEV2_SET_LOCAL_KEY, mp);
16248
16249   clib_memcpy (mp->key_file, file, vec_len (file));
16250   vec_free (file);
16251
16252   S (mp);
16253   W (ret);
16254   return ret;
16255 }
16256
16257 static int
16258 api_ikev2_set_responder (vat_main_t * vam)
16259 {
16260   unformat_input_t *i = vam->input;
16261   vl_api_ikev2_set_responder_t *mp;
16262   int ret;
16263   u8 *name = 0;
16264   u32 sw_if_index = ~0;
16265   ip4_address_t address;
16266
16267   const char *valid_chars = "a-zA-Z0-9_";
16268
16269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16270     {
16271       if (unformat
16272           (i, "%U interface %d address %U", unformat_token, valid_chars,
16273            &name, &sw_if_index, unformat_ip4_address, &address))
16274         vec_add1 (name, 0);
16275       else
16276         {
16277           errmsg ("parse error '%U'", format_unformat_error, i);
16278           return -99;
16279         }
16280     }
16281
16282   if (!vec_len (name))
16283     {
16284       errmsg ("profile name must be specified");
16285       return -99;
16286     }
16287
16288   if (vec_len (name) > 64)
16289     {
16290       errmsg ("profile name too long");
16291       return -99;
16292     }
16293
16294   M (IKEV2_SET_RESPONDER, mp);
16295
16296   clib_memcpy (mp->name, name, vec_len (name));
16297   vec_free (name);
16298
16299   mp->sw_if_index = sw_if_index;
16300   clib_memcpy (mp->address, &address, sizeof (address));
16301
16302   S (mp);
16303   W (ret);
16304   return ret;
16305 }
16306
16307 static int
16308 api_ikev2_set_ike_transforms (vat_main_t * vam)
16309 {
16310   unformat_input_t *i = vam->input;
16311   vl_api_ikev2_set_ike_transforms_t *mp;
16312   int ret;
16313   u8 *name = 0;
16314   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16315
16316   const char *valid_chars = "a-zA-Z0-9_";
16317
16318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16319     {
16320       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16321                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16322         vec_add1 (name, 0);
16323       else
16324         {
16325           errmsg ("parse error '%U'", format_unformat_error, i);
16326           return -99;
16327         }
16328     }
16329
16330   if (!vec_len (name))
16331     {
16332       errmsg ("profile name must be specified");
16333       return -99;
16334     }
16335
16336   if (vec_len (name) > 64)
16337     {
16338       errmsg ("profile name too long");
16339       return -99;
16340     }
16341
16342   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16343
16344   clib_memcpy (mp->name, name, vec_len (name));
16345   vec_free (name);
16346   mp->crypto_alg = crypto_alg;
16347   mp->crypto_key_size = crypto_key_size;
16348   mp->integ_alg = integ_alg;
16349   mp->dh_group = dh_group;
16350
16351   S (mp);
16352   W (ret);
16353   return ret;
16354 }
16355
16356
16357 static int
16358 api_ikev2_set_esp_transforms (vat_main_t * vam)
16359 {
16360   unformat_input_t *i = vam->input;
16361   vl_api_ikev2_set_esp_transforms_t *mp;
16362   int ret;
16363   u8 *name = 0;
16364   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16365
16366   const char *valid_chars = "a-zA-Z0-9_";
16367
16368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16369     {
16370       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16371                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16372         vec_add1 (name, 0);
16373       else
16374         {
16375           errmsg ("parse error '%U'", format_unformat_error, i);
16376           return -99;
16377         }
16378     }
16379
16380   if (!vec_len (name))
16381     {
16382       errmsg ("profile name must be specified");
16383       return -99;
16384     }
16385
16386   if (vec_len (name) > 64)
16387     {
16388       errmsg ("profile name too long");
16389       return -99;
16390     }
16391
16392   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16393
16394   clib_memcpy (mp->name, name, vec_len (name));
16395   vec_free (name);
16396   mp->crypto_alg = crypto_alg;
16397   mp->crypto_key_size = crypto_key_size;
16398   mp->integ_alg = integ_alg;
16399   mp->dh_group = dh_group;
16400
16401   S (mp);
16402   W (ret);
16403   return ret;
16404 }
16405
16406 static int
16407 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16408 {
16409   unformat_input_t *i = vam->input;
16410   vl_api_ikev2_set_sa_lifetime_t *mp;
16411   int ret;
16412   u8 *name = 0;
16413   u64 lifetime, lifetime_maxdata;
16414   u32 lifetime_jitter, handover;
16415
16416   const char *valid_chars = "a-zA-Z0-9_";
16417
16418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16419     {
16420       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16421                     &lifetime, &lifetime_jitter, &handover,
16422                     &lifetime_maxdata))
16423         vec_add1 (name, 0);
16424       else
16425         {
16426           errmsg ("parse error '%U'", format_unformat_error, i);
16427           return -99;
16428         }
16429     }
16430
16431   if (!vec_len (name))
16432     {
16433       errmsg ("profile name must be specified");
16434       return -99;
16435     }
16436
16437   if (vec_len (name) > 64)
16438     {
16439       errmsg ("profile name too long");
16440       return -99;
16441     }
16442
16443   M (IKEV2_SET_SA_LIFETIME, mp);
16444
16445   clib_memcpy (mp->name, name, vec_len (name));
16446   vec_free (name);
16447   mp->lifetime = lifetime;
16448   mp->lifetime_jitter = lifetime_jitter;
16449   mp->handover = handover;
16450   mp->lifetime_maxdata = lifetime_maxdata;
16451
16452   S (mp);
16453   W (ret);
16454   return ret;
16455 }
16456
16457 static int
16458 api_ikev2_initiate_sa_init (vat_main_t * vam)
16459 {
16460   unformat_input_t *i = vam->input;
16461   vl_api_ikev2_initiate_sa_init_t *mp;
16462   int ret;
16463   u8 *name = 0;
16464
16465   const char *valid_chars = "a-zA-Z0-9_";
16466
16467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16468     {
16469       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16470         vec_add1 (name, 0);
16471       else
16472         {
16473           errmsg ("parse error '%U'", format_unformat_error, i);
16474           return -99;
16475         }
16476     }
16477
16478   if (!vec_len (name))
16479     {
16480       errmsg ("profile name must be specified");
16481       return -99;
16482     }
16483
16484   if (vec_len (name) > 64)
16485     {
16486       errmsg ("profile name too long");
16487       return -99;
16488     }
16489
16490   M (IKEV2_INITIATE_SA_INIT, mp);
16491
16492   clib_memcpy (mp->name, name, vec_len (name));
16493   vec_free (name);
16494
16495   S (mp);
16496   W (ret);
16497   return ret;
16498 }
16499
16500 static int
16501 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16502 {
16503   unformat_input_t *i = vam->input;
16504   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16505   int ret;
16506   u64 ispi;
16507
16508
16509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16510     {
16511       if (unformat (i, "%lx", &ispi))
16512         ;
16513       else
16514         {
16515           errmsg ("parse error '%U'", format_unformat_error, i);
16516           return -99;
16517         }
16518     }
16519
16520   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16521
16522   mp->ispi = ispi;
16523
16524   S (mp);
16525   W (ret);
16526   return ret;
16527 }
16528
16529 static int
16530 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16531 {
16532   unformat_input_t *i = vam->input;
16533   vl_api_ikev2_initiate_del_child_sa_t *mp;
16534   int ret;
16535   u32 ispi;
16536
16537
16538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16539     {
16540       if (unformat (i, "%x", &ispi))
16541         ;
16542       else
16543         {
16544           errmsg ("parse error '%U'", format_unformat_error, i);
16545           return -99;
16546         }
16547     }
16548
16549   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16550
16551   mp->ispi = ispi;
16552
16553   S (mp);
16554   W (ret);
16555   return ret;
16556 }
16557
16558 static int
16559 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16560 {
16561   unformat_input_t *i = vam->input;
16562   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16563   int ret;
16564   u32 ispi;
16565
16566
16567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16568     {
16569       if (unformat (i, "%x", &ispi))
16570         ;
16571       else
16572         {
16573           errmsg ("parse error '%U'", format_unformat_error, i);
16574           return -99;
16575         }
16576     }
16577
16578   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16579
16580   mp->ispi = ispi;
16581
16582   S (mp);
16583   W (ret);
16584   return ret;
16585 }
16586
16587 static int
16588 api_get_first_msg_id (vat_main_t * vam)
16589 {
16590   vl_api_get_first_msg_id_t *mp;
16591   unformat_input_t *i = vam->input;
16592   u8 *name;
16593   u8 name_set = 0;
16594   int ret;
16595
16596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16597     {
16598       if (unformat (i, "client %s", &name))
16599         name_set = 1;
16600       else
16601         break;
16602     }
16603
16604   if (name_set == 0)
16605     {
16606       errmsg ("missing client name");
16607       return -99;
16608     }
16609   vec_add1 (name, 0);
16610
16611   if (vec_len (name) > 63)
16612     {
16613       errmsg ("client name too long");
16614       return -99;
16615     }
16616
16617   M (GET_FIRST_MSG_ID, mp);
16618   clib_memcpy (mp->name, name, vec_len (name));
16619   S (mp);
16620   W (ret);
16621   return ret;
16622 }
16623
16624 static int
16625 api_cop_interface_enable_disable (vat_main_t * vam)
16626 {
16627   unformat_input_t *line_input = vam->input;
16628   vl_api_cop_interface_enable_disable_t *mp;
16629   u32 sw_if_index = ~0;
16630   u8 enable_disable = 1;
16631   int ret;
16632
16633   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16634     {
16635       if (unformat (line_input, "disable"))
16636         enable_disable = 0;
16637       if (unformat (line_input, "enable"))
16638         enable_disable = 1;
16639       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16640                          vam, &sw_if_index))
16641         ;
16642       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16643         ;
16644       else
16645         break;
16646     }
16647
16648   if (sw_if_index == ~0)
16649     {
16650       errmsg ("missing interface name or sw_if_index");
16651       return -99;
16652     }
16653
16654   /* Construct the API message */
16655   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16656   mp->sw_if_index = ntohl (sw_if_index);
16657   mp->enable_disable = enable_disable;
16658
16659   /* send it... */
16660   S (mp);
16661   /* Wait for the reply */
16662   W (ret);
16663   return ret;
16664 }
16665
16666 static int
16667 api_cop_whitelist_enable_disable (vat_main_t * vam)
16668 {
16669   unformat_input_t *line_input = vam->input;
16670   vl_api_cop_whitelist_enable_disable_t *mp;
16671   u32 sw_if_index = ~0;
16672   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16673   u32 fib_id = 0;
16674   int ret;
16675
16676   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16677     {
16678       if (unformat (line_input, "ip4"))
16679         ip4 = 1;
16680       else if (unformat (line_input, "ip6"))
16681         ip6 = 1;
16682       else if (unformat (line_input, "default"))
16683         default_cop = 1;
16684       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16685                          vam, &sw_if_index))
16686         ;
16687       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16688         ;
16689       else if (unformat (line_input, "fib-id %d", &fib_id))
16690         ;
16691       else
16692         break;
16693     }
16694
16695   if (sw_if_index == ~0)
16696     {
16697       errmsg ("missing interface name or sw_if_index");
16698       return -99;
16699     }
16700
16701   /* Construct the API message */
16702   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16703   mp->sw_if_index = ntohl (sw_if_index);
16704   mp->fib_id = ntohl (fib_id);
16705   mp->ip4 = ip4;
16706   mp->ip6 = ip6;
16707   mp->default_cop = default_cop;
16708
16709   /* send it... */
16710   S (mp);
16711   /* Wait for the reply */
16712   W (ret);
16713   return ret;
16714 }
16715
16716 static int
16717 api_get_node_graph (vat_main_t * vam)
16718 {
16719   vl_api_get_node_graph_t *mp;
16720   int ret;
16721
16722   M (GET_NODE_GRAPH, mp);
16723
16724   /* send it... */
16725   S (mp);
16726   /* Wait for the reply */
16727   W (ret);
16728   return ret;
16729 }
16730
16731 /* *INDENT-OFF* */
16732 /** Used for parsing LISP eids */
16733 typedef CLIB_PACKED(struct{
16734   u8 addr[16];   /**< eid address */
16735   u32 len;       /**< prefix length if IP */
16736   u8 type;      /**< type of eid */
16737 }) lisp_eid_vat_t;
16738 /* *INDENT-ON* */
16739
16740 static uword
16741 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16742 {
16743   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16744
16745   memset (a, 0, sizeof (a[0]));
16746
16747   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16748     {
16749       a->type = 0;              /* ipv4 type */
16750     }
16751   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16752     {
16753       a->type = 1;              /* ipv6 type */
16754     }
16755   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16756     {
16757       a->type = 2;              /* mac type */
16758     }
16759   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16760     {
16761       a->type = 3;              /* NSH type */
16762       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16763       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16764     }
16765   else
16766     {
16767       return 0;
16768     }
16769
16770   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16771     {
16772       return 0;
16773     }
16774
16775   return 1;
16776 }
16777
16778 static int
16779 lisp_eid_size_vat (u8 type)
16780 {
16781   switch (type)
16782     {
16783     case 0:
16784       return 4;
16785     case 1:
16786       return 16;
16787     case 2:
16788       return 6;
16789     case 3:
16790       return 5;
16791     }
16792   return 0;
16793 }
16794
16795 static void
16796 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16797 {
16798   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16799 }
16800
16801 static int
16802 api_one_add_del_locator_set (vat_main_t * vam)
16803 {
16804   unformat_input_t *input = vam->input;
16805   vl_api_one_add_del_locator_set_t *mp;
16806   u8 is_add = 1;
16807   u8 *locator_set_name = NULL;
16808   u8 locator_set_name_set = 0;
16809   vl_api_local_locator_t locator, *locators = 0;
16810   u32 sw_if_index, priority, weight;
16811   u32 data_len = 0;
16812
16813   int ret;
16814   /* Parse args required to build the message */
16815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (input, "del"))
16818         {
16819           is_add = 0;
16820         }
16821       else if (unformat (input, "locator-set %s", &locator_set_name))
16822         {
16823           locator_set_name_set = 1;
16824         }
16825       else if (unformat (input, "sw_if_index %u p %u w %u",
16826                          &sw_if_index, &priority, &weight))
16827         {
16828           locator.sw_if_index = htonl (sw_if_index);
16829           locator.priority = priority;
16830           locator.weight = weight;
16831           vec_add1 (locators, locator);
16832         }
16833       else
16834         if (unformat
16835             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16836              &sw_if_index, &priority, &weight))
16837         {
16838           locator.sw_if_index = htonl (sw_if_index);
16839           locator.priority = priority;
16840           locator.weight = weight;
16841           vec_add1 (locators, locator);
16842         }
16843       else
16844         break;
16845     }
16846
16847   if (locator_set_name_set == 0)
16848     {
16849       errmsg ("missing locator-set name");
16850       vec_free (locators);
16851       return -99;
16852     }
16853
16854   if (vec_len (locator_set_name) > 64)
16855     {
16856       errmsg ("locator-set name too long");
16857       vec_free (locator_set_name);
16858       vec_free (locators);
16859       return -99;
16860     }
16861   vec_add1 (locator_set_name, 0);
16862
16863   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
16864
16865   /* Construct the API message */
16866   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
16867
16868   mp->is_add = is_add;
16869   clib_memcpy (mp->locator_set_name, locator_set_name,
16870                vec_len (locator_set_name));
16871   vec_free (locator_set_name);
16872
16873   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
16874   if (locators)
16875     clib_memcpy (mp->locators, locators, data_len);
16876   vec_free (locators);
16877
16878   /* send it... */
16879   S (mp);
16880
16881   /* Wait for a reply... */
16882   W (ret);
16883   return ret;
16884 }
16885
16886 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
16887
16888 static int
16889 api_one_add_del_locator (vat_main_t * vam)
16890 {
16891   unformat_input_t *input = vam->input;
16892   vl_api_one_add_del_locator_t *mp;
16893   u32 tmp_if_index = ~0;
16894   u32 sw_if_index = ~0;
16895   u8 sw_if_index_set = 0;
16896   u8 sw_if_index_if_name_set = 0;
16897   u32 priority = ~0;
16898   u8 priority_set = 0;
16899   u32 weight = ~0;
16900   u8 weight_set = 0;
16901   u8 is_add = 1;
16902   u8 *locator_set_name = NULL;
16903   u8 locator_set_name_set = 0;
16904   int ret;
16905
16906   /* Parse args required to build the message */
16907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16908     {
16909       if (unformat (input, "del"))
16910         {
16911           is_add = 0;
16912         }
16913       else if (unformat (input, "locator-set %s", &locator_set_name))
16914         {
16915           locator_set_name_set = 1;
16916         }
16917       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16918                          &tmp_if_index))
16919         {
16920           sw_if_index_if_name_set = 1;
16921           sw_if_index = tmp_if_index;
16922         }
16923       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16924         {
16925           sw_if_index_set = 1;
16926           sw_if_index = tmp_if_index;
16927         }
16928       else if (unformat (input, "p %d", &priority))
16929         {
16930           priority_set = 1;
16931         }
16932       else if (unformat (input, "w %d", &weight))
16933         {
16934           weight_set = 1;
16935         }
16936       else
16937         break;
16938     }
16939
16940   if (locator_set_name_set == 0)
16941     {
16942       errmsg ("missing locator-set name");
16943       return -99;
16944     }
16945
16946   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16947     {
16948       errmsg ("missing sw_if_index");
16949       vec_free (locator_set_name);
16950       return -99;
16951     }
16952
16953   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16954     {
16955       errmsg ("cannot use both params interface name and sw_if_index");
16956       vec_free (locator_set_name);
16957       return -99;
16958     }
16959
16960   if (priority_set == 0)
16961     {
16962       errmsg ("missing locator-set priority");
16963       vec_free (locator_set_name);
16964       return -99;
16965     }
16966
16967   if (weight_set == 0)
16968     {
16969       errmsg ("missing locator-set weight");
16970       vec_free (locator_set_name);
16971       return -99;
16972     }
16973
16974   if (vec_len (locator_set_name) > 64)
16975     {
16976       errmsg ("locator-set name too long");
16977       vec_free (locator_set_name);
16978       return -99;
16979     }
16980   vec_add1 (locator_set_name, 0);
16981
16982   /* Construct the API message */
16983   M (ONE_ADD_DEL_LOCATOR, mp);
16984
16985   mp->is_add = is_add;
16986   mp->sw_if_index = ntohl (sw_if_index);
16987   mp->priority = priority;
16988   mp->weight = weight;
16989   clib_memcpy (mp->locator_set_name, locator_set_name,
16990                vec_len (locator_set_name));
16991   vec_free (locator_set_name);
16992
16993   /* send it... */
16994   S (mp);
16995
16996   /* Wait for a reply... */
16997   W (ret);
16998   return ret;
16999 }
17000
17001 #define api_lisp_add_del_locator api_one_add_del_locator
17002
17003 uword
17004 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17005 {
17006   u32 *key_id = va_arg (*args, u32 *);
17007   u8 *s = 0;
17008
17009   if (unformat (input, "%s", &s))
17010     {
17011       if (!strcmp ((char *) s, "sha1"))
17012         key_id[0] = HMAC_SHA_1_96;
17013       else if (!strcmp ((char *) s, "sha256"))
17014         key_id[0] = HMAC_SHA_256_128;
17015       else
17016         {
17017           clib_warning ("invalid key_id: '%s'", s);
17018           key_id[0] = HMAC_NO_KEY;
17019         }
17020     }
17021   else
17022     return 0;
17023
17024   vec_free (s);
17025   return 1;
17026 }
17027
17028 static int
17029 api_one_add_del_local_eid (vat_main_t * vam)
17030 {
17031   unformat_input_t *input = vam->input;
17032   vl_api_one_add_del_local_eid_t *mp;
17033   u8 is_add = 1;
17034   u8 eid_set = 0;
17035   lisp_eid_vat_t _eid, *eid = &_eid;
17036   u8 *locator_set_name = 0;
17037   u8 locator_set_name_set = 0;
17038   u32 vni = 0;
17039   u16 key_id = 0;
17040   u8 *key = 0;
17041   int ret;
17042
17043   /* Parse args required to build the message */
17044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17045     {
17046       if (unformat (input, "del"))
17047         {
17048           is_add = 0;
17049         }
17050       else if (unformat (input, "vni %d", &vni))
17051         {
17052           ;
17053         }
17054       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17055         {
17056           eid_set = 1;
17057         }
17058       else if (unformat (input, "locator-set %s", &locator_set_name))
17059         {
17060           locator_set_name_set = 1;
17061         }
17062       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17063         ;
17064       else if (unformat (input, "secret-key %_%v%_", &key))
17065         ;
17066       else
17067         break;
17068     }
17069
17070   if (locator_set_name_set == 0)
17071     {
17072       errmsg ("missing locator-set name");
17073       return -99;
17074     }
17075
17076   if (0 == eid_set)
17077     {
17078       errmsg ("EID address not set!");
17079       vec_free (locator_set_name);
17080       return -99;
17081     }
17082
17083   if (key && (0 == key_id))
17084     {
17085       errmsg ("invalid key_id!");
17086       return -99;
17087     }
17088
17089   if (vec_len (key) > 64)
17090     {
17091       errmsg ("key too long");
17092       vec_free (key);
17093       return -99;
17094     }
17095
17096   if (vec_len (locator_set_name) > 64)
17097     {
17098       errmsg ("locator-set name too long");
17099       vec_free (locator_set_name);
17100       return -99;
17101     }
17102   vec_add1 (locator_set_name, 0);
17103
17104   /* Construct the API message */
17105   M (ONE_ADD_DEL_LOCAL_EID, mp);
17106
17107   mp->is_add = is_add;
17108   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17109   mp->eid_type = eid->type;
17110   mp->prefix_len = eid->len;
17111   mp->vni = clib_host_to_net_u32 (vni);
17112   mp->key_id = clib_host_to_net_u16 (key_id);
17113   clib_memcpy (mp->locator_set_name, locator_set_name,
17114                vec_len (locator_set_name));
17115   clib_memcpy (mp->key, key, vec_len (key));
17116
17117   vec_free (locator_set_name);
17118   vec_free (key);
17119
17120   /* send it... */
17121   S (mp);
17122
17123   /* Wait for a reply... */
17124   W (ret);
17125   return ret;
17126 }
17127
17128 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17129
17130 static int
17131 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17132 {
17133   u32 dp_table = 0, vni = 0;;
17134   unformat_input_t *input = vam->input;
17135   vl_api_gpe_add_del_fwd_entry_t *mp;
17136   u8 is_add = 1;
17137   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17138   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17139   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17140   u32 action = ~0, w;
17141   ip4_address_t rmt_rloc4, lcl_rloc4;
17142   ip6_address_t rmt_rloc6, lcl_rloc6;
17143   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17144   int ret;
17145
17146   memset (&rloc, 0, sizeof (rloc));
17147
17148   /* Parse args required to build the message */
17149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17150     {
17151       if (unformat (input, "del"))
17152         is_add = 0;
17153       else if (unformat (input, "add"))
17154         is_add = 1;
17155       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17156         {
17157           rmt_eid_set = 1;
17158         }
17159       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17160         {
17161           lcl_eid_set = 1;
17162         }
17163       else if (unformat (input, "vrf %d", &dp_table))
17164         ;
17165       else if (unformat (input, "bd %d", &dp_table))
17166         ;
17167       else if (unformat (input, "vni %d", &vni))
17168         ;
17169       else if (unformat (input, "w %d", &w))
17170         {
17171           if (!curr_rloc)
17172             {
17173               errmsg ("No RLOC configured for setting priority/weight!");
17174               return -99;
17175             }
17176           curr_rloc->weight = w;
17177         }
17178       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17179                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17180         {
17181           rloc.is_ip4 = 1;
17182
17183           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17184           rloc.weight = 0;
17185           vec_add1 (lcl_locs, rloc);
17186
17187           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17188           vec_add1 (rmt_locs, rloc);
17189           /* weight saved in rmt loc */
17190           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17191         }
17192       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17193                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17194         {
17195           rloc.is_ip4 = 0;
17196           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17197           rloc.weight = 0;
17198           vec_add1 (lcl_locs, rloc);
17199
17200           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17201           vec_add1 (rmt_locs, rloc);
17202           /* weight saved in rmt loc */
17203           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17204         }
17205       else if (unformat (input, "action %d", &action))
17206         {
17207           ;
17208         }
17209       else
17210         {
17211           clib_warning ("parse error '%U'", format_unformat_error, input);
17212           return -99;
17213         }
17214     }
17215
17216   if (!rmt_eid_set)
17217     {
17218       errmsg ("remote eid addresses not set");
17219       return -99;
17220     }
17221
17222   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17223     {
17224       errmsg ("eid types don't match");
17225       return -99;
17226     }
17227
17228   if (0 == rmt_locs && (u32) ~ 0 == action)
17229     {
17230       errmsg ("action not set for negative mapping");
17231       return -99;
17232     }
17233
17234   /* Construct the API message */
17235   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17236       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17237
17238   mp->is_add = is_add;
17239   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17240   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17241   mp->eid_type = rmt_eid->type;
17242   mp->dp_table = clib_host_to_net_u32 (dp_table);
17243   mp->vni = clib_host_to_net_u32 (vni);
17244   mp->rmt_len = rmt_eid->len;
17245   mp->lcl_len = lcl_eid->len;
17246   mp->action = action;
17247
17248   if (0 != rmt_locs && 0 != lcl_locs)
17249     {
17250       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17251       clib_memcpy (mp->locs, lcl_locs,
17252                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17253
17254       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17255       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17256                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17257     }
17258   vec_free (lcl_locs);
17259   vec_free (rmt_locs);
17260
17261   /* send it... */
17262   S (mp);
17263
17264   /* Wait for a reply... */
17265   W (ret);
17266   return ret;
17267 }
17268
17269 static int
17270 api_one_add_del_map_server (vat_main_t * vam)
17271 {
17272   unformat_input_t *input = vam->input;
17273   vl_api_one_add_del_map_server_t *mp;
17274   u8 is_add = 1;
17275   u8 ipv4_set = 0;
17276   u8 ipv6_set = 0;
17277   ip4_address_t ipv4;
17278   ip6_address_t ipv6;
17279   int ret;
17280
17281   /* Parse args required to build the message */
17282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17283     {
17284       if (unformat (input, "del"))
17285         {
17286           is_add = 0;
17287         }
17288       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17289         {
17290           ipv4_set = 1;
17291         }
17292       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17293         {
17294           ipv6_set = 1;
17295         }
17296       else
17297         break;
17298     }
17299
17300   if (ipv4_set && ipv6_set)
17301     {
17302       errmsg ("both eid v4 and v6 addresses set");
17303       return -99;
17304     }
17305
17306   if (!ipv4_set && !ipv6_set)
17307     {
17308       errmsg ("eid addresses not set");
17309       return -99;
17310     }
17311
17312   /* Construct the API message */
17313   M (ONE_ADD_DEL_MAP_SERVER, mp);
17314
17315   mp->is_add = is_add;
17316   if (ipv6_set)
17317     {
17318       mp->is_ipv6 = 1;
17319       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17320     }
17321   else
17322     {
17323       mp->is_ipv6 = 0;
17324       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17325     }
17326
17327   /* send it... */
17328   S (mp);
17329
17330   /* Wait for a reply... */
17331   W (ret);
17332   return ret;
17333 }
17334
17335 #define api_lisp_add_del_map_server api_one_add_del_map_server
17336
17337 static int
17338 api_one_add_del_map_resolver (vat_main_t * vam)
17339 {
17340   unformat_input_t *input = vam->input;
17341   vl_api_one_add_del_map_resolver_t *mp;
17342   u8 is_add = 1;
17343   u8 ipv4_set = 0;
17344   u8 ipv6_set = 0;
17345   ip4_address_t ipv4;
17346   ip6_address_t ipv6;
17347   int ret;
17348
17349   /* Parse args required to build the message */
17350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17351     {
17352       if (unformat (input, "del"))
17353         {
17354           is_add = 0;
17355         }
17356       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17357         {
17358           ipv4_set = 1;
17359         }
17360       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17361         {
17362           ipv6_set = 1;
17363         }
17364       else
17365         break;
17366     }
17367
17368   if (ipv4_set && ipv6_set)
17369     {
17370       errmsg ("both eid v4 and v6 addresses set");
17371       return -99;
17372     }
17373
17374   if (!ipv4_set && !ipv6_set)
17375     {
17376       errmsg ("eid addresses not set");
17377       return -99;
17378     }
17379
17380   /* Construct the API message */
17381   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17382
17383   mp->is_add = is_add;
17384   if (ipv6_set)
17385     {
17386       mp->is_ipv6 = 1;
17387       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17388     }
17389   else
17390     {
17391       mp->is_ipv6 = 0;
17392       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17393     }
17394
17395   /* send it... */
17396   S (mp);
17397
17398   /* Wait for a reply... */
17399   W (ret);
17400   return ret;
17401 }
17402
17403 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17404
17405 static int
17406 api_lisp_gpe_enable_disable (vat_main_t * vam)
17407 {
17408   unformat_input_t *input = vam->input;
17409   vl_api_gpe_enable_disable_t *mp;
17410   u8 is_set = 0;
17411   u8 is_en = 1;
17412   int ret;
17413
17414   /* Parse args required to build the message */
17415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17416     {
17417       if (unformat (input, "enable"))
17418         {
17419           is_set = 1;
17420           is_en = 1;
17421         }
17422       else if (unformat (input, "disable"))
17423         {
17424           is_set = 1;
17425           is_en = 0;
17426         }
17427       else
17428         break;
17429     }
17430
17431   if (is_set == 0)
17432     {
17433       errmsg ("Value not set");
17434       return -99;
17435     }
17436
17437   /* Construct the API message */
17438   M (GPE_ENABLE_DISABLE, mp);
17439
17440   mp->is_en = is_en;
17441
17442   /* send it... */
17443   S (mp);
17444
17445   /* Wait for a reply... */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 static int
17451 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17452 {
17453   unformat_input_t *input = vam->input;
17454   vl_api_one_rloc_probe_enable_disable_t *mp;
17455   u8 is_set = 0;
17456   u8 is_en = 0;
17457   int ret;
17458
17459   /* Parse args required to build the message */
17460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17461     {
17462       if (unformat (input, "enable"))
17463         {
17464           is_set = 1;
17465           is_en = 1;
17466         }
17467       else if (unformat (input, "disable"))
17468         is_set = 1;
17469       else
17470         break;
17471     }
17472
17473   if (!is_set)
17474     {
17475       errmsg ("Value not set");
17476       return -99;
17477     }
17478
17479   /* Construct the API message */
17480   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17481
17482   mp->is_enabled = is_en;
17483
17484   /* send it... */
17485   S (mp);
17486
17487   /* Wait for a reply... */
17488   W (ret);
17489   return ret;
17490 }
17491
17492 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17493
17494 static int
17495 api_one_map_register_enable_disable (vat_main_t * vam)
17496 {
17497   unformat_input_t *input = vam->input;
17498   vl_api_one_map_register_enable_disable_t *mp;
17499   u8 is_set = 0;
17500   u8 is_en = 0;
17501   int ret;
17502
17503   /* Parse args required to build the message */
17504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17505     {
17506       if (unformat (input, "enable"))
17507         {
17508           is_set = 1;
17509           is_en = 1;
17510         }
17511       else if (unformat (input, "disable"))
17512         is_set = 1;
17513       else
17514         break;
17515     }
17516
17517   if (!is_set)
17518     {
17519       errmsg ("Value not set");
17520       return -99;
17521     }
17522
17523   /* Construct the API message */
17524   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
17525
17526   mp->is_enabled = is_en;
17527
17528   /* send it... */
17529   S (mp);
17530
17531   /* Wait for a reply... */
17532   W (ret);
17533   return ret;
17534 }
17535
17536 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17537
17538 static int
17539 api_one_enable_disable (vat_main_t * vam)
17540 {
17541   unformat_input_t *input = vam->input;
17542   vl_api_one_enable_disable_t *mp;
17543   u8 is_set = 0;
17544   u8 is_en = 0;
17545   int ret;
17546
17547   /* Parse args required to build the message */
17548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17549     {
17550       if (unformat (input, "enable"))
17551         {
17552           is_set = 1;
17553           is_en = 1;
17554         }
17555       else if (unformat (input, "disable"))
17556         {
17557           is_set = 1;
17558         }
17559       else
17560         break;
17561     }
17562
17563   if (!is_set)
17564     {
17565       errmsg ("Value not set");
17566       return -99;
17567     }
17568
17569   /* Construct the API message */
17570   M (ONE_ENABLE_DISABLE, mp);
17571
17572   mp->is_en = is_en;
17573
17574   /* send it... */
17575   S (mp);
17576
17577   /* Wait for a reply... */
17578   W (ret);
17579   return ret;
17580 }
17581
17582 #define api_lisp_enable_disable api_one_enable_disable
17583
17584 static int
17585 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17586 {
17587   unformat_input_t *input = vam->input;
17588   vl_api_one_enable_disable_xtr_mode_t *mp;
17589   u8 is_set = 0;
17590   u8 is_en = 0;
17591   int ret;
17592
17593   /* Parse args required to build the message */
17594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17595     {
17596       if (unformat (input, "enable"))
17597         {
17598           is_set = 1;
17599           is_en = 1;
17600         }
17601       else if (unformat (input, "disable"))
17602         {
17603           is_set = 1;
17604         }
17605       else
17606         break;
17607     }
17608
17609   if (!is_set)
17610     {
17611       errmsg ("Value not set");
17612       return -99;
17613     }
17614
17615   /* Construct the API message */
17616   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17617
17618   mp->is_en = is_en;
17619
17620   /* send it... */
17621   S (mp);
17622
17623   /* Wait for a reply... */
17624   W (ret);
17625   return ret;
17626 }
17627
17628 static int
17629 api_one_show_xtr_mode (vat_main_t * vam)
17630 {
17631   vl_api_one_show_xtr_mode_t *mp;
17632   int ret;
17633
17634   /* Construct the API message */
17635   M (ONE_SHOW_XTR_MODE, mp);
17636
17637   /* send it... */
17638   S (mp);
17639
17640   /* Wait for a reply... */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 static int
17646 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17647 {
17648   unformat_input_t *input = vam->input;
17649   vl_api_one_enable_disable_pitr_mode_t *mp;
17650   u8 is_set = 0;
17651   u8 is_en = 0;
17652   int ret;
17653
17654   /* Parse args required to build the message */
17655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17656     {
17657       if (unformat (input, "enable"))
17658         {
17659           is_set = 1;
17660           is_en = 1;
17661         }
17662       else if (unformat (input, "disable"))
17663         {
17664           is_set = 1;
17665         }
17666       else
17667         break;
17668     }
17669
17670   if (!is_set)
17671     {
17672       errmsg ("Value not set");
17673       return -99;
17674     }
17675
17676   /* Construct the API message */
17677   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17678
17679   mp->is_en = is_en;
17680
17681   /* send it... */
17682   S (mp);
17683
17684   /* Wait for a reply... */
17685   W (ret);
17686   return ret;
17687 }
17688
17689 static int
17690 api_one_show_pitr_mode (vat_main_t * vam)
17691 {
17692   vl_api_one_show_pitr_mode_t *mp;
17693   int ret;
17694
17695   /* Construct the API message */
17696   M (ONE_SHOW_PITR_MODE, mp);
17697
17698   /* send it... */
17699   S (mp);
17700
17701   /* Wait for a reply... */
17702   W (ret);
17703   return ret;
17704 }
17705
17706 static int
17707 api_one_enable_disable_petr_mode (vat_main_t * vam)
17708 {
17709   unformat_input_t *input = vam->input;
17710   vl_api_one_enable_disable_petr_mode_t *mp;
17711   u8 is_set = 0;
17712   u8 is_en = 0;
17713   int ret;
17714
17715   /* Parse args required to build the message */
17716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17717     {
17718       if (unformat (input, "enable"))
17719         {
17720           is_set = 1;
17721           is_en = 1;
17722         }
17723       else if (unformat (input, "disable"))
17724         {
17725           is_set = 1;
17726         }
17727       else
17728         break;
17729     }
17730
17731   if (!is_set)
17732     {
17733       errmsg ("Value not set");
17734       return -99;
17735     }
17736
17737   /* Construct the API message */
17738   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17739
17740   mp->is_en = is_en;
17741
17742   /* send it... */
17743   S (mp);
17744
17745   /* Wait for a reply... */
17746   W (ret);
17747   return ret;
17748 }
17749
17750 static int
17751 api_one_show_petr_mode (vat_main_t * vam)
17752 {
17753   vl_api_one_show_petr_mode_t *mp;
17754   int ret;
17755
17756   /* Construct the API message */
17757   M (ONE_SHOW_PETR_MODE, mp);
17758
17759   /* send it... */
17760   S (mp);
17761
17762   /* Wait for a reply... */
17763   W (ret);
17764   return ret;
17765 }
17766
17767 static int
17768 api_show_one_map_register_state (vat_main_t * vam)
17769 {
17770   vl_api_show_one_map_register_state_t *mp;
17771   int ret;
17772
17773   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17774
17775   /* send */
17776   S (mp);
17777
17778   /* wait for reply */
17779   W (ret);
17780   return ret;
17781 }
17782
17783 #define api_show_lisp_map_register_state api_show_one_map_register_state
17784
17785 static int
17786 api_show_one_rloc_probe_state (vat_main_t * vam)
17787 {
17788   vl_api_show_one_rloc_probe_state_t *mp;
17789   int ret;
17790
17791   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17792
17793   /* send */
17794   S (mp);
17795
17796   /* wait for reply */
17797   W (ret);
17798   return ret;
17799 }
17800
17801 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17802
17803 static int
17804 api_one_add_del_ndp_entry (vat_main_t * vam)
17805 {
17806   vl_api_one_add_del_ndp_entry_t *mp;
17807   unformat_input_t *input = vam->input;
17808   u8 is_add = 1;
17809   u8 mac_set = 0;
17810   u8 bd_set = 0;
17811   u8 ip_set = 0;
17812   u8 mac[6] = { 0, };
17813   u8 ip6[16] = { 0, };
17814   u32 bd = ~0;
17815   int ret;
17816
17817   /* Parse args required to build the message */
17818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17819     {
17820       if (unformat (input, "del"))
17821         is_add = 0;
17822       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17823         mac_set = 1;
17824       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17825         ip_set = 1;
17826       else if (unformat (input, "bd %d", &bd))
17827         bd_set = 1;
17828       else
17829         {
17830           errmsg ("parse error '%U'", format_unformat_error, input);
17831           return -99;
17832         }
17833     }
17834
17835   if (!bd_set || !ip_set || (!mac_set && is_add))
17836     {
17837       errmsg ("Missing BD, IP or MAC!");
17838       return -99;
17839     }
17840
17841   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17842   mp->is_add = is_add;
17843   clib_memcpy (mp->mac, mac, 6);
17844   mp->bd = clib_host_to_net_u32 (bd);
17845   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17846
17847   /* send */
17848   S (mp);
17849
17850   /* wait for reply */
17851   W (ret);
17852   return ret;
17853 }
17854
17855 static int
17856 api_one_add_del_l2_arp_entry (vat_main_t * vam)
17857 {
17858   vl_api_one_add_del_l2_arp_entry_t *mp;
17859   unformat_input_t *input = vam->input;
17860   u8 is_add = 1;
17861   u8 mac_set = 0;
17862   u8 bd_set = 0;
17863   u8 ip_set = 0;
17864   u8 mac[6] = { 0, };
17865   u32 ip4 = 0, bd = ~0;
17866   int ret;
17867
17868   /* Parse args required to build the message */
17869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17870     {
17871       if (unformat (input, "del"))
17872         is_add = 0;
17873       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17874         mac_set = 1;
17875       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
17876         ip_set = 1;
17877       else if (unformat (input, "bd %d", &bd))
17878         bd_set = 1;
17879       else
17880         {
17881           errmsg ("parse error '%U'", format_unformat_error, input);
17882           return -99;
17883         }
17884     }
17885
17886   if (!bd_set || !ip_set || (!mac_set && is_add))
17887     {
17888       errmsg ("Missing BD, IP or MAC!");
17889       return -99;
17890     }
17891
17892   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
17893   mp->is_add = is_add;
17894   clib_memcpy (mp->mac, mac, 6);
17895   mp->bd = clib_host_to_net_u32 (bd);
17896   mp->ip4 = ip4;
17897
17898   /* send */
17899   S (mp);
17900
17901   /* wait for reply */
17902   W (ret);
17903   return ret;
17904 }
17905
17906 static int
17907 api_one_ndp_bd_get (vat_main_t * vam)
17908 {
17909   vl_api_one_ndp_bd_get_t *mp;
17910   int ret;
17911
17912   M (ONE_NDP_BD_GET, mp);
17913
17914   /* send */
17915   S (mp);
17916
17917   /* wait for reply */
17918   W (ret);
17919   return ret;
17920 }
17921
17922 static int
17923 api_one_ndp_entries_get (vat_main_t * vam)
17924 {
17925   vl_api_one_ndp_entries_get_t *mp;
17926   unformat_input_t *input = vam->input;
17927   u8 bd_set = 0;
17928   u32 bd = ~0;
17929   int ret;
17930
17931   /* Parse args required to build the message */
17932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17933     {
17934       if (unformat (input, "bd %d", &bd))
17935         bd_set = 1;
17936       else
17937         {
17938           errmsg ("parse error '%U'", format_unformat_error, input);
17939           return -99;
17940         }
17941     }
17942
17943   if (!bd_set)
17944     {
17945       errmsg ("Expected bridge domain!");
17946       return -99;
17947     }
17948
17949   M (ONE_NDP_ENTRIES_GET, mp);
17950   mp->bd = clib_host_to_net_u32 (bd);
17951
17952   /* send */
17953   S (mp);
17954
17955   /* wait for reply */
17956   W (ret);
17957   return ret;
17958 }
17959
17960 static int
17961 api_one_l2_arp_bd_get (vat_main_t * vam)
17962 {
17963   vl_api_one_l2_arp_bd_get_t *mp;
17964   int ret;
17965
17966   M (ONE_L2_ARP_BD_GET, mp);
17967
17968   /* send */
17969   S (mp);
17970
17971   /* wait for reply */
17972   W (ret);
17973   return ret;
17974 }
17975
17976 static int
17977 api_one_l2_arp_entries_get (vat_main_t * vam)
17978 {
17979   vl_api_one_l2_arp_entries_get_t *mp;
17980   unformat_input_t *input = vam->input;
17981   u8 bd_set = 0;
17982   u32 bd = ~0;
17983   int ret;
17984
17985   /* Parse args required to build the message */
17986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17987     {
17988       if (unformat (input, "bd %d", &bd))
17989         bd_set = 1;
17990       else
17991         {
17992           errmsg ("parse error '%U'", format_unformat_error, input);
17993           return -99;
17994         }
17995     }
17996
17997   if (!bd_set)
17998     {
17999       errmsg ("Expected bridge domain!");
18000       return -99;
18001     }
18002
18003   M (ONE_L2_ARP_ENTRIES_GET, mp);
18004   mp->bd = clib_host_to_net_u32 (bd);
18005
18006   /* send */
18007   S (mp);
18008
18009   /* wait for reply */
18010   W (ret);
18011   return ret;
18012 }
18013
18014 static int
18015 api_one_stats_enable_disable (vat_main_t * vam)
18016 {
18017   vl_api_one_stats_enable_disable_t *mp;
18018   unformat_input_t *input = vam->input;
18019   u8 is_set = 0;
18020   u8 is_en = 0;
18021   int ret;
18022
18023   /* Parse args required to build the message */
18024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18025     {
18026       if (unformat (input, "enable"))
18027         {
18028           is_set = 1;
18029           is_en = 1;
18030         }
18031       else if (unformat (input, "disable"))
18032         {
18033           is_set = 1;
18034         }
18035       else
18036         break;
18037     }
18038
18039   if (!is_set)
18040     {
18041       errmsg ("Value not set");
18042       return -99;
18043     }
18044
18045   M (ONE_STATS_ENABLE_DISABLE, mp);
18046   mp->is_en = is_en;
18047
18048   /* send */
18049   S (mp);
18050
18051   /* wait for reply */
18052   W (ret);
18053   return ret;
18054 }
18055
18056 static int
18057 api_show_one_stats_enable_disable (vat_main_t * vam)
18058 {
18059   vl_api_show_one_stats_enable_disable_t *mp;
18060   int ret;
18061
18062   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18063
18064   /* send */
18065   S (mp);
18066
18067   /* wait for reply */
18068   W (ret);
18069   return ret;
18070 }
18071
18072 static int
18073 api_show_one_map_request_mode (vat_main_t * vam)
18074 {
18075   vl_api_show_one_map_request_mode_t *mp;
18076   int ret;
18077
18078   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18079
18080   /* send */
18081   S (mp);
18082
18083   /* wait for reply */
18084   W (ret);
18085   return ret;
18086 }
18087
18088 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18089
18090 static int
18091 api_one_map_request_mode (vat_main_t * vam)
18092 {
18093   unformat_input_t *input = vam->input;
18094   vl_api_one_map_request_mode_t *mp;
18095   u8 mode = 0;
18096   int ret;
18097
18098   /* Parse args required to build the message */
18099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18100     {
18101       if (unformat (input, "dst-only"))
18102         mode = 0;
18103       else if (unformat (input, "src-dst"))
18104         mode = 1;
18105       else
18106         {
18107           errmsg ("parse error '%U'", format_unformat_error, input);
18108           return -99;
18109         }
18110     }
18111
18112   M (ONE_MAP_REQUEST_MODE, mp);
18113
18114   mp->mode = mode;
18115
18116   /* send */
18117   S (mp);
18118
18119   /* wait for reply */
18120   W (ret);
18121   return ret;
18122 }
18123
18124 #define api_lisp_map_request_mode api_one_map_request_mode
18125
18126 /**
18127  * Enable/disable ONE proxy ITR.
18128  *
18129  * @param vam vpp API test context
18130  * @return return code
18131  */
18132 static int
18133 api_one_pitr_set_locator_set (vat_main_t * vam)
18134 {
18135   u8 ls_name_set = 0;
18136   unformat_input_t *input = vam->input;
18137   vl_api_one_pitr_set_locator_set_t *mp;
18138   u8 is_add = 1;
18139   u8 *ls_name = 0;
18140   int ret;
18141
18142   /* Parse args required to build the message */
18143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18144     {
18145       if (unformat (input, "del"))
18146         is_add = 0;
18147       else if (unformat (input, "locator-set %s", &ls_name))
18148         ls_name_set = 1;
18149       else
18150         {
18151           errmsg ("parse error '%U'", format_unformat_error, input);
18152           return -99;
18153         }
18154     }
18155
18156   if (!ls_name_set)
18157     {
18158       errmsg ("locator-set name not set!");
18159       return -99;
18160     }
18161
18162   M (ONE_PITR_SET_LOCATOR_SET, mp);
18163
18164   mp->is_add = is_add;
18165   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18166   vec_free (ls_name);
18167
18168   /* send */
18169   S (mp);
18170
18171   /* wait for reply */
18172   W (ret);
18173   return ret;
18174 }
18175
18176 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18177
18178 static int
18179 api_one_nsh_set_locator_set (vat_main_t * vam)
18180 {
18181   u8 ls_name_set = 0;
18182   unformat_input_t *input = vam->input;
18183   vl_api_one_nsh_set_locator_set_t *mp;
18184   u8 is_add = 1;
18185   u8 *ls_name = 0;
18186   int ret;
18187
18188   /* Parse args required to build the message */
18189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18190     {
18191       if (unformat (input, "del"))
18192         is_add = 0;
18193       else if (unformat (input, "ls %s", &ls_name))
18194         ls_name_set = 1;
18195       else
18196         {
18197           errmsg ("parse error '%U'", format_unformat_error, input);
18198           return -99;
18199         }
18200     }
18201
18202   if (!ls_name_set && is_add)
18203     {
18204       errmsg ("locator-set name not set!");
18205       return -99;
18206     }
18207
18208   M (ONE_NSH_SET_LOCATOR_SET, mp);
18209
18210   mp->is_add = is_add;
18211   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18212   vec_free (ls_name);
18213
18214   /* send */
18215   S (mp);
18216
18217   /* wait for reply */
18218   W (ret);
18219   return ret;
18220 }
18221
18222 static int
18223 api_show_one_pitr (vat_main_t * vam)
18224 {
18225   vl_api_show_one_pitr_t *mp;
18226   int ret;
18227
18228   if (!vam->json_output)
18229     {
18230       print (vam->ofp, "%=20s", "lisp status:");
18231     }
18232
18233   M (SHOW_ONE_PITR, mp);
18234   /* send it... */
18235   S (mp);
18236
18237   /* Wait for a reply... */
18238   W (ret);
18239   return ret;
18240 }
18241
18242 #define api_show_lisp_pitr api_show_one_pitr
18243
18244 static int
18245 api_one_use_petr (vat_main_t * vam)
18246 {
18247   unformat_input_t *input = vam->input;
18248   vl_api_one_use_petr_t *mp;
18249   u8 is_add = 0;
18250   ip_address_t ip;
18251   int ret;
18252
18253   memset (&ip, 0, sizeof (ip));
18254
18255   /* Parse args required to build the message */
18256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18257     {
18258       if (unformat (input, "disable"))
18259         is_add = 0;
18260       else
18261         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18262         {
18263           is_add = 1;
18264           ip_addr_version (&ip) = IP4;
18265         }
18266       else
18267         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18268         {
18269           is_add = 1;
18270           ip_addr_version (&ip) = IP6;
18271         }
18272       else
18273         {
18274           errmsg ("parse error '%U'", format_unformat_error, input);
18275           return -99;
18276         }
18277     }
18278
18279   M (ONE_USE_PETR, mp);
18280
18281   mp->is_add = is_add;
18282   if (is_add)
18283     {
18284       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18285       if (mp->is_ip4)
18286         clib_memcpy (mp->address, &ip, 4);
18287       else
18288         clib_memcpy (mp->address, &ip, 16);
18289     }
18290
18291   /* send */
18292   S (mp);
18293
18294   /* wait for reply */
18295   W (ret);
18296   return ret;
18297 }
18298
18299 #define api_lisp_use_petr api_one_use_petr
18300
18301 static int
18302 api_show_one_nsh_mapping (vat_main_t * vam)
18303 {
18304   vl_api_show_one_use_petr_t *mp;
18305   int ret;
18306
18307   if (!vam->json_output)
18308     {
18309       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18310     }
18311
18312   M (SHOW_ONE_NSH_MAPPING, mp);
18313   /* send it... */
18314   S (mp);
18315
18316   /* Wait for a reply... */
18317   W (ret);
18318   return ret;
18319 }
18320
18321 static int
18322 api_show_one_use_petr (vat_main_t * vam)
18323 {
18324   vl_api_show_one_use_petr_t *mp;
18325   int ret;
18326
18327   if (!vam->json_output)
18328     {
18329       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18330     }
18331
18332   M (SHOW_ONE_USE_PETR, mp);
18333   /* send it... */
18334   S (mp);
18335
18336   /* Wait for a reply... */
18337   W (ret);
18338   return ret;
18339 }
18340
18341 #define api_show_lisp_use_petr api_show_one_use_petr
18342
18343 /**
18344  * Add/delete mapping between vni and vrf
18345  */
18346 static int
18347 api_one_eid_table_add_del_map (vat_main_t * vam)
18348 {
18349   unformat_input_t *input = vam->input;
18350   vl_api_one_eid_table_add_del_map_t *mp;
18351   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18352   u32 vni, vrf, bd_index;
18353   int ret;
18354
18355   /* Parse args required to build the message */
18356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18357     {
18358       if (unformat (input, "del"))
18359         is_add = 0;
18360       else if (unformat (input, "vrf %d", &vrf))
18361         vrf_set = 1;
18362       else if (unformat (input, "bd_index %d", &bd_index))
18363         bd_index_set = 1;
18364       else if (unformat (input, "vni %d", &vni))
18365         vni_set = 1;
18366       else
18367         break;
18368     }
18369
18370   if (!vni_set || (!vrf_set && !bd_index_set))
18371     {
18372       errmsg ("missing arguments!");
18373       return -99;
18374     }
18375
18376   if (vrf_set && bd_index_set)
18377     {
18378       errmsg ("error: both vrf and bd entered!");
18379       return -99;
18380     }
18381
18382   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18383
18384   mp->is_add = is_add;
18385   mp->vni = htonl (vni);
18386   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18387   mp->is_l2 = bd_index_set;
18388
18389   /* send */
18390   S (mp);
18391
18392   /* wait for reply */
18393   W (ret);
18394   return ret;
18395 }
18396
18397 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18398
18399 uword
18400 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18401 {
18402   u32 *action = va_arg (*args, u32 *);
18403   u8 *s = 0;
18404
18405   if (unformat (input, "%s", &s))
18406     {
18407       if (!strcmp ((char *) s, "no-action"))
18408         action[0] = 0;
18409       else if (!strcmp ((char *) s, "natively-forward"))
18410         action[0] = 1;
18411       else if (!strcmp ((char *) s, "send-map-request"))
18412         action[0] = 2;
18413       else if (!strcmp ((char *) s, "drop"))
18414         action[0] = 3;
18415       else
18416         {
18417           clib_warning ("invalid action: '%s'", s);
18418           action[0] = 3;
18419         }
18420     }
18421   else
18422     return 0;
18423
18424   vec_free (s);
18425   return 1;
18426 }
18427
18428 /**
18429  * Add/del remote mapping to/from ONE control plane
18430  *
18431  * @param vam vpp API test context
18432  * @return return code
18433  */
18434 static int
18435 api_one_add_del_remote_mapping (vat_main_t * vam)
18436 {
18437   unformat_input_t *input = vam->input;
18438   vl_api_one_add_del_remote_mapping_t *mp;
18439   u32 vni = 0;
18440   lisp_eid_vat_t _eid, *eid = &_eid;
18441   lisp_eid_vat_t _seid, *seid = &_seid;
18442   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18443   u32 action = ~0, p, w, data_len;
18444   ip4_address_t rloc4;
18445   ip6_address_t rloc6;
18446   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18447   int ret;
18448
18449   memset (&rloc, 0, sizeof (rloc));
18450
18451   /* Parse args required to build the message */
18452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18453     {
18454       if (unformat (input, "del-all"))
18455         {
18456           del_all = 1;
18457         }
18458       else if (unformat (input, "del"))
18459         {
18460           is_add = 0;
18461         }
18462       else if (unformat (input, "add"))
18463         {
18464           is_add = 1;
18465         }
18466       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18467         {
18468           eid_set = 1;
18469         }
18470       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18471         {
18472           seid_set = 1;
18473         }
18474       else if (unformat (input, "vni %d", &vni))
18475         {
18476           ;
18477         }
18478       else if (unformat (input, "p %d w %d", &p, &w))
18479         {
18480           if (!curr_rloc)
18481             {
18482               errmsg ("No RLOC configured for setting priority/weight!");
18483               return -99;
18484             }
18485           curr_rloc->priority = p;
18486           curr_rloc->weight = w;
18487         }
18488       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18489         {
18490           rloc.is_ip4 = 1;
18491           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18492           vec_add1 (rlocs, rloc);
18493           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18494         }
18495       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18496         {
18497           rloc.is_ip4 = 0;
18498           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18499           vec_add1 (rlocs, rloc);
18500           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18501         }
18502       else if (unformat (input, "action %U",
18503                          unformat_negative_mapping_action, &action))
18504         {
18505           ;
18506         }
18507       else
18508         {
18509           clib_warning ("parse error '%U'", format_unformat_error, input);
18510           return -99;
18511         }
18512     }
18513
18514   if (0 == eid_set)
18515     {
18516       errmsg ("missing params!");
18517       return -99;
18518     }
18519
18520   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18521     {
18522       errmsg ("no action set for negative map-reply!");
18523       return -99;
18524     }
18525
18526   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18527
18528   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18529   mp->is_add = is_add;
18530   mp->vni = htonl (vni);
18531   mp->action = (u8) action;
18532   mp->is_src_dst = seid_set;
18533   mp->eid_len = eid->len;
18534   mp->seid_len = seid->len;
18535   mp->del_all = del_all;
18536   mp->eid_type = eid->type;
18537   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18538   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18539
18540   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18541   clib_memcpy (mp->rlocs, rlocs, data_len);
18542   vec_free (rlocs);
18543
18544   /* send it... */
18545   S (mp);
18546
18547   /* Wait for a reply... */
18548   W (ret);
18549   return ret;
18550 }
18551
18552 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18553
18554 /**
18555  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18556  * forwarding entries in data-plane accordingly.
18557  *
18558  * @param vam vpp API test context
18559  * @return return code
18560  */
18561 static int
18562 api_one_add_del_adjacency (vat_main_t * vam)
18563 {
18564   unformat_input_t *input = vam->input;
18565   vl_api_one_add_del_adjacency_t *mp;
18566   u32 vni = 0;
18567   ip4_address_t leid4, reid4;
18568   ip6_address_t leid6, reid6;
18569   u8 reid_mac[6] = { 0 };
18570   u8 leid_mac[6] = { 0 };
18571   u8 reid_type, leid_type;
18572   u32 leid_len = 0, reid_len = 0, len;
18573   u8 is_add = 1;
18574   int ret;
18575
18576   leid_type = reid_type = (u8) ~ 0;
18577
18578   /* Parse args required to build the message */
18579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18580     {
18581       if (unformat (input, "del"))
18582         {
18583           is_add = 0;
18584         }
18585       else if (unformat (input, "add"))
18586         {
18587           is_add = 1;
18588         }
18589       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18590                          &reid4, &len))
18591         {
18592           reid_type = 0;        /* ipv4 */
18593           reid_len = len;
18594         }
18595       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18596                          &reid6, &len))
18597         {
18598           reid_type = 1;        /* ipv6 */
18599           reid_len = len;
18600         }
18601       else if (unformat (input, "reid %U", unformat_ethernet_address,
18602                          reid_mac))
18603         {
18604           reid_type = 2;        /* mac */
18605         }
18606       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18607                          &leid4, &len))
18608         {
18609           leid_type = 0;        /* ipv4 */
18610           leid_len = len;
18611         }
18612       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18613                          &leid6, &len))
18614         {
18615           leid_type = 1;        /* ipv6 */
18616           leid_len = len;
18617         }
18618       else if (unformat (input, "leid %U", unformat_ethernet_address,
18619                          leid_mac))
18620         {
18621           leid_type = 2;        /* mac */
18622         }
18623       else if (unformat (input, "vni %d", &vni))
18624         {
18625           ;
18626         }
18627       else
18628         {
18629           errmsg ("parse error '%U'", format_unformat_error, input);
18630           return -99;
18631         }
18632     }
18633
18634   if ((u8) ~ 0 == reid_type)
18635     {
18636       errmsg ("missing params!");
18637       return -99;
18638     }
18639
18640   if (leid_type != reid_type)
18641     {
18642       errmsg ("remote and local EIDs are of different types!");
18643       return -99;
18644     }
18645
18646   M (ONE_ADD_DEL_ADJACENCY, mp);
18647   mp->is_add = is_add;
18648   mp->vni = htonl (vni);
18649   mp->leid_len = leid_len;
18650   mp->reid_len = reid_len;
18651   mp->eid_type = reid_type;
18652
18653   switch (mp->eid_type)
18654     {
18655     case 0:
18656       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18657       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18658       break;
18659     case 1:
18660       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18661       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18662       break;
18663     case 2:
18664       clib_memcpy (mp->leid, leid_mac, 6);
18665       clib_memcpy (mp->reid, reid_mac, 6);
18666       break;
18667     default:
18668       errmsg ("unknown EID type %d!", mp->eid_type);
18669       return 0;
18670     }
18671
18672   /* send it... */
18673   S (mp);
18674
18675   /* Wait for a reply... */
18676   W (ret);
18677   return ret;
18678 }
18679
18680 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18681
18682 uword
18683 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18684 {
18685   u32 *mode = va_arg (*args, u32 *);
18686
18687   if (unformat (input, "lisp"))
18688     *mode = 0;
18689   else if (unformat (input, "vxlan"))
18690     *mode = 1;
18691   else
18692     return 0;
18693
18694   return 1;
18695 }
18696
18697 static int
18698 api_gpe_get_encap_mode (vat_main_t * vam)
18699 {
18700   vl_api_gpe_get_encap_mode_t *mp;
18701   int ret;
18702
18703   /* Construct the API message */
18704   M (GPE_GET_ENCAP_MODE, mp);
18705
18706   /* send it... */
18707   S (mp);
18708
18709   /* Wait for a reply... */
18710   W (ret);
18711   return ret;
18712 }
18713
18714 static int
18715 api_gpe_set_encap_mode (vat_main_t * vam)
18716 {
18717   unformat_input_t *input = vam->input;
18718   vl_api_gpe_set_encap_mode_t *mp;
18719   int ret;
18720   u32 mode = 0;
18721
18722   /* Parse args required to build the message */
18723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18724     {
18725       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18726         ;
18727       else
18728         break;
18729     }
18730
18731   /* Construct the API message */
18732   M (GPE_SET_ENCAP_MODE, mp);
18733
18734   mp->mode = mode;
18735
18736   /* send it... */
18737   S (mp);
18738
18739   /* Wait for a reply... */
18740   W (ret);
18741   return ret;
18742 }
18743
18744 static int
18745 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18746 {
18747   unformat_input_t *input = vam->input;
18748   vl_api_gpe_add_del_iface_t *mp;
18749   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18750   u32 dp_table = 0, vni = 0;
18751   int ret;
18752
18753   /* Parse args required to build the message */
18754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18755     {
18756       if (unformat (input, "up"))
18757         {
18758           action_set = 1;
18759           is_add = 1;
18760         }
18761       else if (unformat (input, "down"))
18762         {
18763           action_set = 1;
18764           is_add = 0;
18765         }
18766       else if (unformat (input, "table_id %d", &dp_table))
18767         {
18768           dp_table_set = 1;
18769         }
18770       else if (unformat (input, "bd_id %d", &dp_table))
18771         {
18772           dp_table_set = 1;
18773           is_l2 = 1;
18774         }
18775       else if (unformat (input, "vni %d", &vni))
18776         {
18777           vni_set = 1;
18778         }
18779       else
18780         break;
18781     }
18782
18783   if (action_set == 0)
18784     {
18785       errmsg ("Action not set");
18786       return -99;
18787     }
18788   if (dp_table_set == 0 || vni_set == 0)
18789     {
18790       errmsg ("vni and dp_table must be set");
18791       return -99;
18792     }
18793
18794   /* Construct the API message */
18795   M (GPE_ADD_DEL_IFACE, mp);
18796
18797   mp->is_add = is_add;
18798   mp->dp_table = clib_host_to_net_u32 (dp_table);
18799   mp->is_l2 = is_l2;
18800   mp->vni = clib_host_to_net_u32 (vni);
18801
18802   /* send it... */
18803   S (mp);
18804
18805   /* Wait for a reply... */
18806   W (ret);
18807   return ret;
18808 }
18809
18810 static int
18811 api_one_map_register_fallback_threshold (vat_main_t * vam)
18812 {
18813   unformat_input_t *input = vam->input;
18814   vl_api_one_map_register_fallback_threshold_t *mp;
18815   u32 value = 0;
18816   u8 is_set = 0;
18817   int ret;
18818
18819   /* Parse args required to build the message */
18820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18821     {
18822       if (unformat (input, "%u", &value))
18823         is_set = 1;
18824       else
18825         {
18826           clib_warning ("parse error '%U'", format_unformat_error, input);
18827           return -99;
18828         }
18829     }
18830
18831   if (!is_set)
18832     {
18833       errmsg ("fallback threshold value is missing!");
18834       return -99;
18835     }
18836
18837   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18838   mp->value = clib_host_to_net_u32 (value);
18839
18840   /* send it... */
18841   S (mp);
18842
18843   /* Wait for a reply... */
18844   W (ret);
18845   return ret;
18846 }
18847
18848 static int
18849 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
18850 {
18851   vl_api_show_one_map_register_fallback_threshold_t *mp;
18852   int ret;
18853
18854   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18855
18856   /* send it... */
18857   S (mp);
18858
18859   /* Wait for a reply... */
18860   W (ret);
18861   return ret;
18862 }
18863
18864 uword
18865 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
18866 {
18867   u32 *proto = va_arg (*args, u32 *);
18868
18869   if (unformat (input, "udp"))
18870     *proto = 1;
18871   else if (unformat (input, "api"))
18872     *proto = 2;
18873   else
18874     return 0;
18875
18876   return 1;
18877 }
18878
18879 static int
18880 api_one_set_transport_protocol (vat_main_t * vam)
18881 {
18882   unformat_input_t *input = vam->input;
18883   vl_api_one_set_transport_protocol_t *mp;
18884   u8 is_set = 0;
18885   u32 protocol = 0;
18886   int ret;
18887
18888   /* Parse args required to build the message */
18889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18890     {
18891       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
18892         is_set = 1;
18893       else
18894         {
18895           clib_warning ("parse error '%U'", format_unformat_error, input);
18896           return -99;
18897         }
18898     }
18899
18900   if (!is_set)
18901     {
18902       errmsg ("Transport protocol missing!");
18903       return -99;
18904     }
18905
18906   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18907   mp->protocol = (u8) protocol;
18908
18909   /* send it... */
18910   S (mp);
18911
18912   /* Wait for a reply... */
18913   W (ret);
18914   return ret;
18915 }
18916
18917 static int
18918 api_one_get_transport_protocol (vat_main_t * vam)
18919 {
18920   vl_api_one_get_transport_protocol_t *mp;
18921   int ret;
18922
18923   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18924
18925   /* send it... */
18926   S (mp);
18927
18928   /* Wait for a reply... */
18929   W (ret);
18930   return ret;
18931 }
18932
18933 static int
18934 api_one_map_register_set_ttl (vat_main_t * vam)
18935 {
18936   unformat_input_t *input = vam->input;
18937   vl_api_one_map_register_set_ttl_t *mp;
18938   u32 ttl = 0;
18939   u8 is_set = 0;
18940   int ret;
18941
18942   /* Parse args required to build the message */
18943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18944     {
18945       if (unformat (input, "%u", &ttl))
18946         is_set = 1;
18947       else
18948         {
18949           clib_warning ("parse error '%U'", format_unformat_error, input);
18950           return -99;
18951         }
18952     }
18953
18954   if (!is_set)
18955     {
18956       errmsg ("TTL value missing!");
18957       return -99;
18958     }
18959
18960   M (ONE_MAP_REGISTER_SET_TTL, mp);
18961   mp->ttl = clib_host_to_net_u32 (ttl);
18962
18963   /* send it... */
18964   S (mp);
18965
18966   /* Wait for a reply... */
18967   W (ret);
18968   return ret;
18969 }
18970
18971 static int
18972 api_show_one_map_register_ttl (vat_main_t * vam)
18973 {
18974   vl_api_show_one_map_register_ttl_t *mp;
18975   int ret;
18976
18977   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18978
18979   /* send it... */
18980   S (mp);
18981
18982   /* Wait for a reply... */
18983   W (ret);
18984   return ret;
18985 }
18986
18987 /**
18988  * Add/del map request itr rlocs from ONE control plane and updates
18989  *
18990  * @param vam vpp API test context
18991  * @return return code
18992  */
18993 static int
18994 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18995 {
18996   unformat_input_t *input = vam->input;
18997   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18998   u8 *locator_set_name = 0;
18999   u8 locator_set_name_set = 0;
19000   u8 is_add = 1;
19001   int ret;
19002
19003   /* Parse args required to build the message */
19004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19005     {
19006       if (unformat (input, "del"))
19007         {
19008           is_add = 0;
19009         }
19010       else if (unformat (input, "%_%v%_", &locator_set_name))
19011         {
19012           locator_set_name_set = 1;
19013         }
19014       else
19015         {
19016           clib_warning ("parse error '%U'", format_unformat_error, input);
19017           return -99;
19018         }
19019     }
19020
19021   if (is_add && !locator_set_name_set)
19022     {
19023       errmsg ("itr-rloc is not set!");
19024       return -99;
19025     }
19026
19027   if (is_add && vec_len (locator_set_name) > 64)
19028     {
19029       errmsg ("itr-rloc locator-set name too long");
19030       vec_free (locator_set_name);
19031       return -99;
19032     }
19033
19034   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19035   mp->is_add = is_add;
19036   if (is_add)
19037     {
19038       clib_memcpy (mp->locator_set_name, locator_set_name,
19039                    vec_len (locator_set_name));
19040     }
19041   else
19042     {
19043       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19044     }
19045   vec_free (locator_set_name);
19046
19047   /* send it... */
19048   S (mp);
19049
19050   /* Wait for a reply... */
19051   W (ret);
19052   return ret;
19053 }
19054
19055 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19056
19057 static int
19058 api_one_locator_dump (vat_main_t * vam)
19059 {
19060   unformat_input_t *input = vam->input;
19061   vl_api_one_locator_dump_t *mp;
19062   vl_api_control_ping_t *mp_ping;
19063   u8 is_index_set = 0, is_name_set = 0;
19064   u8 *ls_name = 0;
19065   u32 ls_index = ~0;
19066   int ret;
19067
19068   /* Parse args required to build the message */
19069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19070     {
19071       if (unformat (input, "ls_name %_%v%_", &ls_name))
19072         {
19073           is_name_set = 1;
19074         }
19075       else if (unformat (input, "ls_index %d", &ls_index))
19076         {
19077           is_index_set = 1;
19078         }
19079       else
19080         {
19081           errmsg ("parse error '%U'", format_unformat_error, input);
19082           return -99;
19083         }
19084     }
19085
19086   if (!is_index_set && !is_name_set)
19087     {
19088       errmsg ("error: expected one of index or name!");
19089       return -99;
19090     }
19091
19092   if (is_index_set && is_name_set)
19093     {
19094       errmsg ("error: only one param expected!");
19095       return -99;
19096     }
19097
19098   if (vec_len (ls_name) > 62)
19099     {
19100       errmsg ("error: locator set name too long!");
19101       return -99;
19102     }
19103
19104   if (!vam->json_output)
19105     {
19106       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19107     }
19108
19109   M (ONE_LOCATOR_DUMP, mp);
19110   mp->is_index_set = is_index_set;
19111
19112   if (is_index_set)
19113     mp->ls_index = clib_host_to_net_u32 (ls_index);
19114   else
19115     {
19116       vec_add1 (ls_name, 0);
19117       strncpy ((char *) mp->ls_name, (char *) ls_name,
19118                sizeof (mp->ls_name) - 1);
19119     }
19120
19121   /* send it... */
19122   S (mp);
19123
19124   /* Use a control ping for synchronization */
19125   MPING (CONTROL_PING, mp_ping);
19126   S (mp_ping);
19127
19128   /* Wait for a reply... */
19129   W (ret);
19130   return ret;
19131 }
19132
19133 #define api_lisp_locator_dump api_one_locator_dump
19134
19135 static int
19136 api_one_locator_set_dump (vat_main_t * vam)
19137 {
19138   vl_api_one_locator_set_dump_t *mp;
19139   vl_api_control_ping_t *mp_ping;
19140   unformat_input_t *input = vam->input;
19141   u8 filter = 0;
19142   int ret;
19143
19144   /* Parse args required to build the message */
19145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19146     {
19147       if (unformat (input, "local"))
19148         {
19149           filter = 1;
19150         }
19151       else if (unformat (input, "remote"))
19152         {
19153           filter = 2;
19154         }
19155       else
19156         {
19157           errmsg ("parse error '%U'", format_unformat_error, input);
19158           return -99;
19159         }
19160     }
19161
19162   if (!vam->json_output)
19163     {
19164       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19165     }
19166
19167   M (ONE_LOCATOR_SET_DUMP, mp);
19168
19169   mp->filter = filter;
19170
19171   /* send it... */
19172   S (mp);
19173
19174   /* Use a control ping for synchronization */
19175   MPING (CONTROL_PING, mp_ping);
19176   S (mp_ping);
19177
19178   /* Wait for a reply... */
19179   W (ret);
19180   return ret;
19181 }
19182
19183 #define api_lisp_locator_set_dump api_one_locator_set_dump
19184
19185 static int
19186 api_one_eid_table_map_dump (vat_main_t * vam)
19187 {
19188   u8 is_l2 = 0;
19189   u8 mode_set = 0;
19190   unformat_input_t *input = vam->input;
19191   vl_api_one_eid_table_map_dump_t *mp;
19192   vl_api_control_ping_t *mp_ping;
19193   int ret;
19194
19195   /* Parse args required to build the message */
19196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19197     {
19198       if (unformat (input, "l2"))
19199         {
19200           is_l2 = 1;
19201           mode_set = 1;
19202         }
19203       else if (unformat (input, "l3"))
19204         {
19205           is_l2 = 0;
19206           mode_set = 1;
19207         }
19208       else
19209         {
19210           errmsg ("parse error '%U'", format_unformat_error, input);
19211           return -99;
19212         }
19213     }
19214
19215   if (!mode_set)
19216     {
19217       errmsg ("expected one of 'l2' or 'l3' parameter!");
19218       return -99;
19219     }
19220
19221   if (!vam->json_output)
19222     {
19223       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19224     }
19225
19226   M (ONE_EID_TABLE_MAP_DUMP, mp);
19227   mp->is_l2 = is_l2;
19228
19229   /* send it... */
19230   S (mp);
19231
19232   /* Use a control ping for synchronization */
19233   MPING (CONTROL_PING, mp_ping);
19234   S (mp_ping);
19235
19236   /* Wait for a reply... */
19237   W (ret);
19238   return ret;
19239 }
19240
19241 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19242
19243 static int
19244 api_one_eid_table_vni_dump (vat_main_t * vam)
19245 {
19246   vl_api_one_eid_table_vni_dump_t *mp;
19247   vl_api_control_ping_t *mp_ping;
19248   int ret;
19249
19250   if (!vam->json_output)
19251     {
19252       print (vam->ofp, "VNI");
19253     }
19254
19255   M (ONE_EID_TABLE_VNI_DUMP, mp);
19256
19257   /* send it... */
19258   S (mp);
19259
19260   /* Use a control ping for synchronization */
19261   MPING (CONTROL_PING, mp_ping);
19262   S (mp_ping);
19263
19264   /* Wait for a reply... */
19265   W (ret);
19266   return ret;
19267 }
19268
19269 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19270
19271 static int
19272 api_one_eid_table_dump (vat_main_t * vam)
19273 {
19274   unformat_input_t *i = vam->input;
19275   vl_api_one_eid_table_dump_t *mp;
19276   vl_api_control_ping_t *mp_ping;
19277   struct in_addr ip4;
19278   struct in6_addr ip6;
19279   u8 mac[6];
19280   u8 eid_type = ~0, eid_set = 0;
19281   u32 prefix_length = ~0, t, vni = 0;
19282   u8 filter = 0;
19283   int ret;
19284   lisp_nsh_api_t nsh;
19285
19286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19287     {
19288       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19289         {
19290           eid_set = 1;
19291           eid_type = 0;
19292           prefix_length = t;
19293         }
19294       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19295         {
19296           eid_set = 1;
19297           eid_type = 1;
19298           prefix_length = t;
19299         }
19300       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19301         {
19302           eid_set = 1;
19303           eid_type = 2;
19304         }
19305       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19306         {
19307           eid_set = 1;
19308           eid_type = 3;
19309         }
19310       else if (unformat (i, "vni %d", &t))
19311         {
19312           vni = t;
19313         }
19314       else if (unformat (i, "local"))
19315         {
19316           filter = 1;
19317         }
19318       else if (unformat (i, "remote"))
19319         {
19320           filter = 2;
19321         }
19322       else
19323         {
19324           errmsg ("parse error '%U'", format_unformat_error, i);
19325           return -99;
19326         }
19327     }
19328
19329   if (!vam->json_output)
19330     {
19331       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19332              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19333     }
19334
19335   M (ONE_EID_TABLE_DUMP, mp);
19336
19337   mp->filter = filter;
19338   if (eid_set)
19339     {
19340       mp->eid_set = 1;
19341       mp->vni = htonl (vni);
19342       mp->eid_type = eid_type;
19343       switch (eid_type)
19344         {
19345         case 0:
19346           mp->prefix_length = prefix_length;
19347           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19348           break;
19349         case 1:
19350           mp->prefix_length = prefix_length;
19351           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19352           break;
19353         case 2:
19354           clib_memcpy (mp->eid, mac, sizeof (mac));
19355           break;
19356         case 3:
19357           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19358           break;
19359         default:
19360           errmsg ("unknown EID type %d!", eid_type);
19361           return -99;
19362         }
19363     }
19364
19365   /* send it... */
19366   S (mp);
19367
19368   /* Use a control ping for synchronization */
19369   MPING (CONTROL_PING, mp_ping);
19370   S (mp_ping);
19371
19372   /* Wait for a reply... */
19373   W (ret);
19374   return ret;
19375 }
19376
19377 #define api_lisp_eid_table_dump api_one_eid_table_dump
19378
19379 static int
19380 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19381 {
19382   unformat_input_t *i = vam->input;
19383   vl_api_gpe_fwd_entries_get_t *mp;
19384   u8 vni_set = 0;
19385   u32 vni = ~0;
19386   int ret;
19387
19388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19389     {
19390       if (unformat (i, "vni %d", &vni))
19391         {
19392           vni_set = 1;
19393         }
19394       else
19395         {
19396           errmsg ("parse error '%U'", format_unformat_error, i);
19397           return -99;
19398         }
19399     }
19400
19401   if (!vni_set)
19402     {
19403       errmsg ("vni not set!");
19404       return -99;
19405     }
19406
19407   if (!vam->json_output)
19408     {
19409       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19410              "leid", "reid");
19411     }
19412
19413   M (GPE_FWD_ENTRIES_GET, mp);
19414   mp->vni = clib_host_to_net_u32 (vni);
19415
19416   /* send it... */
19417   S (mp);
19418
19419   /* Wait for a reply... */
19420   W (ret);
19421   return ret;
19422 }
19423
19424 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19425 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19426 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19427 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19428 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19429 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19430 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19431 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19432
19433 static int
19434 api_one_adjacencies_get (vat_main_t * vam)
19435 {
19436   unformat_input_t *i = vam->input;
19437   vl_api_one_adjacencies_get_t *mp;
19438   u8 vni_set = 0;
19439   u32 vni = ~0;
19440   int ret;
19441
19442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19443     {
19444       if (unformat (i, "vni %d", &vni))
19445         {
19446           vni_set = 1;
19447         }
19448       else
19449         {
19450           errmsg ("parse error '%U'", format_unformat_error, i);
19451           return -99;
19452         }
19453     }
19454
19455   if (!vni_set)
19456     {
19457       errmsg ("vni not set!");
19458       return -99;
19459     }
19460
19461   if (!vam->json_output)
19462     {
19463       print (vam->ofp, "%s %40s", "leid", "reid");
19464     }
19465
19466   M (ONE_ADJACENCIES_GET, mp);
19467   mp->vni = clib_host_to_net_u32 (vni);
19468
19469   /* send it... */
19470   S (mp);
19471
19472   /* Wait for a reply... */
19473   W (ret);
19474   return ret;
19475 }
19476
19477 #define api_lisp_adjacencies_get api_one_adjacencies_get
19478
19479 static int
19480 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19481 {
19482   unformat_input_t *i = vam->input;
19483   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19484   int ret;
19485   u8 ip_family_set = 0, is_ip4 = 1;
19486
19487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19488     {
19489       if (unformat (i, "ip4"))
19490         {
19491           ip_family_set = 1;
19492           is_ip4 = 1;
19493         }
19494       else if (unformat (i, "ip6"))
19495         {
19496           ip_family_set = 1;
19497           is_ip4 = 0;
19498         }
19499       else
19500         {
19501           errmsg ("parse error '%U'", format_unformat_error, i);
19502           return -99;
19503         }
19504     }
19505
19506   if (!ip_family_set)
19507     {
19508       errmsg ("ip family not set!");
19509       return -99;
19510     }
19511
19512   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19513   mp->is_ip4 = is_ip4;
19514
19515   /* send it... */
19516   S (mp);
19517
19518   /* Wait for a reply... */
19519   W (ret);
19520   return ret;
19521 }
19522
19523 static int
19524 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19525 {
19526   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19527   int ret;
19528
19529   if (!vam->json_output)
19530     {
19531       print (vam->ofp, "VNIs");
19532     }
19533
19534   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19535
19536   /* send it... */
19537   S (mp);
19538
19539   /* Wait for a reply... */
19540   W (ret);
19541   return ret;
19542 }
19543
19544 static int
19545 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19546 {
19547   unformat_input_t *i = vam->input;
19548   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19549   int ret = 0;
19550   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19551   struct in_addr ip4;
19552   struct in6_addr ip6;
19553   u32 table_id = 0, nh_sw_if_index = ~0;
19554
19555   memset (&ip4, 0, sizeof (ip4));
19556   memset (&ip6, 0, sizeof (ip6));
19557
19558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19559     {
19560       if (unformat (i, "del"))
19561         is_add = 0;
19562       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19563                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19564         {
19565           ip_set = 1;
19566           is_ip4 = 1;
19567         }
19568       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19569                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19570         {
19571           ip_set = 1;
19572           is_ip4 = 0;
19573         }
19574       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19575         {
19576           ip_set = 1;
19577           is_ip4 = 1;
19578           nh_sw_if_index = ~0;
19579         }
19580       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19581         {
19582           ip_set = 1;
19583           is_ip4 = 0;
19584           nh_sw_if_index = ~0;
19585         }
19586       else if (unformat (i, "table %d", &table_id))
19587         ;
19588       else
19589         {
19590           errmsg ("parse error '%U'", format_unformat_error, i);
19591           return -99;
19592         }
19593     }
19594
19595   if (!ip_set)
19596     {
19597       errmsg ("nh addr not set!");
19598       return -99;
19599     }
19600
19601   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19602   mp->is_add = is_add;
19603   mp->table_id = clib_host_to_net_u32 (table_id);
19604   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19605   mp->is_ip4 = is_ip4;
19606   if (is_ip4)
19607     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19608   else
19609     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19610
19611   /* send it... */
19612   S (mp);
19613
19614   /* Wait for a reply... */
19615   W (ret);
19616   return ret;
19617 }
19618
19619 static int
19620 api_one_map_server_dump (vat_main_t * vam)
19621 {
19622   vl_api_one_map_server_dump_t *mp;
19623   vl_api_control_ping_t *mp_ping;
19624   int ret;
19625
19626   if (!vam->json_output)
19627     {
19628       print (vam->ofp, "%=20s", "Map server");
19629     }
19630
19631   M (ONE_MAP_SERVER_DUMP, mp);
19632   /* send it... */
19633   S (mp);
19634
19635   /* Use a control ping for synchronization */
19636   MPING (CONTROL_PING, mp_ping);
19637   S (mp_ping);
19638
19639   /* Wait for a reply... */
19640   W (ret);
19641   return ret;
19642 }
19643
19644 #define api_lisp_map_server_dump api_one_map_server_dump
19645
19646 static int
19647 api_one_map_resolver_dump (vat_main_t * vam)
19648 {
19649   vl_api_one_map_resolver_dump_t *mp;
19650   vl_api_control_ping_t *mp_ping;
19651   int ret;
19652
19653   if (!vam->json_output)
19654     {
19655       print (vam->ofp, "%=20s", "Map resolver");
19656     }
19657
19658   M (ONE_MAP_RESOLVER_DUMP, mp);
19659   /* send it... */
19660   S (mp);
19661
19662   /* Use a control ping for synchronization */
19663   MPING (CONTROL_PING, mp_ping);
19664   S (mp_ping);
19665
19666   /* Wait for a reply... */
19667   W (ret);
19668   return ret;
19669 }
19670
19671 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19672
19673 static int
19674 api_one_stats_flush (vat_main_t * vam)
19675 {
19676   vl_api_one_stats_flush_t *mp;
19677   int ret = 0;
19678
19679   M (ONE_STATS_FLUSH, mp);
19680   S (mp);
19681   W (ret);
19682   return ret;
19683 }
19684
19685 static int
19686 api_one_stats_dump (vat_main_t * vam)
19687 {
19688   vl_api_one_stats_dump_t *mp;
19689   vl_api_control_ping_t *mp_ping;
19690   int ret;
19691
19692   M (ONE_STATS_DUMP, mp);
19693   /* send it... */
19694   S (mp);
19695
19696   /* Use a control ping for synchronization */
19697   MPING (CONTROL_PING, mp_ping);
19698   S (mp_ping);
19699
19700   /* Wait for a reply... */
19701   W (ret);
19702   return ret;
19703 }
19704
19705 static int
19706 api_show_one_status (vat_main_t * vam)
19707 {
19708   vl_api_show_one_status_t *mp;
19709   int ret;
19710
19711   if (!vam->json_output)
19712     {
19713       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19714     }
19715
19716   M (SHOW_ONE_STATUS, mp);
19717   /* send it... */
19718   S (mp);
19719   /* Wait for a reply... */
19720   W (ret);
19721   return ret;
19722 }
19723
19724 #define api_show_lisp_status api_show_one_status
19725
19726 static int
19727 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19728 {
19729   vl_api_gpe_fwd_entry_path_dump_t *mp;
19730   vl_api_control_ping_t *mp_ping;
19731   unformat_input_t *i = vam->input;
19732   u32 fwd_entry_index = ~0;
19733   int ret;
19734
19735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19736     {
19737       if (unformat (i, "index %d", &fwd_entry_index))
19738         ;
19739       else
19740         break;
19741     }
19742
19743   if (~0 == fwd_entry_index)
19744     {
19745       errmsg ("no index specified!");
19746       return -99;
19747     }
19748
19749   if (!vam->json_output)
19750     {
19751       print (vam->ofp, "first line");
19752     }
19753
19754   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19755
19756   /* send it... */
19757   S (mp);
19758   /* Use a control ping for synchronization */
19759   MPING (CONTROL_PING, mp_ping);
19760   S (mp_ping);
19761
19762   /* Wait for a reply... */
19763   W (ret);
19764   return ret;
19765 }
19766
19767 static int
19768 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19769 {
19770   vl_api_one_get_map_request_itr_rlocs_t *mp;
19771   int ret;
19772
19773   if (!vam->json_output)
19774     {
19775       print (vam->ofp, "%=20s", "itr-rlocs:");
19776     }
19777
19778   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19779   /* send it... */
19780   S (mp);
19781   /* Wait for a reply... */
19782   W (ret);
19783   return ret;
19784 }
19785
19786 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19787
19788 static int
19789 api_af_packet_create (vat_main_t * vam)
19790 {
19791   unformat_input_t *i = vam->input;
19792   vl_api_af_packet_create_t *mp;
19793   u8 *host_if_name = 0;
19794   u8 hw_addr[6];
19795   u8 random_hw_addr = 1;
19796   int ret;
19797
19798   memset (hw_addr, 0, sizeof (hw_addr));
19799
19800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19801     {
19802       if (unformat (i, "name %s", &host_if_name))
19803         vec_add1 (host_if_name, 0);
19804       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19805         random_hw_addr = 0;
19806       else
19807         break;
19808     }
19809
19810   if (!vec_len (host_if_name))
19811     {
19812       errmsg ("host-interface name must be specified");
19813       return -99;
19814     }
19815
19816   if (vec_len (host_if_name) > 64)
19817     {
19818       errmsg ("host-interface name too long");
19819       return -99;
19820     }
19821
19822   M (AF_PACKET_CREATE, mp);
19823
19824   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19825   clib_memcpy (mp->hw_addr, hw_addr, 6);
19826   mp->use_random_hw_addr = random_hw_addr;
19827   vec_free (host_if_name);
19828
19829   S (mp);
19830
19831   /* *INDENT-OFF* */
19832   W2 (ret,
19833       ({
19834         if (ret == 0)
19835           fprintf (vam->ofp ? vam->ofp : stderr,
19836                    " new sw_if_index = %d\n", vam->sw_if_index);
19837       }));
19838   /* *INDENT-ON* */
19839   return ret;
19840 }
19841
19842 static int
19843 api_af_packet_delete (vat_main_t * vam)
19844 {
19845   unformat_input_t *i = vam->input;
19846   vl_api_af_packet_delete_t *mp;
19847   u8 *host_if_name = 0;
19848   int ret;
19849
19850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19851     {
19852       if (unformat (i, "name %s", &host_if_name))
19853         vec_add1 (host_if_name, 0);
19854       else
19855         break;
19856     }
19857
19858   if (!vec_len (host_if_name))
19859     {
19860       errmsg ("host-interface name must be specified");
19861       return -99;
19862     }
19863
19864   if (vec_len (host_if_name) > 64)
19865     {
19866       errmsg ("host-interface name too long");
19867       return -99;
19868     }
19869
19870   M (AF_PACKET_DELETE, mp);
19871
19872   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19873   vec_free (host_if_name);
19874
19875   S (mp);
19876   W (ret);
19877   return ret;
19878 }
19879
19880 static void vl_api_af_packet_details_t_handler
19881   (vl_api_af_packet_details_t * mp)
19882 {
19883   vat_main_t *vam = &vat_main;
19884
19885   print (vam->ofp, "%-16s %d",
19886          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
19887 }
19888
19889 static void vl_api_af_packet_details_t_handler_json
19890   (vl_api_af_packet_details_t * mp)
19891 {
19892   vat_main_t *vam = &vat_main;
19893   vat_json_node_t *node = NULL;
19894
19895   if (VAT_JSON_ARRAY != vam->json_tree.type)
19896     {
19897       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19898       vat_json_init_array (&vam->json_tree);
19899     }
19900   node = vat_json_array_add (&vam->json_tree);
19901
19902   vat_json_init_object (node);
19903   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19904   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
19905 }
19906
19907 static int
19908 api_af_packet_dump (vat_main_t * vam)
19909 {
19910   vl_api_af_packet_dump_t *mp;
19911   vl_api_control_ping_t *mp_ping;
19912   int ret;
19913
19914   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
19915   /* Get list of tap interfaces */
19916   M (AF_PACKET_DUMP, mp);
19917   S (mp);
19918
19919   /* Use a control ping for synchronization */
19920   MPING (CONTROL_PING, mp_ping);
19921   S (mp_ping);
19922
19923   W (ret);
19924   return ret;
19925 }
19926
19927 static int
19928 api_policer_add_del (vat_main_t * vam)
19929 {
19930   unformat_input_t *i = vam->input;
19931   vl_api_policer_add_del_t *mp;
19932   u8 is_add = 1;
19933   u8 *name = 0;
19934   u32 cir = 0;
19935   u32 eir = 0;
19936   u64 cb = 0;
19937   u64 eb = 0;
19938   u8 rate_type = 0;
19939   u8 round_type = 0;
19940   u8 type = 0;
19941   u8 color_aware = 0;
19942   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19943   int ret;
19944
19945   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19946   conform_action.dscp = 0;
19947   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19948   exceed_action.dscp = 0;
19949   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19950   violate_action.dscp = 0;
19951
19952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19953     {
19954       if (unformat (i, "del"))
19955         is_add = 0;
19956       else if (unformat (i, "name %s", &name))
19957         vec_add1 (name, 0);
19958       else if (unformat (i, "cir %u", &cir))
19959         ;
19960       else if (unformat (i, "eir %u", &eir))
19961         ;
19962       else if (unformat (i, "cb %u", &cb))
19963         ;
19964       else if (unformat (i, "eb %u", &eb))
19965         ;
19966       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19967                          &rate_type))
19968         ;
19969       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19970                          &round_type))
19971         ;
19972       else if (unformat (i, "type %U", unformat_policer_type, &type))
19973         ;
19974       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19975                          &conform_action))
19976         ;
19977       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19978                          &exceed_action))
19979         ;
19980       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19981                          &violate_action))
19982         ;
19983       else if (unformat (i, "color-aware"))
19984         color_aware = 1;
19985       else
19986         break;
19987     }
19988
19989   if (!vec_len (name))
19990     {
19991       errmsg ("policer name must be specified");
19992       return -99;
19993     }
19994
19995   if (vec_len (name) > 64)
19996     {
19997       errmsg ("policer name too long");
19998       return -99;
19999     }
20000
20001   M (POLICER_ADD_DEL, mp);
20002
20003   clib_memcpy (mp->name, name, vec_len (name));
20004   vec_free (name);
20005   mp->is_add = is_add;
20006   mp->cir = ntohl (cir);
20007   mp->eir = ntohl (eir);
20008   mp->cb = clib_net_to_host_u64 (cb);
20009   mp->eb = clib_net_to_host_u64 (eb);
20010   mp->rate_type = rate_type;
20011   mp->round_type = round_type;
20012   mp->type = type;
20013   mp->conform_action_type = conform_action.action_type;
20014   mp->conform_dscp = conform_action.dscp;
20015   mp->exceed_action_type = exceed_action.action_type;
20016   mp->exceed_dscp = exceed_action.dscp;
20017   mp->violate_action_type = violate_action.action_type;
20018   mp->violate_dscp = violate_action.dscp;
20019   mp->color_aware = color_aware;
20020
20021   S (mp);
20022   W (ret);
20023   return ret;
20024 }
20025
20026 static int
20027 api_policer_dump (vat_main_t * vam)
20028 {
20029   unformat_input_t *i = vam->input;
20030   vl_api_policer_dump_t *mp;
20031   vl_api_control_ping_t *mp_ping;
20032   u8 *match_name = 0;
20033   u8 match_name_valid = 0;
20034   int ret;
20035
20036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20037     {
20038       if (unformat (i, "name %s", &match_name))
20039         {
20040           vec_add1 (match_name, 0);
20041           match_name_valid = 1;
20042         }
20043       else
20044         break;
20045     }
20046
20047   M (POLICER_DUMP, mp);
20048   mp->match_name_valid = match_name_valid;
20049   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20050   vec_free (match_name);
20051   /* send it... */
20052   S (mp);
20053
20054   /* Use a control ping for synchronization */
20055   MPING (CONTROL_PING, mp_ping);
20056   S (mp_ping);
20057
20058   /* Wait for a reply... */
20059   W (ret);
20060   return ret;
20061 }
20062
20063 static int
20064 api_policer_classify_set_interface (vat_main_t * vam)
20065 {
20066   unformat_input_t *i = vam->input;
20067   vl_api_policer_classify_set_interface_t *mp;
20068   u32 sw_if_index;
20069   int sw_if_index_set;
20070   u32 ip4_table_index = ~0;
20071   u32 ip6_table_index = ~0;
20072   u32 l2_table_index = ~0;
20073   u8 is_add = 1;
20074   int ret;
20075
20076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20077     {
20078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20079         sw_if_index_set = 1;
20080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20081         sw_if_index_set = 1;
20082       else if (unformat (i, "del"))
20083         is_add = 0;
20084       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20085         ;
20086       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20087         ;
20088       else if (unformat (i, "l2-table %d", &l2_table_index))
20089         ;
20090       else
20091         {
20092           clib_warning ("parse error '%U'", format_unformat_error, i);
20093           return -99;
20094         }
20095     }
20096
20097   if (sw_if_index_set == 0)
20098     {
20099       errmsg ("missing interface name or sw_if_index");
20100       return -99;
20101     }
20102
20103   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20104
20105   mp->sw_if_index = ntohl (sw_if_index);
20106   mp->ip4_table_index = ntohl (ip4_table_index);
20107   mp->ip6_table_index = ntohl (ip6_table_index);
20108   mp->l2_table_index = ntohl (l2_table_index);
20109   mp->is_add = is_add;
20110
20111   S (mp);
20112   W (ret);
20113   return ret;
20114 }
20115
20116 static int
20117 api_policer_classify_dump (vat_main_t * vam)
20118 {
20119   unformat_input_t *i = vam->input;
20120   vl_api_policer_classify_dump_t *mp;
20121   vl_api_control_ping_t *mp_ping;
20122   u8 type = POLICER_CLASSIFY_N_TABLES;
20123   int ret;
20124
20125   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20126     ;
20127   else
20128     {
20129       errmsg ("classify table type must be specified");
20130       return -99;
20131     }
20132
20133   if (!vam->json_output)
20134     {
20135       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20136     }
20137
20138   M (POLICER_CLASSIFY_DUMP, mp);
20139   mp->type = type;
20140   /* send it... */
20141   S (mp);
20142
20143   /* Use a control ping for synchronization */
20144   MPING (CONTROL_PING, mp_ping);
20145   S (mp_ping);
20146
20147   /* Wait for a reply... */
20148   W (ret);
20149   return ret;
20150 }
20151
20152 static int
20153 api_netmap_create (vat_main_t * vam)
20154 {
20155   unformat_input_t *i = vam->input;
20156   vl_api_netmap_create_t *mp;
20157   u8 *if_name = 0;
20158   u8 hw_addr[6];
20159   u8 random_hw_addr = 1;
20160   u8 is_pipe = 0;
20161   u8 is_master = 0;
20162   int ret;
20163
20164   memset (hw_addr, 0, sizeof (hw_addr));
20165
20166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20167     {
20168       if (unformat (i, "name %s", &if_name))
20169         vec_add1 (if_name, 0);
20170       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20171         random_hw_addr = 0;
20172       else if (unformat (i, "pipe"))
20173         is_pipe = 1;
20174       else if (unformat (i, "master"))
20175         is_master = 1;
20176       else if (unformat (i, "slave"))
20177         is_master = 0;
20178       else
20179         break;
20180     }
20181
20182   if (!vec_len (if_name))
20183     {
20184       errmsg ("interface name must be specified");
20185       return -99;
20186     }
20187
20188   if (vec_len (if_name) > 64)
20189     {
20190       errmsg ("interface name too long");
20191       return -99;
20192     }
20193
20194   M (NETMAP_CREATE, mp);
20195
20196   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20197   clib_memcpy (mp->hw_addr, hw_addr, 6);
20198   mp->use_random_hw_addr = random_hw_addr;
20199   mp->is_pipe = is_pipe;
20200   mp->is_master = is_master;
20201   vec_free (if_name);
20202
20203   S (mp);
20204   W (ret);
20205   return ret;
20206 }
20207
20208 static int
20209 api_netmap_delete (vat_main_t * vam)
20210 {
20211   unformat_input_t *i = vam->input;
20212   vl_api_netmap_delete_t *mp;
20213   u8 *if_name = 0;
20214   int ret;
20215
20216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20217     {
20218       if (unformat (i, "name %s", &if_name))
20219         vec_add1 (if_name, 0);
20220       else
20221         break;
20222     }
20223
20224   if (!vec_len (if_name))
20225     {
20226       errmsg ("interface name must be specified");
20227       return -99;
20228     }
20229
20230   if (vec_len (if_name) > 64)
20231     {
20232       errmsg ("interface name too long");
20233       return -99;
20234     }
20235
20236   M (NETMAP_DELETE, mp);
20237
20238   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20239   vec_free (if_name);
20240
20241   S (mp);
20242   W (ret);
20243   return ret;
20244 }
20245
20246 static void
20247 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20248 {
20249   if (fp->afi == IP46_TYPE_IP6)
20250     print (vam->ofp,
20251            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20252            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20253            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20254            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20255            format_ip6_address, fp->next_hop);
20256   else if (fp->afi == IP46_TYPE_IP4)
20257     print (vam->ofp,
20258            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20259            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20260            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20261            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20262            format_ip4_address, fp->next_hop);
20263 }
20264
20265 static void
20266 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20267                                  vl_api_fib_path_t * fp)
20268 {
20269   struct in_addr ip4;
20270   struct in6_addr ip6;
20271
20272   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20273   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20274   vat_json_object_add_uint (node, "is_local", fp->is_local);
20275   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20276   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20277   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20278   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20279   if (fp->afi == IP46_TYPE_IP4)
20280     {
20281       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20282       vat_json_object_add_ip4 (node, "next_hop", ip4);
20283     }
20284   else if (fp->afi == IP46_TYPE_IP6)
20285     {
20286       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20287       vat_json_object_add_ip6 (node, "next_hop", ip6);
20288     }
20289 }
20290
20291 static void
20292 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20293 {
20294   vat_main_t *vam = &vat_main;
20295   int count = ntohl (mp->mt_count);
20296   vl_api_fib_path_t *fp;
20297   i32 i;
20298
20299   print (vam->ofp, "[%d]: sw_if_index %d via:",
20300          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20301   fp = mp->mt_paths;
20302   for (i = 0; i < count; i++)
20303     {
20304       vl_api_mpls_fib_path_print (vam, fp);
20305       fp++;
20306     }
20307
20308   print (vam->ofp, "");
20309 }
20310
20311 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20312 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20313
20314 static void
20315 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20316 {
20317   vat_main_t *vam = &vat_main;
20318   vat_json_node_t *node = NULL;
20319   int count = ntohl (mp->mt_count);
20320   vl_api_fib_path_t *fp;
20321   i32 i;
20322
20323   if (VAT_JSON_ARRAY != vam->json_tree.type)
20324     {
20325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20326       vat_json_init_array (&vam->json_tree);
20327     }
20328   node = vat_json_array_add (&vam->json_tree);
20329
20330   vat_json_init_object (node);
20331   vat_json_object_add_uint (node, "tunnel_index",
20332                             ntohl (mp->mt_tunnel_index));
20333   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20334
20335   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20336
20337   fp = mp->mt_paths;
20338   for (i = 0; i < count; i++)
20339     {
20340       vl_api_mpls_fib_path_json_print (node, fp);
20341       fp++;
20342     }
20343 }
20344
20345 static int
20346 api_mpls_tunnel_dump (vat_main_t * vam)
20347 {
20348   vl_api_mpls_tunnel_dump_t *mp;
20349   vl_api_control_ping_t *mp_ping;
20350   i32 index = -1;
20351   int ret;
20352
20353   /* Parse args required to build the message */
20354   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20355     {
20356       if (!unformat (vam->input, "tunnel_index %d", &index))
20357         {
20358           index = -1;
20359           break;
20360         }
20361     }
20362
20363   print (vam->ofp, "  tunnel_index %d", index);
20364
20365   M (MPLS_TUNNEL_DUMP, mp);
20366   mp->tunnel_index = htonl (index);
20367   S (mp);
20368
20369   /* Use a control ping for synchronization */
20370   MPING (CONTROL_PING, mp_ping);
20371   S (mp_ping);
20372
20373   W (ret);
20374   return ret;
20375 }
20376
20377 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20378 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20379
20380
20381 static void
20382 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20383 {
20384   vat_main_t *vam = &vat_main;
20385   int count = ntohl (mp->count);
20386   vl_api_fib_path_t *fp;
20387   int i;
20388
20389   print (vam->ofp,
20390          "table-id %d, label %u, ess_bit %u",
20391          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20392   fp = mp->path;
20393   for (i = 0; i < count; i++)
20394     {
20395       vl_api_mpls_fib_path_print (vam, fp);
20396       fp++;
20397     }
20398 }
20399
20400 static void vl_api_mpls_fib_details_t_handler_json
20401   (vl_api_mpls_fib_details_t * mp)
20402 {
20403   vat_main_t *vam = &vat_main;
20404   int count = ntohl (mp->count);
20405   vat_json_node_t *node = NULL;
20406   vl_api_fib_path_t *fp;
20407   int i;
20408
20409   if (VAT_JSON_ARRAY != vam->json_tree.type)
20410     {
20411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20412       vat_json_init_array (&vam->json_tree);
20413     }
20414   node = vat_json_array_add (&vam->json_tree);
20415
20416   vat_json_init_object (node);
20417   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20418   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20419   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20420   vat_json_object_add_uint (node, "path_count", count);
20421   fp = mp->path;
20422   for (i = 0; i < count; i++)
20423     {
20424       vl_api_mpls_fib_path_json_print (node, fp);
20425       fp++;
20426     }
20427 }
20428
20429 static int
20430 api_mpls_fib_dump (vat_main_t * vam)
20431 {
20432   vl_api_mpls_fib_dump_t *mp;
20433   vl_api_control_ping_t *mp_ping;
20434   int ret;
20435
20436   M (MPLS_FIB_DUMP, mp);
20437   S (mp);
20438
20439   /* Use a control ping for synchronization */
20440   MPING (CONTROL_PING, mp_ping);
20441   S (mp_ping);
20442
20443   W (ret);
20444   return ret;
20445 }
20446
20447 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20448 #define vl_api_ip_fib_details_t_print vl_noop_handler
20449
20450 static void
20451 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20452 {
20453   vat_main_t *vam = &vat_main;
20454   int count = ntohl (mp->count);
20455   vl_api_fib_path_t *fp;
20456   int i;
20457
20458   print (vam->ofp,
20459          "table-id %d, prefix %U/%d stats-index %d",
20460          ntohl (mp->table_id), format_ip4_address, mp->address,
20461          mp->address_length, ntohl (mp->stats_index));
20462   fp = mp->path;
20463   for (i = 0; i < count; i++)
20464     {
20465       if (fp->afi == IP46_TYPE_IP6)
20466         print (vam->ofp,
20467                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20468                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20469                "next_hop_table %d",
20470                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20471                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20472                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20473       else if (fp->afi == IP46_TYPE_IP4)
20474         print (vam->ofp,
20475                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20476                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20477                "next_hop_table %d",
20478                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20479                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20480                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20481       fp++;
20482     }
20483 }
20484
20485 static void vl_api_ip_fib_details_t_handler_json
20486   (vl_api_ip_fib_details_t * mp)
20487 {
20488   vat_main_t *vam = &vat_main;
20489   int count = ntohl (mp->count);
20490   vat_json_node_t *node = NULL;
20491   struct in_addr ip4;
20492   struct in6_addr ip6;
20493   vl_api_fib_path_t *fp;
20494   int i;
20495
20496   if (VAT_JSON_ARRAY != vam->json_tree.type)
20497     {
20498       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20499       vat_json_init_array (&vam->json_tree);
20500     }
20501   node = vat_json_array_add (&vam->json_tree);
20502
20503   vat_json_init_object (node);
20504   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20505   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20506   vat_json_object_add_ip4 (node, "prefix", ip4);
20507   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20508   vat_json_object_add_uint (node, "path_count", count);
20509   fp = mp->path;
20510   for (i = 0; i < count; i++)
20511     {
20512       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20513       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20514       vat_json_object_add_uint (node, "is_local", fp->is_local);
20515       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20516       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20517       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20518       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20519       if (fp->afi == IP46_TYPE_IP4)
20520         {
20521           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20522           vat_json_object_add_ip4 (node, "next_hop", ip4);
20523         }
20524       else if (fp->afi == IP46_TYPE_IP6)
20525         {
20526           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20527           vat_json_object_add_ip6 (node, "next_hop", ip6);
20528         }
20529     }
20530 }
20531
20532 static int
20533 api_ip_fib_dump (vat_main_t * vam)
20534 {
20535   vl_api_ip_fib_dump_t *mp;
20536   vl_api_control_ping_t *mp_ping;
20537   int ret;
20538
20539   M (IP_FIB_DUMP, mp);
20540   S (mp);
20541
20542   /* Use a control ping for synchronization */
20543   MPING (CONTROL_PING, mp_ping);
20544   S (mp_ping);
20545
20546   W (ret);
20547   return ret;
20548 }
20549
20550 static int
20551 api_ip_mfib_dump (vat_main_t * vam)
20552 {
20553   vl_api_ip_mfib_dump_t *mp;
20554   vl_api_control_ping_t *mp_ping;
20555   int ret;
20556
20557   M (IP_MFIB_DUMP, mp);
20558   S (mp);
20559
20560   /* Use a control ping for synchronization */
20561   MPING (CONTROL_PING, mp_ping);
20562   S (mp_ping);
20563
20564   W (ret);
20565   return ret;
20566 }
20567
20568 static void vl_api_ip_neighbor_details_t_handler
20569   (vl_api_ip_neighbor_details_t * mp)
20570 {
20571   vat_main_t *vam = &vat_main;
20572
20573   print (vam->ofp, "%c %U %U",
20574          (mp->is_static) ? 'S' : 'D',
20575          format_ethernet_address, &mp->mac_address,
20576          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20577          &mp->ip_address);
20578 }
20579
20580 static void vl_api_ip_neighbor_details_t_handler_json
20581   (vl_api_ip_neighbor_details_t * mp)
20582 {
20583
20584   vat_main_t *vam = &vat_main;
20585   vat_json_node_t *node;
20586   struct in_addr ip4;
20587   struct in6_addr ip6;
20588
20589   if (VAT_JSON_ARRAY != vam->json_tree.type)
20590     {
20591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20592       vat_json_init_array (&vam->json_tree);
20593     }
20594   node = vat_json_array_add (&vam->json_tree);
20595
20596   vat_json_init_object (node);
20597   vat_json_object_add_string_copy (node, "flag",
20598                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20599                                    "dynamic");
20600
20601   vat_json_object_add_string_copy (node, "link_layer",
20602                                    format (0, "%U", format_ethernet_address,
20603                                            &mp->mac_address));
20604
20605   if (mp->is_ipv6)
20606     {
20607       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20608       vat_json_object_add_ip6 (node, "ip_address", ip6);
20609     }
20610   else
20611     {
20612       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20613       vat_json_object_add_ip4 (node, "ip_address", ip4);
20614     }
20615 }
20616
20617 static int
20618 api_ip_neighbor_dump (vat_main_t * vam)
20619 {
20620   unformat_input_t *i = vam->input;
20621   vl_api_ip_neighbor_dump_t *mp;
20622   vl_api_control_ping_t *mp_ping;
20623   u8 is_ipv6 = 0;
20624   u32 sw_if_index = ~0;
20625   int ret;
20626
20627   /* Parse args required to build the message */
20628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20629     {
20630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20631         ;
20632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20633         ;
20634       else if (unformat (i, "ip6"))
20635         is_ipv6 = 1;
20636       else
20637         break;
20638     }
20639
20640   if (sw_if_index == ~0)
20641     {
20642       errmsg ("missing interface name or sw_if_index");
20643       return -99;
20644     }
20645
20646   M (IP_NEIGHBOR_DUMP, mp);
20647   mp->is_ipv6 = (u8) is_ipv6;
20648   mp->sw_if_index = ntohl (sw_if_index);
20649   S (mp);
20650
20651   /* Use a control ping for synchronization */
20652   MPING (CONTROL_PING, mp_ping);
20653   S (mp_ping);
20654
20655   W (ret);
20656   return ret;
20657 }
20658
20659 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20660 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20661
20662 static void
20663 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20664 {
20665   vat_main_t *vam = &vat_main;
20666   int count = ntohl (mp->count);
20667   vl_api_fib_path_t *fp;
20668   int i;
20669
20670   print (vam->ofp,
20671          "table-id %d, prefix %U/%d stats-index %d",
20672          ntohl (mp->table_id), format_ip6_address, mp->address,
20673          mp->address_length, ntohl (mp->stats_index));
20674   fp = mp->path;
20675   for (i = 0; i < count; i++)
20676     {
20677       if (fp->afi == IP46_TYPE_IP6)
20678         print (vam->ofp,
20679                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20680                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20681                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20682                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20683                format_ip6_address, fp->next_hop);
20684       else if (fp->afi == IP46_TYPE_IP4)
20685         print (vam->ofp,
20686                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20687                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20688                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20689                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20690                format_ip4_address, fp->next_hop);
20691       fp++;
20692     }
20693 }
20694
20695 static void vl_api_ip6_fib_details_t_handler_json
20696   (vl_api_ip6_fib_details_t * mp)
20697 {
20698   vat_main_t *vam = &vat_main;
20699   int count = ntohl (mp->count);
20700   vat_json_node_t *node = NULL;
20701   struct in_addr ip4;
20702   struct in6_addr ip6;
20703   vl_api_fib_path_t *fp;
20704   int i;
20705
20706   if (VAT_JSON_ARRAY != vam->json_tree.type)
20707     {
20708       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20709       vat_json_init_array (&vam->json_tree);
20710     }
20711   node = vat_json_array_add (&vam->json_tree);
20712
20713   vat_json_init_object (node);
20714   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20715   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20716   vat_json_object_add_ip6 (node, "prefix", ip6);
20717   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20718   vat_json_object_add_uint (node, "path_count", count);
20719   fp = mp->path;
20720   for (i = 0; i < count; i++)
20721     {
20722       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20723       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20724       vat_json_object_add_uint (node, "is_local", fp->is_local);
20725       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20726       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20727       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20728       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20729       if (fp->afi == IP46_TYPE_IP4)
20730         {
20731           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20732           vat_json_object_add_ip4 (node, "next_hop", ip4);
20733         }
20734       else if (fp->afi == IP46_TYPE_IP6)
20735         {
20736           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20737           vat_json_object_add_ip6 (node, "next_hop", ip6);
20738         }
20739     }
20740 }
20741
20742 static int
20743 api_ip6_fib_dump (vat_main_t * vam)
20744 {
20745   vl_api_ip6_fib_dump_t *mp;
20746   vl_api_control_ping_t *mp_ping;
20747   int ret;
20748
20749   M (IP6_FIB_DUMP, mp);
20750   S (mp);
20751
20752   /* Use a control ping for synchronization */
20753   MPING (CONTROL_PING, mp_ping);
20754   S (mp_ping);
20755
20756   W (ret);
20757   return ret;
20758 }
20759
20760 static int
20761 api_ip6_mfib_dump (vat_main_t * vam)
20762 {
20763   vl_api_ip6_mfib_dump_t *mp;
20764   vl_api_control_ping_t *mp_ping;
20765   int ret;
20766
20767   M (IP6_MFIB_DUMP, mp);
20768   S (mp);
20769
20770   /* Use a control ping for synchronization */
20771   MPING (CONTROL_PING, mp_ping);
20772   S (mp_ping);
20773
20774   W (ret);
20775   return ret;
20776 }
20777
20778 int
20779 api_classify_table_ids (vat_main_t * vam)
20780 {
20781   vl_api_classify_table_ids_t *mp;
20782   int ret;
20783
20784   /* Construct the API message */
20785   M (CLASSIFY_TABLE_IDS, mp);
20786   mp->context = 0;
20787
20788   S (mp);
20789   W (ret);
20790   return ret;
20791 }
20792
20793 int
20794 api_classify_table_by_interface (vat_main_t * vam)
20795 {
20796   unformat_input_t *input = vam->input;
20797   vl_api_classify_table_by_interface_t *mp;
20798
20799   u32 sw_if_index = ~0;
20800   int ret;
20801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20802     {
20803       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20804         ;
20805       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20806         ;
20807       else
20808         break;
20809     }
20810   if (sw_if_index == ~0)
20811     {
20812       errmsg ("missing interface name or sw_if_index");
20813       return -99;
20814     }
20815
20816   /* Construct the API message */
20817   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20818   mp->context = 0;
20819   mp->sw_if_index = ntohl (sw_if_index);
20820
20821   S (mp);
20822   W (ret);
20823   return ret;
20824 }
20825
20826 int
20827 api_classify_table_info (vat_main_t * vam)
20828 {
20829   unformat_input_t *input = vam->input;
20830   vl_api_classify_table_info_t *mp;
20831
20832   u32 table_id = ~0;
20833   int ret;
20834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20835     {
20836       if (unformat (input, "table_id %d", &table_id))
20837         ;
20838       else
20839         break;
20840     }
20841   if (table_id == ~0)
20842     {
20843       errmsg ("missing table id");
20844       return -99;
20845     }
20846
20847   /* Construct the API message */
20848   M (CLASSIFY_TABLE_INFO, mp);
20849   mp->context = 0;
20850   mp->table_id = ntohl (table_id);
20851
20852   S (mp);
20853   W (ret);
20854   return ret;
20855 }
20856
20857 int
20858 api_classify_session_dump (vat_main_t * vam)
20859 {
20860   unformat_input_t *input = vam->input;
20861   vl_api_classify_session_dump_t *mp;
20862   vl_api_control_ping_t *mp_ping;
20863
20864   u32 table_id = ~0;
20865   int ret;
20866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20867     {
20868       if (unformat (input, "table_id %d", &table_id))
20869         ;
20870       else
20871         break;
20872     }
20873   if (table_id == ~0)
20874     {
20875       errmsg ("missing table id");
20876       return -99;
20877     }
20878
20879   /* Construct the API message */
20880   M (CLASSIFY_SESSION_DUMP, mp);
20881   mp->context = 0;
20882   mp->table_id = ntohl (table_id);
20883   S (mp);
20884
20885   /* Use a control ping for synchronization */
20886   MPING (CONTROL_PING, mp_ping);
20887   S (mp_ping);
20888
20889   W (ret);
20890   return ret;
20891 }
20892
20893 static void
20894 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
20895 {
20896   vat_main_t *vam = &vat_main;
20897
20898   print (vam->ofp, "collector_address %U, collector_port %d, "
20899          "src_address %U, vrf_id %d, path_mtu %u, "
20900          "template_interval %u, udp_checksum %d",
20901          format_ip4_address, mp->collector_address,
20902          ntohs (mp->collector_port),
20903          format_ip4_address, mp->src_address,
20904          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
20905          ntohl (mp->template_interval), mp->udp_checksum);
20906
20907   vam->retval = 0;
20908   vam->result_ready = 1;
20909 }
20910
20911 static void
20912   vl_api_ipfix_exporter_details_t_handler_json
20913   (vl_api_ipfix_exporter_details_t * mp)
20914 {
20915   vat_main_t *vam = &vat_main;
20916   vat_json_node_t node;
20917   struct in_addr collector_address;
20918   struct in_addr src_address;
20919
20920   vat_json_init_object (&node);
20921   clib_memcpy (&collector_address, &mp->collector_address,
20922                sizeof (collector_address));
20923   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
20924   vat_json_object_add_uint (&node, "collector_port",
20925                             ntohs (mp->collector_port));
20926   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
20927   vat_json_object_add_ip4 (&node, "src_address", src_address);
20928   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
20929   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
20930   vat_json_object_add_uint (&node, "template_interval",
20931                             ntohl (mp->template_interval));
20932   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
20933
20934   vat_json_print (vam->ofp, &node);
20935   vat_json_free (&node);
20936   vam->retval = 0;
20937   vam->result_ready = 1;
20938 }
20939
20940 int
20941 api_ipfix_exporter_dump (vat_main_t * vam)
20942 {
20943   vl_api_ipfix_exporter_dump_t *mp;
20944   int ret;
20945
20946   /* Construct the API message */
20947   M (IPFIX_EXPORTER_DUMP, mp);
20948   mp->context = 0;
20949
20950   S (mp);
20951   W (ret);
20952   return ret;
20953 }
20954
20955 static int
20956 api_ipfix_classify_stream_dump (vat_main_t * vam)
20957 {
20958   vl_api_ipfix_classify_stream_dump_t *mp;
20959   int ret;
20960
20961   /* Construct the API message */
20962   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20963   mp->context = 0;
20964
20965   S (mp);
20966   W (ret);
20967   return ret;
20968   /* NOTREACHED */
20969   return 0;
20970 }
20971
20972 static void
20973   vl_api_ipfix_classify_stream_details_t_handler
20974   (vl_api_ipfix_classify_stream_details_t * mp)
20975 {
20976   vat_main_t *vam = &vat_main;
20977   print (vam->ofp, "domain_id %d, src_port %d",
20978          ntohl (mp->domain_id), ntohs (mp->src_port));
20979   vam->retval = 0;
20980   vam->result_ready = 1;
20981 }
20982
20983 static void
20984   vl_api_ipfix_classify_stream_details_t_handler_json
20985   (vl_api_ipfix_classify_stream_details_t * mp)
20986 {
20987   vat_main_t *vam = &vat_main;
20988   vat_json_node_t node;
20989
20990   vat_json_init_object (&node);
20991   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20992   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20993
20994   vat_json_print (vam->ofp, &node);
20995   vat_json_free (&node);
20996   vam->retval = 0;
20997   vam->result_ready = 1;
20998 }
20999
21000 static int
21001 api_ipfix_classify_table_dump (vat_main_t * vam)
21002 {
21003   vl_api_ipfix_classify_table_dump_t *mp;
21004   vl_api_control_ping_t *mp_ping;
21005   int ret;
21006
21007   if (!vam->json_output)
21008     {
21009       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21010              "transport_protocol");
21011     }
21012
21013   /* Construct the API message */
21014   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21015
21016   /* send it... */
21017   S (mp);
21018
21019   /* Use a control ping for synchronization */
21020   MPING (CONTROL_PING, mp_ping);
21021   S (mp_ping);
21022
21023   W (ret);
21024   return ret;
21025 }
21026
21027 static void
21028   vl_api_ipfix_classify_table_details_t_handler
21029   (vl_api_ipfix_classify_table_details_t * mp)
21030 {
21031   vat_main_t *vam = &vat_main;
21032   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21033          mp->transport_protocol);
21034 }
21035
21036 static void
21037   vl_api_ipfix_classify_table_details_t_handler_json
21038   (vl_api_ipfix_classify_table_details_t * mp)
21039 {
21040   vat_json_node_t *node = NULL;
21041   vat_main_t *vam = &vat_main;
21042
21043   if (VAT_JSON_ARRAY != vam->json_tree.type)
21044     {
21045       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21046       vat_json_init_array (&vam->json_tree);
21047     }
21048
21049   node = vat_json_array_add (&vam->json_tree);
21050   vat_json_init_object (node);
21051
21052   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21053   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21054   vat_json_object_add_uint (node, "transport_protocol",
21055                             mp->transport_protocol);
21056 }
21057
21058 static int
21059 api_sw_interface_span_enable_disable (vat_main_t * vam)
21060 {
21061   unformat_input_t *i = vam->input;
21062   vl_api_sw_interface_span_enable_disable_t *mp;
21063   u32 src_sw_if_index = ~0;
21064   u32 dst_sw_if_index = ~0;
21065   u8 state = 3;
21066   int ret;
21067   u8 is_l2 = 0;
21068
21069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21070     {
21071       if (unformat
21072           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21073         ;
21074       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21075         ;
21076       else
21077         if (unformat
21078             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21079         ;
21080       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21081         ;
21082       else if (unformat (i, "disable"))
21083         state = 0;
21084       else if (unformat (i, "rx"))
21085         state = 1;
21086       else if (unformat (i, "tx"))
21087         state = 2;
21088       else if (unformat (i, "both"))
21089         state = 3;
21090       else if (unformat (i, "l2"))
21091         is_l2 = 1;
21092       else
21093         break;
21094     }
21095
21096   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21097
21098   mp->sw_if_index_from = htonl (src_sw_if_index);
21099   mp->sw_if_index_to = htonl (dst_sw_if_index);
21100   mp->state = state;
21101   mp->is_l2 = is_l2;
21102
21103   S (mp);
21104   W (ret);
21105   return ret;
21106 }
21107
21108 static void
21109 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21110                                             * mp)
21111 {
21112   vat_main_t *vam = &vat_main;
21113   u8 *sw_if_from_name = 0;
21114   u8 *sw_if_to_name = 0;
21115   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21116   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21117   char *states[] = { "none", "rx", "tx", "both" };
21118   hash_pair_t *p;
21119
21120   /* *INDENT-OFF* */
21121   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21122   ({
21123     if ((u32) p->value[0] == sw_if_index_from)
21124       {
21125         sw_if_from_name = (u8 *)(p->key);
21126         if (sw_if_to_name)
21127           break;
21128       }
21129     if ((u32) p->value[0] == sw_if_index_to)
21130       {
21131         sw_if_to_name = (u8 *)(p->key);
21132         if (sw_if_from_name)
21133           break;
21134       }
21135   }));
21136   /* *INDENT-ON* */
21137   print (vam->ofp, "%20s => %20s (%s) %s",
21138          sw_if_from_name, sw_if_to_name, states[mp->state],
21139          mp->is_l2 ? "l2" : "device");
21140 }
21141
21142 static void
21143   vl_api_sw_interface_span_details_t_handler_json
21144   (vl_api_sw_interface_span_details_t * mp)
21145 {
21146   vat_main_t *vam = &vat_main;
21147   vat_json_node_t *node = NULL;
21148   u8 *sw_if_from_name = 0;
21149   u8 *sw_if_to_name = 0;
21150   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21151   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21152   hash_pair_t *p;
21153
21154   /* *INDENT-OFF* */
21155   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21156   ({
21157     if ((u32) p->value[0] == sw_if_index_from)
21158       {
21159         sw_if_from_name = (u8 *)(p->key);
21160         if (sw_if_to_name)
21161           break;
21162       }
21163     if ((u32) p->value[0] == sw_if_index_to)
21164       {
21165         sw_if_to_name = (u8 *)(p->key);
21166         if (sw_if_from_name)
21167           break;
21168       }
21169   }));
21170   /* *INDENT-ON* */
21171
21172   if (VAT_JSON_ARRAY != vam->json_tree.type)
21173     {
21174       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21175       vat_json_init_array (&vam->json_tree);
21176     }
21177   node = vat_json_array_add (&vam->json_tree);
21178
21179   vat_json_init_object (node);
21180   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21181   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21182   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21183   if (0 != sw_if_to_name)
21184     {
21185       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21186     }
21187   vat_json_object_add_uint (node, "state", mp->state);
21188   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21189 }
21190
21191 static int
21192 api_sw_interface_span_dump (vat_main_t * vam)
21193 {
21194   unformat_input_t *input = vam->input;
21195   vl_api_sw_interface_span_dump_t *mp;
21196   vl_api_control_ping_t *mp_ping;
21197   u8 is_l2 = 0;
21198   int ret;
21199
21200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21201     {
21202       if (unformat (input, "l2"))
21203         is_l2 = 1;
21204       else
21205         break;
21206     }
21207
21208   M (SW_INTERFACE_SPAN_DUMP, mp);
21209   mp->is_l2 = is_l2;
21210   S (mp);
21211
21212   /* Use a control ping for synchronization */
21213   MPING (CONTROL_PING, mp_ping);
21214   S (mp_ping);
21215
21216   W (ret);
21217   return ret;
21218 }
21219
21220 int
21221 api_pg_create_interface (vat_main_t * vam)
21222 {
21223   unformat_input_t *input = vam->input;
21224   vl_api_pg_create_interface_t *mp;
21225
21226   u32 if_id = ~0;
21227   int ret;
21228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21229     {
21230       if (unformat (input, "if_id %d", &if_id))
21231         ;
21232       else
21233         break;
21234     }
21235   if (if_id == ~0)
21236     {
21237       errmsg ("missing pg interface index");
21238       return -99;
21239     }
21240
21241   /* Construct the API message */
21242   M (PG_CREATE_INTERFACE, mp);
21243   mp->context = 0;
21244   mp->interface_id = ntohl (if_id);
21245
21246   S (mp);
21247   W (ret);
21248   return ret;
21249 }
21250
21251 int
21252 api_pg_capture (vat_main_t * vam)
21253 {
21254   unformat_input_t *input = vam->input;
21255   vl_api_pg_capture_t *mp;
21256
21257   u32 if_id = ~0;
21258   u8 enable = 1;
21259   u32 count = 1;
21260   u8 pcap_file_set = 0;
21261   u8 *pcap_file = 0;
21262   int ret;
21263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21264     {
21265       if (unformat (input, "if_id %d", &if_id))
21266         ;
21267       else if (unformat (input, "pcap %s", &pcap_file))
21268         pcap_file_set = 1;
21269       else if (unformat (input, "count %d", &count))
21270         ;
21271       else if (unformat (input, "disable"))
21272         enable = 0;
21273       else
21274         break;
21275     }
21276   if (if_id == ~0)
21277     {
21278       errmsg ("missing pg interface index");
21279       return -99;
21280     }
21281   if (pcap_file_set > 0)
21282     {
21283       if (vec_len (pcap_file) > 255)
21284         {
21285           errmsg ("pcap file name is too long");
21286           return -99;
21287         }
21288     }
21289
21290   u32 name_len = vec_len (pcap_file);
21291   /* Construct the API message */
21292   M (PG_CAPTURE, mp);
21293   mp->context = 0;
21294   mp->interface_id = ntohl (if_id);
21295   mp->is_enabled = enable;
21296   mp->count = ntohl (count);
21297   mp->pcap_name_length = ntohl (name_len);
21298   if (pcap_file_set != 0)
21299     {
21300       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21301     }
21302   vec_free (pcap_file);
21303
21304   S (mp);
21305   W (ret);
21306   return ret;
21307 }
21308
21309 int
21310 api_pg_enable_disable (vat_main_t * vam)
21311 {
21312   unformat_input_t *input = vam->input;
21313   vl_api_pg_enable_disable_t *mp;
21314
21315   u8 enable = 1;
21316   u8 stream_name_set = 0;
21317   u8 *stream_name = 0;
21318   int ret;
21319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21320     {
21321       if (unformat (input, "stream %s", &stream_name))
21322         stream_name_set = 1;
21323       else if (unformat (input, "disable"))
21324         enable = 0;
21325       else
21326         break;
21327     }
21328
21329   if (stream_name_set > 0)
21330     {
21331       if (vec_len (stream_name) > 255)
21332         {
21333           errmsg ("stream name too long");
21334           return -99;
21335         }
21336     }
21337
21338   u32 name_len = vec_len (stream_name);
21339   /* Construct the API message */
21340   M (PG_ENABLE_DISABLE, mp);
21341   mp->context = 0;
21342   mp->is_enabled = enable;
21343   if (stream_name_set != 0)
21344     {
21345       mp->stream_name_length = ntohl (name_len);
21346       clib_memcpy (mp->stream_name, stream_name, name_len);
21347     }
21348   vec_free (stream_name);
21349
21350   S (mp);
21351   W (ret);
21352   return ret;
21353 }
21354
21355 int
21356 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21357 {
21358   unformat_input_t *input = vam->input;
21359   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21360
21361   u16 *low_ports = 0;
21362   u16 *high_ports = 0;
21363   u16 this_low;
21364   u16 this_hi;
21365   ip4_address_t ip4_addr;
21366   ip6_address_t ip6_addr;
21367   u32 length;
21368   u32 tmp, tmp2;
21369   u8 prefix_set = 0;
21370   u32 vrf_id = ~0;
21371   u8 is_add = 1;
21372   u8 is_ipv6 = 0;
21373   int ret;
21374
21375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21376     {
21377       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21378         {
21379           prefix_set = 1;
21380         }
21381       else
21382         if (unformat
21383             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21384         {
21385           prefix_set = 1;
21386           is_ipv6 = 1;
21387         }
21388       else if (unformat (input, "vrf %d", &vrf_id))
21389         ;
21390       else if (unformat (input, "del"))
21391         is_add = 0;
21392       else if (unformat (input, "port %d", &tmp))
21393         {
21394           if (tmp == 0 || tmp > 65535)
21395             {
21396               errmsg ("port %d out of range", tmp);
21397               return -99;
21398             }
21399           this_low = tmp;
21400           this_hi = this_low + 1;
21401           vec_add1 (low_ports, this_low);
21402           vec_add1 (high_ports, this_hi);
21403         }
21404       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21405         {
21406           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21407             {
21408               errmsg ("incorrect range parameters");
21409               return -99;
21410             }
21411           this_low = tmp;
21412           /* Note: in debug CLI +1 is added to high before
21413              passing to real fn that does "the work"
21414              (ip_source_and_port_range_check_add_del).
21415              This fn is a wrapper around the binary API fn a
21416              control plane will call, which expects this increment
21417              to have occurred. Hence letting the binary API control
21418              plane fn do the increment for consistency between VAT
21419              and other control planes.
21420            */
21421           this_hi = tmp2;
21422           vec_add1 (low_ports, this_low);
21423           vec_add1 (high_ports, this_hi);
21424         }
21425       else
21426         break;
21427     }
21428
21429   if (prefix_set == 0)
21430     {
21431       errmsg ("<address>/<mask> not specified");
21432       return -99;
21433     }
21434
21435   if (vrf_id == ~0)
21436     {
21437       errmsg ("VRF ID required, not specified");
21438       return -99;
21439     }
21440
21441   if (vrf_id == 0)
21442     {
21443       errmsg
21444         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21445       return -99;
21446     }
21447
21448   if (vec_len (low_ports) == 0)
21449     {
21450       errmsg ("At least one port or port range required");
21451       return -99;
21452     }
21453
21454   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21455
21456   mp->is_add = is_add;
21457
21458   if (is_ipv6)
21459     {
21460       mp->is_ipv6 = 1;
21461       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21462     }
21463   else
21464     {
21465       mp->is_ipv6 = 0;
21466       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21467     }
21468
21469   mp->mask_length = length;
21470   mp->number_of_ranges = vec_len (low_ports);
21471
21472   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21473   vec_free (low_ports);
21474
21475   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21476   vec_free (high_ports);
21477
21478   mp->vrf_id = ntohl (vrf_id);
21479
21480   S (mp);
21481   W (ret);
21482   return ret;
21483 }
21484
21485 int
21486 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21487 {
21488   unformat_input_t *input = vam->input;
21489   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21490   u32 sw_if_index = ~0;
21491   int vrf_set = 0;
21492   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21493   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21494   u8 is_add = 1;
21495   int ret;
21496
21497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21498     {
21499       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21500         ;
21501       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21502         ;
21503       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21504         vrf_set = 1;
21505       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21506         vrf_set = 1;
21507       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21508         vrf_set = 1;
21509       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21510         vrf_set = 1;
21511       else if (unformat (input, "del"))
21512         is_add = 0;
21513       else
21514         break;
21515     }
21516
21517   if (sw_if_index == ~0)
21518     {
21519       errmsg ("Interface required but not specified");
21520       return -99;
21521     }
21522
21523   if (vrf_set == 0)
21524     {
21525       errmsg ("VRF ID required but not specified");
21526       return -99;
21527     }
21528
21529   if (tcp_out_vrf_id == 0
21530       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21531     {
21532       errmsg
21533         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21534       return -99;
21535     }
21536
21537   /* Construct the API message */
21538   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21539
21540   mp->sw_if_index = ntohl (sw_if_index);
21541   mp->is_add = is_add;
21542   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21543   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21544   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21545   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21546
21547   /* send it... */
21548   S (mp);
21549
21550   /* Wait for a reply... */
21551   W (ret);
21552   return ret;
21553 }
21554
21555 static int
21556 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21557 {
21558   unformat_input_t *i = vam->input;
21559   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21560   u32 local_sa_id = 0;
21561   u32 remote_sa_id = 0;
21562   ip4_address_t src_address;
21563   ip4_address_t dst_address;
21564   u8 is_add = 1;
21565   int ret;
21566
21567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21568     {
21569       if (unformat (i, "local_sa %d", &local_sa_id))
21570         ;
21571       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21572         ;
21573       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21574         ;
21575       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21576         ;
21577       else if (unformat (i, "del"))
21578         is_add = 0;
21579       else
21580         {
21581           clib_warning ("parse error '%U'", format_unformat_error, i);
21582           return -99;
21583         }
21584     }
21585
21586   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21587
21588   mp->local_sa_id = ntohl (local_sa_id);
21589   mp->remote_sa_id = ntohl (remote_sa_id);
21590   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21591   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21592   mp->is_add = is_add;
21593
21594   S (mp);
21595   W (ret);
21596   return ret;
21597 }
21598
21599 static int
21600 api_punt (vat_main_t * vam)
21601 {
21602   unformat_input_t *i = vam->input;
21603   vl_api_punt_t *mp;
21604   u32 ipv = ~0;
21605   u32 protocol = ~0;
21606   u32 port = ~0;
21607   int is_add = 1;
21608   int ret;
21609
21610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21611     {
21612       if (unformat (i, "ip %d", &ipv))
21613         ;
21614       else if (unformat (i, "protocol %d", &protocol))
21615         ;
21616       else if (unformat (i, "port %d", &port))
21617         ;
21618       else if (unformat (i, "del"))
21619         is_add = 0;
21620       else
21621         {
21622           clib_warning ("parse error '%U'", format_unformat_error, i);
21623           return -99;
21624         }
21625     }
21626
21627   M (PUNT, mp);
21628
21629   mp->is_add = (u8) is_add;
21630   mp->ipv = (u8) ipv;
21631   mp->l4_protocol = (u8) protocol;
21632   mp->l4_port = htons ((u16) port);
21633
21634   S (mp);
21635   W (ret);
21636   return ret;
21637 }
21638
21639 static void vl_api_ipsec_gre_tunnel_details_t_handler
21640   (vl_api_ipsec_gre_tunnel_details_t * mp)
21641 {
21642   vat_main_t *vam = &vat_main;
21643
21644   print (vam->ofp, "%11d%15U%15U%14d%14d",
21645          ntohl (mp->sw_if_index),
21646          format_ip4_address, &mp->src_address,
21647          format_ip4_address, &mp->dst_address,
21648          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21649 }
21650
21651 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21652   (vl_api_ipsec_gre_tunnel_details_t * mp)
21653 {
21654   vat_main_t *vam = &vat_main;
21655   vat_json_node_t *node = NULL;
21656   struct in_addr ip4;
21657
21658   if (VAT_JSON_ARRAY != vam->json_tree.type)
21659     {
21660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21661       vat_json_init_array (&vam->json_tree);
21662     }
21663   node = vat_json_array_add (&vam->json_tree);
21664
21665   vat_json_init_object (node);
21666   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21667   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21668   vat_json_object_add_ip4 (node, "src_address", ip4);
21669   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21670   vat_json_object_add_ip4 (node, "dst_address", ip4);
21671   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21672   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21673 }
21674
21675 static int
21676 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21677 {
21678   unformat_input_t *i = vam->input;
21679   vl_api_ipsec_gre_tunnel_dump_t *mp;
21680   vl_api_control_ping_t *mp_ping;
21681   u32 sw_if_index;
21682   u8 sw_if_index_set = 0;
21683   int ret;
21684
21685   /* Parse args required to build the message */
21686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21687     {
21688       if (unformat (i, "sw_if_index %d", &sw_if_index))
21689         sw_if_index_set = 1;
21690       else
21691         break;
21692     }
21693
21694   if (sw_if_index_set == 0)
21695     {
21696       sw_if_index = ~0;
21697     }
21698
21699   if (!vam->json_output)
21700     {
21701       print (vam->ofp, "%11s%15s%15s%14s%14s",
21702              "sw_if_index", "src_address", "dst_address",
21703              "local_sa_id", "remote_sa_id");
21704     }
21705
21706   /* Get list of gre-tunnel interfaces */
21707   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21708
21709   mp->sw_if_index = htonl (sw_if_index);
21710
21711   S (mp);
21712
21713   /* Use a control ping for synchronization */
21714   MPING (CONTROL_PING, mp_ping);
21715   S (mp_ping);
21716
21717   W (ret);
21718   return ret;
21719 }
21720
21721 static int
21722 api_delete_subif (vat_main_t * vam)
21723 {
21724   unformat_input_t *i = vam->input;
21725   vl_api_delete_subif_t *mp;
21726   u32 sw_if_index = ~0;
21727   int ret;
21728
21729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21730     {
21731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21732         ;
21733       if (unformat (i, "sw_if_index %d", &sw_if_index))
21734         ;
21735       else
21736         break;
21737     }
21738
21739   if (sw_if_index == ~0)
21740     {
21741       errmsg ("missing sw_if_index");
21742       return -99;
21743     }
21744
21745   /* Construct the API message */
21746   M (DELETE_SUBIF, mp);
21747   mp->sw_if_index = ntohl (sw_if_index);
21748
21749   S (mp);
21750   W (ret);
21751   return ret;
21752 }
21753
21754 #define foreach_pbb_vtr_op      \
21755 _("disable",  L2_VTR_DISABLED)  \
21756 _("pop",  L2_VTR_POP_2)         \
21757 _("push",  L2_VTR_PUSH_2)
21758
21759 static int
21760 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21761 {
21762   unformat_input_t *i = vam->input;
21763   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21764   u32 sw_if_index = ~0, vtr_op = ~0;
21765   u16 outer_tag = ~0;
21766   u8 dmac[6], smac[6];
21767   u8 dmac_set = 0, smac_set = 0;
21768   u16 vlanid = 0;
21769   u32 sid = ~0;
21770   u32 tmp;
21771   int ret;
21772
21773   /* Shut up coverity */
21774   memset (dmac, 0, sizeof (dmac));
21775   memset (smac, 0, sizeof (smac));
21776
21777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21778     {
21779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21780         ;
21781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21782         ;
21783       else if (unformat (i, "vtr_op %d", &vtr_op))
21784         ;
21785 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21786       foreach_pbb_vtr_op
21787 #undef _
21788         else if (unformat (i, "translate_pbb_stag"))
21789         {
21790           if (unformat (i, "%d", &tmp))
21791             {
21792               vtr_op = L2_VTR_TRANSLATE_2_1;
21793               outer_tag = tmp;
21794             }
21795           else
21796             {
21797               errmsg
21798                 ("translate_pbb_stag operation requires outer tag definition");
21799               return -99;
21800             }
21801         }
21802       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21803         dmac_set++;
21804       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21805         smac_set++;
21806       else if (unformat (i, "sid %d", &sid))
21807         ;
21808       else if (unformat (i, "vlanid %d", &tmp))
21809         vlanid = tmp;
21810       else
21811         {
21812           clib_warning ("parse error '%U'", format_unformat_error, i);
21813           return -99;
21814         }
21815     }
21816
21817   if ((sw_if_index == ~0) || (vtr_op == ~0))
21818     {
21819       errmsg ("missing sw_if_index or vtr operation");
21820       return -99;
21821     }
21822   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21823       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21824     {
21825       errmsg
21826         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21827       return -99;
21828     }
21829
21830   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21831   mp->sw_if_index = ntohl (sw_if_index);
21832   mp->vtr_op = ntohl (vtr_op);
21833   mp->outer_tag = ntohs (outer_tag);
21834   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21835   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21836   mp->b_vlanid = ntohs (vlanid);
21837   mp->i_sid = ntohl (sid);
21838
21839   S (mp);
21840   W (ret);
21841   return ret;
21842 }
21843
21844 static int
21845 api_flow_classify_set_interface (vat_main_t * vam)
21846 {
21847   unformat_input_t *i = vam->input;
21848   vl_api_flow_classify_set_interface_t *mp;
21849   u32 sw_if_index;
21850   int sw_if_index_set;
21851   u32 ip4_table_index = ~0;
21852   u32 ip6_table_index = ~0;
21853   u8 is_add = 1;
21854   int ret;
21855
21856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21857     {
21858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21859         sw_if_index_set = 1;
21860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21861         sw_if_index_set = 1;
21862       else if (unformat (i, "del"))
21863         is_add = 0;
21864       else if (unformat (i, "ip4-table %d", &ip4_table_index))
21865         ;
21866       else if (unformat (i, "ip6-table %d", &ip6_table_index))
21867         ;
21868       else
21869         {
21870           clib_warning ("parse error '%U'", format_unformat_error, i);
21871           return -99;
21872         }
21873     }
21874
21875   if (sw_if_index_set == 0)
21876     {
21877       errmsg ("missing interface name or sw_if_index");
21878       return -99;
21879     }
21880
21881   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
21882
21883   mp->sw_if_index = ntohl (sw_if_index);
21884   mp->ip4_table_index = ntohl (ip4_table_index);
21885   mp->ip6_table_index = ntohl (ip6_table_index);
21886   mp->is_add = is_add;
21887
21888   S (mp);
21889   W (ret);
21890   return ret;
21891 }
21892
21893 static int
21894 api_flow_classify_dump (vat_main_t * vam)
21895 {
21896   unformat_input_t *i = vam->input;
21897   vl_api_flow_classify_dump_t *mp;
21898   vl_api_control_ping_t *mp_ping;
21899   u8 type = FLOW_CLASSIFY_N_TABLES;
21900   int ret;
21901
21902   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
21903     ;
21904   else
21905     {
21906       errmsg ("classify table type must be specified");
21907       return -99;
21908     }
21909
21910   if (!vam->json_output)
21911     {
21912       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
21913     }
21914
21915   M (FLOW_CLASSIFY_DUMP, mp);
21916   mp->type = type;
21917   /* send it... */
21918   S (mp);
21919
21920   /* Use a control ping for synchronization */
21921   MPING (CONTROL_PING, mp_ping);
21922   S (mp_ping);
21923
21924   /* Wait for a reply... */
21925   W (ret);
21926   return ret;
21927 }
21928
21929 static int
21930 api_feature_enable_disable (vat_main_t * vam)
21931 {
21932   unformat_input_t *i = vam->input;
21933   vl_api_feature_enable_disable_t *mp;
21934   u8 *arc_name = 0;
21935   u8 *feature_name = 0;
21936   u32 sw_if_index = ~0;
21937   u8 enable = 1;
21938   int ret;
21939
21940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21941     {
21942       if (unformat (i, "arc_name %s", &arc_name))
21943         ;
21944       else if (unformat (i, "feature_name %s", &feature_name))
21945         ;
21946       else
21947         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21948         ;
21949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21950         ;
21951       else if (unformat (i, "disable"))
21952         enable = 0;
21953       else
21954         break;
21955     }
21956
21957   if (arc_name == 0)
21958     {
21959       errmsg ("missing arc name");
21960       return -99;
21961     }
21962   if (vec_len (arc_name) > 63)
21963     {
21964       errmsg ("arc name too long");
21965     }
21966
21967   if (feature_name == 0)
21968     {
21969       errmsg ("missing feature name");
21970       return -99;
21971     }
21972   if (vec_len (feature_name) > 63)
21973     {
21974       errmsg ("feature name too long");
21975     }
21976
21977   if (sw_if_index == ~0)
21978     {
21979       errmsg ("missing interface name or sw_if_index");
21980       return -99;
21981     }
21982
21983   /* Construct the API message */
21984   M (FEATURE_ENABLE_DISABLE, mp);
21985   mp->sw_if_index = ntohl (sw_if_index);
21986   mp->enable = enable;
21987   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21988   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21989   vec_free (arc_name);
21990   vec_free (feature_name);
21991
21992   S (mp);
21993   W (ret);
21994   return ret;
21995 }
21996
21997 static int
21998 api_sw_interface_tag_add_del (vat_main_t * vam)
21999 {
22000   unformat_input_t *i = vam->input;
22001   vl_api_sw_interface_tag_add_del_t *mp;
22002   u32 sw_if_index = ~0;
22003   u8 *tag = 0;
22004   u8 enable = 1;
22005   int ret;
22006
22007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22008     {
22009       if (unformat (i, "tag %s", &tag))
22010         ;
22011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22012         ;
22013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22014         ;
22015       else if (unformat (i, "del"))
22016         enable = 0;
22017       else
22018         break;
22019     }
22020
22021   if (sw_if_index == ~0)
22022     {
22023       errmsg ("missing interface name or sw_if_index");
22024       return -99;
22025     }
22026
22027   if (enable && (tag == 0))
22028     {
22029       errmsg ("no tag specified");
22030       return -99;
22031     }
22032
22033   /* Construct the API message */
22034   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22035   mp->sw_if_index = ntohl (sw_if_index);
22036   mp->is_add = enable;
22037   if (enable)
22038     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22039   vec_free (tag);
22040
22041   S (mp);
22042   W (ret);
22043   return ret;
22044 }
22045
22046 static void vl_api_l2_xconnect_details_t_handler
22047   (vl_api_l2_xconnect_details_t * mp)
22048 {
22049   vat_main_t *vam = &vat_main;
22050
22051   print (vam->ofp, "%15d%15d",
22052          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22053 }
22054
22055 static void vl_api_l2_xconnect_details_t_handler_json
22056   (vl_api_l2_xconnect_details_t * mp)
22057 {
22058   vat_main_t *vam = &vat_main;
22059   vat_json_node_t *node = NULL;
22060
22061   if (VAT_JSON_ARRAY != vam->json_tree.type)
22062     {
22063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22064       vat_json_init_array (&vam->json_tree);
22065     }
22066   node = vat_json_array_add (&vam->json_tree);
22067
22068   vat_json_init_object (node);
22069   vat_json_object_add_uint (node, "rx_sw_if_index",
22070                             ntohl (mp->rx_sw_if_index));
22071   vat_json_object_add_uint (node, "tx_sw_if_index",
22072                             ntohl (mp->tx_sw_if_index));
22073 }
22074
22075 static int
22076 api_l2_xconnect_dump (vat_main_t * vam)
22077 {
22078   vl_api_l2_xconnect_dump_t *mp;
22079   vl_api_control_ping_t *mp_ping;
22080   int ret;
22081
22082   if (!vam->json_output)
22083     {
22084       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22085     }
22086
22087   M (L2_XCONNECT_DUMP, mp);
22088
22089   S (mp);
22090
22091   /* Use a control ping for synchronization */
22092   MPING (CONTROL_PING, mp_ping);
22093   S (mp_ping);
22094
22095   W (ret);
22096   return ret;
22097 }
22098
22099 static int
22100 api_hw_interface_set_mtu (vat_main_t * vam)
22101 {
22102   unformat_input_t *i = vam->input;
22103   vl_api_hw_interface_set_mtu_t *mp;
22104   u32 sw_if_index = ~0;
22105   u32 mtu = 0;
22106   int ret;
22107
22108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22109     {
22110       if (unformat (i, "mtu %d", &mtu))
22111         ;
22112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22113         ;
22114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22115         ;
22116       else
22117         break;
22118     }
22119
22120   if (sw_if_index == ~0)
22121     {
22122       errmsg ("missing interface name or sw_if_index");
22123       return -99;
22124     }
22125
22126   if (mtu == 0)
22127     {
22128       errmsg ("no mtu specified");
22129       return -99;
22130     }
22131
22132   /* Construct the API message */
22133   M (HW_INTERFACE_SET_MTU, mp);
22134   mp->sw_if_index = ntohl (sw_if_index);
22135   mp->mtu = ntohs ((u16) mtu);
22136
22137   S (mp);
22138   W (ret);
22139   return ret;
22140 }
22141
22142 static int
22143 api_p2p_ethernet_add (vat_main_t * vam)
22144 {
22145   unformat_input_t *i = vam->input;
22146   vl_api_p2p_ethernet_add_t *mp;
22147   u32 parent_if_index = ~0;
22148   u32 sub_id = ~0;
22149   u8 remote_mac[6];
22150   u8 mac_set = 0;
22151   int ret;
22152
22153   memset (remote_mac, 0, sizeof (remote_mac));
22154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22155     {
22156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22157         ;
22158       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22159         ;
22160       else
22161         if (unformat
22162             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22163         mac_set++;
22164       else if (unformat (i, "sub_id %d", &sub_id))
22165         ;
22166       else
22167         {
22168           clib_warning ("parse error '%U'", format_unformat_error, i);
22169           return -99;
22170         }
22171     }
22172
22173   if (parent_if_index == ~0)
22174     {
22175       errmsg ("missing interface name or sw_if_index");
22176       return -99;
22177     }
22178   if (mac_set == 0)
22179     {
22180       errmsg ("missing remote mac address");
22181       return -99;
22182     }
22183   if (sub_id == ~0)
22184     {
22185       errmsg ("missing sub-interface id");
22186       return -99;
22187     }
22188
22189   M (P2P_ETHERNET_ADD, mp);
22190   mp->parent_if_index = ntohl (parent_if_index);
22191   mp->subif_id = ntohl (sub_id);
22192   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22193
22194   S (mp);
22195   W (ret);
22196   return ret;
22197 }
22198
22199 static int
22200 api_p2p_ethernet_del (vat_main_t * vam)
22201 {
22202   unformat_input_t *i = vam->input;
22203   vl_api_p2p_ethernet_del_t *mp;
22204   u32 parent_if_index = ~0;
22205   u8 remote_mac[6];
22206   u8 mac_set = 0;
22207   int ret;
22208
22209   memset (remote_mac, 0, sizeof (remote_mac));
22210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22211     {
22212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22213         ;
22214       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22215         ;
22216       else
22217         if (unformat
22218             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22219         mac_set++;
22220       else
22221         {
22222           clib_warning ("parse error '%U'", format_unformat_error, i);
22223           return -99;
22224         }
22225     }
22226
22227   if (parent_if_index == ~0)
22228     {
22229       errmsg ("missing interface name or sw_if_index");
22230       return -99;
22231     }
22232   if (mac_set == 0)
22233     {
22234       errmsg ("missing remote mac address");
22235       return -99;
22236     }
22237
22238   M (P2P_ETHERNET_DEL, mp);
22239   mp->parent_if_index = ntohl (parent_if_index);
22240   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22241
22242   S (mp);
22243   W (ret);
22244   return ret;
22245 }
22246
22247 static int
22248 api_lldp_config (vat_main_t * vam)
22249 {
22250   unformat_input_t *i = vam->input;
22251   vl_api_lldp_config_t *mp;
22252   int tx_hold = 0;
22253   int tx_interval = 0;
22254   u8 *sys_name = NULL;
22255   int ret;
22256
22257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22258     {
22259       if (unformat (i, "system-name %s", &sys_name))
22260         ;
22261       else if (unformat (i, "tx-hold %d", &tx_hold))
22262         ;
22263       else if (unformat (i, "tx-interval %d", &tx_interval))
22264         ;
22265       else
22266         {
22267           clib_warning ("parse error '%U'", format_unformat_error, i);
22268           return -99;
22269         }
22270     }
22271
22272   vec_add1 (sys_name, 0);
22273
22274   M (LLDP_CONFIG, mp);
22275   mp->tx_hold = htonl (tx_hold);
22276   mp->tx_interval = htonl (tx_interval);
22277   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22278   vec_free (sys_name);
22279
22280   S (mp);
22281   W (ret);
22282   return ret;
22283 }
22284
22285 static int
22286 api_sw_interface_set_lldp (vat_main_t * vam)
22287 {
22288   unformat_input_t *i = vam->input;
22289   vl_api_sw_interface_set_lldp_t *mp;
22290   u32 sw_if_index = ~0;
22291   u32 enable = 1;
22292   u8 *port_desc = NULL, *mgmt_oid = NULL;
22293   ip4_address_t ip4_addr;
22294   ip6_address_t ip6_addr;
22295   int ret;
22296
22297   memset (&ip4_addr, 0, sizeof (ip4_addr));
22298   memset (&ip6_addr, 0, sizeof (ip6_addr));
22299
22300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22301     {
22302       if (unformat (i, "disable"))
22303         enable = 0;
22304       else
22305         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22306         ;
22307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22308         ;
22309       else if (unformat (i, "port-desc %s", &port_desc))
22310         ;
22311       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22312         ;
22313       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22314         ;
22315       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22316         ;
22317       else
22318         break;
22319     }
22320
22321   if (sw_if_index == ~0)
22322     {
22323       errmsg ("missing interface name or sw_if_index");
22324       return -99;
22325     }
22326
22327   /* Construct the API message */
22328   vec_add1 (port_desc, 0);
22329   vec_add1 (mgmt_oid, 0);
22330   M (SW_INTERFACE_SET_LLDP, mp);
22331   mp->sw_if_index = ntohl (sw_if_index);
22332   mp->enable = enable;
22333   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22334   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22335   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22336   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22337   vec_free (port_desc);
22338   vec_free (mgmt_oid);
22339
22340   S (mp);
22341   W (ret);
22342   return ret;
22343 }
22344
22345 static int
22346 api_tcp_configure_src_addresses (vat_main_t * vam)
22347 {
22348   vl_api_tcp_configure_src_addresses_t *mp;
22349   unformat_input_t *i = vam->input;
22350   ip4_address_t v4first, v4last;
22351   ip6_address_t v6first, v6last;
22352   u8 range_set = 0;
22353   u32 vrf_id = 0;
22354   int ret;
22355
22356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22357     {
22358       if (unformat (i, "%U - %U",
22359                     unformat_ip4_address, &v4first,
22360                     unformat_ip4_address, &v4last))
22361         {
22362           if (range_set)
22363             {
22364               errmsg ("one range per message (range already set)");
22365               return -99;
22366             }
22367           range_set = 1;
22368         }
22369       else if (unformat (i, "%U - %U",
22370                          unformat_ip6_address, &v6first,
22371                          unformat_ip6_address, &v6last))
22372         {
22373           if (range_set)
22374             {
22375               errmsg ("one range per message (range already set)");
22376               return -99;
22377             }
22378           range_set = 2;
22379         }
22380       else if (unformat (i, "vrf %d", &vrf_id))
22381         ;
22382       else
22383         break;
22384     }
22385
22386   if (range_set == 0)
22387     {
22388       errmsg ("address range not set");
22389       return -99;
22390     }
22391
22392   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22393   mp->vrf_id = ntohl (vrf_id);
22394   /* ipv6? */
22395   if (range_set == 2)
22396     {
22397       mp->is_ipv6 = 1;
22398       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22399       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22400     }
22401   else
22402     {
22403       mp->is_ipv6 = 0;
22404       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22405       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22406     }
22407   S (mp);
22408   W (ret);
22409   return ret;
22410 }
22411
22412 static void vl_api_app_namespace_add_del_reply_t_handler
22413   (vl_api_app_namespace_add_del_reply_t * mp)
22414 {
22415   vat_main_t *vam = &vat_main;
22416   i32 retval = ntohl (mp->retval);
22417   if (vam->async_mode)
22418     {
22419       vam->async_errors += (retval < 0);
22420     }
22421   else
22422     {
22423       vam->retval = retval;
22424       if (retval == 0)
22425         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22426       vam->result_ready = 1;
22427     }
22428 }
22429
22430 static void vl_api_app_namespace_add_del_reply_t_handler_json
22431   (vl_api_app_namespace_add_del_reply_t * mp)
22432 {
22433   vat_main_t *vam = &vat_main;
22434   vat_json_node_t node;
22435
22436   vat_json_init_object (&node);
22437   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22438   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22439
22440   vat_json_print (vam->ofp, &node);
22441   vat_json_free (&node);
22442
22443   vam->retval = ntohl (mp->retval);
22444   vam->result_ready = 1;
22445 }
22446
22447 static int
22448 api_app_namespace_add_del (vat_main_t * vam)
22449 {
22450   vl_api_app_namespace_add_del_t *mp;
22451   unformat_input_t *i = vam->input;
22452   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22453   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22454   u64 secret;
22455   int ret;
22456
22457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22458     {
22459       if (unformat (i, "id %_%v%_", &ns_id))
22460         ;
22461       else if (unformat (i, "secret %lu", &secret))
22462         secret_set = 1;
22463       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22464         sw_if_index_set = 1;
22465       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22466         ;
22467       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22468         ;
22469       else
22470         break;
22471     }
22472   if (!ns_id || !secret_set || !sw_if_index_set)
22473     {
22474       errmsg ("namespace id, secret and sw_if_index must be set");
22475       return -99;
22476     }
22477   if (vec_len (ns_id) > 64)
22478     {
22479       errmsg ("namespace id too long");
22480       return -99;
22481     }
22482   M (APP_NAMESPACE_ADD_DEL, mp);
22483
22484   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22485   mp->namespace_id_len = vec_len (ns_id);
22486   mp->secret = clib_host_to_net_u64 (secret);
22487   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22488   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22489   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22490   vec_free (ns_id);
22491   S (mp);
22492   W (ret);
22493   return ret;
22494 }
22495
22496 static int
22497 api_sock_init_shm (vat_main_t * vam)
22498 {
22499 #if VPP_API_TEST_BUILTIN == 0
22500   unformat_input_t *i = vam->input;
22501   vl_api_shm_elem_config_t *config = 0;
22502   u64 size = 64 << 20;
22503   int rv;
22504
22505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22506     {
22507       if (unformat (i, "size %U", unformat_memory_size, &size))
22508         ;
22509       else
22510         break;
22511     }
22512
22513   /*
22514    * Canned custom ring allocator config.
22515    * Should probably parse all of this
22516    */
22517   vec_validate (config, 6);
22518   config[0].type = VL_API_VLIB_RING;
22519   config[0].size = 256;
22520   config[0].count = 32;
22521
22522   config[1].type = VL_API_VLIB_RING;
22523   config[1].size = 1024;
22524   config[1].count = 16;
22525
22526   config[2].type = VL_API_VLIB_RING;
22527   config[2].size = 4096;
22528   config[2].count = 2;
22529
22530   config[3].type = VL_API_CLIENT_RING;
22531   config[3].size = 256;
22532   config[3].count = 32;
22533
22534   config[4].type = VL_API_CLIENT_RING;
22535   config[4].size = 1024;
22536   config[4].count = 16;
22537
22538   config[5].type = VL_API_CLIENT_RING;
22539   config[5].size = 4096;
22540   config[5].count = 2;
22541
22542   config[6].type = VL_API_QUEUE;
22543   config[6].count = 128;
22544   config[6].size = sizeof (uword);
22545
22546   rv = vl_socket_client_init_shm (config);
22547   if (!rv)
22548     vam->client_index_invalid = 1;
22549   return rv;
22550 #else
22551   return -99;
22552 #endif
22553 }
22554
22555 static int
22556 api_dns_enable_disable (vat_main_t * vam)
22557 {
22558   unformat_input_t *line_input = vam->input;
22559   vl_api_dns_enable_disable_t *mp;
22560   u8 enable_disable = 1;
22561   int ret;
22562
22563   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22564     {
22565       if (unformat (line_input, "disable"))
22566         enable_disable = 0;
22567       if (unformat (line_input, "enable"))
22568         enable_disable = 1;
22569       else
22570         break;
22571     }
22572
22573   /* Construct the API message */
22574   M (DNS_ENABLE_DISABLE, mp);
22575   mp->enable = enable_disable;
22576
22577   /* send it... */
22578   S (mp);
22579   /* Wait for the reply */
22580   W (ret);
22581   return ret;
22582 }
22583
22584 static int
22585 api_dns_resolve_name (vat_main_t * vam)
22586 {
22587   unformat_input_t *line_input = vam->input;
22588   vl_api_dns_resolve_name_t *mp;
22589   u8 *name = 0;
22590   int ret;
22591
22592   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22593     {
22594       if (unformat (line_input, "%s", &name))
22595         ;
22596       else
22597         break;
22598     }
22599
22600   if (vec_len (name) > 127)
22601     {
22602       errmsg ("name too long");
22603       return -99;
22604     }
22605
22606   /* Construct the API message */
22607   M (DNS_RESOLVE_NAME, mp);
22608   memcpy (mp->name, name, vec_len (name));
22609   vec_free (name);
22610
22611   /* send it... */
22612   S (mp);
22613   /* Wait for the reply */
22614   W (ret);
22615   return ret;
22616 }
22617
22618 static int
22619 api_dns_resolve_ip (vat_main_t * vam)
22620 {
22621   unformat_input_t *line_input = vam->input;
22622   vl_api_dns_resolve_ip_t *mp;
22623   int is_ip6 = -1;
22624   ip4_address_t addr4;
22625   ip6_address_t addr6;
22626   int ret;
22627
22628   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22629     {
22630       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22631         is_ip6 = 1;
22632       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22633         is_ip6 = 0;
22634       else
22635         break;
22636     }
22637
22638   if (is_ip6 == -1)
22639     {
22640       errmsg ("missing address");
22641       return -99;
22642     }
22643
22644   /* Construct the API message */
22645   M (DNS_RESOLVE_IP, mp);
22646   mp->is_ip6 = is_ip6;
22647   if (is_ip6)
22648     memcpy (mp->address, &addr6, sizeof (addr6));
22649   else
22650     memcpy (mp->address, &addr4, sizeof (addr4));
22651
22652   /* send it... */
22653   S (mp);
22654   /* Wait for the reply */
22655   W (ret);
22656   return ret;
22657 }
22658
22659 static int
22660 api_dns_name_server_add_del (vat_main_t * vam)
22661 {
22662   unformat_input_t *i = vam->input;
22663   vl_api_dns_name_server_add_del_t *mp;
22664   u8 is_add = 1;
22665   ip6_address_t ip6_server;
22666   ip4_address_t ip4_server;
22667   int ip6_set = 0;
22668   int ip4_set = 0;
22669   int ret = 0;
22670
22671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22672     {
22673       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22674         ip6_set = 1;
22675       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22676         ip4_set = 1;
22677       else if (unformat (i, "del"))
22678         is_add = 0;
22679       else
22680         {
22681           clib_warning ("parse error '%U'", format_unformat_error, i);
22682           return -99;
22683         }
22684     }
22685
22686   if (ip4_set && ip6_set)
22687     {
22688       errmsg ("Only one server address allowed per message");
22689       return -99;
22690     }
22691   if ((ip4_set + ip6_set) == 0)
22692     {
22693       errmsg ("Server address required");
22694       return -99;
22695     }
22696
22697   /* Construct the API message */
22698   M (DNS_NAME_SERVER_ADD_DEL, mp);
22699
22700   if (ip6_set)
22701     {
22702       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22703       mp->is_ip6 = 1;
22704     }
22705   else
22706     {
22707       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22708       mp->is_ip6 = 0;
22709     }
22710
22711   mp->is_add = is_add;
22712
22713   /* send it... */
22714   S (mp);
22715
22716   /* Wait for a reply, return good/bad news  */
22717   W (ret);
22718   return ret;
22719 }
22720
22721 static void
22722 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22723 {
22724   vat_main_t *vam = &vat_main;
22725
22726   if (mp->is_ip4)
22727     {
22728       print (vam->ofp,
22729              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22730              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22731              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22732              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22733              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22734              clib_net_to_host_u32 (mp->action_index), mp->tag);
22735     }
22736   else
22737     {
22738       print (vam->ofp,
22739              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22740              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22741              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22742              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22743              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22744              clib_net_to_host_u32 (mp->action_index), mp->tag);
22745     }
22746 }
22747
22748 static void
22749 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22750                                              mp)
22751 {
22752   vat_main_t *vam = &vat_main;
22753   vat_json_node_t *node = NULL;
22754   struct in6_addr ip6;
22755   struct in_addr ip4;
22756
22757   if (VAT_JSON_ARRAY != vam->json_tree.type)
22758     {
22759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22760       vat_json_init_array (&vam->json_tree);
22761     }
22762   node = vat_json_array_add (&vam->json_tree);
22763   vat_json_init_object (node);
22764
22765   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22766   vat_json_object_add_uint (node, "appns_index",
22767                             clib_net_to_host_u32 (mp->appns_index));
22768   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22769   vat_json_object_add_uint (node, "scope", mp->scope);
22770   vat_json_object_add_uint (node, "action_index",
22771                             clib_net_to_host_u32 (mp->action_index));
22772   vat_json_object_add_uint (node, "lcl_port",
22773                             clib_net_to_host_u16 (mp->lcl_port));
22774   vat_json_object_add_uint (node, "rmt_port",
22775                             clib_net_to_host_u16 (mp->rmt_port));
22776   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22777   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22778   vat_json_object_add_string_copy (node, "tag", mp->tag);
22779   if (mp->is_ip4)
22780     {
22781       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22782       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22783       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22784       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22785     }
22786   else
22787     {
22788       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22789       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22790       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22791       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22792     }
22793 }
22794
22795 static int
22796 api_session_rule_add_del (vat_main_t * vam)
22797 {
22798   vl_api_session_rule_add_del_t *mp;
22799   unformat_input_t *i = vam->input;
22800   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22801   u32 appns_index = 0, scope = 0;
22802   ip4_address_t lcl_ip4, rmt_ip4;
22803   ip6_address_t lcl_ip6, rmt_ip6;
22804   u8 is_ip4 = 1, conn_set = 0;
22805   u8 is_add = 1, *tag = 0;
22806   int ret;
22807
22808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22809     {
22810       if (unformat (i, "del"))
22811         is_add = 0;
22812       else if (unformat (i, "add"))
22813         ;
22814       else if (unformat (i, "proto tcp"))
22815         proto = 0;
22816       else if (unformat (i, "proto udp"))
22817         proto = 1;
22818       else if (unformat (i, "appns %d", &appns_index))
22819         ;
22820       else if (unformat (i, "scope %d", &scope))
22821         ;
22822       else if (unformat (i, "tag %_%v%_", &tag))
22823         ;
22824       else
22825         if (unformat
22826             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22827              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22828              &rmt_port))
22829         {
22830           is_ip4 = 1;
22831           conn_set = 1;
22832         }
22833       else
22834         if (unformat
22835             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22836              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22837              &rmt_port))
22838         {
22839           is_ip4 = 0;
22840           conn_set = 1;
22841         }
22842       else if (unformat (i, "action %d", &action))
22843         ;
22844       else
22845         break;
22846     }
22847   if (proto == ~0 || !conn_set || action == ~0)
22848     {
22849       errmsg ("transport proto, connection and action must be set");
22850       return -99;
22851     }
22852
22853   if (scope > 3)
22854     {
22855       errmsg ("scope should be 0-3");
22856       return -99;
22857     }
22858
22859   M (SESSION_RULE_ADD_DEL, mp);
22860
22861   mp->is_ip4 = is_ip4;
22862   mp->transport_proto = proto;
22863   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
22864   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
22865   mp->lcl_plen = lcl_plen;
22866   mp->rmt_plen = rmt_plen;
22867   mp->action_index = clib_host_to_net_u32 (action);
22868   mp->appns_index = clib_host_to_net_u32 (appns_index);
22869   mp->scope = scope;
22870   mp->is_add = is_add;
22871   if (is_ip4)
22872     {
22873       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
22874       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
22875     }
22876   else
22877     {
22878       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
22879       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
22880     }
22881   if (tag)
22882     {
22883       clib_memcpy (mp->tag, tag, vec_len (tag));
22884       vec_free (tag);
22885     }
22886
22887   S (mp);
22888   W (ret);
22889   return ret;
22890 }
22891
22892 static int
22893 api_session_rules_dump (vat_main_t * vam)
22894 {
22895   vl_api_session_rules_dump_t *mp;
22896   vl_api_control_ping_t *mp_ping;
22897   int ret;
22898
22899   if (!vam->json_output)
22900     {
22901       print (vam->ofp, "%=20s", "Session Rules");
22902     }
22903
22904   M (SESSION_RULES_DUMP, mp);
22905   /* send it... */
22906   S (mp);
22907
22908   /* Use a control ping for synchronization */
22909   MPING (CONTROL_PING, mp_ping);
22910   S (mp_ping);
22911
22912   /* Wait for a reply... */
22913   W (ret);
22914   return ret;
22915 }
22916
22917 static int
22918 api_ip_container_proxy_add_del (vat_main_t * vam)
22919 {
22920   vl_api_ip_container_proxy_add_del_t *mp;
22921   unformat_input_t *i = vam->input;
22922   u32 plen = ~0, sw_if_index = ~0;
22923   ip4_address_t ip4;
22924   ip6_address_t ip6;
22925   u8 is_ip4 = 1;
22926   u8 is_add = 1;
22927   int ret;
22928
22929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22930     {
22931       if (unformat (i, "del"))
22932         is_add = 0;
22933       else if (unformat (i, "add"))
22934         ;
22935       if (unformat (i, "%U", unformat_ip4_address, &ip4))
22936         {
22937           is_ip4 = 1;
22938           plen = 32;
22939         }
22940       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
22941         {
22942           is_ip4 = 0;
22943           plen = 128;
22944         }
22945       else if (unformat (i, "sw_if_index %u", &sw_if_index))
22946         ;
22947       else
22948         break;
22949     }
22950   if (sw_if_index == ~0 || plen == ~0)
22951     {
22952       errmsg ("address and sw_if_index must be set");
22953       return -99;
22954     }
22955
22956   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
22957
22958   mp->is_ip4 = is_ip4;
22959   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22960   mp->plen = plen;
22961   mp->is_add = is_add;
22962   if (is_ip4)
22963     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
22964   else
22965     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
22966
22967   S (mp);
22968   W (ret);
22969   return ret;
22970 }
22971
22972 static int
22973 api_qos_record_enable_disable (vat_main_t * vam)
22974 {
22975   unformat_input_t *i = vam->input;
22976   vl_api_qos_record_enable_disable_t *mp;
22977   u32 sw_if_index, qs = 0xff;
22978   u8 sw_if_index_set = 0;
22979   u8 enable = 1;
22980   int ret;
22981
22982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22983     {
22984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22985         sw_if_index_set = 1;
22986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22987         sw_if_index_set = 1;
22988       else if (unformat (i, "%U", unformat_qos_source, &qs))
22989         ;
22990       else if (unformat (i, "disable"))
22991         enable = 0;
22992       else
22993         {
22994           clib_warning ("parse error '%U'", format_unformat_error, i);
22995           return -99;
22996         }
22997     }
22998
22999   if (sw_if_index_set == 0)
23000     {
23001       errmsg ("missing interface name or sw_if_index");
23002       return -99;
23003     }
23004   if (qs == 0xff)
23005     {
23006       errmsg ("input location must be specified");
23007       return -99;
23008     }
23009
23010   M (QOS_RECORD_ENABLE_DISABLE, mp);
23011
23012   mp->sw_if_index = ntohl (sw_if_index);
23013   mp->input_source = qs;
23014   mp->enable = enable;
23015
23016   S (mp);
23017   W (ret);
23018   return ret;
23019 }
23020
23021
23022 static int
23023 q_or_quit (vat_main_t * vam)
23024 {
23025 #if VPP_API_TEST_BUILTIN == 0
23026   longjmp (vam->jump_buf, 1);
23027 #endif
23028   return 0;                     /* not so much */
23029 }
23030
23031 static int
23032 q (vat_main_t * vam)
23033 {
23034   return q_or_quit (vam);
23035 }
23036
23037 static int
23038 quit (vat_main_t * vam)
23039 {
23040   return q_or_quit (vam);
23041 }
23042
23043 static int
23044 comment (vat_main_t * vam)
23045 {
23046   return 0;
23047 }
23048
23049 static int
23050 statseg (vat_main_t * vam)
23051 {
23052   ssvm_private_t *ssvmp = &vam->stat_segment;
23053   ssvm_shared_header_t *shared_header = ssvmp->sh;
23054   vlib_counter_t **counters;
23055   u64 thread0_index1_packets;
23056   u64 thread0_index1_bytes;
23057   f64 vector_rate, input_rate;
23058   uword *p;
23059
23060   uword *counter_vector_by_name;
23061   if (vam->stat_segment_lockp == 0)
23062     {
23063       errmsg ("Stat segment not mapped...");
23064       return -99;
23065     }
23066
23067   /* look up "/if/rx for sw_if_index 1 as a test */
23068
23069   clib_spinlock_lock (vam->stat_segment_lockp);
23070
23071   counter_vector_by_name = (uword *) shared_header->opaque[1];
23072
23073   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23074   if (p == 0)
23075     {
23076       clib_spinlock_unlock (vam->stat_segment_lockp);
23077       errmsg ("/if/tx not found?");
23078       return -99;
23079     }
23080
23081   /* Fish per-thread vector of combined counters from shared memory */
23082   counters = (vlib_counter_t **) p[0];
23083
23084   if (vec_len (counters[0]) < 2)
23085     {
23086       clib_spinlock_unlock (vam->stat_segment_lockp);
23087       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23088       return -99;
23089     }
23090
23091   /* Read thread 0 sw_if_index 1 counter */
23092   thread0_index1_packets = counters[0][1].packets;
23093   thread0_index1_bytes = counters[0][1].bytes;
23094
23095   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23096   if (p == 0)
23097     {
23098       clib_spinlock_unlock (vam->stat_segment_lockp);
23099       errmsg ("vector_rate not found?");
23100       return -99;
23101     }
23102
23103   vector_rate = *(f64 *) (p[0]);
23104   p = hash_get_mem (counter_vector_by_name, "input_rate");
23105   if (p == 0)
23106     {
23107       clib_spinlock_unlock (vam->stat_segment_lockp);
23108       errmsg ("input_rate not found?");
23109       return -99;
23110     }
23111   input_rate = *(f64 *) (p[0]);
23112
23113   clib_spinlock_unlock (vam->stat_segment_lockp);
23114
23115   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23116          vector_rate, input_rate);
23117   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23118          thread0_index1_packets, thread0_index1_bytes);
23119
23120   return 0;
23121 }
23122
23123 static int
23124 cmd_cmp (void *a1, void *a2)
23125 {
23126   u8 **c1 = a1;
23127   u8 **c2 = a2;
23128
23129   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23130 }
23131
23132 static int
23133 help (vat_main_t * vam)
23134 {
23135   u8 **cmds = 0;
23136   u8 *name = 0;
23137   hash_pair_t *p;
23138   unformat_input_t *i = vam->input;
23139   int j;
23140
23141   if (unformat (i, "%s", &name))
23142     {
23143       uword *hs;
23144
23145       vec_add1 (name, 0);
23146
23147       hs = hash_get_mem (vam->help_by_name, name);
23148       if (hs)
23149         print (vam->ofp, "usage: %s %s", name, hs[0]);
23150       else
23151         print (vam->ofp, "No such msg / command '%s'", name);
23152       vec_free (name);
23153       return 0;
23154     }
23155
23156   print (vam->ofp, "Help is available for the following:");
23157
23158     /* *INDENT-OFF* */
23159     hash_foreach_pair (p, vam->function_by_name,
23160     ({
23161       vec_add1 (cmds, (u8 *)(p->key));
23162     }));
23163     /* *INDENT-ON* */
23164
23165   vec_sort_with_function (cmds, cmd_cmp);
23166
23167   for (j = 0; j < vec_len (cmds); j++)
23168     print (vam->ofp, "%s", cmds[j]);
23169
23170   vec_free (cmds);
23171   return 0;
23172 }
23173
23174 static int
23175 set (vat_main_t * vam)
23176 {
23177   u8 *name = 0, *value = 0;
23178   unformat_input_t *i = vam->input;
23179
23180   if (unformat (i, "%s", &name))
23181     {
23182       /* The input buffer is a vector, not a string. */
23183       value = vec_dup (i->buffer);
23184       vec_delete (value, i->index, 0);
23185       /* Almost certainly has a trailing newline */
23186       if (value[vec_len (value) - 1] == '\n')
23187         value[vec_len (value) - 1] = 0;
23188       /* Make sure it's a proper string, one way or the other */
23189       vec_add1 (value, 0);
23190       (void) clib_macro_set_value (&vam->macro_main,
23191                                    (char *) name, (char *) value);
23192     }
23193   else
23194     errmsg ("usage: set <name> <value>");
23195
23196   vec_free (name);
23197   vec_free (value);
23198   return 0;
23199 }
23200
23201 static int
23202 unset (vat_main_t * vam)
23203 {
23204   u8 *name = 0;
23205
23206   if (unformat (vam->input, "%s", &name))
23207     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23208       errmsg ("unset: %s wasn't set", name);
23209   vec_free (name);
23210   return 0;
23211 }
23212
23213 typedef struct
23214 {
23215   u8 *name;
23216   u8 *value;
23217 } macro_sort_t;
23218
23219
23220 static int
23221 macro_sort_cmp (void *a1, void *a2)
23222 {
23223   macro_sort_t *s1 = a1;
23224   macro_sort_t *s2 = a2;
23225
23226   return strcmp ((char *) (s1->name), (char *) (s2->name));
23227 }
23228
23229 static int
23230 dump_macro_table (vat_main_t * vam)
23231 {
23232   macro_sort_t *sort_me = 0, *sm;
23233   int i;
23234   hash_pair_t *p;
23235
23236     /* *INDENT-OFF* */
23237     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23238     ({
23239       vec_add2 (sort_me, sm, 1);
23240       sm->name = (u8 *)(p->key);
23241       sm->value = (u8 *) (p->value[0]);
23242     }));
23243     /* *INDENT-ON* */
23244
23245   vec_sort_with_function (sort_me, macro_sort_cmp);
23246
23247   if (vec_len (sort_me))
23248     print (vam->ofp, "%-15s%s", "Name", "Value");
23249   else
23250     print (vam->ofp, "The macro table is empty...");
23251
23252   for (i = 0; i < vec_len (sort_me); i++)
23253     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23254   return 0;
23255 }
23256
23257 static int
23258 dump_node_table (vat_main_t * vam)
23259 {
23260   int i, j;
23261   vlib_node_t *node, *next_node;
23262
23263   if (vec_len (vam->graph_nodes) == 0)
23264     {
23265       print (vam->ofp, "Node table empty, issue get_node_graph...");
23266       return 0;
23267     }
23268
23269   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23270     {
23271       node = vam->graph_nodes[0][i];
23272       print (vam->ofp, "[%d] %s", i, node->name);
23273       for (j = 0; j < vec_len (node->next_nodes); j++)
23274         {
23275           if (node->next_nodes[j] != ~0)
23276             {
23277               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23278               print (vam->ofp, "  [%d] %s", j, next_node->name);
23279             }
23280         }
23281     }
23282   return 0;
23283 }
23284
23285 static int
23286 value_sort_cmp (void *a1, void *a2)
23287 {
23288   name_sort_t *n1 = a1;
23289   name_sort_t *n2 = a2;
23290
23291   if (n1->value < n2->value)
23292     return -1;
23293   if (n1->value > n2->value)
23294     return 1;
23295   return 0;
23296 }
23297
23298
23299 static int
23300 dump_msg_api_table (vat_main_t * vam)
23301 {
23302   api_main_t *am = &api_main;
23303   name_sort_t *nses = 0, *ns;
23304   hash_pair_t *hp;
23305   int i;
23306
23307   /* *INDENT-OFF* */
23308   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23309   ({
23310     vec_add2 (nses, ns, 1);
23311     ns->name = (u8 *)(hp->key);
23312     ns->value = (u32) hp->value[0];
23313   }));
23314   /* *INDENT-ON* */
23315
23316   vec_sort_with_function (nses, value_sort_cmp);
23317
23318   for (i = 0; i < vec_len (nses); i++)
23319     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23320   vec_free (nses);
23321   return 0;
23322 }
23323
23324 static int
23325 get_msg_id (vat_main_t * vam)
23326 {
23327   u8 *name_and_crc;
23328   u32 message_index;
23329
23330   if (unformat (vam->input, "%s", &name_and_crc))
23331     {
23332       message_index = vl_msg_api_get_msg_index (name_and_crc);
23333       if (message_index == ~0)
23334         {
23335           print (vam->ofp, " '%s' not found", name_and_crc);
23336           return 0;
23337         }
23338       print (vam->ofp, " '%s' has message index %d",
23339              name_and_crc, message_index);
23340       return 0;
23341     }
23342   errmsg ("name_and_crc required...");
23343   return 0;
23344 }
23345
23346 static int
23347 search_node_table (vat_main_t * vam)
23348 {
23349   unformat_input_t *line_input = vam->input;
23350   u8 *node_to_find;
23351   int j;
23352   vlib_node_t *node, *next_node;
23353   uword *p;
23354
23355   if (vam->graph_node_index_by_name == 0)
23356     {
23357       print (vam->ofp, "Node table empty, issue get_node_graph...");
23358       return 0;
23359     }
23360
23361   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23362     {
23363       if (unformat (line_input, "%s", &node_to_find))
23364         {
23365           vec_add1 (node_to_find, 0);
23366           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23367           if (p == 0)
23368             {
23369               print (vam->ofp, "%s not found...", node_to_find);
23370               goto out;
23371             }
23372           node = vam->graph_nodes[0][p[0]];
23373           print (vam->ofp, "[%d] %s", p[0], node->name);
23374           for (j = 0; j < vec_len (node->next_nodes); j++)
23375             {
23376               if (node->next_nodes[j] != ~0)
23377                 {
23378                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23379                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23380                 }
23381             }
23382         }
23383
23384       else
23385         {
23386           clib_warning ("parse error '%U'", format_unformat_error,
23387                         line_input);
23388           return -99;
23389         }
23390
23391     out:
23392       vec_free (node_to_find);
23393
23394     }
23395
23396   return 0;
23397 }
23398
23399
23400 static int
23401 script (vat_main_t * vam)
23402 {
23403 #if (VPP_API_TEST_BUILTIN==0)
23404   u8 *s = 0;
23405   char *save_current_file;
23406   unformat_input_t save_input;
23407   jmp_buf save_jump_buf;
23408   u32 save_line_number;
23409
23410   FILE *new_fp, *save_ifp;
23411
23412   if (unformat (vam->input, "%s", &s))
23413     {
23414       new_fp = fopen ((char *) s, "r");
23415       if (new_fp == 0)
23416         {
23417           errmsg ("Couldn't open script file %s", s);
23418           vec_free (s);
23419           return -99;
23420         }
23421     }
23422   else
23423     {
23424       errmsg ("Missing script name");
23425       return -99;
23426     }
23427
23428   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23429   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23430   save_ifp = vam->ifp;
23431   save_line_number = vam->input_line_number;
23432   save_current_file = (char *) vam->current_file;
23433
23434   vam->input_line_number = 0;
23435   vam->ifp = new_fp;
23436   vam->current_file = s;
23437   do_one_file (vam);
23438
23439   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23440   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23441   vam->ifp = save_ifp;
23442   vam->input_line_number = save_line_number;
23443   vam->current_file = (u8 *) save_current_file;
23444   vec_free (s);
23445
23446   return 0;
23447 #else
23448   clib_warning ("use the exec command...");
23449   return -99;
23450 #endif
23451 }
23452
23453 static int
23454 echo (vat_main_t * vam)
23455 {
23456   print (vam->ofp, "%v", vam->input->buffer);
23457   return 0;
23458 }
23459
23460 /* List of API message constructors, CLI names map to api_xxx */
23461 #define foreach_vpe_api_msg                                             \
23462 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23463 _(sw_interface_dump,"")                                                 \
23464 _(sw_interface_set_flags,                                               \
23465   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23466 _(sw_interface_add_del_address,                                         \
23467   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23468 _(sw_interface_set_rx_mode,                                             \
23469   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23470 _(sw_interface_set_rx_placement,                                        \
23471   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23472 _(sw_interface_set_table,                                               \
23473   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23474 _(sw_interface_set_mpls_enable,                                         \
23475   "<intfc> | sw_if_index [disable | dis]")                              \
23476 _(sw_interface_set_vpath,                                               \
23477   "<intfc> | sw_if_index <id> enable | disable")                        \
23478 _(sw_interface_set_vxlan_bypass,                                        \
23479   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23480 _(sw_interface_set_geneve_bypass,                                       \
23481   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23482 _(sw_interface_set_l2_xconnect,                                         \
23483   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23484   "enable | disable")                                                   \
23485 _(sw_interface_set_l2_bridge,                                           \
23486   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23487   "[shg <split-horizon-group>] [bvi]\n"                                 \
23488   "enable | disable")                                                   \
23489 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23490 _(bridge_domain_add_del,                                                \
23491   "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") \
23492 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23493 _(l2fib_add_del,                                                        \
23494   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23495 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23496 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23497 _(l2_flags,                                                             \
23498   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23499 _(bridge_flags,                                                         \
23500   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23501 _(tap_connect,                                                          \
23502   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23503 _(tap_modify,                                                           \
23504   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23505 _(tap_delete,                                                           \
23506   "<vpp-if-name> | sw_if_index <id>")                                   \
23507 _(sw_interface_tap_dump, "")                                            \
23508 _(tap_create_v2,                                                        \
23509   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23510 _(tap_delete_v2,                                                        \
23511   "<vpp-if-name> | sw_if_index <id>")                                   \
23512 _(sw_interface_tap_v2_dump, "")                                         \
23513 _(bond_create,                                                          \
23514   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23515   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23516 _(bond_delete,                                                          \
23517   "<vpp-if-name> | sw_if_index <id>")                                   \
23518 _(bond_enslave,                                                         \
23519   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23520 _(bond_detach_slave,                                                    \
23521   "sw_if_index <n>")                                                    \
23522 _(sw_interface_bond_dump, "")                                           \
23523 _(sw_interface_slave_dump,                                              \
23524   "<vpp-if-name> | sw_if_index <id>")                                   \
23525 _(ip_table_add_del,                                                     \
23526   "table <n> [ipv6] [add | del]\n")                                     \
23527 _(ip_add_del_route,                                                     \
23528   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23529   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23530   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23531   "[multipath] [count <n>]")                                            \
23532 _(ip_mroute_add_del,                                                    \
23533   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23534   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23535 _(mpls_table_add_del,                                                   \
23536   "table <n> [add | del]\n")                                            \
23537 _(mpls_route_add_del,                                                   \
23538   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23539   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23540   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23541   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23542   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23543 _(mpls_ip_bind_unbind,                                                  \
23544   "<label> <addr/len>")                                                 \
23545 _(mpls_tunnel_add_del,                                                  \
23546   " via <addr> [table-id <n>]\n"                                        \
23547   "sw_if_index <id>] [l2]  [del]")                                      \
23548 _(sr_mpls_policy_add,                                                   \
23549   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23550 _(sr_mpls_policy_del,                                                   \
23551   "bsid <id>")                                                          \
23552 _(bier_table_add_del,                                                   \
23553   "<label> <sub-domain> <set> <bsl> [del]")                             \
23554 _(bier_route_add_del,                                                   \
23555   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23556   "[<intfc> | sw_if_index <id>]"                                        \
23557   "[weight <n>] [del] [multipath]")                                     \
23558 _(proxy_arp_add_del,                                                    \
23559   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23560 _(proxy_arp_intfc_enable_disable,                                       \
23561   "<intfc> | sw_if_index <id> enable | disable")                        \
23562 _(sw_interface_set_unnumbered,                                          \
23563   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23564 _(ip_neighbor_add_del,                                                  \
23565   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23566   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23567 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23568 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23569   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23570   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23571   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23572 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23573 _(reset_fib, "vrf <n> [ipv6]")                                          \
23574 _(dhcp_proxy_config,                                                    \
23575   "svr <v46-address> src <v46-address>\n"                               \
23576    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23577 _(dhcp_proxy_set_vss,                                                   \
23578   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23579 _(dhcp_proxy_dump, "ip6")                                               \
23580 _(dhcp_client_config,                                                   \
23581   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23582 _(set_ip_flow_hash,                                                     \
23583   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23584 _(sw_interface_ip6_enable_disable,                                      \
23585   "<intfc> | sw_if_index <id> enable | disable")                        \
23586 _(sw_interface_ip6_set_link_local_address,                              \
23587   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23588 _(ip6nd_proxy_add_del,                                                  \
23589   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23590 _(ip6nd_proxy_dump, "")                                                 \
23591 _(sw_interface_ip6nd_ra_prefix,                                         \
23592   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23593   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23594   "[nolink] [isno]")                                                    \
23595 _(sw_interface_ip6nd_ra_config,                                         \
23596   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23597   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23598   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23599 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23600 _(l2_patch_add_del,                                                     \
23601   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23602   "enable | disable")                                                   \
23603 _(sr_localsid_add_del,                                                  \
23604   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23605   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23606 _(classify_add_del_table,                                               \
23607   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23608   " [del] [del-chain] mask <mask-value>\n"                              \
23609   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23610   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23611 _(classify_add_del_session,                                             \
23612   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23613   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23614   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23615   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23616 _(classify_set_interface_ip_table,                                      \
23617   "<intfc> | sw_if_index <nn> table <nn>")                              \
23618 _(classify_set_interface_l2_tables,                                     \
23619   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23620   "  [other-table <nn>]")                                               \
23621 _(get_node_index, "node <node-name")                                    \
23622 _(add_node_next, "node <node-name> next <next-node-name>")              \
23623 _(l2tpv3_create_tunnel,                                                 \
23624   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23625   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23626   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23627 _(l2tpv3_set_tunnel_cookies,                                            \
23628   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23629   "[new_remote_cookie <nn>]\n")                                         \
23630 _(l2tpv3_interface_enable_disable,                                      \
23631   "<intfc> | sw_if_index <nn> enable | disable")                        \
23632 _(l2tpv3_set_lookup_key,                                                \
23633   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23634 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23635 _(vxlan_offload_rx,                                                     \
23636   "hw { <interface name> | hw_if_index <nn>} "                          \
23637   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23638 _(vxlan_add_del_tunnel,                                                 \
23639   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23640   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23641   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23642 _(geneve_add_del_tunnel,                                                \
23643   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23644   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23645   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23646 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23647 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23648 _(gre_add_del_tunnel,                                                   \
23649   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23650   "[teb | erspan <session-id>] [del]")                                  \
23651 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23652 _(l2_fib_clear_table, "")                                               \
23653 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23654 _(l2_interface_vlan_tag_rewrite,                                        \
23655   "<intfc> | sw_if_index <nn> \n"                                       \
23656   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23657   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23658 _(create_vhost_user_if,                                                 \
23659         "socket <filename> [server] [renumber <dev_instance>] "         \
23660         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23661         "[mac <mac_address>]")                                          \
23662 _(modify_vhost_user_if,                                                 \
23663         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23664         "[server] [renumber <dev_instance>]")                           \
23665 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23666 _(sw_interface_vhost_user_dump, "")                                     \
23667 _(show_version, "")                                                     \
23668 _(vxlan_gpe_add_del_tunnel,                                             \
23669   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23670   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23671   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23672   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23673 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23674 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23675 _(interface_name_renumber,                                              \
23676   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23677 _(input_acl_set_interface,                                              \
23678   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23679   "  [l2-table <nn>] [del]")                                            \
23680 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23681 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23682   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23683 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23684 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23685 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23686 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23687 _(ip_dump, "ipv4 | ipv6")                                               \
23688 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23689 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23690   "  spid_id <n> ")                                                     \
23691 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23692   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23693   "  integ_alg <alg> integ_key <hex>")                                  \
23694 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23695   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23696   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23697   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23698 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23699 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23700   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23701   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23702   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23703   "  [instance <n>]")     \
23704 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23705 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23706   "  <alg> <hex>\n")                                                    \
23707 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23708 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23709 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23710   "(auth_data 0x<data> | auth_data <data>)")                            \
23711 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23712   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23713 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23714   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23715   "(local|remote)")                                                     \
23716 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23717 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23718 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23719 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23720 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23721 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23722 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23723 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23724 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23725 _(delete_loopback,"sw_if_index <nn>")                                   \
23726 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23727 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23728 _(want_interface_events,  "enable|disable")                             \
23729 _(want_stats,"enable|disable")                                          \
23730 _(get_first_msg_id, "client <name>")                                    \
23731 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23732 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23733   "fib-id <nn> [ip4][ip6][default]")                                    \
23734 _(get_node_graph, " ")                                                  \
23735 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23736 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23737 _(ioam_disable, "")                                                     \
23738 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23739                             " sw_if_index <sw_if_index> p <priority> "  \
23740                             "w <weight>] [del]")                        \
23741 _(one_add_del_locator, "locator-set <locator_name> "                    \
23742                         "iface <intf> | sw_if_index <sw_if_index> "     \
23743                         "p <priority> w <weight> [del]")                \
23744 _(one_add_del_local_eid,"vni <vni> eid "                                \
23745                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23746                          "locator-set <locator_name> [del]"             \
23747                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23748 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23749 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23750 _(one_enable_disable, "enable|disable")                                 \
23751 _(one_map_register_enable_disable, "enable|disable")                    \
23752 _(one_map_register_fallback_threshold, "<value>")                       \
23753 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23754 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23755                                "[seid <seid>] "                         \
23756                                "rloc <locator> p <prio> "               \
23757                                "w <weight> [rloc <loc> ... ] "          \
23758                                "action <action> [del-all]")             \
23759 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23760                           "<local-eid>")                                \
23761 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23762 _(one_use_petr, "ip-address> | disable")                                \
23763 _(one_map_request_mode, "src-dst|dst-only")                             \
23764 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23765 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23766 _(one_locator_set_dump, "[local | remote]")                             \
23767 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23768 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23769                        "[local] | [remote]")                            \
23770 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23771 _(one_ndp_bd_get, "")                                                   \
23772 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23773 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23774 _(one_l2_arp_bd_get, "")                                                \
23775 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23776 _(one_stats_enable_disable, "enable|disalbe")                           \
23777 _(show_one_stats_enable_disable, "")                                    \
23778 _(one_eid_table_vni_dump, "")                                           \
23779 _(one_eid_table_map_dump, "l2|l3")                                      \
23780 _(one_map_resolver_dump, "")                                            \
23781 _(one_map_server_dump, "")                                              \
23782 _(one_adjacencies_get, "vni <vni>")                                     \
23783 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23784 _(show_one_rloc_probe_state, "")                                        \
23785 _(show_one_map_register_state, "")                                      \
23786 _(show_one_status, "")                                                  \
23787 _(one_stats_dump, "")                                                   \
23788 _(one_stats_flush, "")                                                  \
23789 _(one_get_map_request_itr_rlocs, "")                                    \
23790 _(one_map_register_set_ttl, "<ttl>")                                    \
23791 _(one_set_transport_protocol, "udp|api")                                \
23792 _(one_get_transport_protocol, "")                                       \
23793 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23794 _(one_show_xtr_mode, "")                                                \
23795 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23796 _(one_show_pitr_mode, "")                                               \
23797 _(one_enable_disable_petr_mode, "enable|disable")                       \
23798 _(one_show_petr_mode, "")                                               \
23799 _(show_one_nsh_mapping, "")                                             \
23800 _(show_one_pitr, "")                                                    \
23801 _(show_one_use_petr, "")                                                \
23802 _(show_one_map_request_mode, "")                                        \
23803 _(show_one_map_register_ttl, "")                                        \
23804 _(show_one_map_register_fallback_threshold, "")                         \
23805 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23806                             " sw_if_index <sw_if_index> p <priority> "  \
23807                             "w <weight>] [del]")                        \
23808 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23809                         "iface <intf> | sw_if_index <sw_if_index> "     \
23810                         "p <priority> w <weight> [del]")                \
23811 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23812                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23813                          "locator-set <locator_name> [del]"             \
23814                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23815 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23816 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23817 _(lisp_enable_disable, "enable|disable")                                \
23818 _(lisp_map_register_enable_disable, "enable|disable")                   \
23819 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23820 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23821                                "[seid <seid>] "                         \
23822                                "rloc <locator> p <prio> "               \
23823                                "w <weight> [rloc <loc> ... ] "          \
23824                                "action <action> [del-all]")             \
23825 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23826                           "<local-eid>")                                \
23827 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23828 _(lisp_use_petr, "<ip-address> | disable")                              \
23829 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23830 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23831 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23832 _(lisp_locator_set_dump, "[local | remote]")                            \
23833 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23834 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23835                        "[local] | [remote]")                            \
23836 _(lisp_eid_table_vni_dump, "")                                          \
23837 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23838 _(lisp_map_resolver_dump, "")                                           \
23839 _(lisp_map_server_dump, "")                                             \
23840 _(lisp_adjacencies_get, "vni <vni>")                                    \
23841 _(gpe_fwd_entry_vnis_get, "")                                           \
23842 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23843 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23844                                 "[table <table-id>]")                   \
23845 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23846 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
23847 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
23848 _(gpe_get_encap_mode, "")                                               \
23849 _(lisp_gpe_add_del_iface, "up|down")                                    \
23850 _(lisp_gpe_enable_disable, "enable|disable")                            \
23851 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
23852   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
23853 _(show_lisp_rloc_probe_state, "")                                       \
23854 _(show_lisp_map_register_state, "")                                     \
23855 _(show_lisp_status, "")                                                 \
23856 _(lisp_get_map_request_itr_rlocs, "")                                   \
23857 _(show_lisp_pitr, "")                                                   \
23858 _(show_lisp_use_petr, "")                                               \
23859 _(show_lisp_map_request_mode, "")                                       \
23860 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
23861 _(af_packet_delete, "name <host interface name>")                       \
23862 _(af_packet_dump, "")                                                   \
23863 _(policer_add_del, "name <policer name> <params> [del]")                \
23864 _(policer_dump, "[name <policer name>]")                                \
23865 _(policer_classify_set_interface,                                       \
23866   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23867   "  [l2-table <nn>] [del]")                                            \
23868 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
23869 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
23870     "[master|slave]")                                                   \
23871 _(netmap_delete, "name <interface name>")                               \
23872 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
23873 _(mpls_fib_dump, "")                                                    \
23874 _(classify_table_ids, "")                                               \
23875 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
23876 _(classify_table_info, "table_id <nn>")                                 \
23877 _(classify_session_dump, "table_id <nn>")                               \
23878 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
23879     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
23880     "[template_interval <nn>] [udp_checksum]")                          \
23881 _(ipfix_exporter_dump, "")                                              \
23882 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
23883 _(ipfix_classify_stream_dump, "")                                       \
23884 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
23885 _(ipfix_classify_table_dump, "")                                        \
23886 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
23887 _(sw_interface_span_dump, "[l2]")                                           \
23888 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
23889 _(pg_create_interface, "if_id <nn>")                                    \
23890 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
23891 _(pg_enable_disable, "[stream <id>] disable")                           \
23892 _(ip_source_and_port_range_check_add_del,                               \
23893   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
23894 _(ip_source_and_port_range_check_interface_add_del,                     \
23895   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
23896   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
23897 _(ipsec_gre_add_del_tunnel,                                             \
23898   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
23899 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
23900 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
23901 _(l2_interface_pbb_tag_rewrite,                                         \
23902   "<intfc> | sw_if_index <nn> \n"                                       \
23903   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
23904   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
23905 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
23906 _(flow_classify_set_interface,                                          \
23907   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
23908 _(flow_classify_dump, "type [ip4|ip6]")                                 \
23909 _(ip_fib_dump, "")                                                      \
23910 _(ip_mfib_dump, "")                                                     \
23911 _(ip6_fib_dump, "")                                                     \
23912 _(ip6_mfib_dump, "")                                                    \
23913 _(feature_enable_disable, "arc_name <arc_name> "                        \
23914   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
23915 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
23916 "[disable]")                                                            \
23917 _(l2_xconnect_dump, "")                                                 \
23918 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
23919 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
23920 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
23921 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
23922 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
23923 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
23924 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
23925   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
23926 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
23927 _(sock_init_shm, "size <nnn>")                                          \
23928 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
23929 _(dns_enable_disable, "[enable][disable]")                              \
23930 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23931 _(dns_resolve_name, "<hostname>")                                       \
23932 _(dns_resolve_ip, "<ip4|ip6>")                                          \
23933 _(dns_name_server_add_del, "<ip-address> [del]")                        \
23934 _(dns_resolve_name, "<hostname>")                                       \
23935 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
23936   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
23937 _(session_rules_dump, "")                                               \
23938 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
23939 _(output_acl_set_interface,                                             \
23940   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23941   "  [l2-table <nn>] [del]")                                            \
23942 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
23943
23944 /* List of command functions, CLI names map directly to functions */
23945 #define foreach_cli_function                                    \
23946 _(comment, "usage: comment <ignore-rest-of-line>")              \
23947 _(dump_interface_table, "usage: dump_interface_table")          \
23948 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
23949 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
23950 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
23951 _(dump_stats_table, "usage: dump_stats_table")                  \
23952 _(dump_macro_table, "usage: dump_macro_table ")                 \
23953 _(dump_node_table, "usage: dump_node_table")                    \
23954 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
23955 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
23956 _(echo, "usage: echo <message>")                                \
23957 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
23958 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
23959 _(help, "usage: help")                                          \
23960 _(q, "usage: quit")                                             \
23961 _(quit, "usage: quit")                                          \
23962 _(search_node_table, "usage: search_node_table <name>...")      \
23963 _(set, "usage: set <variable-name> <value>")                    \
23964 _(script, "usage: script <file-name>")                          \
23965 _(statseg, "usage: statseg");                                   \
23966 _(unset, "usage: unset <variable-name>")
23967
23968 #define _(N,n)                                  \
23969     static void vl_api_##n##_t_handler_uni      \
23970     (vl_api_##n##_t * mp)                       \
23971     {                                           \
23972         vat_main_t * vam = &vat_main;           \
23973         if (vam->json_output) {                 \
23974             vl_api_##n##_t_handler_json(mp);    \
23975         } else {                                \
23976             vl_api_##n##_t_handler(mp);         \
23977         }                                       \
23978     }
23979 foreach_vpe_api_reply_msg;
23980 #if VPP_API_TEST_BUILTIN == 0
23981 foreach_standalone_reply_msg;
23982 #endif
23983 #undef _
23984
23985 void
23986 vat_api_hookup (vat_main_t * vam)
23987 {
23988 #define _(N,n)                                                  \
23989     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
23990                            vl_api_##n##_t_handler_uni,          \
23991                            vl_noop_handler,                     \
23992                            vl_api_##n##_t_endian,               \
23993                            vl_api_##n##_t_print,                \
23994                            sizeof(vl_api_##n##_t), 1);
23995   foreach_vpe_api_reply_msg;
23996 #if VPP_API_TEST_BUILTIN == 0
23997   foreach_standalone_reply_msg;
23998 #endif
23999 #undef _
24000
24001 #if (VPP_API_TEST_BUILTIN==0)
24002   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24003
24004   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24005
24006   vam->function_by_name = hash_create_string (0, sizeof (uword));
24007
24008   vam->help_by_name = hash_create_string (0, sizeof (uword));
24009 #endif
24010
24011   /* API messages we can send */
24012 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24013   foreach_vpe_api_msg;
24014 #undef _
24015
24016   /* Help strings */
24017 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24018   foreach_vpe_api_msg;
24019 #undef _
24020
24021   /* CLI functions */
24022 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24023   foreach_cli_function;
24024 #undef _
24025
24026   /* Help strings */
24027 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24028   foreach_cli_function;
24029 #undef _
24030 }
24031
24032 #if VPP_API_TEST_BUILTIN
24033 static clib_error_t *
24034 vat_api_hookup_shim (vlib_main_t * vm)
24035 {
24036   vat_api_hookup (&vat_main);
24037   return 0;
24038 }
24039
24040 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24041 #endif
24042
24043 /*
24044  * fd.io coding-style-patch-verification: ON
24045  *
24046  * Local Variables:
24047  * eval: (c-set-style "gnu")
24048  * End:
24049  */