vat: fix coverity warning for show_threads
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/ip/ip_neighbor.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51 #include <vnet/mfib/mfib_types.h>
52 #include <vnet/dhcp/dhcp_proxy.h>
53 #include <vnet/bonding/node.h>
54 #include <vnet/qos/qos_types.h>
55 #include "vat/json_format.h"
56
57 #include <inttypes.h>
58 #include <sys/stat.h>
59
60 #define vl_typedefs             /* define message structures */
61 #include <vpp/api/vpe_all_api_h.h>
62 #undef vl_typedefs
63
64 /* declare message handlers for each api */
65
66 #define vl_endianfun            /* define message structures */
67 #include <vpp/api/vpe_all_api_h.h>
68 #undef vl_endianfun
69
70 /* instantiate all the print functions we know about */
71 #define vl_print(handle, ...)
72 #define vl_printfun
73 #include <vpp/api/vpe_all_api_h.h>
74 #undef vl_printfun
75
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
78
79 #if VPP_API_TEST_BUILTIN == 0
80 #include <netdb.h>
81
82 u32
83 vl (void *p)
84 {
85   return vec_len (p);
86 }
87
88 int
89 vat_socket_connect (vat_main_t * vam)
90 {
91   vam->socket_client_main = &socket_client_main;
92   return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
93                                    0 /* default socket rx, tx buffer */ );
94 }
95 #else /* vpp built-in case, we don't do sockets... */
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   return 0;
100 }
101
102 int
103 vl_socket_client_read (int wait)
104 {
105   return -1;
106 };
107
108 int
109 vl_socket_client_write ()
110 {
111   return -1;
112 };
113
114 void *
115 vl_socket_client_msg_alloc (int nbytes)
116 {
117   return 0;
118 }
119 #endif
120
121
122 f64
123 vat_time_now (vat_main_t * vam)
124 {
125 #if VPP_API_TEST_BUILTIN
126   return vlib_time_now (vam->vlib_main);
127 #else
128   return clib_time_now (&vam->clib_time);
129 #endif
130 }
131
132 void
133 errmsg (char *fmt, ...)
134 {
135   vat_main_t *vam = &vat_main;
136   va_list va;
137   u8 *s;
138
139   va_start (va, fmt);
140   s = va_format (0, fmt, &va);
141   va_end (va);
142
143   vec_add1 (s, 0);
144
145 #if VPP_API_TEST_BUILTIN
146   vlib_cli_output (vam->vlib_main, (char *) s);
147 #else
148   {
149     if (vam->ifp != stdin)
150       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
151                vam->input_line_number);
152     fformat (vam->ofp, (char *) s);
153     fflush (vam->ofp);
154   }
155 #endif
156
157   vec_free (s);
158 }
159
160 #if VPP_API_TEST_BUILTIN == 0
161 static uword
162 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
163 {
164   vat_main_t *vam = va_arg (*args, vat_main_t *);
165   u32 *result = va_arg (*args, u32 *);
166   u8 *if_name;
167   uword *p;
168
169   if (!unformat (input, "%s", &if_name))
170     return 0;
171
172   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
173   if (p == 0)
174     return 0;
175   *result = p[0];
176   return 1;
177 }
178
179 static uword
180 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
181 {
182   return 0;
183 }
184
185 /* Parse an IP4 address %d.%d.%d.%d. */
186 uword
187 unformat_ip4_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   unsigned a[4];
191
192   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
193     return 0;
194
195   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
196     return 0;
197
198   result[0] = a[0];
199   result[1] = a[1];
200   result[2] = a[2];
201   result[3] = a[3];
202
203   return 1;
204 }
205
206 uword
207 unformat_ethernet_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   u32 i, a[6];
211
212   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
213                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
214     return 0;
215
216   /* Check range. */
217   for (i = 0; i < 6; i++)
218     if (a[i] >= (1 << 8))
219       return 0;
220
221   for (i = 0; i < 6; i++)
222     result[i] = a[i];
223
224   return 1;
225 }
226
227 /* Returns ethernet type as an int in host byte order. */
228 uword
229 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
230                                         va_list * args)
231 {
232   u16 *result = va_arg (*args, u16 *);
233   int type;
234
235   /* Numeric type. */
236   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
237     {
238       if (type >= (1 << 16))
239         return 0;
240       *result = type;
241       return 1;
242     }
243   return 0;
244 }
245
246 /* Parse an IP6 address. */
247 uword
248 unformat_ip6_address (unformat_input_t * input, va_list * args)
249 {
250   ip6_address_t *result = va_arg (*args, ip6_address_t *);
251   u16 hex_quads[8];
252   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
253   uword c, n_colon, double_colon_index;
254
255   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
256   double_colon_index = ARRAY_LEN (hex_quads);
257   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
258     {
259       hex_digit = 16;
260       if (c >= '0' && c <= '9')
261         hex_digit = c - '0';
262       else if (c >= 'a' && c <= 'f')
263         hex_digit = c + 10 - 'a';
264       else if (c >= 'A' && c <= 'F')
265         hex_digit = c + 10 - 'A';
266       else if (c == ':' && n_colon < 2)
267         n_colon++;
268       else
269         {
270           unformat_put_input (input);
271           break;
272         }
273
274       /* Too many hex quads. */
275       if (n_hex_quads >= ARRAY_LEN (hex_quads))
276         return 0;
277
278       if (hex_digit < 16)
279         {
280           hex_quad = (hex_quad << 4) | hex_digit;
281
282           /* Hex quad must fit in 16 bits. */
283           if (n_hex_digits >= 4)
284             return 0;
285
286           n_colon = 0;
287           n_hex_digits++;
288         }
289
290       /* Save position of :: */
291       if (n_colon == 2)
292         {
293           /* More than one :: ? */
294           if (double_colon_index < ARRAY_LEN (hex_quads))
295             return 0;
296           double_colon_index = n_hex_quads;
297         }
298
299       if (n_colon > 0 && n_hex_digits > 0)
300         {
301           hex_quads[n_hex_quads++] = hex_quad;
302           hex_quad = 0;
303           n_hex_digits = 0;
304         }
305     }
306
307   if (n_hex_digits > 0)
308     hex_quads[n_hex_quads++] = hex_quad;
309
310   {
311     word i;
312
313     /* Expand :: to appropriate number of zero hex quads. */
314     if (double_colon_index < ARRAY_LEN (hex_quads))
315       {
316         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
317
318         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
319           hex_quads[n_zero + i] = hex_quads[i];
320
321         for (i = 0; i < n_zero; i++)
322           hex_quads[double_colon_index + i] = 0;
323
324         n_hex_quads = ARRAY_LEN (hex_quads);
325       }
326
327     /* Too few hex quads given. */
328     if (n_hex_quads < ARRAY_LEN (hex_quads))
329       return 0;
330
331     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
332       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
333
334     return 1;
335   }
336 }
337
338 uword
339 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
340 {
341   u32 *r = va_arg (*args, u32 *);
342
343   if (0);
344 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
345   foreach_ipsec_policy_action
346 #undef _
347     else
348     return 0;
349   return 1;
350 }
351
352 uword
353 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
354 {
355   u32 *r = va_arg (*args, u32 *);
356
357   if (0);
358 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
359   foreach_ipsec_crypto_alg
360 #undef _
361     else
362     return 0;
363   return 1;
364 }
365
366 u8 *
367 format_ipsec_crypto_alg (u8 * s, va_list * args)
368 {
369   u32 i = va_arg (*args, u32);
370   u8 *t = 0;
371
372   switch (i)
373     {
374 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
375       foreach_ipsec_crypto_alg
376 #undef _
377     default:
378       return format (s, "unknown");
379     }
380   return format (s, "%s", t);
381 }
382
383 uword
384 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
385 {
386   u32 *r = va_arg (*args, u32 *);
387
388   if (0);
389 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
390   foreach_ipsec_integ_alg
391 #undef _
392     else
393     return 0;
394   return 1;
395 }
396
397 u8 *
398 format_ipsec_integ_alg (u8 * s, va_list * args)
399 {
400   u32 i = va_arg (*args, u32);
401   u8 *t = 0;
402
403   switch (i)
404     {
405 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
406       foreach_ipsec_integ_alg
407 #undef _
408     default:
409       return format (s, "unknown");
410     }
411   return format (s, "%s", t);
412 }
413
414 uword
415 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
416 {
417   u32 *r = va_arg (*args, u32 *);
418
419   if (0);
420 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
421   foreach_ikev2_auth_method
422 #undef _
423     else
424     return 0;
425   return 1;
426 }
427
428 uword
429 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
430 {
431   u32 *r = va_arg (*args, u32 *);
432
433   if (0);
434 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
435   foreach_ikev2_id_type
436 #undef _
437     else
438     return 0;
439   return 1;
440 }
441 #else /* VPP_API_TEST_BUILTIN == 1 */
442 static uword
443 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
444 {
445   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
446   vnet_main_t *vnm = vnet_get_main ();
447   u32 *result = va_arg (*args, u32 *);
448
449   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
450 }
451
452 static uword
453 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
454 {
455   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
456   vnet_main_t *vnm = vnet_get_main ();
457   u32 *result = va_arg (*args, u32 *);
458
459   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
460 }
461
462 #endif /* VPP_API_TEST_BUILTIN */
463
464 static uword
465 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
466 {
467   u8 *r = va_arg (*args, u8 *);
468
469   if (unformat (input, "kbps"))
470     *r = SSE2_QOS_RATE_KBPS;
471   else if (unformat (input, "pps"))
472     *r = SSE2_QOS_RATE_PPS;
473   else
474     return 0;
475   return 1;
476 }
477
478 static uword
479 unformat_policer_round_type (unformat_input_t * input, va_list * args)
480 {
481   u8 *r = va_arg (*args, u8 *);
482
483   if (unformat (input, "closest"))
484     *r = SSE2_QOS_ROUND_TO_CLOSEST;
485   else if (unformat (input, "up"))
486     *r = SSE2_QOS_ROUND_TO_UP;
487   else if (unformat (input, "down"))
488     *r = SSE2_QOS_ROUND_TO_DOWN;
489   else
490     return 0;
491   return 1;
492 }
493
494 static uword
495 unformat_policer_type (unformat_input_t * input, va_list * args)
496 {
497   u8 *r = va_arg (*args, u8 *);
498
499   if (unformat (input, "1r2c"))
500     *r = SSE2_QOS_POLICER_TYPE_1R2C;
501   else if (unformat (input, "1r3c"))
502     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
503   else if (unformat (input, "2r3c-2698"))
504     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
505   else if (unformat (input, "2r3c-4115"))
506     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
507   else if (unformat (input, "2r3c-mef5cf1"))
508     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
509   else
510     return 0;
511   return 1;
512 }
513
514 static uword
515 unformat_dscp (unformat_input_t * input, va_list * va)
516 {
517   u8 *r = va_arg (*va, u8 *);
518
519   if (0);
520 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
521   foreach_vnet_dscp
522 #undef _
523     else
524     return 0;
525   return 1;
526 }
527
528 static uword
529 unformat_policer_action_type (unformat_input_t * input, va_list * va)
530 {
531   sse2_qos_pol_action_params_st *a
532     = va_arg (*va, sse2_qos_pol_action_params_st *);
533
534   if (unformat (input, "drop"))
535     a->action_type = SSE2_QOS_ACTION_DROP;
536   else if (unformat (input, "transmit"))
537     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
538   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
539     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
540   else
541     return 0;
542   return 1;
543 }
544
545 static uword
546 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
547 {
548   u32 *r = va_arg (*va, u32 *);
549   u32 tid;
550
551   if (unformat (input, "ip4"))
552     tid = POLICER_CLASSIFY_TABLE_IP4;
553   else if (unformat (input, "ip6"))
554     tid = POLICER_CLASSIFY_TABLE_IP6;
555   else if (unformat (input, "l2"))
556     tid = POLICER_CLASSIFY_TABLE_L2;
557   else
558     return 0;
559
560   *r = tid;
561   return 1;
562 }
563
564 static uword
565 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
566 {
567   u32 *r = va_arg (*va, u32 *);
568   u32 tid;
569
570   if (unformat (input, "ip4"))
571     tid = FLOW_CLASSIFY_TABLE_IP4;
572   else if (unformat (input, "ip6"))
573     tid = FLOW_CLASSIFY_TABLE_IP6;
574   else
575     return 0;
576
577   *r = tid;
578   return 1;
579 }
580
581 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
582 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
583 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
584 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
585
586 #if (VPP_API_TEST_BUILTIN==0)
587 uword
588 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
589 {
590   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
591   mfib_itf_attribute_t attr;
592
593   old = *iflags;
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_long_names[attr]))
597       *iflags |= (1 << attr);
598   }
599   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
600   {
601     if (unformat (input, mfib_itf_flag_names[attr]))
602       *iflags |= (1 << attr);
603   }
604
605   return (old == *iflags ? 0 : 1);
606 }
607
608 uword
609 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
610 {
611   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
612   mfib_entry_attribute_t attr;
613
614   old = *eflags;
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_long_names[attr]))
618       *eflags |= (1 << attr);
619   }
620   FOR_EACH_MFIB_ATTRIBUTE (attr)
621   {
622     if (unformat (input, mfib_flag_names[attr]))
623       *eflags |= (1 << attr);
624   }
625
626   return (old == *eflags ? 0 : 1);
627 }
628
629 u8 *
630 format_ip4_address (u8 * s, va_list * args)
631 {
632   u8 *a = va_arg (*args, u8 *);
633   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
634 }
635
636 u8 *
637 format_ip6_address (u8 * s, va_list * args)
638 {
639   ip6_address_t *a = va_arg (*args, ip6_address_t *);
640   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
641
642   i_max_n_zero = ARRAY_LEN (a->as_u16);
643   max_n_zeros = 0;
644   i_first_zero = i_max_n_zero;
645   n_zeros = 0;
646   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
647     {
648       u32 is_zero = a->as_u16[i] == 0;
649       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
650         {
651           i_first_zero = i;
652           n_zeros = 0;
653         }
654       n_zeros += is_zero;
655       if ((!is_zero && n_zeros > max_n_zeros)
656           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
657         {
658           i_max_n_zero = i_first_zero;
659           max_n_zeros = n_zeros;
660           i_first_zero = ARRAY_LEN (a->as_u16);
661           n_zeros = 0;
662         }
663     }
664
665   last_double_colon = 0;
666   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
667     {
668       if (i == i_max_n_zero && max_n_zeros > 1)
669         {
670           s = format (s, "::");
671           i += max_n_zeros - 1;
672           last_double_colon = 1;
673         }
674       else
675         {
676           s = format (s, "%s%x",
677                       (last_double_colon || i == 0) ? "" : ":",
678                       clib_net_to_host_u16 (a->as_u16[i]));
679           last_double_colon = 0;
680         }
681     }
682
683   return s;
684 }
685
686 /* Format an IP46 address. */
687 u8 *
688 format_ip46_address (u8 * s, va_list * args)
689 {
690   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
691   ip46_type_t type = va_arg (*args, ip46_type_t);
692   int is_ip4 = 1;
693
694   switch (type)
695     {
696     case IP46_TYPE_ANY:
697       is_ip4 = ip46_address_is_ip4 (ip46);
698       break;
699     case IP46_TYPE_IP4:
700       is_ip4 = 1;
701       break;
702     case IP46_TYPE_IP6:
703       is_ip4 = 0;
704       break;
705     }
706
707   return is_ip4 ?
708     format (s, "%U", format_ip4_address, &ip46->ip4) :
709     format (s, "%U", format_ip6_address, &ip46->ip6);
710 }
711
712 u8 *
713 format_ethernet_address (u8 * s, va_list * args)
714 {
715   u8 *a = va_arg (*args, u8 *);
716
717   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
718                  a[0], a[1], a[2], a[3], a[4], a[5]);
719 }
720 #endif
721
722 static void
723 increment_v4_address (ip4_address_t * a)
724 {
725   u32 v;
726
727   v = ntohl (a->as_u32) + 1;
728   a->as_u32 = ntohl (v);
729 }
730
731 static void
732 increment_v6_address (ip6_address_t * a)
733 {
734   u64 v0, v1;
735
736   v0 = clib_net_to_host_u64 (a->as_u64[0]);
737   v1 = clib_net_to_host_u64 (a->as_u64[1]);
738
739   v1 += 1;
740   if (v1 == 0)
741     v0 += 1;
742   a->as_u64[0] = clib_net_to_host_u64 (v0);
743   a->as_u64[1] = clib_net_to_host_u64 (v1);
744 }
745
746 static void
747 increment_mac_address (u8 * mac)
748 {
749   u64 tmp = *((u64 *) mac);
750   tmp = clib_net_to_host_u64 (tmp);
751   tmp += 1 << 16;               /* skip unused (least significant) octets */
752   tmp = clib_host_to_net_u64 (tmp);
753
754   clib_memcpy (mac, &tmp, 6);
755 }
756
757 static void vl_api_create_loopback_reply_t_handler
758   (vl_api_create_loopback_reply_t * mp)
759 {
760   vat_main_t *vam = &vat_main;
761   i32 retval = ntohl (mp->retval);
762
763   vam->retval = retval;
764   vam->regenerate_interface_table = 1;
765   vam->sw_if_index = ntohl (mp->sw_if_index);
766   vam->result_ready = 1;
767 }
768
769 static void vl_api_create_loopback_reply_t_handler_json
770   (vl_api_create_loopback_reply_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   vat_json_node_t node;
774
775   vat_json_init_object (&node);
776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
777   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
778
779   vat_json_print (vam->ofp, &node);
780   vat_json_free (&node);
781   vam->retval = ntohl (mp->retval);
782   vam->result_ready = 1;
783 }
784
785 static void vl_api_create_loopback_instance_reply_t_handler
786   (vl_api_create_loopback_instance_reply_t * mp)
787 {
788   vat_main_t *vam = &vat_main;
789   i32 retval = ntohl (mp->retval);
790
791   vam->retval = retval;
792   vam->regenerate_interface_table = 1;
793   vam->sw_if_index = ntohl (mp->sw_if_index);
794   vam->result_ready = 1;
795 }
796
797 static void vl_api_create_loopback_instance_reply_t_handler_json
798   (vl_api_create_loopback_instance_reply_t * mp)
799 {
800   vat_main_t *vam = &vat_main;
801   vat_json_node_t node;
802
803   vat_json_init_object (&node);
804   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
805   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
806
807   vat_json_print (vam->ofp, &node);
808   vat_json_free (&node);
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_af_packet_create_reply_t_handler
814   (vl_api_af_packet_create_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_af_packet_create_reply_t_handler_json
826   (vl_api_af_packet_create_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_vlan_subif_reply_t_handler
843   (vl_api_create_vlan_subif_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->sw_if_index = ntohl (mp->sw_if_index);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_vlan_subif_reply_t_handler_json
855   (vl_api_create_vlan_subif_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   vat_json_node_t node;
859
860   vat_json_init_object (&node);
861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
863
864   vat_json_print (vam->ofp, &node);
865   vat_json_free (&node);
866
867   vam->retval = ntohl (mp->retval);
868   vam->result_ready = 1;
869 }
870
871 static void vl_api_create_subif_reply_t_handler
872   (vl_api_create_subif_reply_t * mp)
873 {
874   vat_main_t *vam = &vat_main;
875   i32 retval = ntohl (mp->retval);
876
877   vam->retval = retval;
878   vam->regenerate_interface_table = 1;
879   vam->sw_if_index = ntohl (mp->sw_if_index);
880   vam->result_ready = 1;
881 }
882
883 static void vl_api_create_subif_reply_t_handler_json
884   (vl_api_create_subif_reply_t * mp)
885 {
886   vat_main_t *vam = &vat_main;
887   vat_json_node_t node;
888
889   vat_json_init_object (&node);
890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
892
893   vat_json_print (vam->ofp, &node);
894   vat_json_free (&node);
895
896   vam->retval = ntohl (mp->retval);
897   vam->result_ready = 1;
898 }
899
900 static void vl_api_interface_name_renumber_reply_t_handler
901   (vl_api_interface_name_renumber_reply_t * mp)
902 {
903   vat_main_t *vam = &vat_main;
904   i32 retval = ntohl (mp->retval);
905
906   vam->retval = retval;
907   vam->regenerate_interface_table = 1;
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_interface_name_renumber_reply_t_handler_json
912   (vl_api_interface_name_renumber_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   vat_json_node_t node;
916
917   vat_json_init_object (&node);
918   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
919
920   vat_json_print (vam->ofp, &node);
921   vat_json_free (&node);
922
923   vam->retval = ntohl (mp->retval);
924   vam->result_ready = 1;
925 }
926
927 /*
928  * Special-case: build the interface table, maintain
929  * the next loopback sw_if_index vbl.
930  */
931 static void vl_api_sw_interface_details_t_handler
932   (vl_api_sw_interface_details_t * mp)
933 {
934   vat_main_t *vam = &vat_main;
935   u8 *s = format (0, "%s%c", mp->interface_name, 0);
936
937   hash_set_mem (vam->sw_if_index_by_interface_name, s,
938                 ntohl (mp->sw_if_index));
939
940   /* In sub interface case, fill the sub interface table entry */
941   if (mp->sw_if_index != mp->sup_sw_if_index)
942     {
943       sw_interface_subif_t *sub = NULL;
944
945       vec_add2 (vam->sw_if_subif_table, sub, 1);
946
947       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
948       strncpy ((char *) sub->interface_name, (char *) s,
949                vec_len (sub->interface_name));
950       sub->sw_if_index = ntohl (mp->sw_if_index);
951       sub->sub_id = ntohl (mp->sub_id);
952
953       sub->sub_dot1ad = mp->sub_dot1ad;
954       sub->sub_number_of_tags = mp->sub_number_of_tags;
955       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
956       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
957       sub->sub_exact_match = mp->sub_exact_match;
958       sub->sub_default = mp->sub_default;
959       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
960       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
961
962       /* vlan tag rewrite */
963       sub->vtr_op = ntohl (mp->vtr_op);
964       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
965       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
966       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
967     }
968 }
969
970 static void vl_api_sw_interface_details_t_handler_json
971   (vl_api_sw_interface_details_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t *node = NULL;
975
976   if (VAT_JSON_ARRAY != vam->json_tree.type)
977     {
978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
979       vat_json_init_array (&vam->json_tree);
980     }
981   node = vat_json_array_add (&vam->json_tree);
982
983   vat_json_init_object (node);
984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
985   vat_json_object_add_uint (node, "sup_sw_if_index",
986                             ntohl (mp->sup_sw_if_index));
987   vat_json_object_add_uint (node, "l2_address_length",
988                             ntohl (mp->l2_address_length));
989   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
990                              sizeof (mp->l2_address));
991   vat_json_object_add_string_copy (node, "interface_name",
992                                    mp->interface_name);
993   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
994   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
995   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
996   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
997   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
998   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
999   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
1000   vat_json_object_add_uint (node, "sub_number_of_tags",
1001                             mp->sub_number_of_tags);
1002   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1003                             ntohs (mp->sub_outer_vlan_id));
1004   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1005                             ntohs (mp->sub_inner_vlan_id));
1006   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
1007   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
1008   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
1009                             mp->sub_outer_vlan_id_any);
1010   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
1011                             mp->sub_inner_vlan_id_any);
1012   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1013   vat_json_object_add_uint (node, "vtr_push_dot1q",
1014                             ntohl (mp->vtr_push_dot1q));
1015   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1016   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1017   if (mp->sub_dot1ah)
1018     {
1019       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1020                                        format (0, "%U",
1021                                                format_ethernet_address,
1022                                                &mp->b_dmac));
1023       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1024                                        format (0, "%U",
1025                                                format_ethernet_address,
1026                                                &mp->b_smac));
1027       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1028       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1029     }
1030 }
1031
1032 #if VPP_API_TEST_BUILTIN == 0
1033 static void vl_api_sw_interface_event_t_handler
1034   (vl_api_sw_interface_event_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   if (vam->interface_event_display)
1038     errmsg ("interface flags: sw_if_index %d %s %s",
1039             ntohl (mp->sw_if_index),
1040             mp->admin_up_down ? "admin-up" : "admin-down",
1041             mp->link_up_down ? "link-up" : "link-down");
1042 }
1043 #endif
1044
1045 static void vl_api_sw_interface_event_t_handler_json
1046   (vl_api_sw_interface_event_t * mp)
1047 {
1048   /* JSON output not supported */
1049 }
1050
1051 static void
1052 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1053 {
1054   vat_main_t *vam = &vat_main;
1055   i32 retval = ntohl (mp->retval);
1056
1057   vam->retval = retval;
1058   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void
1063 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   vat_json_node_t node;
1067   api_main_t *am = &api_main;
1068   void *oldheap;
1069   u8 *reply;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "reply_in_shmem",
1074                             ntohl (mp->reply_in_shmem));
1075   /* Toss the shared-memory original... */
1076   pthread_mutex_lock (&am->vlib_rp->mutex);
1077   oldheap = svm_push_data_heap (am->vlib_rp);
1078
1079   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1080   vec_free (reply);
1081
1082   svm_pop_heap (oldheap);
1083   pthread_mutex_unlock (&am->vlib_rp->mutex);
1084
1085   vat_json_print (vam->ofp, &node);
1086   vat_json_free (&node);
1087
1088   vam->retval = ntohl (mp->retval);
1089   vam->result_ready = 1;
1090 }
1091
1092 static void
1093 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1094 {
1095   vat_main_t *vam = &vat_main;
1096   i32 retval = ntohl (mp->retval);
1097   u32 length = ntohl (mp->length);
1098
1099   vec_reset_length (vam->cmd_reply);
1100
1101   vam->retval = retval;
1102   if (retval == 0)
1103     {
1104       vec_validate (vam->cmd_reply, length);
1105       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1106       vam->cmd_reply[length] = 0;
1107     }
1108   vam->result_ready = 1;
1109 }
1110
1111 static void
1112 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   vat_json_node_t node;
1116
1117   vec_reset_length (vam->cmd_reply);
1118
1119   vat_json_init_object (&node);
1120   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1121   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1122
1123   vat_json_print (vam->ofp, &node);
1124   vat_json_free (&node);
1125
1126   vam->retval = ntohl (mp->retval);
1127   vam->result_ready = 1;
1128 }
1129
1130 static void vl_api_classify_add_del_table_reply_t_handler
1131   (vl_api_classify_add_del_table_reply_t * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134   i32 retval = ntohl (mp->retval);
1135   if (vam->async_mode)
1136     {
1137       vam->async_errors += (retval < 0);
1138     }
1139   else
1140     {
1141       vam->retval = retval;
1142       if (retval == 0 &&
1143           ((mp->new_table_index != 0xFFFFFFFF) ||
1144            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1145            (mp->match_n_vectors != 0xFFFFFFFF)))
1146         /*
1147          * Note: this is just barely thread-safe, depends on
1148          * the main thread spinning waiting for an answer...
1149          */
1150         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1151                 ntohl (mp->new_table_index),
1152                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1153       vam->result_ready = 1;
1154     }
1155 }
1156
1157 static void vl_api_classify_add_del_table_reply_t_handler_json
1158   (vl_api_classify_add_del_table_reply_t * mp)
1159 {
1160   vat_main_t *vam = &vat_main;
1161   vat_json_node_t node;
1162
1163   vat_json_init_object (&node);
1164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1165   vat_json_object_add_uint (&node, "new_table_index",
1166                             ntohl (mp->new_table_index));
1167   vat_json_object_add_uint (&node, "skip_n_vectors",
1168                             ntohl (mp->skip_n_vectors));
1169   vat_json_object_add_uint (&node, "match_n_vectors",
1170                             ntohl (mp->match_n_vectors));
1171
1172   vat_json_print (vam->ofp, &node);
1173   vat_json_free (&node);
1174
1175   vam->retval = ntohl (mp->retval);
1176   vam->result_ready = 1;
1177 }
1178
1179 static void vl_api_get_node_index_reply_t_handler
1180   (vl_api_get_node_index_reply_t * mp)
1181 {
1182   vat_main_t *vam = &vat_main;
1183   i32 retval = ntohl (mp->retval);
1184   if (vam->async_mode)
1185     {
1186       vam->async_errors += (retval < 0);
1187     }
1188   else
1189     {
1190       vam->retval = retval;
1191       if (retval == 0)
1192         errmsg ("node index %d", ntohl (mp->node_index));
1193       vam->result_ready = 1;
1194     }
1195 }
1196
1197 static void vl_api_get_node_index_reply_t_handler_json
1198   (vl_api_get_node_index_reply_t * mp)
1199 {
1200   vat_main_t *vam = &vat_main;
1201   vat_json_node_t node;
1202
1203   vat_json_init_object (&node);
1204   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1205   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_next_index_reply_t_handler
1215   (vl_api_get_next_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("next node index %d", ntohl (mp->next_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_next_index_reply_t_handler_json
1233   (vl_api_get_next_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_add_node_next_reply_t_handler
1250   (vl_api_add_node_next_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_add_node_next_reply_t_handler_json
1268   (vl_api_add_node_next_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_show_version_reply_t_handler
1285   (vl_api_show_version_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289
1290   if (retval >= 0)
1291     {
1292       errmsg ("        program: %s", mp->program);
1293       errmsg ("        version: %s", mp->version);
1294       errmsg ("     build date: %s", mp->build_date);
1295       errmsg ("build directory: %s", mp->build_directory);
1296     }
1297   vam->retval = retval;
1298   vam->result_ready = 1;
1299 }
1300
1301 static void vl_api_show_version_reply_t_handler_json
1302   (vl_api_show_version_reply_t * mp)
1303 {
1304   vat_main_t *vam = &vat_main;
1305   vat_json_node_t node;
1306
1307   vat_json_init_object (&node);
1308   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1309   vat_json_object_add_string_copy (&node, "program", mp->program);
1310   vat_json_object_add_string_copy (&node, "version", mp->version);
1311   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1312   vat_json_object_add_string_copy (&node, "build_directory",
1313                                    mp->build_directory);
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void vl_api_show_threads_reply_t_handler
1323   (vl_api_show_threads_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327   int i, count = 0;
1328
1329   if (retval >= 0)
1330     count = ntohl (mp->count);
1331
1332   for (i = 0; i < count; i++)
1333     print (vam->ofp,
1334            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1335            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1336            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1337            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1338            ntohl (mp->thread_data[i].cpu_socket));
1339
1340   vam->retval = retval;
1341   vam->result_ready = 1;
1342 }
1343
1344 static void vl_api_show_threads_reply_t_handler_json
1345   (vl_api_show_threads_reply_t * mp)
1346 {
1347   vat_main_t *vam = &vat_main;
1348   vat_json_node_t node;
1349   vl_api_thread_data_t *td;
1350   i32 retval = ntohl (mp->retval);
1351   int i, count = 0;
1352
1353   if (retval >= 0)
1354     count = ntohl (mp->count);
1355
1356   vat_json_init_object (&node);
1357   vat_json_object_add_int (&node, "retval", retval);
1358   vat_json_object_add_uint (&node, "count", count);
1359
1360   for (i = 0; i < count; i++)
1361     {
1362       td = &mp->thread_data[i];
1363       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1364       vat_json_object_add_string_copy (&node, "name", td->name);
1365       vat_json_object_add_string_copy (&node, "type", td->type);
1366       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1367       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1368       vat_json_object_add_int (&node, "core", ntohl (td->id));
1369       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1370     }
1371
1372   vat_json_print (vam->ofp, &node);
1373   vat_json_free (&node);
1374
1375   vam->retval = retval;
1376   vam->result_ready = 1;
1377 }
1378
1379 static int
1380 api_show_threads (vat_main_t * vam)
1381 {
1382   vl_api_show_threads_t *mp;
1383   int ret;
1384
1385   print (vam->ofp,
1386          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1387          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1388
1389   M (SHOW_THREADS, mp);
1390
1391   S (mp);
1392   W (ret);
1393   return ret;
1394 }
1395
1396 static void
1397 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1398 {
1399   u32 sw_if_index = ntohl (mp->sw_if_index);
1400   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1401           mp->mac_ip ? "mac/ip binding" : "address resolution",
1402           ntohl (mp->pid), format_ip4_address, &mp->address,
1403           format_ethernet_address, mp->new_mac, sw_if_index);
1404 }
1405
1406 static void
1407 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1408 {
1409   /* JSON output not supported */
1410 }
1411
1412 static void
1413 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1414 {
1415   u32 sw_if_index = ntohl (mp->sw_if_index);
1416   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1417           mp->mac_ip ? "mac/ip binding" : "address resolution",
1418           ntohl (mp->pid), format_ip6_address, mp->address,
1419           format_ethernet_address, mp->new_mac, sw_if_index);
1420 }
1421
1422 static void
1423 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1424 {
1425   /* JSON output not supported */
1426 }
1427
1428 static void
1429 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1430 {
1431   u32 n_macs = ntohl (mp->n_macs);
1432   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1433           ntohl (mp->pid), mp->client_index, n_macs);
1434   int i;
1435   for (i = 0; i < n_macs; i++)
1436     {
1437       vl_api_mac_entry_t *mac = &mp->mac[i];
1438       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1439               i + 1, ntohl (mac->sw_if_index),
1440               format_ethernet_address, mac->mac_addr, mac->action);
1441       if (i == 1000)
1442         break;
1443     }
1444 }
1445
1446 static void
1447 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1448 {
1449   /* JSON output not supported */
1450 }
1451
1452 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1453 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1454
1455 /*
1456  * Special-case: build the bridge domain table, maintain
1457  * the next bd id vbl.
1458  */
1459 static void vl_api_bridge_domain_details_t_handler
1460   (vl_api_bridge_domain_details_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1464   int i;
1465
1466   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1467          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1468
1469   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1470          ntohl (mp->bd_id), mp->learn, mp->forward,
1471          mp->flood, ntohl (mp->bvi_sw_if_index),
1472          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1473
1474   if (n_sw_ifs)
1475     {
1476       vl_api_bridge_domain_sw_if_t *sw_ifs;
1477       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1478              "Interface Name");
1479
1480       sw_ifs = mp->sw_if_details;
1481       for (i = 0; i < n_sw_ifs; i++)
1482         {
1483           u8 *sw_if_name = 0;
1484           u32 sw_if_index;
1485           hash_pair_t *p;
1486
1487           sw_if_index = ntohl (sw_ifs->sw_if_index);
1488
1489           /* *INDENT-OFF* */
1490           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1491                              ({
1492                                if ((u32) p->value[0] == sw_if_index)
1493                                  {
1494                                    sw_if_name = (u8 *)(p->key);
1495                                    break;
1496                                  }
1497                              }));
1498           /* *INDENT-ON* */
1499           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1500                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1501                  "sw_if_index not found!");
1502
1503           sw_ifs++;
1504         }
1505     }
1506 }
1507
1508 static void vl_api_bridge_domain_details_t_handler_json
1509   (vl_api_bridge_domain_details_t * mp)
1510 {
1511   vat_main_t *vam = &vat_main;
1512   vat_json_node_t *node, *array = NULL;
1513   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1514
1515   if (VAT_JSON_ARRAY != vam->json_tree.type)
1516     {
1517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1518       vat_json_init_array (&vam->json_tree);
1519     }
1520   node = vat_json_array_add (&vam->json_tree);
1521
1522   vat_json_init_object (node);
1523   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1524   vat_json_object_add_uint (node, "flood", mp->flood);
1525   vat_json_object_add_uint (node, "forward", mp->forward);
1526   vat_json_object_add_uint (node, "learn", mp->learn);
1527   vat_json_object_add_uint (node, "bvi_sw_if_index",
1528                             ntohl (mp->bvi_sw_if_index));
1529   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1530   array = vat_json_object_add (node, "sw_if");
1531   vat_json_init_array (array);
1532
1533
1534
1535   if (n_sw_ifs)
1536     {
1537       vl_api_bridge_domain_sw_if_t *sw_ifs;
1538       int i;
1539
1540       sw_ifs = mp->sw_if_details;
1541       for (i = 0; i < n_sw_ifs; i++)
1542         {
1543           node = vat_json_array_add (array);
1544           vat_json_init_object (node);
1545           vat_json_object_add_uint (node, "sw_if_index",
1546                                     ntohl (sw_ifs->sw_if_index));
1547           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1548           sw_ifs++;
1549         }
1550     }
1551 }
1552
1553 static void vl_api_control_ping_reply_t_handler
1554   (vl_api_control_ping_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   if (vam->socket_client_main)
1568     vam->socket_client_main->control_pings_outstanding--;
1569 }
1570
1571 static void vl_api_control_ping_reply_t_handler_json
1572   (vl_api_control_ping_reply_t * mp)
1573 {
1574   vat_main_t *vam = &vat_main;
1575   i32 retval = ntohl (mp->retval);
1576
1577   if (VAT_JSON_NONE != vam->json_tree.type)
1578     {
1579       vat_json_print (vam->ofp, &vam->json_tree);
1580       vat_json_free (&vam->json_tree);
1581       vam->json_tree.type = VAT_JSON_NONE;
1582     }
1583   else
1584     {
1585       /* just print [] */
1586       vat_json_init_array (&vam->json_tree);
1587       vat_json_print (vam->ofp, &vam->json_tree);
1588       vam->json_tree.type = VAT_JSON_NONE;
1589     }
1590
1591   vam->retval = retval;
1592   vam->result_ready = 1;
1593 }
1594
1595 static void
1596   vl_api_bridge_domain_set_mac_age_reply_t_handler
1597   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   i32 retval = ntohl (mp->retval);
1601   if (vam->async_mode)
1602     {
1603       vam->async_errors += (retval < 0);
1604     }
1605   else
1606     {
1607       vam->retval = retval;
1608       vam->result_ready = 1;
1609     }
1610 }
1611
1612 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1613   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1614 {
1615   vat_main_t *vam = &vat_main;
1616   vat_json_node_t node;
1617
1618   vat_json_init_object (&node);
1619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1620
1621   vat_json_print (vam->ofp, &node);
1622   vat_json_free (&node);
1623
1624   vam->retval = ntohl (mp->retval);
1625   vam->result_ready = 1;
1626 }
1627
1628 static void
1629 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1630 {
1631   vat_main_t *vam = &vat_main;
1632   i32 retval = ntohl (mp->retval);
1633   if (vam->async_mode)
1634     {
1635       vam->async_errors += (retval < 0);
1636     }
1637   else
1638     {
1639       vam->retval = retval;
1640       vam->result_ready = 1;
1641     }
1642 }
1643
1644 static void vl_api_l2_flags_reply_t_handler_json
1645   (vl_api_l2_flags_reply_t * mp)
1646 {
1647   vat_main_t *vam = &vat_main;
1648   vat_json_node_t node;
1649
1650   vat_json_init_object (&node);
1651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1653                             ntohl (mp->resulting_feature_bitmap));
1654
1655   vat_json_print (vam->ofp, &node);
1656   vat_json_free (&node);
1657
1658   vam->retval = ntohl (mp->retval);
1659   vam->result_ready = 1;
1660 }
1661
1662 static void vl_api_bridge_flags_reply_t_handler
1663   (vl_api_bridge_flags_reply_t * mp)
1664 {
1665   vat_main_t *vam = &vat_main;
1666   i32 retval = ntohl (mp->retval);
1667   if (vam->async_mode)
1668     {
1669       vam->async_errors += (retval < 0);
1670     }
1671   else
1672     {
1673       vam->retval = retval;
1674       vam->result_ready = 1;
1675     }
1676 }
1677
1678 static void vl_api_bridge_flags_reply_t_handler_json
1679   (vl_api_bridge_flags_reply_t * mp)
1680 {
1681   vat_main_t *vam = &vat_main;
1682   vat_json_node_t node;
1683
1684   vat_json_init_object (&node);
1685   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1686   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1687                             ntohl (mp->resulting_feature_bitmap));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_tap_connect_reply_t_handler
1697   (vl_api_tap_connect_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->sw_if_index = ntohl (mp->sw_if_index);
1709       vam->result_ready = 1;
1710     }
1711
1712 }
1713
1714 static void vl_api_tap_connect_reply_t_handler_json
1715   (vl_api_tap_connect_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729
1730 }
1731
1732 static void
1733 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_tap_modify_reply_t_handler_json
1750   (vl_api_tap_modify_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764 }
1765
1766 static void
1767 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->result_ready = 1;
1779     }
1780 }
1781
1782 static void vl_api_tap_delete_reply_t_handler_json
1783   (vl_api_tap_delete_reply_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t node;
1787
1788   vat_json_init_object (&node);
1789   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void
1799 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813
1814 }
1815
1816 static void vl_api_tap_create_v2_reply_t_handler_json
1817   (vl_api_tap_create_v2_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831
1832 }
1833
1834 static void
1835 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   i32 retval = ntohl (mp->retval);
1839   if (vam->async_mode)
1840     {
1841       vam->async_errors += (retval < 0);
1842     }
1843   else
1844     {
1845       vam->retval = retval;
1846       vam->result_ready = 1;
1847     }
1848 }
1849
1850 static void vl_api_tap_delete_v2_reply_t_handler_json
1851   (vl_api_tap_delete_v2_reply_t * mp)
1852 {
1853   vat_main_t *vam = &vat_main;
1854   vat_json_node_t node;
1855
1856   vat_json_init_object (&node);
1857   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void
1867 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871
1872   if (vam->async_mode)
1873     {
1874       vam->async_errors += (retval < 0);
1875     }
1876   else
1877     {
1878       vam->retval = retval;
1879       vam->sw_if_index = ntohl (mp->sw_if_index);
1880       vam->result_ready = 1;
1881     }
1882 }
1883
1884 static void vl_api_bond_create_reply_t_handler_json
1885   (vl_api_bond_create_reply_t * mp)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   vat_json_node_t node;
1889
1890   vat_json_init_object (&node);
1891   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1892   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1893
1894   vat_json_print (vam->ofp, &node);
1895   vat_json_free (&node);
1896
1897   vam->retval = ntohl (mp->retval);
1898   vam->result_ready = 1;
1899 }
1900
1901 static void
1902 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   i32 retval = ntohl (mp->retval);
1906
1907   if (vam->async_mode)
1908     {
1909       vam->async_errors += (retval < 0);
1910     }
1911   else
1912     {
1913       vam->retval = retval;
1914       vam->result_ready = 1;
1915     }
1916 }
1917
1918 static void vl_api_bond_delete_reply_t_handler_json
1919   (vl_api_bond_delete_reply_t * mp)
1920 {
1921   vat_main_t *vam = &vat_main;
1922   vat_json_node_t node;
1923
1924   vat_json_init_object (&node);
1925   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1926
1927   vat_json_print (vam->ofp, &node);
1928   vat_json_free (&node);
1929
1930   vam->retval = ntohl (mp->retval);
1931   vam->result_ready = 1;
1932 }
1933
1934 static void
1935 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1936 {
1937   vat_main_t *vam = &vat_main;
1938   i32 retval = ntohl (mp->retval);
1939
1940   if (vam->async_mode)
1941     {
1942       vam->async_errors += (retval < 0);
1943     }
1944   else
1945     {
1946       vam->retval = retval;
1947       vam->result_ready = 1;
1948     }
1949 }
1950
1951 static void vl_api_bond_enslave_reply_t_handler_json
1952   (vl_api_bond_enslave_reply_t * mp)
1953 {
1954   vat_main_t *vam = &vat_main;
1955   vat_json_node_t node;
1956
1957   vat_json_init_object (&node);
1958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1959
1960   vat_json_print (vam->ofp, &node);
1961   vat_json_free (&node);
1962
1963   vam->retval = ntohl (mp->retval);
1964   vam->result_ready = 1;
1965 }
1966
1967 static void
1968 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1969                                           mp)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   i32 retval = ntohl (mp->retval);
1973
1974   if (vam->async_mode)
1975     {
1976       vam->async_errors += (retval < 0);
1977     }
1978   else
1979     {
1980       vam->retval = retval;
1981       vam->result_ready = 1;
1982     }
1983 }
1984
1985 static void vl_api_bond_detach_slave_reply_t_handler_json
1986   (vl_api_bond_detach_slave_reply_t * mp)
1987 {
1988   vat_main_t *vam = &vat_main;
1989   vat_json_node_t node;
1990
1991   vat_json_init_object (&node);
1992   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1993
1994   vat_json_print (vam->ofp, &node);
1995   vat_json_free (&node);
1996
1997   vam->retval = ntohl (mp->retval);
1998   vam->result_ready = 1;
1999 }
2000
2001 static void vl_api_sw_interface_bond_details_t_handler
2002   (vl_api_sw_interface_bond_details_t * mp)
2003 {
2004   vat_main_t *vam = &vat_main;
2005
2006   print (vam->ofp,
2007          "%-16s %-12d %-12U %-13U %-14u %-14u",
2008          mp->interface_name, ntohl (mp->sw_if_index),
2009          format_bond_mode, mp->mode, format_bond_load_balance, mp->lb,
2010          ntohl (mp->active_slaves), ntohl (mp->slaves));
2011 }
2012
2013 static void vl_api_sw_interface_bond_details_t_handler_json
2014   (vl_api_sw_interface_bond_details_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017   vat_json_node_t *node = NULL;
2018
2019   if (VAT_JSON_ARRAY != vam->json_tree.type)
2020     {
2021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2022       vat_json_init_array (&vam->json_tree);
2023     }
2024   node = vat_json_array_add (&vam->json_tree);
2025
2026   vat_json_init_object (node);
2027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2028   vat_json_object_add_string_copy (node, "interface_name",
2029                                    mp->interface_name);
2030   vat_json_object_add_uint (node, "mode", mp->mode);
2031   vat_json_object_add_uint (node, "load_balance", mp->lb);
2032   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2033   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2034 }
2035
2036 static int
2037 api_sw_interface_bond_dump (vat_main_t * vam)
2038 {
2039   vl_api_sw_interface_bond_dump_t *mp;
2040   vl_api_control_ping_t *mp_ping;
2041   int ret;
2042
2043   print (vam->ofp,
2044          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2045          "interface name", "sw_if_index", "mode", "load balance",
2046          "active slaves", "slaves");
2047
2048   /* Get list of bond interfaces */
2049   M (SW_INTERFACE_BOND_DUMP, mp);
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_sw_interface_slave_details_t_handler
2061   (vl_api_sw_interface_slave_details_t * mp)
2062 {
2063   vat_main_t *vam = &vat_main;
2064
2065   print (vam->ofp,
2066          "%-25s %-12d %-12d %d", mp->interface_name,
2067          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout);
2068 }
2069
2070 static void vl_api_sw_interface_slave_details_t_handler_json
2071   (vl_api_sw_interface_slave_details_t * mp)
2072 {
2073   vat_main_t *vam = &vat_main;
2074   vat_json_node_t *node = NULL;
2075
2076   if (VAT_JSON_ARRAY != vam->json_tree.type)
2077     {
2078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2079       vat_json_init_array (&vam->json_tree);
2080     }
2081   node = vat_json_array_add (&vam->json_tree);
2082
2083   vat_json_init_object (node);
2084   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2085   vat_json_object_add_string_copy (node, "interface_name",
2086                                    mp->interface_name);
2087   vat_json_object_add_uint (node, "passive", mp->is_passive);
2088   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2089 }
2090
2091 static int
2092 api_sw_interface_slave_dump (vat_main_t * vam)
2093 {
2094   unformat_input_t *i = vam->input;
2095   vl_api_sw_interface_slave_dump_t *mp;
2096   vl_api_control_ping_t *mp_ping;
2097   u32 sw_if_index = ~0;
2098   u8 sw_if_index_set = 0;
2099   int ret;
2100
2101   /* Parse args required to build the message */
2102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2103     {
2104       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2105         sw_if_index_set = 1;
2106       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2107         sw_if_index_set = 1;
2108       else
2109         break;
2110     }
2111
2112   if (sw_if_index_set == 0)
2113     {
2114       errmsg ("missing vpp interface name. ");
2115       return -99;
2116     }
2117
2118   print (vam->ofp,
2119          "\n%-25s %-12s %-12s %s",
2120          "slave interface name", "sw_if_index", "passive", "long_timeout");
2121
2122   /* Get list of bond interfaces */
2123   M (SW_INTERFACE_SLAVE_DUMP, mp);
2124   mp->sw_if_index = ntohl (sw_if_index);
2125   S (mp);
2126
2127   /* Use a control ping for synchronization */
2128   MPING (CONTROL_PING, mp_ping);
2129   S (mp_ping);
2130
2131   W (ret);
2132   return ret;
2133 }
2134
2135 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2136   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   i32 retval = ntohl (mp->retval);
2140   if (vam->async_mode)
2141     {
2142       vam->async_errors += (retval < 0);
2143     }
2144   else
2145     {
2146       vam->retval = retval;
2147       vam->result_ready = 1;
2148     }
2149 }
2150
2151 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2152   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2153 {
2154   vat_main_t *vam = &vat_main;
2155   vat_json_node_t node;
2156
2157   vat_json_init_object (&node);
2158   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2159   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2160                             ntohl (mp->sw_if_index));
2161
2162   vat_json_print (vam->ofp, &node);
2163   vat_json_free (&node);
2164
2165   vam->retval = ntohl (mp->retval);
2166   vam->result_ready = 1;
2167 }
2168
2169 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2170   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2171 {
2172   vat_main_t *vam = &vat_main;
2173   i32 retval = ntohl (mp->retval);
2174   if (vam->async_mode)
2175     {
2176       vam->async_errors += (retval < 0);
2177     }
2178   else
2179     {
2180       vam->retval = retval;
2181       vam->sw_if_index = ntohl (mp->sw_if_index);
2182       vam->result_ready = 1;
2183     }
2184 }
2185
2186 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2187   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2188 {
2189   vat_main_t *vam = &vat_main;
2190   vat_json_node_t node;
2191
2192   vat_json_init_object (&node);
2193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2194   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2195
2196   vat_json_print (vam->ofp, &node);
2197   vat_json_free (&node);
2198
2199   vam->retval = ntohl (mp->retval);
2200   vam->result_ready = 1;
2201 }
2202
2203 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2204   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2205 {
2206   vat_main_t *vam = &vat_main;
2207   i32 retval = ntohl (mp->retval);
2208   if (vam->async_mode)
2209     {
2210       vam->async_errors += (retval < 0);
2211     }
2212   else
2213     {
2214       vam->retval = retval;
2215       vam->result_ready = 1;
2216     }
2217 }
2218
2219 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2220   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2221 {
2222   vat_main_t *vam = &vat_main;
2223   vat_json_node_t node;
2224
2225   vat_json_init_object (&node);
2226   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2227   vat_json_object_add_uint (&node, "fwd_entry_index",
2228                             clib_net_to_host_u32 (mp->fwd_entry_index));
2229
2230   vat_json_print (vam->ofp, &node);
2231   vat_json_free (&node);
2232
2233   vam->retval = ntohl (mp->retval);
2234   vam->result_ready = 1;
2235 }
2236
2237 u8 *
2238 format_lisp_transport_protocol (u8 * s, va_list * args)
2239 {
2240   u32 proto = va_arg (*args, u32);
2241
2242   switch (proto)
2243     {
2244     case 1:
2245       return format (s, "udp");
2246     case 2:
2247       return format (s, "api");
2248     default:
2249       return 0;
2250     }
2251   return 0;
2252 }
2253
2254 static void vl_api_one_get_transport_protocol_reply_t_handler
2255   (vl_api_one_get_transport_protocol_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   i32 retval = ntohl (mp->retval);
2259   if (vam->async_mode)
2260     {
2261       vam->async_errors += (retval < 0);
2262     }
2263   else
2264     {
2265       u32 proto = mp->protocol;
2266       print (vam->ofp, "Transport protocol: %U",
2267              format_lisp_transport_protocol, proto);
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271 }
2272
2273 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2274   (vl_api_one_get_transport_protocol_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   vat_json_node_t node;
2278   u8 *s;
2279
2280   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2281   vec_add1 (s, 0);
2282
2283   vat_json_init_object (&node);
2284   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2285   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2286
2287   vec_free (s);
2288   vat_json_print (vam->ofp, &node);
2289   vat_json_free (&node);
2290
2291   vam->retval = ntohl (mp->retval);
2292   vam->result_ready = 1;
2293 }
2294
2295 static void vl_api_one_add_del_locator_set_reply_t_handler
2296   (vl_api_one_add_del_locator_set_reply_t * mp)
2297 {
2298   vat_main_t *vam = &vat_main;
2299   i32 retval = ntohl (mp->retval);
2300   if (vam->async_mode)
2301     {
2302       vam->async_errors += (retval < 0);
2303     }
2304   else
2305     {
2306       vam->retval = retval;
2307       vam->result_ready = 1;
2308     }
2309 }
2310
2311 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2312   (vl_api_one_add_del_locator_set_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   vat_json_node_t node;
2316
2317   vat_json_init_object (&node);
2318   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2319   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2320
2321   vat_json_print (vam->ofp, &node);
2322   vat_json_free (&node);
2323
2324   vam->retval = ntohl (mp->retval);
2325   vam->result_ready = 1;
2326 }
2327
2328 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2329   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2330 {
2331   vat_main_t *vam = &vat_main;
2332   i32 retval = ntohl (mp->retval);
2333   if (vam->async_mode)
2334     {
2335       vam->async_errors += (retval < 0);
2336     }
2337   else
2338     {
2339       vam->retval = retval;
2340       vam->sw_if_index = ntohl (mp->sw_if_index);
2341       vam->result_ready = 1;
2342     }
2343   vam->regenerate_interface_table = 1;
2344 }
2345
2346 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2347   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   vat_json_node_t node;
2351
2352   vat_json_init_object (&node);
2353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2354   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2355
2356   vat_json_print (vam->ofp, &node);
2357   vat_json_free (&node);
2358
2359   vam->retval = ntohl (mp->retval);
2360   vam->result_ready = 1;
2361 }
2362
2363 static void vl_api_vxlan_offload_rx_reply_t_handler
2364   (vl_api_vxlan_offload_rx_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   i32 retval = ntohl (mp->retval);
2368   if (vam->async_mode)
2369     {
2370       vam->async_errors += (retval < 0);
2371     }
2372   else
2373     {
2374       vam->retval = retval;
2375       vam->result_ready = 1;
2376     }
2377 }
2378
2379 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2380   (vl_api_vxlan_offload_rx_reply_t * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   vat_json_node_t node;
2384
2385   vat_json_init_object (&node);
2386   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2387
2388   vat_json_print (vam->ofp, &node);
2389   vat_json_free (&node);
2390
2391   vam->retval = ntohl (mp->retval);
2392   vam->result_ready = 1;
2393 }
2394
2395 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2396   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   i32 retval = ntohl (mp->retval);
2400   if (vam->async_mode)
2401     {
2402       vam->async_errors += (retval < 0);
2403     }
2404   else
2405     {
2406       vam->retval = retval;
2407       vam->sw_if_index = ntohl (mp->sw_if_index);
2408       vam->result_ready = 1;
2409     }
2410 }
2411
2412 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2413   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2414 {
2415   vat_main_t *vam = &vat_main;
2416   vat_json_node_t node;
2417
2418   vat_json_init_object (&node);
2419   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2420   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2421
2422   vat_json_print (vam->ofp, &node);
2423   vat_json_free (&node);
2424
2425   vam->retval = ntohl (mp->retval);
2426   vam->result_ready = 1;
2427 }
2428
2429 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2430   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   i32 retval = ntohl (mp->retval);
2434   if (vam->async_mode)
2435     {
2436       vam->async_errors += (retval < 0);
2437     }
2438   else
2439     {
2440       vam->retval = retval;
2441       vam->sw_if_index = ntohl (mp->sw_if_index);
2442       vam->result_ready = 1;
2443     }
2444   vam->regenerate_interface_table = 1;
2445 }
2446
2447 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2448   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451   vat_json_node_t node;
2452
2453   vat_json_init_object (&node);
2454   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2455   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2456
2457   vat_json_print (vam->ofp, &node);
2458   vat_json_free (&node);
2459
2460   vam->retval = ntohl (mp->retval);
2461   vam->result_ready = 1;
2462 }
2463
2464 static void vl_api_gre_add_del_tunnel_reply_t_handler
2465   (vl_api_gre_add_del_tunnel_reply_t * mp)
2466 {
2467   vat_main_t *vam = &vat_main;
2468   i32 retval = ntohl (mp->retval);
2469   if (vam->async_mode)
2470     {
2471       vam->async_errors += (retval < 0);
2472     }
2473   else
2474     {
2475       vam->retval = retval;
2476       vam->sw_if_index = ntohl (mp->sw_if_index);
2477       vam->result_ready = 1;
2478     }
2479 }
2480
2481 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2482   (vl_api_gre_add_del_tunnel_reply_t * mp)
2483 {
2484   vat_main_t *vam = &vat_main;
2485   vat_json_node_t node;
2486
2487   vat_json_init_object (&node);
2488   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2489   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2490
2491   vat_json_print (vam->ofp, &node);
2492   vat_json_free (&node);
2493
2494   vam->retval = ntohl (mp->retval);
2495   vam->result_ready = 1;
2496 }
2497
2498 static void vl_api_create_vhost_user_if_reply_t_handler
2499   (vl_api_create_vhost_user_if_reply_t * mp)
2500 {
2501   vat_main_t *vam = &vat_main;
2502   i32 retval = ntohl (mp->retval);
2503   if (vam->async_mode)
2504     {
2505       vam->async_errors += (retval < 0);
2506     }
2507   else
2508     {
2509       vam->retval = retval;
2510       vam->sw_if_index = ntohl (mp->sw_if_index);
2511       vam->result_ready = 1;
2512     }
2513   vam->regenerate_interface_table = 1;
2514 }
2515
2516 static void vl_api_create_vhost_user_if_reply_t_handler_json
2517   (vl_api_create_vhost_user_if_reply_t * mp)
2518 {
2519   vat_main_t *vam = &vat_main;
2520   vat_json_node_t node;
2521
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2525
2526   vat_json_print (vam->ofp, &node);
2527   vat_json_free (&node);
2528
2529   vam->retval = ntohl (mp->retval);
2530   vam->result_ready = 1;
2531 }
2532
2533 static void vl_api_dns_resolve_name_reply_t_handler
2534   (vl_api_dns_resolve_name_reply_t * mp)
2535 {
2536   vat_main_t *vam = &vat_main;
2537   i32 retval = ntohl (mp->retval);
2538   if (vam->async_mode)
2539     {
2540       vam->async_errors += (retval < 0);
2541     }
2542   else
2543     {
2544       vam->retval = retval;
2545       vam->result_ready = 1;
2546
2547       if (retval == 0)
2548         {
2549           if (mp->ip4_set)
2550             clib_warning ("ip4 address %U", format_ip4_address,
2551                           (ip4_address_t *) mp->ip4_address);
2552           if (mp->ip6_set)
2553             clib_warning ("ip6 address %U", format_ip6_address,
2554                           (ip6_address_t *) mp->ip6_address);
2555         }
2556       else
2557         clib_warning ("retval %d", retval);
2558     }
2559 }
2560
2561 static void vl_api_dns_resolve_name_reply_t_handler_json
2562   (vl_api_dns_resolve_name_reply_t * mp)
2563 {
2564   clib_warning ("not implemented");
2565 }
2566
2567 static void vl_api_dns_resolve_ip_reply_t_handler
2568   (vl_api_dns_resolve_ip_reply_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   i32 retval = ntohl (mp->retval);
2572   if (vam->async_mode)
2573     {
2574       vam->async_errors += (retval < 0);
2575     }
2576   else
2577     {
2578       vam->retval = retval;
2579       vam->result_ready = 1;
2580
2581       if (retval == 0)
2582         {
2583           clib_warning ("canonical name %s", mp->name);
2584         }
2585       else
2586         clib_warning ("retval %d", retval);
2587     }
2588 }
2589
2590 static void vl_api_dns_resolve_ip_reply_t_handler_json
2591   (vl_api_dns_resolve_ip_reply_t * mp)
2592 {
2593   clib_warning ("not implemented");
2594 }
2595
2596
2597 static void vl_api_ip_address_details_t_handler
2598   (vl_api_ip_address_details_t * mp)
2599 {
2600   vat_main_t *vam = &vat_main;
2601   static ip_address_details_t empty_ip_address_details = { {0} };
2602   ip_address_details_t *address = NULL;
2603   ip_details_t *current_ip_details = NULL;
2604   ip_details_t *details = NULL;
2605
2606   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2607
2608   if (!details || vam->current_sw_if_index >= vec_len (details)
2609       || !details[vam->current_sw_if_index].present)
2610     {
2611       errmsg ("ip address details arrived but not stored");
2612       errmsg ("ip_dump should be called first");
2613       return;
2614     }
2615
2616   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2617
2618 #define addresses (current_ip_details->addr)
2619
2620   vec_validate_init_empty (addresses, vec_len (addresses),
2621                            empty_ip_address_details);
2622
2623   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2624
2625   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2626   address->prefix_length = mp->prefix_length;
2627 #undef addresses
2628 }
2629
2630 static void vl_api_ip_address_details_t_handler_json
2631   (vl_api_ip_address_details_t * mp)
2632 {
2633   vat_main_t *vam = &vat_main;
2634   vat_json_node_t *node = NULL;
2635   struct in6_addr ip6;
2636   struct in_addr ip4;
2637
2638   if (VAT_JSON_ARRAY != vam->json_tree.type)
2639     {
2640       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2641       vat_json_init_array (&vam->json_tree);
2642     }
2643   node = vat_json_array_add (&vam->json_tree);
2644
2645   vat_json_init_object (node);
2646   if (vam->is_ipv6)
2647     {
2648       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2649       vat_json_object_add_ip6 (node, "ip", ip6);
2650     }
2651   else
2652     {
2653       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2654       vat_json_object_add_ip4 (node, "ip", ip4);
2655     }
2656   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2657 }
2658
2659 static void
2660 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2661 {
2662   vat_main_t *vam = &vat_main;
2663   static ip_details_t empty_ip_details = { 0 };
2664   ip_details_t *ip = NULL;
2665   u32 sw_if_index = ~0;
2666
2667   sw_if_index = ntohl (mp->sw_if_index);
2668
2669   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2670                            sw_if_index, empty_ip_details);
2671
2672   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2673                          sw_if_index);
2674
2675   ip->present = 1;
2676 }
2677
2678 static void
2679 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2680 {
2681   vat_main_t *vam = &vat_main;
2682
2683   if (VAT_JSON_ARRAY != vam->json_tree.type)
2684     {
2685       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2686       vat_json_init_array (&vam->json_tree);
2687     }
2688   vat_json_array_add_uint (&vam->json_tree,
2689                            clib_net_to_host_u32 (mp->sw_if_index));
2690 }
2691
2692 static void
2693 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2694 {
2695   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2696           "router_addr %U host_mac %U",
2697           ntohl (mp->pid), mp->lease.is_ipv6 ? "ipv6" : "ipv4",
2698           mp->lease.hostname,
2699           format_ip4_address, &mp->lease.host_address,
2700           format_ip4_address, &mp->lease.router_address,
2701           format_ethernet_address, mp->lease.host_mac);
2702 }
2703
2704 static void vl_api_dhcp_compl_event_t_handler_json
2705   (vl_api_dhcp_compl_event_t * mp)
2706 {
2707   /* JSON output not supported */
2708 }
2709
2710 static void
2711 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2712                               u32 counter)
2713 {
2714   vat_main_t *vam = &vat_main;
2715   static u64 default_counter = 0;
2716
2717   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2718                            NULL);
2719   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2720                            sw_if_index, default_counter);
2721   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2722 }
2723
2724 static void
2725 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2726                                 interface_counter_t counter)
2727 {
2728   vat_main_t *vam = &vat_main;
2729   static interface_counter_t default_counter = { 0, };
2730
2731   vec_validate_init_empty (vam->combined_interface_counters,
2732                            vnet_counter_type, NULL);
2733   vec_validate_init_empty (vam->combined_interface_counters
2734                            [vnet_counter_type], sw_if_index, default_counter);
2735   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2736 }
2737
2738 static void vl_api_vnet_interface_simple_counters_t_handler
2739   (vl_api_vnet_interface_simple_counters_t * mp)
2740 {
2741   /* not supported */
2742 }
2743
2744 static void vl_api_vnet_interface_combined_counters_t_handler
2745   (vl_api_vnet_interface_combined_counters_t * mp)
2746 {
2747   /* not supported */
2748 }
2749
2750 static void vl_api_vnet_interface_simple_counters_t_handler_json
2751   (vl_api_vnet_interface_simple_counters_t * mp)
2752 {
2753   u64 *v_packets;
2754   u64 packets;
2755   u32 count;
2756   u32 first_sw_if_index;
2757   int i;
2758
2759   count = ntohl (mp->count);
2760   first_sw_if_index = ntohl (mp->first_sw_if_index);
2761
2762   v_packets = (u64 *) & mp->data;
2763   for (i = 0; i < count; i++)
2764     {
2765       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2766       set_simple_interface_counter (mp->vnet_counter_type,
2767                                     first_sw_if_index + i, packets);
2768       v_packets++;
2769     }
2770 }
2771
2772 static void vl_api_vnet_interface_combined_counters_t_handler_json
2773   (vl_api_vnet_interface_combined_counters_t * mp)
2774 {
2775   interface_counter_t counter;
2776   vlib_counter_t *v;
2777   u32 first_sw_if_index;
2778   int i;
2779   u32 count;
2780
2781   count = ntohl (mp->count);
2782   first_sw_if_index = ntohl (mp->first_sw_if_index);
2783
2784   v = (vlib_counter_t *) & mp->data;
2785   for (i = 0; i < count; i++)
2786     {
2787       counter.packets =
2788         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2789       counter.bytes =
2790         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2791       set_combined_interface_counter (mp->vnet_counter_type,
2792                                       first_sw_if_index + i, counter);
2793       v++;
2794     }
2795 }
2796
2797 static u32
2798 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   u32 i;
2802
2803   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2804     {
2805       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2806         {
2807           return i;
2808         }
2809     }
2810   return ~0;
2811 }
2812
2813 static u32
2814 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2815 {
2816   vat_main_t *vam = &vat_main;
2817   u32 i;
2818
2819   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2820     {
2821       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2822         {
2823           return i;
2824         }
2825     }
2826   return ~0;
2827 }
2828
2829 static void vl_api_vnet_ip4_fib_counters_t_handler
2830   (vl_api_vnet_ip4_fib_counters_t * mp)
2831 {
2832   /* not supported */
2833 }
2834
2835 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2836   (vl_api_vnet_ip4_fib_counters_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   vl_api_ip4_fib_counter_t *v;
2840   ip4_fib_counter_t *counter;
2841   struct in_addr ip4;
2842   u32 vrf_id;
2843   u32 vrf_index;
2844   u32 count;
2845   int i;
2846
2847   vrf_id = ntohl (mp->vrf_id);
2848   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2849   if (~0 == vrf_index)
2850     {
2851       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2852       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2853       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2854       vec_validate (vam->ip4_fib_counters, vrf_index);
2855       vam->ip4_fib_counters[vrf_index] = NULL;
2856     }
2857
2858   vec_free (vam->ip4_fib_counters[vrf_index]);
2859   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2860   count = ntohl (mp->count);
2861   for (i = 0; i < count; i++)
2862     {
2863       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2864       counter = &vam->ip4_fib_counters[vrf_index][i];
2865       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2866       counter->address = ip4;
2867       counter->address_length = v->address_length;
2868       counter->packets = clib_net_to_host_u64 (v->packets);
2869       counter->bytes = clib_net_to_host_u64 (v->bytes);
2870       v++;
2871     }
2872 }
2873
2874 static void vl_api_vnet_ip4_nbr_counters_t_handler
2875   (vl_api_vnet_ip4_nbr_counters_t * mp)
2876 {
2877   /* not supported */
2878 }
2879
2880 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2881   (vl_api_vnet_ip4_nbr_counters_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vl_api_ip4_nbr_counter_t *v;
2885   ip4_nbr_counter_t *counter;
2886   u32 sw_if_index;
2887   u32 count;
2888   int i;
2889
2890   sw_if_index = ntohl (mp->sw_if_index);
2891   count = ntohl (mp->count);
2892   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2893
2894   if (mp->begin)
2895     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2896
2897   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2898   for (i = 0; i < count; i++)
2899     {
2900       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2901       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2902       counter->address.s_addr = v->address;
2903       counter->packets = clib_net_to_host_u64 (v->packets);
2904       counter->bytes = clib_net_to_host_u64 (v->bytes);
2905       counter->linkt = v->link_type;
2906       v++;
2907     }
2908 }
2909
2910 static void vl_api_vnet_ip6_fib_counters_t_handler
2911   (vl_api_vnet_ip6_fib_counters_t * mp)
2912 {
2913   /* not supported */
2914 }
2915
2916 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2917   (vl_api_vnet_ip6_fib_counters_t * mp)
2918 {
2919   vat_main_t *vam = &vat_main;
2920   vl_api_ip6_fib_counter_t *v;
2921   ip6_fib_counter_t *counter;
2922   struct in6_addr ip6;
2923   u32 vrf_id;
2924   u32 vrf_index;
2925   u32 count;
2926   int i;
2927
2928   vrf_id = ntohl (mp->vrf_id);
2929   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2930   if (~0 == vrf_index)
2931     {
2932       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2933       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2934       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2935       vec_validate (vam->ip6_fib_counters, vrf_index);
2936       vam->ip6_fib_counters[vrf_index] = NULL;
2937     }
2938
2939   vec_free (vam->ip6_fib_counters[vrf_index]);
2940   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2941   count = ntohl (mp->count);
2942   for (i = 0; i < count; i++)
2943     {
2944       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2945       counter = &vam->ip6_fib_counters[vrf_index][i];
2946       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2947       counter->address = ip6;
2948       counter->address_length = v->address_length;
2949       counter->packets = clib_net_to_host_u64 (v->packets);
2950       counter->bytes = clib_net_to_host_u64 (v->bytes);
2951       v++;
2952     }
2953 }
2954
2955 static void vl_api_vnet_ip6_nbr_counters_t_handler
2956   (vl_api_vnet_ip6_nbr_counters_t * mp)
2957 {
2958   /* not supported */
2959 }
2960
2961 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2962   (vl_api_vnet_ip6_nbr_counters_t * mp)
2963 {
2964   vat_main_t *vam = &vat_main;
2965   vl_api_ip6_nbr_counter_t *v;
2966   ip6_nbr_counter_t *counter;
2967   struct in6_addr ip6;
2968   u32 sw_if_index;
2969   u32 count;
2970   int i;
2971
2972   sw_if_index = ntohl (mp->sw_if_index);
2973   count = ntohl (mp->count);
2974   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2975
2976   if (mp->begin)
2977     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2978
2979   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2980   for (i = 0; i < count; i++)
2981     {
2982       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2983       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2984       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2985       counter->address = ip6;
2986       counter->packets = clib_net_to_host_u64 (v->packets);
2987       counter->bytes = clib_net_to_host_u64 (v->bytes);
2988       v++;
2989     }
2990 }
2991
2992 static void vl_api_get_first_msg_id_reply_t_handler
2993   (vl_api_get_first_msg_id_reply_t * mp)
2994 {
2995   vat_main_t *vam = &vat_main;
2996   i32 retval = ntohl (mp->retval);
2997
2998   if (vam->async_mode)
2999     {
3000       vam->async_errors += (retval < 0);
3001     }
3002   else
3003     {
3004       vam->retval = retval;
3005       vam->result_ready = 1;
3006     }
3007   if (retval >= 0)
3008     {
3009       errmsg ("first message id %d", ntohs (mp->first_msg_id));
3010     }
3011 }
3012
3013 static void vl_api_get_first_msg_id_reply_t_handler_json
3014   (vl_api_get_first_msg_id_reply_t * mp)
3015 {
3016   vat_main_t *vam = &vat_main;
3017   vat_json_node_t node;
3018
3019   vat_json_init_object (&node);
3020   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3021   vat_json_object_add_uint (&node, "first_msg_id",
3022                             (uint) ntohs (mp->first_msg_id));
3023
3024   vat_json_print (vam->ofp, &node);
3025   vat_json_free (&node);
3026
3027   vam->retval = ntohl (mp->retval);
3028   vam->result_ready = 1;
3029 }
3030
3031 static void vl_api_get_node_graph_reply_t_handler
3032   (vl_api_get_node_graph_reply_t * mp)
3033 {
3034   vat_main_t *vam = &vat_main;
3035   api_main_t *am = &api_main;
3036   i32 retval = ntohl (mp->retval);
3037   u8 *pvt_copy, *reply;
3038   void *oldheap;
3039   vlib_node_t *node;
3040   int i;
3041
3042   if (vam->async_mode)
3043     {
3044       vam->async_errors += (retval < 0);
3045     }
3046   else
3047     {
3048       vam->retval = retval;
3049       vam->result_ready = 1;
3050     }
3051
3052   /* "Should never happen..." */
3053   if (retval != 0)
3054     return;
3055
3056   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3057   pvt_copy = vec_dup (reply);
3058
3059   /* Toss the shared-memory original... */
3060   pthread_mutex_lock (&am->vlib_rp->mutex);
3061   oldheap = svm_push_data_heap (am->vlib_rp);
3062
3063   vec_free (reply);
3064
3065   svm_pop_heap (oldheap);
3066   pthread_mutex_unlock (&am->vlib_rp->mutex);
3067
3068   if (vam->graph_nodes)
3069     {
3070       hash_free (vam->graph_node_index_by_name);
3071
3072       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3073         {
3074           node = vam->graph_nodes[0][i];
3075           vec_free (node->name);
3076           vec_free (node->next_nodes);
3077           vec_free (node);
3078         }
3079       vec_free (vam->graph_nodes[0]);
3080       vec_free (vam->graph_nodes);
3081     }
3082
3083   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
3084   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
3085   vec_free (pvt_copy);
3086
3087   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
3088     {
3089       node = vam->graph_nodes[0][i];
3090       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
3091     }
3092 }
3093
3094 static void vl_api_get_node_graph_reply_t_handler_json
3095   (vl_api_get_node_graph_reply_t * mp)
3096 {
3097   vat_main_t *vam = &vat_main;
3098   api_main_t *am = &api_main;
3099   void *oldheap;
3100   vat_json_node_t node;
3101   u8 *reply;
3102
3103   /* $$$$ make this real? */
3104   vat_json_init_object (&node);
3105   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3106   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
3107
3108   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
3109
3110   /* Toss the shared-memory original... */
3111   pthread_mutex_lock (&am->vlib_rp->mutex);
3112   oldheap = svm_push_data_heap (am->vlib_rp);
3113
3114   vec_free (reply);
3115
3116   svm_pop_heap (oldheap);
3117   pthread_mutex_unlock (&am->vlib_rp->mutex);
3118
3119   vat_json_print (vam->ofp, &node);
3120   vat_json_free (&node);
3121
3122   vam->retval = ntohl (mp->retval);
3123   vam->result_ready = 1;
3124 }
3125
3126 static void
3127 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
3128 {
3129   vat_main_t *vam = &vat_main;
3130   u8 *s = 0;
3131
3132   if (mp->local)
3133     {
3134       s = format (s, "%=16d%=16d%=16d",
3135                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
3136     }
3137   else
3138     {
3139       s = format (s, "%=16U%=16d%=16d",
3140                   mp->is_ipv6 ? format_ip6_address :
3141                   format_ip4_address,
3142                   mp->ip_address, mp->priority, mp->weight);
3143     }
3144
3145   print (vam->ofp, "%v", s);
3146   vec_free (s);
3147 }
3148
3149 static void
3150 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   vat_json_node_t *node = NULL;
3154   struct in6_addr ip6;
3155   struct in_addr ip4;
3156
3157   if (VAT_JSON_ARRAY != vam->json_tree.type)
3158     {
3159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3160       vat_json_init_array (&vam->json_tree);
3161     }
3162   node = vat_json_array_add (&vam->json_tree);
3163   vat_json_init_object (node);
3164
3165   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
3166   vat_json_object_add_uint (node, "priority", mp->priority);
3167   vat_json_object_add_uint (node, "weight", mp->weight);
3168
3169   if (mp->local)
3170     vat_json_object_add_uint (node, "sw_if_index",
3171                               clib_net_to_host_u32 (mp->sw_if_index));
3172   else
3173     {
3174       if (mp->is_ipv6)
3175         {
3176           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3177           vat_json_object_add_ip6 (node, "address", ip6);
3178         }
3179       else
3180         {
3181           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3182           vat_json_object_add_ip4 (node, "address", ip4);
3183         }
3184     }
3185 }
3186
3187 static void
3188 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
3189                                           mp)
3190 {
3191   vat_main_t *vam = &vat_main;
3192   u8 *ls_name = 0;
3193
3194   ls_name = format (0, "%s", mp->ls_name);
3195
3196   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
3197          ls_name);
3198   vec_free (ls_name);
3199 }
3200
3201 static void
3202   vl_api_one_locator_set_details_t_handler_json
3203   (vl_api_one_locator_set_details_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   vat_json_node_t *node = 0;
3207   u8 *ls_name = 0;
3208
3209   ls_name = format (0, "%s", mp->ls_name);
3210   vec_add1 (ls_name, 0);
3211
3212   if (VAT_JSON_ARRAY != vam->json_tree.type)
3213     {
3214       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3215       vat_json_init_array (&vam->json_tree);
3216     }
3217   node = vat_json_array_add (&vam->json_tree);
3218
3219   vat_json_init_object (node);
3220   vat_json_object_add_string_copy (node, "ls_name", ls_name);
3221   vat_json_object_add_uint (node, "ls_index",
3222                             clib_net_to_host_u32 (mp->ls_index));
3223   vec_free (ls_name);
3224 }
3225
3226 typedef struct
3227 {
3228   u32 spi;
3229   u8 si;
3230 } __attribute__ ((__packed__)) lisp_nsh_api_t;
3231
3232 uword
3233 unformat_nsh_address (unformat_input_t * input, va_list * args)
3234 {
3235   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
3236   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
3237 }
3238
3239 u8 *
3240 format_nsh_address_vat (u8 * s, va_list * args)
3241 {
3242   nsh_t *a = va_arg (*args, nsh_t *);
3243   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
3244 }
3245
3246 static u8 *
3247 format_lisp_flat_eid (u8 * s, va_list * args)
3248 {
3249   u32 type = va_arg (*args, u32);
3250   u8 *eid = va_arg (*args, u8 *);
3251   u32 eid_len = va_arg (*args, u32);
3252
3253   switch (type)
3254     {
3255     case 0:
3256       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
3257     case 1:
3258       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
3259     case 2:
3260       return format (s, "%U", format_ethernet_address, eid);
3261     case 3:
3262       return format (s, "%U", format_nsh_address_vat, eid);
3263     }
3264   return 0;
3265 }
3266
3267 static u8 *
3268 format_lisp_eid_vat (u8 * s, va_list * args)
3269 {
3270   u32 type = va_arg (*args, u32);
3271   u8 *eid = va_arg (*args, u8 *);
3272   u32 eid_len = va_arg (*args, u32);
3273   u8 *seid = va_arg (*args, u8 *);
3274   u32 seid_len = va_arg (*args, u32);
3275   u32 is_src_dst = va_arg (*args, u32);
3276
3277   if (is_src_dst)
3278     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3279
3280   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3281
3282   return s;
3283 }
3284
3285 static void
3286 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   u8 *s = 0, *eid = 0;
3290
3291   if (~0 == mp->locator_set_index)
3292     s = format (0, "action: %d", mp->action);
3293   else
3294     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3295
3296   eid = format (0, "%U", format_lisp_eid_vat,
3297                 mp->eid_type,
3298                 mp->eid,
3299                 mp->eid_prefix_len,
3300                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3301   vec_add1 (eid, 0);
3302
3303   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3304          clib_net_to_host_u32 (mp->vni),
3305          eid,
3306          mp->is_local ? "local" : "remote",
3307          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3308          clib_net_to_host_u16 (mp->key_id), mp->key);
3309
3310   vec_free (s);
3311   vec_free (eid);
3312 }
3313
3314 static void
3315 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3316                                              * mp)
3317 {
3318   vat_main_t *vam = &vat_main;
3319   vat_json_node_t *node = 0;
3320   u8 *eid = 0;
3321
3322   if (VAT_JSON_ARRAY != vam->json_tree.type)
3323     {
3324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3325       vat_json_init_array (&vam->json_tree);
3326     }
3327   node = vat_json_array_add (&vam->json_tree);
3328
3329   vat_json_init_object (node);
3330   if (~0 == mp->locator_set_index)
3331     vat_json_object_add_uint (node, "action", mp->action);
3332   else
3333     vat_json_object_add_uint (node, "locator_set_index",
3334                               clib_net_to_host_u32 (mp->locator_set_index));
3335
3336   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3337   if (mp->eid_type == 3)
3338     {
3339       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3340       vat_json_init_object (nsh_json);
3341       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3342       vat_json_object_add_uint (nsh_json, "spi",
3343                                 clib_net_to_host_u32 (nsh->spi));
3344       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3345     }
3346   else
3347     {
3348       eid = format (0, "%U", format_lisp_eid_vat,
3349                     mp->eid_type,
3350                     mp->eid,
3351                     mp->eid_prefix_len,
3352                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3353       vec_add1 (eid, 0);
3354       vat_json_object_add_string_copy (node, "eid", eid);
3355       vec_free (eid);
3356     }
3357   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3358   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3359   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3360
3361   if (mp->key_id)
3362     {
3363       vat_json_object_add_uint (node, "key_id",
3364                                 clib_net_to_host_u16 (mp->key_id));
3365       vat_json_object_add_string_copy (node, "key", mp->key);
3366     }
3367 }
3368
3369 static void
3370 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373   u8 *seid = 0, *deid = 0;
3374   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3375
3376   deid = format (0, "%U", format_lisp_eid_vat,
3377                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3378
3379   seid = format (0, "%U", format_lisp_eid_vat,
3380                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3381
3382   vec_add1 (deid, 0);
3383   vec_add1 (seid, 0);
3384
3385   if (mp->is_ip4)
3386     format_ip_address_fcn = format_ip4_address;
3387   else
3388     format_ip_address_fcn = format_ip6_address;
3389
3390
3391   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3392          clib_net_to_host_u32 (mp->vni),
3393          seid, deid,
3394          format_ip_address_fcn, mp->lloc,
3395          format_ip_address_fcn, mp->rloc,
3396          clib_net_to_host_u32 (mp->pkt_count),
3397          clib_net_to_host_u32 (mp->bytes));
3398
3399   vec_free (deid);
3400   vec_free (seid);
3401 }
3402
3403 static void
3404 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3405 {
3406   struct in6_addr ip6;
3407   struct in_addr ip4;
3408   vat_main_t *vam = &vat_main;
3409   vat_json_node_t *node = 0;
3410   u8 *deid = 0, *seid = 0;
3411
3412   if (VAT_JSON_ARRAY != vam->json_tree.type)
3413     {
3414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415       vat_json_init_array (&vam->json_tree);
3416     }
3417   node = vat_json_array_add (&vam->json_tree);
3418
3419   vat_json_init_object (node);
3420   deid = format (0, "%U", format_lisp_eid_vat,
3421                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3422
3423   seid = format (0, "%U", format_lisp_eid_vat,
3424                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3425
3426   vec_add1 (deid, 0);
3427   vec_add1 (seid, 0);
3428
3429   vat_json_object_add_string_copy (node, "seid", seid);
3430   vat_json_object_add_string_copy (node, "deid", deid);
3431   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3432
3433   if (mp->is_ip4)
3434     {
3435       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3436       vat_json_object_add_ip4 (node, "lloc", ip4);
3437       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3438       vat_json_object_add_ip4 (node, "rloc", ip4);
3439     }
3440   else
3441     {
3442       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3443       vat_json_object_add_ip6 (node, "lloc", ip6);
3444       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3445       vat_json_object_add_ip6 (node, "rloc", ip6);
3446     }
3447   vat_json_object_add_uint (node, "pkt_count",
3448                             clib_net_to_host_u32 (mp->pkt_count));
3449   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3450
3451   vec_free (deid);
3452   vec_free (seid);
3453 }
3454
3455 static void
3456   vl_api_one_eid_table_map_details_t_handler
3457   (vl_api_one_eid_table_map_details_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460
3461   u8 *line = format (0, "%=10d%=10d",
3462                      clib_net_to_host_u32 (mp->vni),
3463                      clib_net_to_host_u32 (mp->dp_table));
3464   print (vam->ofp, "%v", line);
3465   vec_free (line);
3466 }
3467
3468 static void
3469   vl_api_one_eid_table_map_details_t_handler_json
3470   (vl_api_one_eid_table_map_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473   vat_json_node_t *node = NULL;
3474
3475   if (VAT_JSON_ARRAY != vam->json_tree.type)
3476     {
3477       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3478       vat_json_init_array (&vam->json_tree);
3479     }
3480   node = vat_json_array_add (&vam->json_tree);
3481   vat_json_init_object (node);
3482   vat_json_object_add_uint (node, "dp_table",
3483                             clib_net_to_host_u32 (mp->dp_table));
3484   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3485 }
3486
3487 static void
3488   vl_api_one_eid_table_vni_details_t_handler
3489   (vl_api_one_eid_table_vni_details_t * mp)
3490 {
3491   vat_main_t *vam = &vat_main;
3492
3493   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3494   print (vam->ofp, "%v", line);
3495   vec_free (line);
3496 }
3497
3498 static void
3499   vl_api_one_eid_table_vni_details_t_handler_json
3500   (vl_api_one_eid_table_vni_details_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503   vat_json_node_t *node = NULL;
3504
3505   if (VAT_JSON_ARRAY != vam->json_tree.type)
3506     {
3507       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3508       vat_json_init_array (&vam->json_tree);
3509     }
3510   node = vat_json_array_add (&vam->json_tree);
3511   vat_json_init_object (node);
3512   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3513 }
3514
3515 static void
3516   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3517   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3518 {
3519   vat_main_t *vam = &vat_main;
3520   int retval = clib_net_to_host_u32 (mp->retval);
3521
3522   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3523   print (vam->ofp, "fallback threshold value: %d", mp->value);
3524
3525   vam->retval = retval;
3526   vam->result_ready = 1;
3527 }
3528
3529 static void
3530   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3531   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3532 {
3533   vat_main_t *vam = &vat_main;
3534   vat_json_node_t _node, *node = &_node;
3535   int retval = clib_net_to_host_u32 (mp->retval);
3536
3537   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3538   vat_json_init_object (node);
3539   vat_json_object_add_uint (node, "value", mp->value);
3540
3541   vat_json_print (vam->ofp, node);
3542   vat_json_free (node);
3543
3544   vam->retval = retval;
3545   vam->result_ready = 1;
3546 }
3547
3548 static void
3549   vl_api_show_one_map_register_state_reply_t_handler
3550   (vl_api_show_one_map_register_state_reply_t * mp)
3551 {
3552   vat_main_t *vam = &vat_main;
3553   int retval = clib_net_to_host_u32 (mp->retval);
3554
3555   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3556
3557   vam->retval = retval;
3558   vam->result_ready = 1;
3559 }
3560
3561 static void
3562   vl_api_show_one_map_register_state_reply_t_handler_json
3563   (vl_api_show_one_map_register_state_reply_t * mp)
3564 {
3565   vat_main_t *vam = &vat_main;
3566   vat_json_node_t _node, *node = &_node;
3567   int retval = clib_net_to_host_u32 (mp->retval);
3568
3569   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3570
3571   vat_json_init_object (node);
3572   vat_json_object_add_string_copy (node, "state", s);
3573
3574   vat_json_print (vam->ofp, node);
3575   vat_json_free (node);
3576
3577   vam->retval = retval;
3578   vam->result_ready = 1;
3579   vec_free (s);
3580 }
3581
3582 static void
3583   vl_api_show_one_rloc_probe_state_reply_t_handler
3584   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   int retval = clib_net_to_host_u32 (mp->retval);
3588
3589   if (retval)
3590     goto end;
3591
3592   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3593 end:
3594   vam->retval = retval;
3595   vam->result_ready = 1;
3596 }
3597
3598 static void
3599   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3600   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3601 {
3602   vat_main_t *vam = &vat_main;
3603   vat_json_node_t _node, *node = &_node;
3604   int retval = clib_net_to_host_u32 (mp->retval);
3605
3606   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3607   vat_json_init_object (node);
3608   vat_json_object_add_string_copy (node, "state", s);
3609
3610   vat_json_print (vam->ofp, node);
3611   vat_json_free (node);
3612
3613   vam->retval = retval;
3614   vam->result_ready = 1;
3615   vec_free (s);
3616 }
3617
3618 static void
3619   vl_api_show_one_stats_enable_disable_reply_t_handler
3620   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3621 {
3622   vat_main_t *vam = &vat_main;
3623   int retval = clib_net_to_host_u32 (mp->retval);
3624
3625   if (retval)
3626     goto end;
3627
3628   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3629 end:
3630   vam->retval = retval;
3631   vam->result_ready = 1;
3632 }
3633
3634 static void
3635   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3636   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3637 {
3638   vat_main_t *vam = &vat_main;
3639   vat_json_node_t _node, *node = &_node;
3640   int retval = clib_net_to_host_u32 (mp->retval);
3641
3642   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3643   vat_json_init_object (node);
3644   vat_json_object_add_string_copy (node, "state", s);
3645
3646   vat_json_print (vam->ofp, node);
3647   vat_json_free (node);
3648
3649   vam->retval = retval;
3650   vam->result_ready = 1;
3651   vec_free (s);
3652 }
3653
3654 static void
3655 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3656 {
3657   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3658   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3659   e->vni = clib_net_to_host_u32 (e->vni);
3660 }
3661
3662 static void
3663   gpe_fwd_entries_get_reply_t_net_to_host
3664   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3665 {
3666   u32 i;
3667
3668   mp->count = clib_net_to_host_u32 (mp->count);
3669   for (i = 0; i < mp->count; i++)
3670     {
3671       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3672     }
3673 }
3674
3675 static u8 *
3676 format_gpe_encap_mode (u8 * s, va_list * args)
3677 {
3678   u32 mode = va_arg (*args, u32);
3679
3680   switch (mode)
3681     {
3682     case 0:
3683       return format (s, "lisp");
3684     case 1:
3685       return format (s, "vxlan");
3686     }
3687   return 0;
3688 }
3689
3690 static void
3691   vl_api_gpe_get_encap_mode_reply_t_handler
3692   (vl_api_gpe_get_encap_mode_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695
3696   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3697   vam->retval = ntohl (mp->retval);
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_gpe_get_encap_mode_reply_t_handler_json
3703   (vl_api_gpe_get_encap_mode_reply_t * mp)
3704 {
3705   vat_main_t *vam = &vat_main;
3706   vat_json_node_t node;
3707
3708   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3709   vec_add1 (encap_mode, 0);
3710
3711   vat_json_init_object (&node);
3712   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3713
3714   vec_free (encap_mode);
3715   vat_json_print (vam->ofp, &node);
3716   vat_json_free (&node);
3717
3718   vam->retval = ntohl (mp->retval);
3719   vam->result_ready = 1;
3720 }
3721
3722 static void
3723   vl_api_gpe_fwd_entry_path_details_t_handler
3724   (vl_api_gpe_fwd_entry_path_details_t * mp)
3725 {
3726   vat_main_t *vam = &vat_main;
3727   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3728
3729   if (mp->lcl_loc.is_ip4)
3730     format_ip_address_fcn = format_ip4_address;
3731   else
3732     format_ip_address_fcn = format_ip6_address;
3733
3734   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3735          format_ip_address_fcn, &mp->lcl_loc,
3736          format_ip_address_fcn, &mp->rmt_loc);
3737 }
3738
3739 static void
3740 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3741 {
3742   struct in6_addr ip6;
3743   struct in_addr ip4;
3744
3745   if (loc->is_ip4)
3746     {
3747       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3748       vat_json_object_add_ip4 (n, "address", ip4);
3749     }
3750   else
3751     {
3752       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3753       vat_json_object_add_ip6 (n, "address", ip6);
3754     }
3755   vat_json_object_add_uint (n, "weight", loc->weight);
3756 }
3757
3758 static void
3759   vl_api_gpe_fwd_entry_path_details_t_handler_json
3760   (vl_api_gpe_fwd_entry_path_details_t * mp)
3761 {
3762   vat_main_t *vam = &vat_main;
3763   vat_json_node_t *node = NULL;
3764   vat_json_node_t *loc_node;
3765
3766   if (VAT_JSON_ARRAY != vam->json_tree.type)
3767     {
3768       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3769       vat_json_init_array (&vam->json_tree);
3770     }
3771   node = vat_json_array_add (&vam->json_tree);
3772   vat_json_init_object (node);
3773
3774   loc_node = vat_json_object_add (node, "local_locator");
3775   vat_json_init_object (loc_node);
3776   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3777
3778   loc_node = vat_json_object_add (node, "remote_locator");
3779   vat_json_init_object (loc_node);
3780   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3781 }
3782
3783 static void
3784   vl_api_gpe_fwd_entries_get_reply_t_handler
3785   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3786 {
3787   vat_main_t *vam = &vat_main;
3788   u32 i;
3789   int retval = clib_net_to_host_u32 (mp->retval);
3790   vl_api_gpe_fwd_entry_t *e;
3791
3792   if (retval)
3793     goto end;
3794
3795   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3796
3797   for (i = 0; i < mp->count; i++)
3798     {
3799       e = &mp->entries[i];
3800       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3801              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3802              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3803     }
3804
3805 end:
3806   vam->retval = retval;
3807   vam->result_ready = 1;
3808 }
3809
3810 static void
3811   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3812   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3813 {
3814   u8 *s = 0;
3815   vat_main_t *vam = &vat_main;
3816   vat_json_node_t *e = 0, root;
3817   u32 i;
3818   int retval = clib_net_to_host_u32 (mp->retval);
3819   vl_api_gpe_fwd_entry_t *fwd;
3820
3821   if (retval)
3822     goto end;
3823
3824   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3825   vat_json_init_array (&root);
3826
3827   for (i = 0; i < mp->count; i++)
3828     {
3829       e = vat_json_array_add (&root);
3830       fwd = &mp->entries[i];
3831
3832       vat_json_init_object (e);
3833       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3834       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3835       vat_json_object_add_int (e, "vni", fwd->vni);
3836       vat_json_object_add_int (e, "action", fwd->action);
3837
3838       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3839                   fwd->leid_prefix_len);
3840       vec_add1 (s, 0);
3841       vat_json_object_add_string_copy (e, "leid", s);
3842       vec_free (s);
3843
3844       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3845                   fwd->reid_prefix_len);
3846       vec_add1 (s, 0);
3847       vat_json_object_add_string_copy (e, "reid", s);
3848       vec_free (s);
3849     }
3850
3851   vat_json_print (vam->ofp, &root);
3852   vat_json_free (&root);
3853
3854 end:
3855   vam->retval = retval;
3856   vam->result_ready = 1;
3857 }
3858
3859 static void
3860   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3861   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3862 {
3863   vat_main_t *vam = &vat_main;
3864   u32 i, n;
3865   int retval = clib_net_to_host_u32 (mp->retval);
3866   vl_api_gpe_native_fwd_rpath_t *r;
3867
3868   if (retval)
3869     goto end;
3870
3871   n = clib_net_to_host_u32 (mp->count);
3872
3873   for (i = 0; i < n; i++)
3874     {
3875       r = &mp->entries[i];
3876       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3877              clib_net_to_host_u32 (r->fib_index),
3878              clib_net_to_host_u32 (r->nh_sw_if_index),
3879              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3880     }
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3889   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3890 {
3891   vat_main_t *vam = &vat_main;
3892   vat_json_node_t root, *e;
3893   u32 i, n;
3894   int retval = clib_net_to_host_u32 (mp->retval);
3895   vl_api_gpe_native_fwd_rpath_t *r;
3896   u8 *s;
3897
3898   if (retval)
3899     goto end;
3900
3901   n = clib_net_to_host_u32 (mp->count);
3902   vat_json_init_array (&root);
3903
3904   for (i = 0; i < n; i++)
3905     {
3906       e = vat_json_array_add (&root);
3907       vat_json_init_object (e);
3908       r = &mp->entries[i];
3909       s =
3910         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3911                 r->nh_addr);
3912       vec_add1 (s, 0);
3913       vat_json_object_add_string_copy (e, "ip4", s);
3914       vec_free (s);
3915
3916       vat_json_object_add_uint (e, "fib_index",
3917                                 clib_net_to_host_u32 (r->fib_index));
3918       vat_json_object_add_uint (e, "nh_sw_if_index",
3919                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3920     }
3921
3922   vat_json_print (vam->ofp, &root);
3923   vat_json_free (&root);
3924
3925 end:
3926   vam->retval = retval;
3927   vam->result_ready = 1;
3928 }
3929
3930 static void
3931   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3932   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3933 {
3934   vat_main_t *vam = &vat_main;
3935   u32 i, n;
3936   int retval = clib_net_to_host_u32 (mp->retval);
3937
3938   if (retval)
3939     goto end;
3940
3941   n = clib_net_to_host_u32 (mp->count);
3942
3943   for (i = 0; i < n; i++)
3944     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3945
3946 end:
3947   vam->retval = retval;
3948   vam->result_ready = 1;
3949 }
3950
3951 static void
3952   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3953   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3954 {
3955   vat_main_t *vam = &vat_main;
3956   vat_json_node_t root;
3957   u32 i, n;
3958   int retval = clib_net_to_host_u32 (mp->retval);
3959
3960   if (retval)
3961     goto end;
3962
3963   n = clib_net_to_host_u32 (mp->count);
3964   vat_json_init_array (&root);
3965
3966   for (i = 0; i < n; i++)
3967     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3968
3969   vat_json_print (vam->ofp, &root);
3970   vat_json_free (&root);
3971
3972 end:
3973   vam->retval = retval;
3974   vam->result_ready = 1;
3975 }
3976
3977 static void
3978   vl_api_one_ndp_entries_get_reply_t_handler
3979   (vl_api_one_ndp_entries_get_reply_t * mp)
3980 {
3981   vat_main_t *vam = &vat_main;
3982   u32 i, n;
3983   int retval = clib_net_to_host_u32 (mp->retval);
3984
3985   if (retval)
3986     goto end;
3987
3988   n = clib_net_to_host_u32 (mp->count);
3989
3990   for (i = 0; i < n; i++)
3991     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3992            format_ethernet_address, mp->entries[i].mac);
3993
3994 end:
3995   vam->retval = retval;
3996   vam->result_ready = 1;
3997 }
3998
3999 static void
4000   vl_api_one_ndp_entries_get_reply_t_handler_json
4001   (vl_api_one_ndp_entries_get_reply_t * mp)
4002 {
4003   u8 *s = 0;
4004   vat_main_t *vam = &vat_main;
4005   vat_json_node_t *e = 0, root;
4006   u32 i, n;
4007   int retval = clib_net_to_host_u32 (mp->retval);
4008   vl_api_one_ndp_entry_t *arp_entry;
4009
4010   if (retval)
4011     goto end;
4012
4013   n = clib_net_to_host_u32 (mp->count);
4014   vat_json_init_array (&root);
4015
4016   for (i = 0; i < n; i++)
4017     {
4018       e = vat_json_array_add (&root);
4019       arp_entry = &mp->entries[i];
4020
4021       vat_json_init_object (e);
4022       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4023       vec_add1 (s, 0);
4024
4025       vat_json_object_add_string_copy (e, "mac", s);
4026       vec_free (s);
4027
4028       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
4029       vec_add1 (s, 0);
4030       vat_json_object_add_string_copy (e, "ip6", s);
4031       vec_free (s);
4032     }
4033
4034   vat_json_print (vam->ofp, &root);
4035   vat_json_free (&root);
4036
4037 end:
4038   vam->retval = retval;
4039   vam->result_ready = 1;
4040 }
4041
4042 static void
4043   vl_api_one_l2_arp_entries_get_reply_t_handler
4044   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4045 {
4046   vat_main_t *vam = &vat_main;
4047   u32 i, n;
4048   int retval = clib_net_to_host_u32 (mp->retval);
4049
4050   if (retval)
4051     goto end;
4052
4053   n = clib_net_to_host_u32 (mp->count);
4054
4055   for (i = 0; i < n; i++)
4056     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
4057            format_ethernet_address, mp->entries[i].mac);
4058
4059 end:
4060   vam->retval = retval;
4061   vam->result_ready = 1;
4062 }
4063
4064 static void
4065   vl_api_one_l2_arp_entries_get_reply_t_handler_json
4066   (vl_api_one_l2_arp_entries_get_reply_t * mp)
4067 {
4068   u8 *s = 0;
4069   vat_main_t *vam = &vat_main;
4070   vat_json_node_t *e = 0, root;
4071   u32 i, n;
4072   int retval = clib_net_to_host_u32 (mp->retval);
4073   vl_api_one_l2_arp_entry_t *arp_entry;
4074
4075   if (retval)
4076     goto end;
4077
4078   n = clib_net_to_host_u32 (mp->count);
4079   vat_json_init_array (&root);
4080
4081   for (i = 0; i < n; i++)
4082     {
4083       e = vat_json_array_add (&root);
4084       arp_entry = &mp->entries[i];
4085
4086       vat_json_init_object (e);
4087       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
4088       vec_add1 (s, 0);
4089
4090       vat_json_object_add_string_copy (e, "mac", s);
4091       vec_free (s);
4092
4093       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
4094       vec_add1 (s, 0);
4095       vat_json_object_add_string_copy (e, "ip4", s);
4096       vec_free (s);
4097     }
4098
4099   vat_json_print (vam->ofp, &root);
4100   vat_json_free (&root);
4101
4102 end:
4103   vam->retval = retval;
4104   vam->result_ready = 1;
4105 }
4106
4107 static void
4108 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
4109 {
4110   vat_main_t *vam = &vat_main;
4111   u32 i, n;
4112   int retval = clib_net_to_host_u32 (mp->retval);
4113
4114   if (retval)
4115     goto end;
4116
4117   n = clib_net_to_host_u32 (mp->count);
4118
4119   for (i = 0; i < n; i++)
4120     {
4121       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4122     }
4123
4124 end:
4125   vam->retval = retval;
4126   vam->result_ready = 1;
4127 }
4128
4129 static void
4130   vl_api_one_ndp_bd_get_reply_t_handler_json
4131   (vl_api_one_ndp_bd_get_reply_t * mp)
4132 {
4133   vat_main_t *vam = &vat_main;
4134   vat_json_node_t root;
4135   u32 i, n;
4136   int retval = clib_net_to_host_u32 (mp->retval);
4137
4138   if (retval)
4139     goto end;
4140
4141   n = clib_net_to_host_u32 (mp->count);
4142   vat_json_init_array (&root);
4143
4144   for (i = 0; i < n; i++)
4145     {
4146       vat_json_array_add_uint (&root,
4147                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4148     }
4149
4150   vat_json_print (vam->ofp, &root);
4151   vat_json_free (&root);
4152
4153 end:
4154   vam->retval = retval;
4155   vam->result_ready = 1;
4156 }
4157
4158 static void
4159   vl_api_one_l2_arp_bd_get_reply_t_handler
4160   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4161 {
4162   vat_main_t *vam = &vat_main;
4163   u32 i, n;
4164   int retval = clib_net_to_host_u32 (mp->retval);
4165
4166   if (retval)
4167     goto end;
4168
4169   n = clib_net_to_host_u32 (mp->count);
4170
4171   for (i = 0; i < n; i++)
4172     {
4173       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
4174     }
4175
4176 end:
4177   vam->retval = retval;
4178   vam->result_ready = 1;
4179 }
4180
4181 static void
4182   vl_api_one_l2_arp_bd_get_reply_t_handler_json
4183   (vl_api_one_l2_arp_bd_get_reply_t * mp)
4184 {
4185   vat_main_t *vam = &vat_main;
4186   vat_json_node_t root;
4187   u32 i, n;
4188   int retval = clib_net_to_host_u32 (mp->retval);
4189
4190   if (retval)
4191     goto end;
4192
4193   n = clib_net_to_host_u32 (mp->count);
4194   vat_json_init_array (&root);
4195
4196   for (i = 0; i < n; i++)
4197     {
4198       vat_json_array_add_uint (&root,
4199                                clib_net_to_host_u32 (mp->bridge_domains[i]));
4200     }
4201
4202   vat_json_print (vam->ofp, &root);
4203   vat_json_free (&root);
4204
4205 end:
4206   vam->retval = retval;
4207   vam->result_ready = 1;
4208 }
4209
4210 static void
4211   vl_api_one_adjacencies_get_reply_t_handler
4212   (vl_api_one_adjacencies_get_reply_t * mp)
4213 {
4214   vat_main_t *vam = &vat_main;
4215   u32 i, n;
4216   int retval = clib_net_to_host_u32 (mp->retval);
4217   vl_api_one_adjacency_t *a;
4218
4219   if (retval)
4220     goto end;
4221
4222   n = clib_net_to_host_u32 (mp->count);
4223
4224   for (i = 0; i < n; i++)
4225     {
4226       a = &mp->adjacencies[i];
4227       print (vam->ofp, "%U %40U",
4228              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
4229              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
4230     }
4231
4232 end:
4233   vam->retval = retval;
4234   vam->result_ready = 1;
4235 }
4236
4237 static void
4238   vl_api_one_adjacencies_get_reply_t_handler_json
4239   (vl_api_one_adjacencies_get_reply_t * mp)
4240 {
4241   u8 *s = 0;
4242   vat_main_t *vam = &vat_main;
4243   vat_json_node_t *e = 0, root;
4244   u32 i, n;
4245   int retval = clib_net_to_host_u32 (mp->retval);
4246   vl_api_one_adjacency_t *a;
4247
4248   if (retval)
4249     goto end;
4250
4251   n = clib_net_to_host_u32 (mp->count);
4252   vat_json_init_array (&root);
4253
4254   for (i = 0; i < n; i++)
4255     {
4256       e = vat_json_array_add (&root);
4257       a = &mp->adjacencies[i];
4258
4259       vat_json_init_object (e);
4260       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4261                   a->leid_prefix_len);
4262       vec_add1 (s, 0);
4263       vat_json_object_add_string_copy (e, "leid", s);
4264       vec_free (s);
4265
4266       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4267                   a->reid_prefix_len);
4268       vec_add1 (s, 0);
4269       vat_json_object_add_string_copy (e, "reid", s);
4270       vec_free (s);
4271     }
4272
4273   vat_json_print (vam->ofp, &root);
4274   vat_json_free (&root);
4275
4276 end:
4277   vam->retval = retval;
4278   vam->result_ready = 1;
4279 }
4280
4281 static void
4282 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285
4286   print (vam->ofp, "%=20U",
4287          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4288          mp->ip_address);
4289 }
4290
4291 static void
4292   vl_api_one_map_server_details_t_handler_json
4293   (vl_api_one_map_server_details_t * mp)
4294 {
4295   vat_main_t *vam = &vat_main;
4296   vat_json_node_t *node = NULL;
4297   struct in6_addr ip6;
4298   struct in_addr ip4;
4299
4300   if (VAT_JSON_ARRAY != vam->json_tree.type)
4301     {
4302       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4303       vat_json_init_array (&vam->json_tree);
4304     }
4305   node = vat_json_array_add (&vam->json_tree);
4306
4307   vat_json_init_object (node);
4308   if (mp->is_ipv6)
4309     {
4310       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4311       vat_json_object_add_ip6 (node, "map-server", ip6);
4312     }
4313   else
4314     {
4315       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4316       vat_json_object_add_ip4 (node, "map-server", ip4);
4317     }
4318 }
4319
4320 static void
4321 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4322                                            * mp)
4323 {
4324   vat_main_t *vam = &vat_main;
4325
4326   print (vam->ofp, "%=20U",
4327          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4328          mp->ip_address);
4329 }
4330
4331 static void
4332   vl_api_one_map_resolver_details_t_handler_json
4333   (vl_api_one_map_resolver_details_t * mp)
4334 {
4335   vat_main_t *vam = &vat_main;
4336   vat_json_node_t *node = NULL;
4337   struct in6_addr ip6;
4338   struct in_addr ip4;
4339
4340   if (VAT_JSON_ARRAY != vam->json_tree.type)
4341     {
4342       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4343       vat_json_init_array (&vam->json_tree);
4344     }
4345   node = vat_json_array_add (&vam->json_tree);
4346
4347   vat_json_init_object (node);
4348   if (mp->is_ipv6)
4349     {
4350       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4351       vat_json_object_add_ip6 (node, "map resolver", ip6);
4352     }
4353   else
4354     {
4355       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4356       vat_json_object_add_ip4 (node, "map resolver", ip4);
4357     }
4358 }
4359
4360 static void
4361 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4362 {
4363   vat_main_t *vam = &vat_main;
4364   i32 retval = ntohl (mp->retval);
4365
4366   if (0 <= retval)
4367     {
4368       print (vam->ofp, "feature: %s\ngpe: %s",
4369              mp->feature_status ? "enabled" : "disabled",
4370              mp->gpe_status ? "enabled" : "disabled");
4371     }
4372
4373   vam->retval = retval;
4374   vam->result_ready = 1;
4375 }
4376
4377 static void
4378   vl_api_show_one_status_reply_t_handler_json
4379   (vl_api_show_one_status_reply_t * mp)
4380 {
4381   vat_main_t *vam = &vat_main;
4382   vat_json_node_t node;
4383   u8 *gpe_status = NULL;
4384   u8 *feature_status = NULL;
4385
4386   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4387   feature_status = format (0, "%s",
4388                            mp->feature_status ? "enabled" : "disabled");
4389   vec_add1 (gpe_status, 0);
4390   vec_add1 (feature_status, 0);
4391
4392   vat_json_init_object (&node);
4393   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4394   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4395
4396   vec_free (gpe_status);
4397   vec_free (feature_status);
4398
4399   vat_json_print (vam->ofp, &node);
4400   vat_json_free (&node);
4401
4402   vam->retval = ntohl (mp->retval);
4403   vam->result_ready = 1;
4404 }
4405
4406 static void
4407   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4408   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4409 {
4410   vat_main_t *vam = &vat_main;
4411   i32 retval = ntohl (mp->retval);
4412
4413   if (retval >= 0)
4414     {
4415       print (vam->ofp, "%=20s", mp->locator_set_name);
4416     }
4417
4418   vam->retval = retval;
4419   vam->result_ready = 1;
4420 }
4421
4422 static void
4423   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4424   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4425 {
4426   vat_main_t *vam = &vat_main;
4427   vat_json_node_t *node = NULL;
4428
4429   if (VAT_JSON_ARRAY != vam->json_tree.type)
4430     {
4431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4432       vat_json_init_array (&vam->json_tree);
4433     }
4434   node = vat_json_array_add (&vam->json_tree);
4435
4436   vat_json_init_object (node);
4437   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4438
4439   vat_json_print (vam->ofp, node);
4440   vat_json_free (node);
4441
4442   vam->retval = ntohl (mp->retval);
4443   vam->result_ready = 1;
4444 }
4445
4446 static u8 *
4447 format_lisp_map_request_mode (u8 * s, va_list * args)
4448 {
4449   u32 mode = va_arg (*args, u32);
4450
4451   switch (mode)
4452     {
4453     case 0:
4454       return format (0, "dst-only");
4455     case 1:
4456       return format (0, "src-dst");
4457     }
4458   return 0;
4459 }
4460
4461 static void
4462   vl_api_show_one_map_request_mode_reply_t_handler
4463   (vl_api_show_one_map_request_mode_reply_t * mp)
4464 {
4465   vat_main_t *vam = &vat_main;
4466   i32 retval = ntohl (mp->retval);
4467
4468   if (0 <= retval)
4469     {
4470       u32 mode = mp->mode;
4471       print (vam->ofp, "map_request_mode: %U",
4472              format_lisp_map_request_mode, mode);
4473     }
4474
4475   vam->retval = retval;
4476   vam->result_ready = 1;
4477 }
4478
4479 static void
4480   vl_api_show_one_map_request_mode_reply_t_handler_json
4481   (vl_api_show_one_map_request_mode_reply_t * mp)
4482 {
4483   vat_main_t *vam = &vat_main;
4484   vat_json_node_t node;
4485   u8 *s = 0;
4486   u32 mode;
4487
4488   mode = mp->mode;
4489   s = format (0, "%U", format_lisp_map_request_mode, mode);
4490   vec_add1 (s, 0);
4491
4492   vat_json_init_object (&node);
4493   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4494   vat_json_print (vam->ofp, &node);
4495   vat_json_free (&node);
4496
4497   vec_free (s);
4498   vam->retval = ntohl (mp->retval);
4499   vam->result_ready = 1;
4500 }
4501
4502 static void
4503   vl_api_one_show_xtr_mode_reply_t_handler
4504   (vl_api_one_show_xtr_mode_reply_t * mp)
4505 {
4506   vat_main_t *vam = &vat_main;
4507   i32 retval = ntohl (mp->retval);
4508
4509   if (0 <= retval)
4510     {
4511       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4512     }
4513
4514   vam->retval = retval;
4515   vam->result_ready = 1;
4516 }
4517
4518 static void
4519   vl_api_one_show_xtr_mode_reply_t_handler_json
4520   (vl_api_one_show_xtr_mode_reply_t * mp)
4521 {
4522   vat_main_t *vam = &vat_main;
4523   vat_json_node_t node;
4524   u8 *status = 0;
4525
4526   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4527   vec_add1 (status, 0);
4528
4529   vat_json_init_object (&node);
4530   vat_json_object_add_string_copy (&node, "status", status);
4531
4532   vec_free (status);
4533
4534   vat_json_print (vam->ofp, &node);
4535   vat_json_free (&node);
4536
4537   vam->retval = ntohl (mp->retval);
4538   vam->result_ready = 1;
4539 }
4540
4541 static void
4542   vl_api_one_show_pitr_mode_reply_t_handler
4543   (vl_api_one_show_pitr_mode_reply_t * mp)
4544 {
4545   vat_main_t *vam = &vat_main;
4546   i32 retval = ntohl (mp->retval);
4547
4548   if (0 <= retval)
4549     {
4550       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4551     }
4552
4553   vam->retval = retval;
4554   vam->result_ready = 1;
4555 }
4556
4557 static void
4558   vl_api_one_show_pitr_mode_reply_t_handler_json
4559   (vl_api_one_show_pitr_mode_reply_t * mp)
4560 {
4561   vat_main_t *vam = &vat_main;
4562   vat_json_node_t node;
4563   u8 *status = 0;
4564
4565   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4566   vec_add1 (status, 0);
4567
4568   vat_json_init_object (&node);
4569   vat_json_object_add_string_copy (&node, "status", status);
4570
4571   vec_free (status);
4572
4573   vat_json_print (vam->ofp, &node);
4574   vat_json_free (&node);
4575
4576   vam->retval = ntohl (mp->retval);
4577   vam->result_ready = 1;
4578 }
4579
4580 static void
4581   vl_api_one_show_petr_mode_reply_t_handler
4582   (vl_api_one_show_petr_mode_reply_t * mp)
4583 {
4584   vat_main_t *vam = &vat_main;
4585   i32 retval = ntohl (mp->retval);
4586
4587   if (0 <= retval)
4588     {
4589       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4590     }
4591
4592   vam->retval = retval;
4593   vam->result_ready = 1;
4594 }
4595
4596 static void
4597   vl_api_one_show_petr_mode_reply_t_handler_json
4598   (vl_api_one_show_petr_mode_reply_t * mp)
4599 {
4600   vat_main_t *vam = &vat_main;
4601   vat_json_node_t node;
4602   u8 *status = 0;
4603
4604   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4605   vec_add1 (status, 0);
4606
4607   vat_json_init_object (&node);
4608   vat_json_object_add_string_copy (&node, "status", status);
4609
4610   vec_free (status);
4611
4612   vat_json_print (vam->ofp, &node);
4613   vat_json_free (&node);
4614
4615   vam->retval = ntohl (mp->retval);
4616   vam->result_ready = 1;
4617 }
4618
4619 static void
4620   vl_api_show_one_use_petr_reply_t_handler
4621   (vl_api_show_one_use_petr_reply_t * mp)
4622 {
4623   vat_main_t *vam = &vat_main;
4624   i32 retval = ntohl (mp->retval);
4625
4626   if (0 <= retval)
4627     {
4628       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4629       if (mp->status)
4630         {
4631           print (vam->ofp, "Proxy-ETR address; %U",
4632                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4633                  mp->address);
4634         }
4635     }
4636
4637   vam->retval = retval;
4638   vam->result_ready = 1;
4639 }
4640
4641 static void
4642   vl_api_show_one_use_petr_reply_t_handler_json
4643   (vl_api_show_one_use_petr_reply_t * mp)
4644 {
4645   vat_main_t *vam = &vat_main;
4646   vat_json_node_t node;
4647   u8 *status = 0;
4648   struct in_addr ip4;
4649   struct in6_addr ip6;
4650
4651   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4652   vec_add1 (status, 0);
4653
4654   vat_json_init_object (&node);
4655   vat_json_object_add_string_copy (&node, "status", status);
4656   if (mp->status)
4657     {
4658       if (mp->is_ip4)
4659         {
4660           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4661           vat_json_object_add_ip6 (&node, "address", ip6);
4662         }
4663       else
4664         {
4665           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4666           vat_json_object_add_ip4 (&node, "address", ip4);
4667         }
4668     }
4669
4670   vec_free (status);
4671
4672   vat_json_print (vam->ofp, &node);
4673   vat_json_free (&node);
4674
4675   vam->retval = ntohl (mp->retval);
4676   vam->result_ready = 1;
4677 }
4678
4679 static void
4680   vl_api_show_one_nsh_mapping_reply_t_handler
4681   (vl_api_show_one_nsh_mapping_reply_t * mp)
4682 {
4683   vat_main_t *vam = &vat_main;
4684   i32 retval = ntohl (mp->retval);
4685
4686   if (0 <= retval)
4687     {
4688       print (vam->ofp, "%-20s%-16s",
4689              mp->is_set ? "set" : "not-set",
4690              mp->is_set ? (char *) mp->locator_set_name : "");
4691     }
4692
4693   vam->retval = retval;
4694   vam->result_ready = 1;
4695 }
4696
4697 static void
4698   vl_api_show_one_nsh_mapping_reply_t_handler_json
4699   (vl_api_show_one_nsh_mapping_reply_t * mp)
4700 {
4701   vat_main_t *vam = &vat_main;
4702   vat_json_node_t node;
4703   u8 *status = 0;
4704
4705   status = format (0, "%s", mp->is_set ? "yes" : "no");
4706   vec_add1 (status, 0);
4707
4708   vat_json_init_object (&node);
4709   vat_json_object_add_string_copy (&node, "is_set", status);
4710   if (mp->is_set)
4711     {
4712       vat_json_object_add_string_copy (&node, "locator_set",
4713                                        mp->locator_set_name);
4714     }
4715
4716   vec_free (status);
4717
4718   vat_json_print (vam->ofp, &node);
4719   vat_json_free (&node);
4720
4721   vam->retval = ntohl (mp->retval);
4722   vam->result_ready = 1;
4723 }
4724
4725 static void
4726   vl_api_show_one_map_register_ttl_reply_t_handler
4727   (vl_api_show_one_map_register_ttl_reply_t * mp)
4728 {
4729   vat_main_t *vam = &vat_main;
4730   i32 retval = ntohl (mp->retval);
4731
4732   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4733
4734   if (0 <= retval)
4735     {
4736       print (vam->ofp, "ttl: %u", mp->ttl);
4737     }
4738
4739   vam->retval = retval;
4740   vam->result_ready = 1;
4741 }
4742
4743 static void
4744   vl_api_show_one_map_register_ttl_reply_t_handler_json
4745   (vl_api_show_one_map_register_ttl_reply_t * mp)
4746 {
4747   vat_main_t *vam = &vat_main;
4748   vat_json_node_t node;
4749
4750   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4751   vat_json_init_object (&node);
4752   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4753
4754   vat_json_print (vam->ofp, &node);
4755   vat_json_free (&node);
4756
4757   vam->retval = ntohl (mp->retval);
4758   vam->result_ready = 1;
4759 }
4760
4761 static void
4762 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4763 {
4764   vat_main_t *vam = &vat_main;
4765   i32 retval = ntohl (mp->retval);
4766
4767   if (0 <= retval)
4768     {
4769       print (vam->ofp, "%-20s%-16s",
4770              mp->status ? "enabled" : "disabled",
4771              mp->status ? (char *) mp->locator_set_name : "");
4772     }
4773
4774   vam->retval = retval;
4775   vam->result_ready = 1;
4776 }
4777
4778 static void
4779 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4780 {
4781   vat_main_t *vam = &vat_main;
4782   vat_json_node_t node;
4783   u8 *status = 0;
4784
4785   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4786   vec_add1 (status, 0);
4787
4788   vat_json_init_object (&node);
4789   vat_json_object_add_string_copy (&node, "status", status);
4790   if (mp->status)
4791     {
4792       vat_json_object_add_string_copy (&node, "locator_set",
4793                                        mp->locator_set_name);
4794     }
4795
4796   vec_free (status);
4797
4798   vat_json_print (vam->ofp, &node);
4799   vat_json_free (&node);
4800
4801   vam->retval = ntohl (mp->retval);
4802   vam->result_ready = 1;
4803 }
4804
4805 static u8 *
4806 format_policer_type (u8 * s, va_list * va)
4807 {
4808   u32 i = va_arg (*va, u32);
4809
4810   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4811     s = format (s, "1r2c");
4812   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4813     s = format (s, "1r3c");
4814   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4815     s = format (s, "2r3c-2698");
4816   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4817     s = format (s, "2r3c-4115");
4818   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4819     s = format (s, "2r3c-mef5cf1");
4820   else
4821     s = format (s, "ILLEGAL");
4822   return s;
4823 }
4824
4825 static u8 *
4826 format_policer_rate_type (u8 * s, va_list * va)
4827 {
4828   u32 i = va_arg (*va, u32);
4829
4830   if (i == SSE2_QOS_RATE_KBPS)
4831     s = format (s, "kbps");
4832   else if (i == SSE2_QOS_RATE_PPS)
4833     s = format (s, "pps");
4834   else
4835     s = format (s, "ILLEGAL");
4836   return s;
4837 }
4838
4839 static u8 *
4840 format_policer_round_type (u8 * s, va_list * va)
4841 {
4842   u32 i = va_arg (*va, u32);
4843
4844   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4845     s = format (s, "closest");
4846   else if (i == SSE2_QOS_ROUND_TO_UP)
4847     s = format (s, "up");
4848   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4849     s = format (s, "down");
4850   else
4851     s = format (s, "ILLEGAL");
4852   return s;
4853 }
4854
4855 static u8 *
4856 format_policer_action_type (u8 * s, va_list * va)
4857 {
4858   u32 i = va_arg (*va, u32);
4859
4860   if (i == SSE2_QOS_ACTION_DROP)
4861     s = format (s, "drop");
4862   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4863     s = format (s, "transmit");
4864   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4865     s = format (s, "mark-and-transmit");
4866   else
4867     s = format (s, "ILLEGAL");
4868   return s;
4869 }
4870
4871 static u8 *
4872 format_dscp (u8 * s, va_list * va)
4873 {
4874   u32 i = va_arg (*va, u32);
4875   char *t = 0;
4876
4877   switch (i)
4878     {
4879 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4880       foreach_vnet_dscp
4881 #undef _
4882     default:
4883       return format (s, "ILLEGAL");
4884     }
4885   s = format (s, "%s", t);
4886   return s;
4887 }
4888
4889 static void
4890 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4891 {
4892   vat_main_t *vam = &vat_main;
4893   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4894
4895   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4896     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4897   else
4898     conform_dscp_str = format (0, "");
4899
4900   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4901     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4902   else
4903     exceed_dscp_str = format (0, "");
4904
4905   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4906     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4907   else
4908     violate_dscp_str = format (0, "");
4909
4910   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4911          "rate type %U, round type %U, %s rate, %s color-aware, "
4912          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4913          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4914          "conform action %U%s, exceed action %U%s, violate action %U%s",
4915          mp->name,
4916          format_policer_type, mp->type,
4917          ntohl (mp->cir),
4918          ntohl (mp->eir),
4919          clib_net_to_host_u64 (mp->cb),
4920          clib_net_to_host_u64 (mp->eb),
4921          format_policer_rate_type, mp->rate_type,
4922          format_policer_round_type, mp->round_type,
4923          mp->single_rate ? "single" : "dual",
4924          mp->color_aware ? "is" : "not",
4925          ntohl (mp->cir_tokens_per_period),
4926          ntohl (mp->pir_tokens_per_period),
4927          ntohl (mp->scale),
4928          ntohl (mp->current_limit),
4929          ntohl (mp->current_bucket),
4930          ntohl (mp->extended_limit),
4931          ntohl (mp->extended_bucket),
4932          clib_net_to_host_u64 (mp->last_update_time),
4933          format_policer_action_type, mp->conform_action_type,
4934          conform_dscp_str,
4935          format_policer_action_type, mp->exceed_action_type,
4936          exceed_dscp_str,
4937          format_policer_action_type, mp->violate_action_type,
4938          violate_dscp_str);
4939
4940   vec_free (conform_dscp_str);
4941   vec_free (exceed_dscp_str);
4942   vec_free (violate_dscp_str);
4943 }
4944
4945 static void vl_api_policer_details_t_handler_json
4946   (vl_api_policer_details_t * mp)
4947 {
4948   vat_main_t *vam = &vat_main;
4949   vat_json_node_t *node;
4950   u8 *rate_type_str, *round_type_str, *type_str;
4951   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4952
4953   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4954   round_type_str =
4955     format (0, "%U", format_policer_round_type, mp->round_type);
4956   type_str = format (0, "%U", format_policer_type, mp->type);
4957   conform_action_str = format (0, "%U", format_policer_action_type,
4958                                mp->conform_action_type);
4959   exceed_action_str = format (0, "%U", format_policer_action_type,
4960                               mp->exceed_action_type);
4961   violate_action_str = format (0, "%U", format_policer_action_type,
4962                                mp->violate_action_type);
4963
4964   if (VAT_JSON_ARRAY != vam->json_tree.type)
4965     {
4966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4967       vat_json_init_array (&vam->json_tree);
4968     }
4969   node = vat_json_array_add (&vam->json_tree);
4970
4971   vat_json_init_object (node);
4972   vat_json_object_add_string_copy (node, "name", mp->name);
4973   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4974   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4975   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4976   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4977   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4978   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4979   vat_json_object_add_string_copy (node, "type", type_str);
4980   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4981   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4982   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4983   vat_json_object_add_uint (node, "cir_tokens_per_period",
4984                             ntohl (mp->cir_tokens_per_period));
4985   vat_json_object_add_uint (node, "eir_tokens_per_period",
4986                             ntohl (mp->pir_tokens_per_period));
4987   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4988   vat_json_object_add_uint (node, "current_bucket",
4989                             ntohl (mp->current_bucket));
4990   vat_json_object_add_uint (node, "extended_limit",
4991                             ntohl (mp->extended_limit));
4992   vat_json_object_add_uint (node, "extended_bucket",
4993                             ntohl (mp->extended_bucket));
4994   vat_json_object_add_uint (node, "last_update_time",
4995                             ntohl (mp->last_update_time));
4996   vat_json_object_add_string_copy (node, "conform_action",
4997                                    conform_action_str);
4998   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4999     {
5000       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
5001       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
5002       vec_free (dscp_str);
5003     }
5004   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
5005   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5006     {
5007       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
5008       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
5009       vec_free (dscp_str);
5010     }
5011   vat_json_object_add_string_copy (node, "violate_action",
5012                                    violate_action_str);
5013   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
5014     {
5015       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
5016       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
5017       vec_free (dscp_str);
5018     }
5019
5020   vec_free (rate_type_str);
5021   vec_free (round_type_str);
5022   vec_free (type_str);
5023   vec_free (conform_action_str);
5024   vec_free (exceed_action_str);
5025   vec_free (violate_action_str);
5026 }
5027
5028 static void
5029 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
5030                                            mp)
5031 {
5032   vat_main_t *vam = &vat_main;
5033   int i, count = ntohl (mp->count);
5034
5035   if (count > 0)
5036     print (vam->ofp, "classify table ids (%d) : ", count);
5037   for (i = 0; i < count; i++)
5038     {
5039       print (vam->ofp, "%d", ntohl (mp->ids[i]));
5040       print (vam->ofp, (i < count - 1) ? "," : "");
5041     }
5042   vam->retval = ntohl (mp->retval);
5043   vam->result_ready = 1;
5044 }
5045
5046 static void
5047   vl_api_classify_table_ids_reply_t_handler_json
5048   (vl_api_classify_table_ids_reply_t * mp)
5049 {
5050   vat_main_t *vam = &vat_main;
5051   int i, count = ntohl (mp->count);
5052
5053   if (count > 0)
5054     {
5055       vat_json_node_t node;
5056
5057       vat_json_init_object (&node);
5058       for (i = 0; i < count; i++)
5059         {
5060           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
5061         }
5062       vat_json_print (vam->ofp, &node);
5063       vat_json_free (&node);
5064     }
5065   vam->retval = ntohl (mp->retval);
5066   vam->result_ready = 1;
5067 }
5068
5069 static void
5070   vl_api_classify_table_by_interface_reply_t_handler
5071   (vl_api_classify_table_by_interface_reply_t * mp)
5072 {
5073   vat_main_t *vam = &vat_main;
5074   u32 table_id;
5075
5076   table_id = ntohl (mp->l2_table_id);
5077   if (table_id != ~0)
5078     print (vam->ofp, "l2 table id : %d", table_id);
5079   else
5080     print (vam->ofp, "l2 table id : No input ACL tables configured");
5081   table_id = ntohl (mp->ip4_table_id);
5082   if (table_id != ~0)
5083     print (vam->ofp, "ip4 table id : %d", table_id);
5084   else
5085     print (vam->ofp, "ip4 table id : No input ACL tables configured");
5086   table_id = ntohl (mp->ip6_table_id);
5087   if (table_id != ~0)
5088     print (vam->ofp, "ip6 table id : %d", table_id);
5089   else
5090     print (vam->ofp, "ip6 table id : No input ACL tables configured");
5091   vam->retval = ntohl (mp->retval);
5092   vam->result_ready = 1;
5093 }
5094
5095 static void
5096   vl_api_classify_table_by_interface_reply_t_handler_json
5097   (vl_api_classify_table_by_interface_reply_t * mp)
5098 {
5099   vat_main_t *vam = &vat_main;
5100   vat_json_node_t node;
5101
5102   vat_json_init_object (&node);
5103
5104   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
5105   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
5106   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
5107
5108   vat_json_print (vam->ofp, &node);
5109   vat_json_free (&node);
5110
5111   vam->retval = ntohl (mp->retval);
5112   vam->result_ready = 1;
5113 }
5114
5115 static void vl_api_policer_add_del_reply_t_handler
5116   (vl_api_policer_add_del_reply_t * mp)
5117 {
5118   vat_main_t *vam = &vat_main;
5119   i32 retval = ntohl (mp->retval);
5120   if (vam->async_mode)
5121     {
5122       vam->async_errors += (retval < 0);
5123     }
5124   else
5125     {
5126       vam->retval = retval;
5127       vam->result_ready = 1;
5128       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
5129         /*
5130          * Note: this is just barely thread-safe, depends on
5131          * the main thread spinning waiting for an answer...
5132          */
5133         errmsg ("policer index %d", ntohl (mp->policer_index));
5134     }
5135 }
5136
5137 static void vl_api_policer_add_del_reply_t_handler_json
5138   (vl_api_policer_add_del_reply_t * mp)
5139 {
5140   vat_main_t *vam = &vat_main;
5141   vat_json_node_t node;
5142
5143   vat_json_init_object (&node);
5144   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5145   vat_json_object_add_uint (&node, "policer_index",
5146                             ntohl (mp->policer_index));
5147
5148   vat_json_print (vam->ofp, &node);
5149   vat_json_free (&node);
5150
5151   vam->retval = ntohl (mp->retval);
5152   vam->result_ready = 1;
5153 }
5154
5155 /* Format hex dump. */
5156 u8 *
5157 format_hex_bytes (u8 * s, va_list * va)
5158 {
5159   u8 *bytes = va_arg (*va, u8 *);
5160   int n_bytes = va_arg (*va, int);
5161   uword i;
5162
5163   /* Print short or long form depending on byte count. */
5164   uword short_form = n_bytes <= 32;
5165   u32 indent = format_get_indent (s);
5166
5167   if (n_bytes == 0)
5168     return s;
5169
5170   for (i = 0; i < n_bytes; i++)
5171     {
5172       if (!short_form && (i % 32) == 0)
5173         s = format (s, "%08x: ", i);
5174       s = format (s, "%02x", bytes[i]);
5175       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
5176         s = format (s, "\n%U", format_white_space, indent);
5177     }
5178
5179   return s;
5180 }
5181
5182 static void
5183 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
5184                                             * mp)
5185 {
5186   vat_main_t *vam = &vat_main;
5187   i32 retval = ntohl (mp->retval);
5188   if (retval == 0)
5189     {
5190       print (vam->ofp, "classify table info :");
5191       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
5192              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
5193              ntohl (mp->miss_next_index));
5194       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
5195              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
5196              ntohl (mp->match_n_vectors));
5197       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
5198              ntohl (mp->mask_length));
5199     }
5200   vam->retval = retval;
5201   vam->result_ready = 1;
5202 }
5203
5204 static void
5205   vl_api_classify_table_info_reply_t_handler_json
5206   (vl_api_classify_table_info_reply_t * mp)
5207 {
5208   vat_main_t *vam = &vat_main;
5209   vat_json_node_t node;
5210
5211   i32 retval = ntohl (mp->retval);
5212   if (retval == 0)
5213     {
5214       vat_json_init_object (&node);
5215
5216       vat_json_object_add_int (&node, "sessions",
5217                                ntohl (mp->active_sessions));
5218       vat_json_object_add_int (&node, "nexttbl",
5219                                ntohl (mp->next_table_index));
5220       vat_json_object_add_int (&node, "nextnode",
5221                                ntohl (mp->miss_next_index));
5222       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
5223       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
5224       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
5225       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
5226                       ntohl (mp->mask_length), 0);
5227       vat_json_object_add_string_copy (&node, "mask", s);
5228
5229       vat_json_print (vam->ofp, &node);
5230       vat_json_free (&node);
5231     }
5232   vam->retval = ntohl (mp->retval);
5233   vam->result_ready = 1;
5234 }
5235
5236 static void
5237 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
5238                                            mp)
5239 {
5240   vat_main_t *vam = &vat_main;
5241
5242   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
5243          ntohl (mp->hit_next_index), ntohl (mp->advance),
5244          ntohl (mp->opaque_index));
5245   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
5246          ntohl (mp->match_length));
5247 }
5248
5249 static void
5250   vl_api_classify_session_details_t_handler_json
5251   (vl_api_classify_session_details_t * mp)
5252 {
5253   vat_main_t *vam = &vat_main;
5254   vat_json_node_t *node = NULL;
5255
5256   if (VAT_JSON_ARRAY != vam->json_tree.type)
5257     {
5258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5259       vat_json_init_array (&vam->json_tree);
5260     }
5261   node = vat_json_array_add (&vam->json_tree);
5262
5263   vat_json_init_object (node);
5264   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5265   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5266   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5267   u8 *s =
5268     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5269             0);
5270   vat_json_object_add_string_copy (node, "match", s);
5271 }
5272
5273 static void vl_api_pg_create_interface_reply_t_handler
5274   (vl_api_pg_create_interface_reply_t * mp)
5275 {
5276   vat_main_t *vam = &vat_main;
5277
5278   vam->retval = ntohl (mp->retval);
5279   vam->result_ready = 1;
5280 }
5281
5282 static void vl_api_pg_create_interface_reply_t_handler_json
5283   (vl_api_pg_create_interface_reply_t * mp)
5284 {
5285   vat_main_t *vam = &vat_main;
5286   vat_json_node_t node;
5287
5288   i32 retval = ntohl (mp->retval);
5289   if (retval == 0)
5290     {
5291       vat_json_init_object (&node);
5292
5293       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5294
5295       vat_json_print (vam->ofp, &node);
5296       vat_json_free (&node);
5297     }
5298   vam->retval = ntohl (mp->retval);
5299   vam->result_ready = 1;
5300 }
5301
5302 static void vl_api_policer_classify_details_t_handler
5303   (vl_api_policer_classify_details_t * mp)
5304 {
5305   vat_main_t *vam = &vat_main;
5306
5307   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5308          ntohl (mp->table_index));
5309 }
5310
5311 static void vl_api_policer_classify_details_t_handler_json
5312   (vl_api_policer_classify_details_t * mp)
5313 {
5314   vat_main_t *vam = &vat_main;
5315   vat_json_node_t *node;
5316
5317   if (VAT_JSON_ARRAY != vam->json_tree.type)
5318     {
5319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5320       vat_json_init_array (&vam->json_tree);
5321     }
5322   node = vat_json_array_add (&vam->json_tree);
5323
5324   vat_json_init_object (node);
5325   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5326   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5327 }
5328
5329 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5330   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5331 {
5332   vat_main_t *vam = &vat_main;
5333   i32 retval = ntohl (mp->retval);
5334   if (vam->async_mode)
5335     {
5336       vam->async_errors += (retval < 0);
5337     }
5338   else
5339     {
5340       vam->retval = retval;
5341       vam->sw_if_index = ntohl (mp->sw_if_index);
5342       vam->result_ready = 1;
5343     }
5344   vam->regenerate_interface_table = 1;
5345 }
5346
5347 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5348   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5349 {
5350   vat_main_t *vam = &vat_main;
5351   vat_json_node_t node;
5352
5353   vat_json_init_object (&node);
5354   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5355   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5356
5357   vat_json_print (vam->ofp, &node);
5358   vat_json_free (&node);
5359
5360   vam->retval = ntohl (mp->retval);
5361   vam->result_ready = 1;
5362 }
5363
5364 static void vl_api_flow_classify_details_t_handler
5365   (vl_api_flow_classify_details_t * mp)
5366 {
5367   vat_main_t *vam = &vat_main;
5368
5369   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5370          ntohl (mp->table_index));
5371 }
5372
5373 static void vl_api_flow_classify_details_t_handler_json
5374   (vl_api_flow_classify_details_t * mp)
5375 {
5376   vat_main_t *vam = &vat_main;
5377   vat_json_node_t *node;
5378
5379   if (VAT_JSON_ARRAY != vam->json_tree.type)
5380     {
5381       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5382       vat_json_init_array (&vam->json_tree);
5383     }
5384   node = vat_json_array_add (&vam->json_tree);
5385
5386   vat_json_init_object (node);
5387   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5388   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5389 }
5390
5391 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5392 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5393 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5394 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5395 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5396 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5397 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5398 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5399 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5400 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5401 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5402 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5403 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5404 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5405 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5406 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5407 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5408 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5409 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5410 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5411 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5412 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5413
5414 /*
5415  * Generate boilerplate reply handlers, which
5416  * dig the return value out of the xxx_reply_t API message,
5417  * stick it into vam->retval, and set vam->result_ready
5418  *
5419  * Could also do this by pointing N message decode slots at
5420  * a single function, but that could break in subtle ways.
5421  */
5422
5423 #define foreach_standard_reply_retval_handler           \
5424 _(sw_interface_set_flags_reply)                         \
5425 _(sw_interface_add_del_address_reply)                   \
5426 _(sw_interface_set_rx_mode_reply)                       \
5427 _(sw_interface_set_rx_placement_reply)                  \
5428 _(sw_interface_set_table_reply)                         \
5429 _(sw_interface_set_mpls_enable_reply)                   \
5430 _(sw_interface_set_vpath_reply)                         \
5431 _(sw_interface_set_vxlan_bypass_reply)                  \
5432 _(sw_interface_set_geneve_bypass_reply)                 \
5433 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5434 _(sw_interface_set_l2_bridge_reply)                     \
5435 _(bridge_domain_add_del_reply)                          \
5436 _(sw_interface_set_l2_xconnect_reply)                   \
5437 _(l2fib_add_del_reply)                                  \
5438 _(l2fib_flush_int_reply)                                \
5439 _(l2fib_flush_bd_reply)                                 \
5440 _(ip_add_del_route_reply)                               \
5441 _(ip_table_add_del_reply)                               \
5442 _(ip_mroute_add_del_reply)                              \
5443 _(mpls_route_add_del_reply)                             \
5444 _(mpls_table_add_del_reply)                             \
5445 _(mpls_ip_bind_unbind_reply)                            \
5446 _(bier_route_add_del_reply)                             \
5447 _(bier_table_add_del_reply)                             \
5448 _(proxy_arp_add_del_reply)                              \
5449 _(proxy_arp_intfc_enable_disable_reply)                 \
5450 _(sw_interface_set_unnumbered_reply)                    \
5451 _(ip_neighbor_add_del_reply)                            \
5452 _(oam_add_del_reply)                                    \
5453 _(reset_fib_reply)                                      \
5454 _(dhcp_proxy_config_reply)                              \
5455 _(dhcp_proxy_set_vss_reply)                             \
5456 _(dhcp_client_config_reply)                             \
5457 _(set_ip_flow_hash_reply)                               \
5458 _(sw_interface_ip6_enable_disable_reply)                \
5459 _(sw_interface_ip6_set_link_local_address_reply)        \
5460 _(ip6nd_proxy_add_del_reply)                            \
5461 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5462 _(sw_interface_ip6nd_ra_config_reply)                   \
5463 _(set_arp_neighbor_limit_reply)                         \
5464 _(l2_patch_add_del_reply)                               \
5465 _(sr_mpls_policy_add_reply)                             \
5466 _(sr_mpls_policy_mod_reply)                             \
5467 _(sr_mpls_policy_del_reply)                             \
5468 _(sr_policy_add_reply)                                  \
5469 _(sr_policy_mod_reply)                                  \
5470 _(sr_policy_del_reply)                                  \
5471 _(sr_localsid_add_del_reply)                            \
5472 _(sr_steering_add_del_reply)                            \
5473 _(classify_add_del_session_reply)                       \
5474 _(classify_set_interface_ip_table_reply)                \
5475 _(classify_set_interface_l2_tables_reply)               \
5476 _(l2tpv3_set_tunnel_cookies_reply)                      \
5477 _(l2tpv3_interface_enable_disable_reply)                \
5478 _(l2tpv3_set_lookup_key_reply)                          \
5479 _(l2_fib_clear_table_reply)                             \
5480 _(l2_interface_efp_filter_reply)                        \
5481 _(l2_interface_vlan_tag_rewrite_reply)                  \
5482 _(modify_vhost_user_if_reply)                           \
5483 _(delete_vhost_user_if_reply)                           \
5484 _(ip_probe_neighbor_reply)                              \
5485 _(ip_scan_neighbor_enable_disable_reply)                \
5486 _(want_ip4_arp_events_reply)                            \
5487 _(want_ip6_nd_events_reply)                             \
5488 _(want_l2_macs_events_reply)                            \
5489 _(input_acl_set_interface_reply)                        \
5490 _(ipsec_spd_add_del_reply)                              \
5491 _(ipsec_interface_add_del_spd_reply)                    \
5492 _(ipsec_spd_add_del_entry_reply)                        \
5493 _(ipsec_sad_add_del_entry_reply)                        \
5494 _(ipsec_sa_set_key_reply)                               \
5495 _(ipsec_tunnel_if_add_del_reply)                        \
5496 _(ipsec_tunnel_if_set_key_reply)                        \
5497 _(ipsec_tunnel_if_set_sa_reply)                         \
5498 _(ikev2_profile_add_del_reply)                          \
5499 _(ikev2_profile_set_auth_reply)                         \
5500 _(ikev2_profile_set_id_reply)                           \
5501 _(ikev2_profile_set_ts_reply)                           \
5502 _(ikev2_set_local_key_reply)                            \
5503 _(ikev2_set_responder_reply)                            \
5504 _(ikev2_set_ike_transforms_reply)                       \
5505 _(ikev2_set_esp_transforms_reply)                       \
5506 _(ikev2_set_sa_lifetime_reply)                          \
5507 _(ikev2_initiate_sa_init_reply)                         \
5508 _(ikev2_initiate_del_ike_sa_reply)                      \
5509 _(ikev2_initiate_del_child_sa_reply)                    \
5510 _(ikev2_initiate_rekey_child_sa_reply)                  \
5511 _(delete_loopback_reply)                                \
5512 _(bd_ip_mac_add_del_reply)                              \
5513 _(want_interface_events_reply)                          \
5514 _(want_stats_reply)                                     \
5515 _(cop_interface_enable_disable_reply)                   \
5516 _(cop_whitelist_enable_disable_reply)                   \
5517 _(sw_interface_clear_stats_reply)                       \
5518 _(ioam_enable_reply)                                    \
5519 _(ioam_disable_reply)                                   \
5520 _(one_add_del_locator_reply)                            \
5521 _(one_add_del_local_eid_reply)                          \
5522 _(one_add_del_remote_mapping_reply)                     \
5523 _(one_add_del_adjacency_reply)                          \
5524 _(one_add_del_map_resolver_reply)                       \
5525 _(one_add_del_map_server_reply)                         \
5526 _(one_enable_disable_reply)                             \
5527 _(one_rloc_probe_enable_disable_reply)                  \
5528 _(one_map_register_enable_disable_reply)                \
5529 _(one_map_register_set_ttl_reply)                       \
5530 _(one_set_transport_protocol_reply)                     \
5531 _(one_map_register_fallback_threshold_reply)            \
5532 _(one_pitr_set_locator_set_reply)                       \
5533 _(one_map_request_mode_reply)                           \
5534 _(one_add_del_map_request_itr_rlocs_reply)              \
5535 _(one_eid_table_add_del_map_reply)                      \
5536 _(one_use_petr_reply)                                   \
5537 _(one_stats_enable_disable_reply)                       \
5538 _(one_add_del_l2_arp_entry_reply)                       \
5539 _(one_add_del_ndp_entry_reply)                          \
5540 _(one_stats_flush_reply)                                \
5541 _(one_enable_disable_xtr_mode_reply)                    \
5542 _(one_enable_disable_pitr_mode_reply)                   \
5543 _(one_enable_disable_petr_mode_reply)                   \
5544 _(gpe_enable_disable_reply)                             \
5545 _(gpe_set_encap_mode_reply)                             \
5546 _(gpe_add_del_iface_reply)                              \
5547 _(gpe_add_del_native_fwd_rpath_reply)                   \
5548 _(af_packet_delete_reply)                               \
5549 _(policer_classify_set_interface_reply)                 \
5550 _(netmap_create_reply)                                  \
5551 _(netmap_delete_reply)                                  \
5552 _(set_ipfix_exporter_reply)                             \
5553 _(set_ipfix_classify_stream_reply)                      \
5554 _(ipfix_classify_table_add_del_reply)                   \
5555 _(flow_classify_set_interface_reply)                    \
5556 _(sw_interface_span_enable_disable_reply)               \
5557 _(pg_capture_reply)                                     \
5558 _(pg_enable_disable_reply)                              \
5559 _(ip_source_and_port_range_check_add_del_reply)         \
5560 _(ip_source_and_port_range_check_interface_add_del_reply)\
5561 _(delete_subif_reply)                                   \
5562 _(l2_interface_pbb_tag_rewrite_reply)                   \
5563 _(punt_reply)                                           \
5564 _(feature_enable_disable_reply)                         \
5565 _(sw_interface_tag_add_del_reply)                       \
5566 _(hw_interface_set_mtu_reply)                           \
5567 _(p2p_ethernet_add_reply)                               \
5568 _(p2p_ethernet_del_reply)                               \
5569 _(lldp_config_reply)                                    \
5570 _(sw_interface_set_lldp_reply)                          \
5571 _(tcp_configure_src_addresses_reply)                    \
5572 _(dns_enable_disable_reply)                             \
5573 _(dns_name_server_add_del_reply)                        \
5574 _(session_rule_add_del_reply)                           \
5575 _(ip_container_proxy_add_del_reply)                     \
5576 _(output_acl_set_interface_reply)                       \
5577 _(qos_record_enable_disable_reply)
5578
5579 #define _(n)                                    \
5580     static void vl_api_##n##_t_handler          \
5581     (vl_api_##n##_t * mp)                       \
5582     {                                           \
5583         vat_main_t * vam = &vat_main;           \
5584         i32 retval = ntohl(mp->retval);         \
5585         if (vam->async_mode) {                  \
5586             vam->async_errors += (retval < 0);  \
5587         } else {                                \
5588             vam->retval = retval;               \
5589             vam->result_ready = 1;              \
5590         }                                       \
5591     }
5592 foreach_standard_reply_retval_handler;
5593 #undef _
5594
5595 #define _(n)                                    \
5596     static void vl_api_##n##_t_handler_json     \
5597     (vl_api_##n##_t * mp)                       \
5598     {                                           \
5599         vat_main_t * vam = &vat_main;           \
5600         vat_json_node_t node;                   \
5601         vat_json_init_object(&node);            \
5602         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5603         vat_json_print(vam->ofp, &node);        \
5604         vam->retval = ntohl(mp->retval);        \
5605         vam->result_ready = 1;                  \
5606     }
5607 foreach_standard_reply_retval_handler;
5608 #undef _
5609
5610 /*
5611  * Table of message reply handlers, must include boilerplate handlers
5612  * we just generated
5613  */
5614
5615 #define foreach_vpe_api_reply_msg                                       \
5616 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5617 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5618 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5619 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5620 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5621 _(CLI_REPLY, cli_reply)                                                 \
5622 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5623 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5624   sw_interface_add_del_address_reply)                                   \
5625 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5626 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5627 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5628 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5629 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5630 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5631 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5632 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5633 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5634 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5635   sw_interface_set_l2_xconnect_reply)                                   \
5636 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5637   sw_interface_set_l2_bridge_reply)                                     \
5638 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5639 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5640 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5641 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5642 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5643 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5644 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5645 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5646 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5647 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5648 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5649 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5650 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5651 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5652 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5653 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5654 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5655 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5656 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5657 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5658 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5659 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5660 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5661 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5662 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5663 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5664 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5665 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5666 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5667 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5668 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5669   proxy_arp_intfc_enable_disable_reply)                                 \
5670 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5671 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5672   sw_interface_set_unnumbered_reply)                                    \
5673 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5674 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5675 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5676 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5677 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5678 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5679 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5680 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5681 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5682 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5683 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5684   sw_interface_ip6_enable_disable_reply)                                \
5685 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5686   sw_interface_ip6_set_link_local_address_reply)                        \
5687 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5688 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5689 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5690   sw_interface_ip6nd_ra_prefix_reply)                                   \
5691 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5692   sw_interface_ip6nd_ra_config_reply)                                   \
5693 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5694 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5695 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5696 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5697 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5698 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5699 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5700 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5701 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5702 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5703 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5704 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5705 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5706 classify_set_interface_ip_table_reply)                                  \
5707 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5708   classify_set_interface_l2_tables_reply)                               \
5709 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5710 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5711 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5712 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5713 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5714   l2tpv3_interface_enable_disable_reply)                                \
5715 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5716 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5717 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5718 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5719 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5720 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5721 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5722 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5723 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5724 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5725 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5726 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5727 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5728 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5729 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5730 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5731 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5732 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5733 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5734 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5735 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5736 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5737 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5738 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5739 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5740 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5741 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5742 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5743 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5744 _(L2_MACS_EVENT, l2_macs_event)                                         \
5745 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5746 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5747 _(IP_DETAILS, ip_details)                                               \
5748 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5749 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5750 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5751 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5752 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5753 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5754 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5755 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5756 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5757 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5758 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5759 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5760 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5761 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5762 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5763 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5764 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5765 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5766 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5767 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5768 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5769 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5770 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5771 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5772 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5773 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5774 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5775 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5776 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5777 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5778 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5779 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5780 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5781 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5782 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5783 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5784 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5785 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5786 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5787 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5788 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5789 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5790 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5791 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5792   one_map_register_enable_disable_reply)                                \
5793 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5794 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5795 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5796 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5797   one_map_register_fallback_threshold_reply)                            \
5798 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5799   one_rloc_probe_enable_disable_reply)                                  \
5800 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5801 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5802 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5803 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5804 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5805 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5806 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5807 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5808 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5809 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5810 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5811 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5812 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5813 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5814 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5815 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5816   show_one_stats_enable_disable_reply)                                  \
5817 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5818 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5819 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5820 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5821 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5822 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5823 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5824 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5825   one_enable_disable_pitr_mode_reply)                                   \
5826 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5827   one_enable_disable_petr_mode_reply)                                   \
5828 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5829 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5830 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5831 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5832 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5833 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5834 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5835 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5836 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5837 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5838 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5839 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5840   gpe_add_del_native_fwd_rpath_reply)                                   \
5841 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5842   gpe_fwd_entry_path_details)                                           \
5843 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5844 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5845   one_add_del_map_request_itr_rlocs_reply)                              \
5846 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5847   one_get_map_request_itr_rlocs_reply)                                  \
5848 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5849 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5850 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5851 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5852 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5853 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5854   show_one_map_register_state_reply)                                    \
5855 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5856 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5857   show_one_map_register_fallback_threshold_reply)                       \
5858 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5859 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5860 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5861 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5862 _(POLICER_DETAILS, policer_details)                                     \
5863 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5864 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5865 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5866 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5867 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5868 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5869 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5870 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5871 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5872 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5873 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5874 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5875 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5876 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5877 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5878 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5879 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5880 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5881 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5882 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5883 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5884 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5885 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5886 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5887 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5888  ip_source_and_port_range_check_add_del_reply)                          \
5889 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5890  ip_source_and_port_range_check_interface_add_del_reply)                \
5891 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5892 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5893 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5894 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5895 _(PUNT_REPLY, punt_reply)                                               \
5896 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5897 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5898 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5899 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5900 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5901 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5902 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5903 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5904 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5905 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5906 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5907 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5908 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5909 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5910 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5911 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5912 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5913 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5914 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5915 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5916 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5917 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5918 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5919
5920 #define foreach_standalone_reply_msg                                    \
5921 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5922 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5923 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5924 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5925 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5926 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5927 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5928
5929 typedef struct
5930 {
5931   u8 *name;
5932   u32 value;
5933 } name_sort_t;
5934
5935 #define STR_VTR_OP_CASE(op)     \
5936     case L2_VTR_ ## op:         \
5937         return "" # op;
5938
5939 static const char *
5940 str_vtr_op (u32 vtr_op)
5941 {
5942   switch (vtr_op)
5943     {
5944       STR_VTR_OP_CASE (DISABLED);
5945       STR_VTR_OP_CASE (PUSH_1);
5946       STR_VTR_OP_CASE (PUSH_2);
5947       STR_VTR_OP_CASE (POP_1);
5948       STR_VTR_OP_CASE (POP_2);
5949       STR_VTR_OP_CASE (TRANSLATE_1_1);
5950       STR_VTR_OP_CASE (TRANSLATE_1_2);
5951       STR_VTR_OP_CASE (TRANSLATE_2_1);
5952       STR_VTR_OP_CASE (TRANSLATE_2_2);
5953     }
5954
5955   return "UNKNOWN";
5956 }
5957
5958 static int
5959 dump_sub_interface_table (vat_main_t * vam)
5960 {
5961   const sw_interface_subif_t *sub = NULL;
5962
5963   if (vam->json_output)
5964     {
5965       clib_warning
5966         ("JSON output supported only for VPE API calls and dump_stats_table");
5967       return -99;
5968     }
5969
5970   print (vam->ofp,
5971          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5972          "Interface", "sw_if_index",
5973          "sub id", "dot1ad", "tags", "outer id",
5974          "inner id", "exact", "default", "outer any", "inner any");
5975
5976   vec_foreach (sub, vam->sw_if_subif_table)
5977   {
5978     print (vam->ofp,
5979            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5980            sub->interface_name,
5981            sub->sw_if_index,
5982            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5983            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5984            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5985            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5986     if (sub->vtr_op != L2_VTR_DISABLED)
5987       {
5988         print (vam->ofp,
5989                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5990                "tag1: %d tag2: %d ]",
5991                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5992                sub->vtr_tag1, sub->vtr_tag2);
5993       }
5994   }
5995
5996   return 0;
5997 }
5998
5999 static int
6000 name_sort_cmp (void *a1, void *a2)
6001 {
6002   name_sort_t *n1 = a1;
6003   name_sort_t *n2 = a2;
6004
6005   return strcmp ((char *) n1->name, (char *) n2->name);
6006 }
6007
6008 static int
6009 dump_interface_table (vat_main_t * vam)
6010 {
6011   hash_pair_t *p;
6012   name_sort_t *nses = 0, *ns;
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   /* *INDENT-OFF* */
6022   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6023   ({
6024     vec_add2 (nses, ns, 1);
6025     ns->name = (u8 *)(p->key);
6026     ns->value = (u32) p->value[0];
6027   }));
6028   /* *INDENT-ON* */
6029
6030   vec_sort_with_function (nses, name_sort_cmp);
6031
6032   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
6033   vec_foreach (ns, nses)
6034   {
6035     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
6036   }
6037   vec_free (nses);
6038   return 0;
6039 }
6040
6041 static int
6042 dump_ip_table (vat_main_t * vam, int is_ipv6)
6043 {
6044   const ip_details_t *det = NULL;
6045   const ip_address_details_t *address = NULL;
6046   u32 i = ~0;
6047
6048   print (vam->ofp, "%-12s", "sw_if_index");
6049
6050   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
6051   {
6052     i++;
6053     if (!det->present)
6054       {
6055         continue;
6056       }
6057     print (vam->ofp, "%-12d", i);
6058     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
6059     if (!det->addr)
6060       {
6061         continue;
6062       }
6063     vec_foreach (address, det->addr)
6064     {
6065       print (vam->ofp,
6066              "            %-30U%-13d",
6067              is_ipv6 ? format_ip6_address : format_ip4_address,
6068              address->ip, address->prefix_length);
6069     }
6070   }
6071
6072   return 0;
6073 }
6074
6075 static int
6076 dump_ipv4_table (vat_main_t * vam)
6077 {
6078   if (vam->json_output)
6079     {
6080       clib_warning
6081         ("JSON output supported only for VPE API calls and dump_stats_table");
6082       return -99;
6083     }
6084
6085   return dump_ip_table (vam, 0);
6086 }
6087
6088 static int
6089 dump_ipv6_table (vat_main_t * vam)
6090 {
6091   if (vam->json_output)
6092     {
6093       clib_warning
6094         ("JSON output supported only for VPE API calls and dump_stats_table");
6095       return -99;
6096     }
6097
6098   return dump_ip_table (vam, 1);
6099 }
6100
6101 static char *
6102 counter_type_to_str (u8 counter_type, u8 is_combined)
6103 {
6104   if (!is_combined)
6105     {
6106       switch (counter_type)
6107         {
6108         case VNET_INTERFACE_COUNTER_DROP:
6109           return "drop";
6110         case VNET_INTERFACE_COUNTER_PUNT:
6111           return "punt";
6112         case VNET_INTERFACE_COUNTER_IP4:
6113           return "ip4";
6114         case VNET_INTERFACE_COUNTER_IP6:
6115           return "ip6";
6116         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
6117           return "rx-no-buf";
6118         case VNET_INTERFACE_COUNTER_RX_MISS:
6119           return "rx-miss";
6120         case VNET_INTERFACE_COUNTER_RX_ERROR:
6121           return "rx-error";
6122         case VNET_INTERFACE_COUNTER_TX_ERROR:
6123           return "tx-error";
6124         default:
6125           return "INVALID-COUNTER-TYPE";
6126         }
6127     }
6128   else
6129     {
6130       switch (counter_type)
6131         {
6132         case VNET_INTERFACE_COUNTER_RX:
6133           return "rx";
6134         case VNET_INTERFACE_COUNTER_TX:
6135           return "tx";
6136         default:
6137           return "INVALID-COUNTER-TYPE";
6138         }
6139     }
6140 }
6141
6142 static int
6143 dump_stats_table (vat_main_t * vam)
6144 {
6145   vat_json_node_t node;
6146   vat_json_node_t *msg_array;
6147   vat_json_node_t *msg;
6148   vat_json_node_t *counter_array;
6149   vat_json_node_t *counter;
6150   interface_counter_t c;
6151   u64 packets;
6152   ip4_fib_counter_t *c4;
6153   ip6_fib_counter_t *c6;
6154   ip4_nbr_counter_t *n4;
6155   ip6_nbr_counter_t *n6;
6156   int i, j;
6157
6158   if (!vam->json_output)
6159     {
6160       clib_warning ("dump_stats_table supported only in JSON format");
6161       return -99;
6162     }
6163
6164   vat_json_init_object (&node);
6165
6166   /* interface counters */
6167   msg_array = vat_json_object_add (&node, "interface_counters");
6168   vat_json_init_array (msg_array);
6169   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
6170     {
6171       msg = vat_json_array_add (msg_array);
6172       vat_json_init_object (msg);
6173       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6174                                        (u8 *) counter_type_to_str (i, 0));
6175       vat_json_object_add_int (msg, "is_combined", 0);
6176       counter_array = vat_json_object_add (msg, "data");
6177       vat_json_init_array (counter_array);
6178       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
6179         {
6180           packets = vam->simple_interface_counters[i][j];
6181           vat_json_array_add_uint (counter_array, packets);
6182         }
6183     }
6184   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
6185     {
6186       msg = vat_json_array_add (msg_array);
6187       vat_json_init_object (msg);
6188       vat_json_object_add_string_copy (msg, "vnet_counter_type",
6189                                        (u8 *) counter_type_to_str (i, 1));
6190       vat_json_object_add_int (msg, "is_combined", 1);
6191       counter_array = vat_json_object_add (msg, "data");
6192       vat_json_init_array (counter_array);
6193       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
6194         {
6195           c = vam->combined_interface_counters[i][j];
6196           counter = vat_json_array_add (counter_array);
6197           vat_json_init_object (counter);
6198           vat_json_object_add_uint (counter, "packets", c.packets);
6199           vat_json_object_add_uint (counter, "bytes", c.bytes);
6200         }
6201     }
6202
6203   /* ip4 fib counters */
6204   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
6205   vat_json_init_array (msg_array);
6206   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
6207     {
6208       msg = vat_json_array_add (msg_array);
6209       vat_json_init_object (msg);
6210       vat_json_object_add_uint (msg, "vrf_id",
6211                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
6212       counter_array = vat_json_object_add (msg, "c");
6213       vat_json_init_array (counter_array);
6214       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
6215         {
6216           counter = vat_json_array_add (counter_array);
6217           vat_json_init_object (counter);
6218           c4 = &vam->ip4_fib_counters[i][j];
6219           vat_json_object_add_ip4 (counter, "address", c4->address);
6220           vat_json_object_add_uint (counter, "address_length",
6221                                     c4->address_length);
6222           vat_json_object_add_uint (counter, "packets", c4->packets);
6223           vat_json_object_add_uint (counter, "bytes", c4->bytes);
6224         }
6225     }
6226
6227   /* ip6 fib counters */
6228   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
6229   vat_json_init_array (msg_array);
6230   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
6231     {
6232       msg = vat_json_array_add (msg_array);
6233       vat_json_init_object (msg);
6234       vat_json_object_add_uint (msg, "vrf_id",
6235                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
6236       counter_array = vat_json_object_add (msg, "c");
6237       vat_json_init_array (counter_array);
6238       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
6239         {
6240           counter = vat_json_array_add (counter_array);
6241           vat_json_init_object (counter);
6242           c6 = &vam->ip6_fib_counters[i][j];
6243           vat_json_object_add_ip6 (counter, "address", c6->address);
6244           vat_json_object_add_uint (counter, "address_length",
6245                                     c6->address_length);
6246           vat_json_object_add_uint (counter, "packets", c6->packets);
6247           vat_json_object_add_uint (counter, "bytes", c6->bytes);
6248         }
6249     }
6250
6251   /* ip4 nbr counters */
6252   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
6253   vat_json_init_array (msg_array);
6254   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
6255     {
6256       msg = vat_json_array_add (msg_array);
6257       vat_json_init_object (msg);
6258       vat_json_object_add_uint (msg, "sw_if_index", i);
6259       counter_array = vat_json_object_add (msg, "c");
6260       vat_json_init_array (counter_array);
6261       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
6262         {
6263           counter = vat_json_array_add (counter_array);
6264           vat_json_init_object (counter);
6265           n4 = &vam->ip4_nbr_counters[i][j];
6266           vat_json_object_add_ip4 (counter, "address", n4->address);
6267           vat_json_object_add_uint (counter, "link-type", n4->linkt);
6268           vat_json_object_add_uint (counter, "packets", n4->packets);
6269           vat_json_object_add_uint (counter, "bytes", n4->bytes);
6270         }
6271     }
6272
6273   /* ip6 nbr counters */
6274   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
6275   vat_json_init_array (msg_array);
6276   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
6277     {
6278       msg = vat_json_array_add (msg_array);
6279       vat_json_init_object (msg);
6280       vat_json_object_add_uint (msg, "sw_if_index", i);
6281       counter_array = vat_json_object_add (msg, "c");
6282       vat_json_init_array (counter_array);
6283       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6284         {
6285           counter = vat_json_array_add (counter_array);
6286           vat_json_init_object (counter);
6287           n6 = &vam->ip6_nbr_counters[i][j];
6288           vat_json_object_add_ip6 (counter, "address", n6->address);
6289           vat_json_object_add_uint (counter, "packets", n6->packets);
6290           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6291         }
6292     }
6293
6294   vat_json_print (vam->ofp, &node);
6295   vat_json_free (&node);
6296
6297   return 0;
6298 }
6299
6300 /*
6301  * Pass CLI buffers directly in the CLI_INBAND API message,
6302  * instead of an additional shared memory area.
6303  */
6304 static int
6305 exec_inband (vat_main_t * vam)
6306 {
6307   vl_api_cli_inband_t *mp;
6308   unformat_input_t *i = vam->input;
6309   int ret;
6310
6311   if (vec_len (i->buffer) == 0)
6312     return -1;
6313
6314   if (vam->exec_mode == 0 && unformat (i, "mode"))
6315     {
6316       vam->exec_mode = 1;
6317       return 0;
6318     }
6319   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6320     {
6321       vam->exec_mode = 0;
6322       return 0;
6323     }
6324
6325   /*
6326    * In order for the CLI command to work, it
6327    * must be a vector ending in \n, not a C-string ending
6328    * in \n\0.
6329    */
6330   u32 len = vec_len (vam->input->buffer);
6331   M2 (CLI_INBAND, mp, len);
6332   clib_memcpy (mp->cmd, vam->input->buffer, len);
6333   mp->length = htonl (len);
6334
6335   S (mp);
6336   W (ret);
6337   /* json responses may or may not include a useful reply... */
6338   if (vec_len (vam->cmd_reply))
6339     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6340   return ret;
6341 }
6342
6343 int
6344 exec (vat_main_t * vam)
6345 {
6346   return exec_inband (vam);
6347 }
6348
6349 static int
6350 api_create_loopback (vat_main_t * vam)
6351 {
6352   unformat_input_t *i = vam->input;
6353   vl_api_create_loopback_t *mp;
6354   vl_api_create_loopback_instance_t *mp_lbi;
6355   u8 mac_address[6];
6356   u8 mac_set = 0;
6357   u8 is_specified = 0;
6358   u32 user_instance = 0;
6359   int ret;
6360
6361   memset (mac_address, 0, sizeof (mac_address));
6362
6363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6364     {
6365       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6366         mac_set = 1;
6367       if (unformat (i, "instance %d", &user_instance))
6368         is_specified = 1;
6369       else
6370         break;
6371     }
6372
6373   if (is_specified)
6374     {
6375       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6376       mp_lbi->is_specified = is_specified;
6377       if (is_specified)
6378         mp_lbi->user_instance = htonl (user_instance);
6379       if (mac_set)
6380         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6381       S (mp_lbi);
6382     }
6383   else
6384     {
6385       /* Construct the API message */
6386       M (CREATE_LOOPBACK, mp);
6387       if (mac_set)
6388         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6389       S (mp);
6390     }
6391
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_delete_loopback (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_delete_loopback_t *mp;
6401   u32 sw_if_index = ~0;
6402   int ret;
6403
6404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6405     {
6406       if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         ;
6408       else
6409         break;
6410     }
6411
6412   if (sw_if_index == ~0)
6413     {
6414       errmsg ("missing sw_if_index");
6415       return -99;
6416     }
6417
6418   /* Construct the API message */
6419   M (DELETE_LOOPBACK, mp);
6420   mp->sw_if_index = ntohl (sw_if_index);
6421
6422   S (mp);
6423   W (ret);
6424   return ret;
6425 }
6426
6427 static int
6428 api_want_stats (vat_main_t * vam)
6429 {
6430   unformat_input_t *i = vam->input;
6431   vl_api_want_stats_t *mp;
6432   int enable = -1;
6433   int ret;
6434
6435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (i, "enable"))
6438         enable = 1;
6439       else if (unformat (i, "disable"))
6440         enable = 0;
6441       else
6442         break;
6443     }
6444
6445   if (enable == -1)
6446     {
6447       errmsg ("missing enable|disable");
6448       return -99;
6449     }
6450
6451   M (WANT_STATS, mp);
6452   mp->enable_disable = enable;
6453
6454   S (mp);
6455   W (ret);
6456   return ret;
6457 }
6458
6459 static int
6460 api_want_interface_events (vat_main_t * vam)
6461 {
6462   unformat_input_t *i = vam->input;
6463   vl_api_want_interface_events_t *mp;
6464   int enable = -1;
6465   int ret;
6466
6467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6468     {
6469       if (unformat (i, "enable"))
6470         enable = 1;
6471       else if (unformat (i, "disable"))
6472         enable = 0;
6473       else
6474         break;
6475     }
6476
6477   if (enable == -1)
6478     {
6479       errmsg ("missing enable|disable");
6480       return -99;
6481     }
6482
6483   M (WANT_INTERFACE_EVENTS, mp);
6484   mp->enable_disable = enable;
6485
6486   vam->interface_event_display = enable;
6487
6488   S (mp);
6489   W (ret);
6490   return ret;
6491 }
6492
6493
6494 /* Note: non-static, called once to set up the initial intfc table */
6495 int
6496 api_sw_interface_dump (vat_main_t * vam)
6497 {
6498   vl_api_sw_interface_dump_t *mp;
6499   vl_api_control_ping_t *mp_ping;
6500   hash_pair_t *p;
6501   name_sort_t *nses = 0, *ns;
6502   sw_interface_subif_t *sub = NULL;
6503   int ret;
6504
6505   /* Toss the old name table */
6506   /* *INDENT-OFF* */
6507   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6508   ({
6509     vec_add2 (nses, ns, 1);
6510     ns->name = (u8 *)(p->key);
6511     ns->value = (u32) p->value[0];
6512   }));
6513   /* *INDENT-ON* */
6514
6515   hash_free (vam->sw_if_index_by_interface_name);
6516
6517   vec_foreach (ns, nses) vec_free (ns->name);
6518
6519   vec_free (nses);
6520
6521   vec_foreach (sub, vam->sw_if_subif_table)
6522   {
6523     vec_free (sub->interface_name);
6524   }
6525   vec_free (vam->sw_if_subif_table);
6526
6527   /* recreate the interface name hash table */
6528   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6529
6530   /*
6531    * Ask for all interface names. Otherwise, the epic catalog of
6532    * name filters becomes ridiculously long, and vat ends up needing
6533    * to be taught about new interface types.
6534    */
6535   M (SW_INTERFACE_DUMP, mp);
6536   S (mp);
6537
6538   /* Use a control ping for synchronization */
6539   MPING (CONTROL_PING, mp_ping);
6540   S (mp_ping);
6541
6542   W (ret);
6543   return ret;
6544 }
6545
6546 static int
6547 api_sw_interface_set_flags (vat_main_t * vam)
6548 {
6549   unformat_input_t *i = vam->input;
6550   vl_api_sw_interface_set_flags_t *mp;
6551   u32 sw_if_index;
6552   u8 sw_if_index_set = 0;
6553   u8 admin_up = 0;
6554   int ret;
6555
6556   /* Parse args required to build the message */
6557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6558     {
6559       if (unformat (i, "admin-up"))
6560         admin_up = 1;
6561       else if (unformat (i, "admin-down"))
6562         admin_up = 0;
6563       else
6564         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6565         sw_if_index_set = 1;
6566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6567         sw_if_index_set = 1;
6568       else
6569         break;
6570     }
6571
6572   if (sw_if_index_set == 0)
6573     {
6574       errmsg ("missing interface name or sw_if_index");
6575       return -99;
6576     }
6577
6578   /* Construct the API message */
6579   M (SW_INTERFACE_SET_FLAGS, mp);
6580   mp->sw_if_index = ntohl (sw_if_index);
6581   mp->admin_up_down = admin_up;
6582
6583   /* send it... */
6584   S (mp);
6585
6586   /* Wait for a reply, return the good/bad news... */
6587   W (ret);
6588   return ret;
6589 }
6590
6591 static int
6592 api_sw_interface_set_rx_mode (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_sw_interface_set_rx_mode_t *mp;
6596   u32 sw_if_index;
6597   u8 sw_if_index_set = 0;
6598   int ret;
6599   u8 queue_id_valid = 0;
6600   u32 queue_id;
6601   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6602
6603   /* Parse args required to build the message */
6604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6605     {
6606       if (unformat (i, "queue %d", &queue_id))
6607         queue_id_valid = 1;
6608       else if (unformat (i, "polling"))
6609         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6610       else if (unformat (i, "interrupt"))
6611         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6612       else if (unformat (i, "adaptive"))
6613         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6614       else
6615         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else
6620         break;
6621     }
6622
6623   if (sw_if_index_set == 0)
6624     {
6625       errmsg ("missing interface name or sw_if_index");
6626       return -99;
6627     }
6628   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6629     {
6630       errmsg ("missing rx-mode");
6631       return -99;
6632     }
6633
6634   /* Construct the API message */
6635   M (SW_INTERFACE_SET_RX_MODE, mp);
6636   mp->sw_if_index = ntohl (sw_if_index);
6637   mp->mode = mode;
6638   mp->queue_id_valid = queue_id_valid;
6639   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6640
6641   /* send it... */
6642   S (mp);
6643
6644   /* Wait for a reply, return the good/bad news... */
6645   W (ret);
6646   return ret;
6647 }
6648
6649 static int
6650 api_sw_interface_set_rx_placement (vat_main_t * vam)
6651 {
6652   unformat_input_t *i = vam->input;
6653   vl_api_sw_interface_set_rx_placement_t *mp;
6654   u32 sw_if_index;
6655   u8 sw_if_index_set = 0;
6656   int ret;
6657   u8 is_main = 0;
6658   u32 queue_id, thread_index;
6659
6660   /* Parse args required to build the message */
6661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6662     {
6663       if (unformat (i, "queue %d", &queue_id))
6664         ;
6665       else if (unformat (i, "main"))
6666         is_main = 1;
6667       else if (unformat (i, "worker %d", &thread_index))
6668         ;
6669       else
6670         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6671         sw_if_index_set = 1;
6672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6673         sw_if_index_set = 1;
6674       else
6675         break;
6676     }
6677
6678   if (sw_if_index_set == 0)
6679     {
6680       errmsg ("missing interface name or sw_if_index");
6681       return -99;
6682     }
6683
6684   if (is_main)
6685     thread_index = 0;
6686   /* Construct the API message */
6687   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6688   mp->sw_if_index = ntohl (sw_if_index);
6689   mp->worker_id = ntohl (thread_index);
6690   mp->queue_id = ntohl (queue_id);
6691   mp->is_main = is_main;
6692
6693   /* send it... */
6694   S (mp);
6695   /* Wait for a reply, return the good/bad news... */
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static void vl_api_sw_interface_rx_placement_details_t_handler
6701   (vl_api_sw_interface_rx_placement_details_t * mp)
6702 {
6703   vat_main_t *vam = &vat_main;
6704   u32 worker_id = ntohl (mp->worker_id);
6705
6706   print (vam->ofp,
6707          "\n%-11d %-11s %-6d %-5d %-9s",
6708          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6709          worker_id, ntohl (mp->queue_id),
6710          (mp->mode ==
6711           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6712 }
6713
6714 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6715   (vl_api_sw_interface_rx_placement_details_t * mp)
6716 {
6717   vat_main_t *vam = &vat_main;
6718   vat_json_node_t *node = NULL;
6719
6720   if (VAT_JSON_ARRAY != vam->json_tree.type)
6721     {
6722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6723       vat_json_init_array (&vam->json_tree);
6724     }
6725   node = vat_json_array_add (&vam->json_tree);
6726
6727   vat_json_init_object (node);
6728   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6729   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6730   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6731   vat_json_object_add_uint (node, "mode", mp->mode);
6732 }
6733
6734 static int
6735 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6736 {
6737   unformat_input_t *i = vam->input;
6738   vl_api_sw_interface_rx_placement_dump_t *mp;
6739   vl_api_control_ping_t *mp_ping;
6740   int ret;
6741   u32 sw_if_index;
6742   u8 sw_if_index_set = 0;
6743
6744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6745     {
6746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6747         sw_if_index_set++;
6748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6749         sw_if_index_set++;
6750       else
6751         break;
6752     }
6753
6754   print (vam->ofp,
6755          "\n%-11s %-11s %-6s %-5s %-4s",
6756          "sw_if_index", "main/worker", "thread", "queue", "mode");
6757
6758   /* Dump Interface rx placement */
6759   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6760
6761   if (sw_if_index_set)
6762     mp->sw_if_index = htonl (sw_if_index);
6763   else
6764     mp->sw_if_index = ~0;
6765
6766   S (mp);
6767
6768   /* Use a control ping for synchronization */
6769   MPING (CONTROL_PING, mp_ping);
6770   S (mp_ping);
6771
6772   W (ret);
6773   return ret;
6774 }
6775
6776 static int
6777 api_sw_interface_clear_stats (vat_main_t * vam)
6778 {
6779   unformat_input_t *i = vam->input;
6780   vl_api_sw_interface_clear_stats_t *mp;
6781   u32 sw_if_index;
6782   u8 sw_if_index_set = 0;
6783   int ret;
6784
6785   /* Parse args required to build the message */
6786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6787     {
6788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6789         sw_if_index_set = 1;
6790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6791         sw_if_index_set = 1;
6792       else
6793         break;
6794     }
6795
6796   /* Construct the API message */
6797   M (SW_INTERFACE_CLEAR_STATS, mp);
6798
6799   if (sw_if_index_set == 1)
6800     mp->sw_if_index = ntohl (sw_if_index);
6801   else
6802     mp->sw_if_index = ~0;
6803
6804   /* send it... */
6805   S (mp);
6806
6807   /* Wait for a reply, return the good/bad news... */
6808   W (ret);
6809   return ret;
6810 }
6811
6812 static int
6813 api_sw_interface_add_del_address (vat_main_t * vam)
6814 {
6815   unformat_input_t *i = vam->input;
6816   vl_api_sw_interface_add_del_address_t *mp;
6817   u32 sw_if_index;
6818   u8 sw_if_index_set = 0;
6819   u8 is_add = 1, del_all = 0;
6820   u32 address_length = 0;
6821   u8 v4_address_set = 0;
6822   u8 v6_address_set = 0;
6823   ip4_address_t v4address;
6824   ip6_address_t v6address;
6825   int ret;
6826
6827   /* Parse args required to build the message */
6828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6829     {
6830       if (unformat (i, "del-all"))
6831         del_all = 1;
6832       else if (unformat (i, "del"))
6833         is_add = 0;
6834       else
6835         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6836         sw_if_index_set = 1;
6837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "%U/%d",
6840                          unformat_ip4_address, &v4address, &address_length))
6841         v4_address_set = 1;
6842       else if (unformat (i, "%U/%d",
6843                          unformat_ip6_address, &v6address, &address_length))
6844         v6_address_set = 1;
6845       else
6846         break;
6847     }
6848
6849   if (sw_if_index_set == 0)
6850     {
6851       errmsg ("missing interface name or sw_if_index");
6852       return -99;
6853     }
6854   if (v4_address_set && v6_address_set)
6855     {
6856       errmsg ("both v4 and v6 addresses set");
6857       return -99;
6858     }
6859   if (!v4_address_set && !v6_address_set && !del_all)
6860     {
6861       errmsg ("no addresses set");
6862       return -99;
6863     }
6864
6865   /* Construct the API message */
6866   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6867
6868   mp->sw_if_index = ntohl (sw_if_index);
6869   mp->is_add = is_add;
6870   mp->del_all = del_all;
6871   if (v6_address_set)
6872     {
6873       mp->is_ipv6 = 1;
6874       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6875     }
6876   else
6877     {
6878       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6879     }
6880   mp->address_length = address_length;
6881
6882   /* send it... */
6883   S (mp);
6884
6885   /* Wait for a reply, return good/bad news  */
6886   W (ret);
6887   return ret;
6888 }
6889
6890 static int
6891 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6892 {
6893   unformat_input_t *i = vam->input;
6894   vl_api_sw_interface_set_mpls_enable_t *mp;
6895   u32 sw_if_index;
6896   u8 sw_if_index_set = 0;
6897   u8 enable = 1;
6898   int ret;
6899
6900   /* Parse args required to build the message */
6901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6902     {
6903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6904         sw_if_index_set = 1;
6905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6906         sw_if_index_set = 1;
6907       else if (unformat (i, "disable"))
6908         enable = 0;
6909       else if (unformat (i, "dis"))
6910         enable = 0;
6911       else
6912         break;
6913     }
6914
6915   if (sw_if_index_set == 0)
6916     {
6917       errmsg ("missing interface name or sw_if_index");
6918       return -99;
6919     }
6920
6921   /* Construct the API message */
6922   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6923
6924   mp->sw_if_index = ntohl (sw_if_index);
6925   mp->enable = enable;
6926
6927   /* send it... */
6928   S (mp);
6929
6930   /* Wait for a reply... */
6931   W (ret);
6932   return ret;
6933 }
6934
6935 static int
6936 api_sw_interface_set_table (vat_main_t * vam)
6937 {
6938   unformat_input_t *i = vam->input;
6939   vl_api_sw_interface_set_table_t *mp;
6940   u32 sw_if_index, vrf_id = 0;
6941   u8 sw_if_index_set = 0;
6942   u8 is_ipv6 = 0;
6943   int ret;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6951         sw_if_index_set = 1;
6952       else if (unformat (i, "vrf %d", &vrf_id))
6953         ;
6954       else if (unformat (i, "ipv6"))
6955         is_ipv6 = 1;
6956       else
6957         break;
6958     }
6959
6960   if (sw_if_index_set == 0)
6961     {
6962       errmsg ("missing interface name or sw_if_index");
6963       return -99;
6964     }
6965
6966   /* Construct the API message */
6967   M (SW_INTERFACE_SET_TABLE, mp);
6968
6969   mp->sw_if_index = ntohl (sw_if_index);
6970   mp->is_ipv6 = is_ipv6;
6971   mp->vrf_id = ntohl (vrf_id);
6972
6973   /* send it... */
6974   S (mp);
6975
6976   /* Wait for a reply... */
6977   W (ret);
6978   return ret;
6979 }
6980
6981 static void vl_api_sw_interface_get_table_reply_t_handler
6982   (vl_api_sw_interface_get_table_reply_t * mp)
6983 {
6984   vat_main_t *vam = &vat_main;
6985
6986   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6987
6988   vam->retval = ntohl (mp->retval);
6989   vam->result_ready = 1;
6990
6991 }
6992
6993 static void vl_api_sw_interface_get_table_reply_t_handler_json
6994   (vl_api_sw_interface_get_table_reply_t * mp)
6995 {
6996   vat_main_t *vam = &vat_main;
6997   vat_json_node_t node;
6998
6999   vat_json_init_object (&node);
7000   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
7001   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
7002
7003   vat_json_print (vam->ofp, &node);
7004   vat_json_free (&node);
7005
7006   vam->retval = ntohl (mp->retval);
7007   vam->result_ready = 1;
7008 }
7009
7010 static int
7011 api_sw_interface_get_table (vat_main_t * vam)
7012 {
7013   unformat_input_t *i = vam->input;
7014   vl_api_sw_interface_get_table_t *mp;
7015   u32 sw_if_index;
7016   u8 sw_if_index_set = 0;
7017   u8 is_ipv6 = 0;
7018   int ret;
7019
7020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7021     {
7022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7023         sw_if_index_set = 1;
7024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7025         sw_if_index_set = 1;
7026       else if (unformat (i, "ipv6"))
7027         is_ipv6 = 1;
7028       else
7029         break;
7030     }
7031
7032   if (sw_if_index_set == 0)
7033     {
7034       errmsg ("missing interface name or sw_if_index");
7035       return -99;
7036     }
7037
7038   M (SW_INTERFACE_GET_TABLE, mp);
7039   mp->sw_if_index = htonl (sw_if_index);
7040   mp->is_ipv6 = is_ipv6;
7041
7042   S (mp);
7043   W (ret);
7044   return ret;
7045 }
7046
7047 static int
7048 api_sw_interface_set_vpath (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_sw_interface_set_vpath_t *mp;
7052   u32 sw_if_index = 0;
7053   u8 sw_if_index_set = 0;
7054   u8 is_enable = 0;
7055   int ret;
7056
7057   /* Parse args required to build the message */
7058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059     {
7060       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7061         sw_if_index_set = 1;
7062       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7063         sw_if_index_set = 1;
7064       else if (unformat (i, "enable"))
7065         is_enable = 1;
7066       else if (unformat (i, "disable"))
7067         is_enable = 0;
7068       else
7069         break;
7070     }
7071
7072   if (sw_if_index_set == 0)
7073     {
7074       errmsg ("missing interface name or sw_if_index");
7075       return -99;
7076     }
7077
7078   /* Construct the API message */
7079   M (SW_INTERFACE_SET_VPATH, mp);
7080
7081   mp->sw_if_index = ntohl (sw_if_index);
7082   mp->enable = is_enable;
7083
7084   /* send it... */
7085   S (mp);
7086
7087   /* Wait for a reply... */
7088   W (ret);
7089   return ret;
7090 }
7091
7092 static int
7093 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
7094 {
7095   unformat_input_t *i = vam->input;
7096   vl_api_sw_interface_set_vxlan_bypass_t *mp;
7097   u32 sw_if_index = 0;
7098   u8 sw_if_index_set = 0;
7099   u8 is_enable = 1;
7100   u8 is_ipv6 = 0;
7101   int ret;
7102
7103   /* Parse args required to build the message */
7104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7105     {
7106       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7107         sw_if_index_set = 1;
7108       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7109         sw_if_index_set = 1;
7110       else if (unformat (i, "enable"))
7111         is_enable = 1;
7112       else if (unformat (i, "disable"))
7113         is_enable = 0;
7114       else if (unformat (i, "ip4"))
7115         is_ipv6 = 0;
7116       else if (unformat (i, "ip6"))
7117         is_ipv6 = 1;
7118       else
7119         break;
7120     }
7121
7122   if (sw_if_index_set == 0)
7123     {
7124       errmsg ("missing interface name or sw_if_index");
7125       return -99;
7126     }
7127
7128   /* Construct the API message */
7129   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
7130
7131   mp->sw_if_index = ntohl (sw_if_index);
7132   mp->enable = is_enable;
7133   mp->is_ipv6 = is_ipv6;
7134
7135   /* send it... */
7136   S (mp);
7137
7138   /* Wait for a reply... */
7139   W (ret);
7140   return ret;
7141 }
7142
7143 static int
7144 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
7145 {
7146   unformat_input_t *i = vam->input;
7147   vl_api_sw_interface_set_geneve_bypass_t *mp;
7148   u32 sw_if_index = 0;
7149   u8 sw_if_index_set = 0;
7150   u8 is_enable = 1;
7151   u8 is_ipv6 = 0;
7152   int ret;
7153
7154   /* Parse args required to build the message */
7155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7156     {
7157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7160         sw_if_index_set = 1;
7161       else if (unformat (i, "enable"))
7162         is_enable = 1;
7163       else if (unformat (i, "disable"))
7164         is_enable = 0;
7165       else if (unformat (i, "ip4"))
7166         is_ipv6 = 0;
7167       else if (unformat (i, "ip6"))
7168         is_ipv6 = 1;
7169       else
7170         break;
7171     }
7172
7173   if (sw_if_index_set == 0)
7174     {
7175       errmsg ("missing interface name or sw_if_index");
7176       return -99;
7177     }
7178
7179   /* Construct the API message */
7180   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
7181
7182   mp->sw_if_index = ntohl (sw_if_index);
7183   mp->enable = is_enable;
7184   mp->is_ipv6 = is_ipv6;
7185
7186   /* send it... */
7187   S (mp);
7188
7189   /* Wait for a reply... */
7190   W (ret);
7191   return ret;
7192 }
7193
7194 static int
7195 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
7196 {
7197   unformat_input_t *i = vam->input;
7198   vl_api_sw_interface_set_l2_xconnect_t *mp;
7199   u32 rx_sw_if_index;
7200   u8 rx_sw_if_index_set = 0;
7201   u32 tx_sw_if_index;
7202   u8 tx_sw_if_index_set = 0;
7203   u8 enable = 1;
7204   int ret;
7205
7206   /* Parse args required to build the message */
7207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7208     {
7209       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7210         rx_sw_if_index_set = 1;
7211       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7212         tx_sw_if_index_set = 1;
7213       else if (unformat (i, "rx"))
7214         {
7215           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216             {
7217               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7218                             &rx_sw_if_index))
7219                 rx_sw_if_index_set = 1;
7220             }
7221           else
7222             break;
7223         }
7224       else if (unformat (i, "tx"))
7225         {
7226           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227             {
7228               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7229                             &tx_sw_if_index))
7230                 tx_sw_if_index_set = 1;
7231             }
7232           else
7233             break;
7234         }
7235       else if (unformat (i, "enable"))
7236         enable = 1;
7237       else if (unformat (i, "disable"))
7238         enable = 0;
7239       else
7240         break;
7241     }
7242
7243   if (rx_sw_if_index_set == 0)
7244     {
7245       errmsg ("missing rx interface name or rx_sw_if_index");
7246       return -99;
7247     }
7248
7249   if (enable && (tx_sw_if_index_set == 0))
7250     {
7251       errmsg ("missing tx interface name or tx_sw_if_index");
7252       return -99;
7253     }
7254
7255   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
7256
7257   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7258   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7259   mp->enable = enable;
7260
7261   S (mp);
7262   W (ret);
7263   return ret;
7264 }
7265
7266 static int
7267 api_sw_interface_set_l2_bridge (vat_main_t * vam)
7268 {
7269   unformat_input_t *i = vam->input;
7270   vl_api_sw_interface_set_l2_bridge_t *mp;
7271   vl_api_l2_port_type_t port_type;
7272   u32 rx_sw_if_index;
7273   u8 rx_sw_if_index_set = 0;
7274   u32 bd_id;
7275   u8 bd_id_set = 0;
7276   u32 shg = 0;
7277   u8 enable = 1;
7278   int ret;
7279
7280   port_type = L2_API_PORT_TYPE_NORMAL;
7281
7282   /* Parse args required to build the message */
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
7286         rx_sw_if_index_set = 1;
7287       else if (unformat (i, "bd_id %d", &bd_id))
7288         bd_id_set = 1;
7289       else
7290         if (unformat
7291             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
7292         rx_sw_if_index_set = 1;
7293       else if (unformat (i, "shg %d", &shg))
7294         ;
7295       else if (unformat (i, "bvi"))
7296         port_type = L2_API_PORT_TYPE_BVI;
7297       else if (unformat (i, "uu-fwd"))
7298         port_type = L2_API_PORT_TYPE_UU_FWD;
7299       else if (unformat (i, "enable"))
7300         enable = 1;
7301       else if (unformat (i, "disable"))
7302         enable = 0;
7303       else
7304         break;
7305     }
7306
7307   if (rx_sw_if_index_set == 0)
7308     {
7309       errmsg ("missing rx interface name or sw_if_index");
7310       return -99;
7311     }
7312
7313   if (enable && (bd_id_set == 0))
7314     {
7315       errmsg ("missing bridge domain");
7316       return -99;
7317     }
7318
7319   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
7320
7321   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7322   mp->bd_id = ntohl (bd_id);
7323   mp->shg = (u8) shg;
7324   mp->port_type = ntohl (port_type);
7325   mp->enable = enable;
7326
7327   S (mp);
7328   W (ret);
7329   return ret;
7330 }
7331
7332 static int
7333 api_bridge_domain_dump (vat_main_t * vam)
7334 {
7335   unformat_input_t *i = vam->input;
7336   vl_api_bridge_domain_dump_t *mp;
7337   vl_api_control_ping_t *mp_ping;
7338   u32 bd_id = ~0;
7339   int ret;
7340
7341   /* Parse args required to build the message */
7342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7343     {
7344       if (unformat (i, "bd_id %d", &bd_id))
7345         ;
7346       else
7347         break;
7348     }
7349
7350   M (BRIDGE_DOMAIN_DUMP, mp);
7351   mp->bd_id = ntohl (bd_id);
7352   S (mp);
7353
7354   /* Use a control ping for synchronization */
7355   MPING (CONTROL_PING, mp_ping);
7356   S (mp_ping);
7357
7358   W (ret);
7359   return ret;
7360 }
7361
7362 static int
7363 api_bridge_domain_add_del (vat_main_t * vam)
7364 {
7365   unformat_input_t *i = vam->input;
7366   vl_api_bridge_domain_add_del_t *mp;
7367   u32 bd_id = ~0;
7368   u8 is_add = 1;
7369   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7370   u8 *bd_tag = NULL;
7371   u32 mac_age = 0;
7372   int ret;
7373
7374   /* Parse args required to build the message */
7375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7376     {
7377       if (unformat (i, "bd_id %d", &bd_id))
7378         ;
7379       else if (unformat (i, "flood %d", &flood))
7380         ;
7381       else if (unformat (i, "uu-flood %d", &uu_flood))
7382         ;
7383       else if (unformat (i, "forward %d", &forward))
7384         ;
7385       else if (unformat (i, "learn %d", &learn))
7386         ;
7387       else if (unformat (i, "arp-term %d", &arp_term))
7388         ;
7389       else if (unformat (i, "mac-age %d", &mac_age))
7390         ;
7391       else if (unformat (i, "bd-tag %s", &bd_tag))
7392         ;
7393       else if (unformat (i, "del"))
7394         {
7395           is_add = 0;
7396           flood = uu_flood = forward = learn = 0;
7397         }
7398       else
7399         break;
7400     }
7401
7402   if (bd_id == ~0)
7403     {
7404       errmsg ("missing bridge domain");
7405       ret = -99;
7406       goto done;
7407     }
7408
7409   if (mac_age > 255)
7410     {
7411       errmsg ("mac age must be less than 256 ");
7412       ret = -99;
7413       goto done;
7414     }
7415
7416   if ((bd_tag) && (vec_len (bd_tag) > 63))
7417     {
7418       errmsg ("bd-tag cannot be longer than 63");
7419       ret = -99;
7420       goto done;
7421     }
7422
7423   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7424
7425   mp->bd_id = ntohl (bd_id);
7426   mp->flood = flood;
7427   mp->uu_flood = uu_flood;
7428   mp->forward = forward;
7429   mp->learn = learn;
7430   mp->arp_term = arp_term;
7431   mp->is_add = is_add;
7432   mp->mac_age = (u8) mac_age;
7433   if (bd_tag)
7434     {
7435       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
7436       mp->bd_tag[vec_len (bd_tag)] = 0;
7437     }
7438   S (mp);
7439   W (ret);
7440
7441 done:
7442   vec_free (bd_tag);
7443   return ret;
7444 }
7445
7446 static int
7447 api_l2fib_flush_bd (vat_main_t * vam)
7448 {
7449   unformat_input_t *i = vam->input;
7450   vl_api_l2fib_flush_bd_t *mp;
7451   u32 bd_id = ~0;
7452   int ret;
7453
7454   /* Parse args required to build the message */
7455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7456     {
7457       if (unformat (i, "bd_id %d", &bd_id));
7458       else
7459         break;
7460     }
7461
7462   if (bd_id == ~0)
7463     {
7464       errmsg ("missing bridge domain");
7465       return -99;
7466     }
7467
7468   M (L2FIB_FLUSH_BD, mp);
7469
7470   mp->bd_id = htonl (bd_id);
7471
7472   S (mp);
7473   W (ret);
7474   return ret;
7475 }
7476
7477 static int
7478 api_l2fib_flush_int (vat_main_t * vam)
7479 {
7480   unformat_input_t *i = vam->input;
7481   vl_api_l2fib_flush_int_t *mp;
7482   u32 sw_if_index = ~0;
7483   int ret;
7484
7485   /* Parse args required to build the message */
7486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7487     {
7488       if (unformat (i, "sw_if_index %d", &sw_if_index));
7489       else
7490         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7491       else
7492         break;
7493     }
7494
7495   if (sw_if_index == ~0)
7496     {
7497       errmsg ("missing interface name or sw_if_index");
7498       return -99;
7499     }
7500
7501   M (L2FIB_FLUSH_INT, mp);
7502
7503   mp->sw_if_index = ntohl (sw_if_index);
7504
7505   S (mp);
7506   W (ret);
7507   return ret;
7508 }
7509
7510 static int
7511 api_l2fib_add_del (vat_main_t * vam)
7512 {
7513   unformat_input_t *i = vam->input;
7514   vl_api_l2fib_add_del_t *mp;
7515   f64 timeout;
7516   u8 mac[6] = { 0 };
7517   u8 mac_set = 0;
7518   u32 bd_id;
7519   u8 bd_id_set = 0;
7520   u32 sw_if_index = 0;
7521   u8 sw_if_index_set = 0;
7522   u8 is_add = 1;
7523   u8 static_mac = 0;
7524   u8 filter_mac = 0;
7525   u8 bvi_mac = 0;
7526   int count = 1;
7527   f64 before = 0;
7528   int j;
7529
7530   /* Parse args required to build the message */
7531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7532     {
7533       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7534         mac_set = 1;
7535       else if (unformat (i, "bd_id %d", &bd_id))
7536         bd_id_set = 1;
7537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7538         sw_if_index_set = 1;
7539       else if (unformat (i, "sw_if"))
7540         {
7541           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7542             {
7543               if (unformat
7544                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7545                 sw_if_index_set = 1;
7546             }
7547           else
7548             break;
7549         }
7550       else if (unformat (i, "static"))
7551         static_mac = 1;
7552       else if (unformat (i, "filter"))
7553         {
7554           filter_mac = 1;
7555           static_mac = 1;
7556         }
7557       else if (unformat (i, "bvi"))
7558         {
7559           bvi_mac = 1;
7560           static_mac = 1;
7561         }
7562       else if (unformat (i, "del"))
7563         is_add = 0;
7564       else if (unformat (i, "count %d", &count))
7565         ;
7566       else
7567         break;
7568     }
7569
7570   if (mac_set == 0)
7571     {
7572       errmsg ("missing mac address");
7573       return -99;
7574     }
7575
7576   if (bd_id_set == 0)
7577     {
7578       errmsg ("missing bridge domain");
7579       return -99;
7580     }
7581
7582   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7583     {
7584       errmsg ("missing interface name or sw_if_index");
7585       return -99;
7586     }
7587
7588   if (count > 1)
7589     {
7590       /* Turn on async mode */
7591       vam->async_mode = 1;
7592       vam->async_errors = 0;
7593       before = vat_time_now (vam);
7594     }
7595
7596   for (j = 0; j < count; j++)
7597     {
7598       M (L2FIB_ADD_DEL, mp);
7599
7600       clib_memcpy (mp->mac, mac, 6);
7601       mp->bd_id = ntohl (bd_id);
7602       mp->is_add = is_add;
7603       mp->sw_if_index = ntohl (sw_if_index);
7604
7605       if (is_add)
7606         {
7607           mp->static_mac = static_mac;
7608           mp->filter_mac = filter_mac;
7609           mp->bvi_mac = bvi_mac;
7610         }
7611       increment_mac_address (mac);
7612       /* send it... */
7613       S (mp);
7614     }
7615
7616   if (count > 1)
7617     {
7618       vl_api_control_ping_t *mp_ping;
7619       f64 after;
7620
7621       /* Shut off async mode */
7622       vam->async_mode = 0;
7623
7624       MPING (CONTROL_PING, mp_ping);
7625       S (mp_ping);
7626
7627       timeout = vat_time_now (vam) + 1.0;
7628       while (vat_time_now (vam) < timeout)
7629         if (vam->result_ready == 1)
7630           goto out;
7631       vam->retval = -99;
7632
7633     out:
7634       if (vam->retval == -99)
7635         errmsg ("timeout");
7636
7637       if (vam->async_errors > 0)
7638         {
7639           errmsg ("%d asynchronous errors", vam->async_errors);
7640           vam->retval = -98;
7641         }
7642       vam->async_errors = 0;
7643       after = vat_time_now (vam);
7644
7645       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7646              count, after - before, count / (after - before));
7647     }
7648   else
7649     {
7650       int ret;
7651
7652       /* Wait for a reply... */
7653       W (ret);
7654       return ret;
7655     }
7656   /* Return the good/bad news */
7657   return (vam->retval);
7658 }
7659
7660 static int
7661 api_bridge_domain_set_mac_age (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_bridge_domain_set_mac_age_t *mp;
7665   u32 bd_id = ~0;
7666   u32 mac_age = 0;
7667   int ret;
7668
7669   /* Parse args required to build the message */
7670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7671     {
7672       if (unformat (i, "bd_id %d", &bd_id));
7673       else if (unformat (i, "mac-age %d", &mac_age));
7674       else
7675         break;
7676     }
7677
7678   if (bd_id == ~0)
7679     {
7680       errmsg ("missing bridge domain");
7681       return -99;
7682     }
7683
7684   if (mac_age > 255)
7685     {
7686       errmsg ("mac age must be less than 256 ");
7687       return -99;
7688     }
7689
7690   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7691
7692   mp->bd_id = htonl (bd_id);
7693   mp->mac_age = (u8) mac_age;
7694
7695   S (mp);
7696   W (ret);
7697   return ret;
7698 }
7699
7700 static int
7701 api_l2_flags (vat_main_t * vam)
7702 {
7703   unformat_input_t *i = vam->input;
7704   vl_api_l2_flags_t *mp;
7705   u32 sw_if_index;
7706   u32 flags = 0;
7707   u8 sw_if_index_set = 0;
7708   u8 is_set = 0;
7709   int ret;
7710
7711   /* Parse args required to build the message */
7712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7713     {
7714       if (unformat (i, "sw_if_index %d", &sw_if_index))
7715         sw_if_index_set = 1;
7716       else if (unformat (i, "sw_if"))
7717         {
7718           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7719             {
7720               if (unformat
7721                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7722                 sw_if_index_set = 1;
7723             }
7724           else
7725             break;
7726         }
7727       else if (unformat (i, "learn"))
7728         flags |= L2_LEARN;
7729       else if (unformat (i, "forward"))
7730         flags |= L2_FWD;
7731       else if (unformat (i, "flood"))
7732         flags |= L2_FLOOD;
7733       else if (unformat (i, "uu-flood"))
7734         flags |= L2_UU_FLOOD;
7735       else if (unformat (i, "arp-term"))
7736         flags |= L2_ARP_TERM;
7737       else if (unformat (i, "off"))
7738         is_set = 0;
7739       else if (unformat (i, "disable"))
7740         is_set = 0;
7741       else
7742         break;
7743     }
7744
7745   if (sw_if_index_set == 0)
7746     {
7747       errmsg ("missing interface name or sw_if_index");
7748       return -99;
7749     }
7750
7751   M (L2_FLAGS, mp);
7752
7753   mp->sw_if_index = ntohl (sw_if_index);
7754   mp->feature_bitmap = ntohl (flags);
7755   mp->is_set = is_set;
7756
7757   S (mp);
7758   W (ret);
7759   return ret;
7760 }
7761
7762 static int
7763 api_bridge_flags (vat_main_t * vam)
7764 {
7765   unformat_input_t *i = vam->input;
7766   vl_api_bridge_flags_t *mp;
7767   u32 bd_id;
7768   u8 bd_id_set = 0;
7769   u8 is_set = 1;
7770   bd_flags_t flags = 0;
7771   int ret;
7772
7773   /* Parse args required to build the message */
7774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7775     {
7776       if (unformat (i, "bd_id %d", &bd_id))
7777         bd_id_set = 1;
7778       else if (unformat (i, "learn"))
7779         flags |= BRIDGE_API_FLAG_LEARN;
7780       else if (unformat (i, "forward"))
7781         flags |= BRIDGE_API_FLAG_FWD;
7782       else if (unformat (i, "flood"))
7783         flags |= BRIDGE_API_FLAG_FLOOD;
7784       else if (unformat (i, "uu-flood"))
7785         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7786       else if (unformat (i, "arp-term"))
7787         flags |= BRIDGE_API_FLAG_ARP_TERM;
7788       else if (unformat (i, "off"))
7789         is_set = 0;
7790       else if (unformat (i, "disable"))
7791         is_set = 0;
7792       else
7793         break;
7794     }
7795
7796   if (bd_id_set == 0)
7797     {
7798       errmsg ("missing bridge domain");
7799       return -99;
7800     }
7801
7802   M (BRIDGE_FLAGS, mp);
7803
7804   mp->bd_id = ntohl (bd_id);
7805   mp->flags = ntohl (flags);
7806   mp->is_set = is_set;
7807
7808   S (mp);
7809   W (ret);
7810   return ret;
7811 }
7812
7813 static int
7814 api_bd_ip_mac_add_del (vat_main_t * vam)
7815 {
7816   unformat_input_t *i = vam->input;
7817   vl_api_bd_ip_mac_add_del_t *mp;
7818   u32 bd_id;
7819   u8 is_ipv6 = 0;
7820   u8 is_add = 1;
7821   u8 bd_id_set = 0;
7822   u8 ip_set = 0;
7823   u8 mac_set = 0;
7824   ip4_address_t v4addr;
7825   ip6_address_t v6addr;
7826   u8 macaddr[6];
7827   int ret;
7828
7829
7830   /* Parse args required to build the message */
7831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7832     {
7833       if (unformat (i, "bd_id %d", &bd_id))
7834         {
7835           bd_id_set++;
7836         }
7837       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7838         {
7839           ip_set++;
7840         }
7841       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7842         {
7843           ip_set++;
7844           is_ipv6++;
7845         }
7846       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7847         {
7848           mac_set++;
7849         }
7850       else if (unformat (i, "del"))
7851         is_add = 0;
7852       else
7853         break;
7854     }
7855
7856   if (bd_id_set == 0)
7857     {
7858       errmsg ("missing bridge domain");
7859       return -99;
7860     }
7861   else if (ip_set == 0)
7862     {
7863       errmsg ("missing IP address");
7864       return -99;
7865     }
7866   else if (mac_set == 0)
7867     {
7868       errmsg ("missing MAC address");
7869       return -99;
7870     }
7871
7872   M (BD_IP_MAC_ADD_DEL, mp);
7873
7874   mp->bd_id = ntohl (bd_id);
7875   mp->is_ipv6 = is_ipv6;
7876   mp->is_add = is_add;
7877   if (is_ipv6)
7878     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7879   else
7880     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7881   clib_memcpy (mp->mac_address, macaddr, 6);
7882   S (mp);
7883   W (ret);
7884   return ret;
7885 }
7886
7887 static void vl_api_bd_ip_mac_details_t_handler
7888   (vl_api_bd_ip_mac_details_t * mp)
7889 {
7890   vat_main_t *vam = &vat_main;
7891   u8 *ip = 0;
7892
7893   if (!mp->is_ipv6)
7894     ip =
7895       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7896   else
7897     ip =
7898       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7899
7900   print (vam->ofp,
7901          "\n%-5d %-7s %-20U %-30s",
7902          ntohl (mp->bd_id), mp->is_ipv6 ? "ip6" : "ip4",
7903          format_ethernet_address, mp->mac_address, ip);
7904
7905   vec_free (ip);
7906 }
7907
7908 static void vl_api_bd_ip_mac_details_t_handler_json
7909   (vl_api_bd_ip_mac_details_t * mp)
7910 {
7911   vat_main_t *vam = &vat_main;
7912   vat_json_node_t *node = NULL;
7913
7914   if (VAT_JSON_ARRAY != vam->json_tree.type)
7915     {
7916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7917       vat_json_init_array (&vam->json_tree);
7918     }
7919   node = vat_json_array_add (&vam->json_tree);
7920
7921   vat_json_init_object (node);
7922   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
7923   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
7924   vat_json_object_add_string_copy (node, "mac_address",
7925                                    format (0, "%U", format_ethernet_address,
7926                                            &mp->mac_address));
7927   u8 *ip = 0;
7928
7929   if (!mp->is_ipv6)
7930     ip =
7931       format (0, "%U", format_ip4_address, (ip4_address_t *) mp->ip_address);
7932   else
7933     ip =
7934       format (0, "%U", format_ip6_address, (ip6_address_t *) mp->ip_address);
7935   vat_json_object_add_string_copy (node, "ip_address", ip);
7936   vec_free (ip);
7937 }
7938
7939 static int
7940 api_bd_ip_mac_dump (vat_main_t * vam)
7941 {
7942   unformat_input_t *i = vam->input;
7943   vl_api_bd_ip_mac_dump_t *mp;
7944   vl_api_control_ping_t *mp_ping;
7945   int ret;
7946   u32 bd_id;
7947   u8 bd_id_set = 0;
7948
7949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7950     {
7951       if (unformat (i, "bd_id %d", &bd_id))
7952         {
7953           bd_id_set++;
7954         }
7955       else
7956         break;
7957     }
7958
7959   print (vam->ofp,
7960          "\n%-5s %-7s %-20s %-30s",
7961          "bd_id", "is_ipv6", "mac_address", "ip_address");
7962
7963   /* Dump Bridge Domain Ip to Mac entries */
7964   M (BD_IP_MAC_DUMP, mp);
7965
7966   if (bd_id_set)
7967     mp->bd_id = htonl (bd_id);
7968   else
7969     mp->bd_id = ~0;
7970
7971   S (mp);
7972
7973   /* Use a control ping for synchronization */
7974   MPING (CONTROL_PING, mp_ping);
7975   S (mp_ping);
7976
7977   W (ret);
7978   return ret;
7979 }
7980
7981 static int
7982 api_tap_connect (vat_main_t * vam)
7983 {
7984   unformat_input_t *i = vam->input;
7985   vl_api_tap_connect_t *mp;
7986   u8 mac_address[6];
7987   u8 random_mac = 1;
7988   u8 name_set = 0;
7989   u8 *tap_name;
7990   u8 *tag = 0;
7991   ip4_address_t ip4_address;
7992   u32 ip4_mask_width;
7993   int ip4_address_set = 0;
7994   ip6_address_t ip6_address;
7995   u32 ip6_mask_width;
7996   int ip6_address_set = 0;
7997   int ret;
7998
7999   memset (mac_address, 0, sizeof (mac_address));
8000
8001   /* Parse args required to build the message */
8002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8003     {
8004       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8005         {
8006           random_mac = 0;
8007         }
8008       else if (unformat (i, "random-mac"))
8009         random_mac = 1;
8010       else if (unformat (i, "tapname %s", &tap_name))
8011         name_set = 1;
8012       else if (unformat (i, "tag %s", &tag))
8013         ;
8014       else if (unformat (i, "address %U/%d",
8015                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
8016         ip4_address_set = 1;
8017       else if (unformat (i, "address %U/%d",
8018                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
8019         ip6_address_set = 1;
8020       else
8021         break;
8022     }
8023
8024   if (name_set == 0)
8025     {
8026       errmsg ("missing tap name");
8027       return -99;
8028     }
8029   if (vec_len (tap_name) > 63)
8030     {
8031       errmsg ("tap name too long");
8032       return -99;
8033     }
8034   vec_add1 (tap_name, 0);
8035
8036   if (vec_len (tag) > 63)
8037     {
8038       errmsg ("tag too long");
8039       return -99;
8040     }
8041
8042   /* Construct the API message */
8043   M (TAP_CONNECT, mp);
8044
8045   mp->use_random_mac = random_mac;
8046   clib_memcpy (mp->mac_address, mac_address, 6);
8047   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8048   if (tag)
8049     clib_memcpy (mp->tag, tag, vec_len (tag));
8050
8051   if (ip4_address_set)
8052     {
8053       mp->ip4_address_set = 1;
8054       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
8055       mp->ip4_mask_width = ip4_mask_width;
8056     }
8057   if (ip6_address_set)
8058     {
8059       mp->ip6_address_set = 1;
8060       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
8061       mp->ip6_mask_width = ip6_mask_width;
8062     }
8063
8064   vec_free (tap_name);
8065   vec_free (tag);
8066
8067   /* send it... */
8068   S (mp);
8069
8070   /* Wait for a reply... */
8071   W (ret);
8072   return ret;
8073 }
8074
8075 static int
8076 api_tap_modify (vat_main_t * vam)
8077 {
8078   unformat_input_t *i = vam->input;
8079   vl_api_tap_modify_t *mp;
8080   u8 mac_address[6];
8081   u8 random_mac = 1;
8082   u8 name_set = 0;
8083   u8 *tap_name;
8084   u32 sw_if_index = ~0;
8085   u8 sw_if_index_set = 0;
8086   int ret;
8087
8088   memset (mac_address, 0, sizeof (mac_address));
8089
8090   /* Parse args required to build the message */
8091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8092     {
8093       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8094         sw_if_index_set = 1;
8095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8096         sw_if_index_set = 1;
8097       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8098         {
8099           random_mac = 0;
8100         }
8101       else if (unformat (i, "random-mac"))
8102         random_mac = 1;
8103       else if (unformat (i, "tapname %s", &tap_name))
8104         name_set = 1;
8105       else
8106         break;
8107     }
8108
8109   if (sw_if_index_set == 0)
8110     {
8111       errmsg ("missing vpp interface name");
8112       return -99;
8113     }
8114   if (name_set == 0)
8115     {
8116       errmsg ("missing tap name");
8117       return -99;
8118     }
8119   if (vec_len (tap_name) > 63)
8120     {
8121       errmsg ("tap name too long");
8122     }
8123   vec_add1 (tap_name, 0);
8124
8125   /* Construct the API message */
8126   M (TAP_MODIFY, mp);
8127
8128   mp->use_random_mac = random_mac;
8129   mp->sw_if_index = ntohl (sw_if_index);
8130   clib_memcpy (mp->mac_address, mac_address, 6);
8131   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
8132   vec_free (tap_name);
8133
8134   /* send it... */
8135   S (mp);
8136
8137   /* Wait for a reply... */
8138   W (ret);
8139   return ret;
8140 }
8141
8142 static int
8143 api_tap_delete (vat_main_t * vam)
8144 {
8145   unformat_input_t *i = vam->input;
8146   vl_api_tap_delete_t *mp;
8147   u32 sw_if_index = ~0;
8148   u8 sw_if_index_set = 0;
8149   int ret;
8150
8151   /* Parse args required to build the message */
8152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8153     {
8154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8155         sw_if_index_set = 1;
8156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8157         sw_if_index_set = 1;
8158       else
8159         break;
8160     }
8161
8162   if (sw_if_index_set == 0)
8163     {
8164       errmsg ("missing vpp interface name");
8165       return -99;
8166     }
8167
8168   /* Construct the API message */
8169   M (TAP_DELETE, mp);
8170
8171   mp->sw_if_index = ntohl (sw_if_index);
8172
8173   /* send it... */
8174   S (mp);
8175
8176   /* Wait for a reply... */
8177   W (ret);
8178   return ret;
8179 }
8180
8181 static int
8182 api_tap_create_v2 (vat_main_t * vam)
8183 {
8184   unformat_input_t *i = vam->input;
8185   vl_api_tap_create_v2_t *mp;
8186   u8 mac_address[6];
8187   u8 random_mac = 1;
8188   u32 id = ~0;
8189   u8 *host_if_name = 0;
8190   u8 *host_ns = 0;
8191   u8 host_mac_addr[6];
8192   u8 host_mac_addr_set = 0;
8193   u8 *host_bridge = 0;
8194   ip4_address_t host_ip4_addr;
8195   ip4_address_t host_ip4_gw;
8196   u8 host_ip4_gw_set = 0;
8197   u32 host_ip4_prefix_len = 0;
8198   ip6_address_t host_ip6_addr;
8199   ip6_address_t host_ip6_gw;
8200   u8 host_ip6_gw_set = 0;
8201   u32 host_ip6_prefix_len = 0;
8202   int ret;
8203   u32 rx_ring_sz = 0, tx_ring_sz = 0;
8204
8205   memset (mac_address, 0, sizeof (mac_address));
8206
8207   /* Parse args required to build the message */
8208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8209     {
8210       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
8211         {
8212           random_mac = 0;
8213         }
8214       else if (unformat (i, "id %u", &id))
8215         ;
8216       else if (unformat (i, "host-if-name %s", &host_if_name))
8217         ;
8218       else if (unformat (i, "host-ns %s", &host_ns))
8219         ;
8220       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
8221                          host_mac_addr))
8222         host_mac_addr_set = 1;
8223       else if (unformat (i, "host-bridge %s", &host_bridge))
8224         ;
8225       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
8226                          &host_ip4_addr, &host_ip4_prefix_len))
8227         ;
8228       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
8229                          &host_ip6_addr, &host_ip6_prefix_len))
8230         ;
8231       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
8232                          &host_ip4_gw))
8233         host_ip4_gw_set = 1;
8234       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
8235                          &host_ip6_gw))
8236         host_ip6_gw_set = 1;
8237       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
8238         ;
8239       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
8240         ;
8241       else
8242         break;
8243     }
8244
8245   if (vec_len (host_if_name) > 63)
8246     {
8247       errmsg ("tap name too long. ");
8248       return -99;
8249     }
8250   if (vec_len (host_ns) > 63)
8251     {
8252       errmsg ("host name space too long. ");
8253       return -99;
8254     }
8255   if (vec_len (host_bridge) > 63)
8256     {
8257       errmsg ("host bridge name too long. ");
8258       return -99;
8259     }
8260   if (host_ip4_prefix_len > 32)
8261     {
8262       errmsg ("host ip4 prefix length not valid. ");
8263       return -99;
8264     }
8265   if (host_ip6_prefix_len > 128)
8266     {
8267       errmsg ("host ip6 prefix length not valid. ");
8268       return -99;
8269     }
8270   if (!is_pow2 (rx_ring_sz))
8271     {
8272       errmsg ("rx ring size must be power of 2. ");
8273       return -99;
8274     }
8275   if (rx_ring_sz > 32768)
8276     {
8277       errmsg ("rx ring size must be 32768 or lower. ");
8278       return -99;
8279     }
8280   if (!is_pow2 (tx_ring_sz))
8281     {
8282       errmsg ("tx ring size must be power of 2. ");
8283       return -99;
8284     }
8285   if (tx_ring_sz > 32768)
8286     {
8287       errmsg ("tx ring size must be 32768 or lower. ");
8288       return -99;
8289     }
8290
8291   /* Construct the API message */
8292   M (TAP_CREATE_V2, mp);
8293
8294   mp->use_random_mac = random_mac;
8295
8296   mp->id = ntohl (id);
8297   mp->host_namespace_set = host_ns != 0;
8298   mp->host_bridge_set = host_bridge != 0;
8299   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
8300   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
8301   mp->rx_ring_sz = ntohs (rx_ring_sz);
8302   mp->tx_ring_sz = ntohs (tx_ring_sz);
8303
8304   if (random_mac == 0)
8305     clib_memcpy (mp->mac_address, mac_address, 6);
8306   if (host_mac_addr_set)
8307     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
8308   if (host_if_name)
8309     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
8310   if (host_ns)
8311     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
8312   if (host_bridge)
8313     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
8314   if (host_ip4_prefix_len)
8315     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
8316   if (host_ip4_prefix_len)
8317     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
8318   if (host_ip4_gw_set)
8319     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
8320   if (host_ip6_gw_set)
8321     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
8322
8323   vec_free (host_ns);
8324   vec_free (host_if_name);
8325   vec_free (host_bridge);
8326
8327   /* send it... */
8328   S (mp);
8329
8330   /* Wait for a reply... */
8331   W (ret);
8332   return ret;
8333 }
8334
8335 static int
8336 api_tap_delete_v2 (vat_main_t * vam)
8337 {
8338   unformat_input_t *i = vam->input;
8339   vl_api_tap_delete_v2_t *mp;
8340   u32 sw_if_index = ~0;
8341   u8 sw_if_index_set = 0;
8342   int ret;
8343
8344   /* Parse args required to build the message */
8345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8346     {
8347       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8348         sw_if_index_set = 1;
8349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8350         sw_if_index_set = 1;
8351       else
8352         break;
8353     }
8354
8355   if (sw_if_index_set == 0)
8356     {
8357       errmsg ("missing vpp interface name. ");
8358       return -99;
8359     }
8360
8361   /* Construct the API message */
8362   M (TAP_DELETE_V2, mp);
8363
8364   mp->sw_if_index = ntohl (sw_if_index);
8365
8366   /* send it... */
8367   S (mp);
8368
8369   /* Wait for a reply... */
8370   W (ret);
8371   return ret;
8372 }
8373
8374 static int
8375 api_bond_create (vat_main_t * vam)
8376 {
8377   unformat_input_t *i = vam->input;
8378   vl_api_bond_create_t *mp;
8379   u8 mac_address[6];
8380   u8 custom_mac = 0;
8381   int ret;
8382   u8 mode;
8383   u8 lb;
8384   u8 mode_is_set = 0;
8385
8386   memset (mac_address, 0, sizeof (mac_address));
8387   lb = BOND_LB_L2;
8388
8389   /* Parse args required to build the message */
8390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8391     {
8392       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
8393         mode_is_set = 1;
8394       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
8395                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
8396         ;
8397       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
8398                          mac_address))
8399         custom_mac = 1;
8400       else
8401         break;
8402     }
8403
8404   if (mode_is_set == 0)
8405     {
8406       errmsg ("Missing bond mode. ");
8407       return -99;
8408     }
8409
8410   /* Construct the API message */
8411   M (BOND_CREATE, mp);
8412
8413   mp->use_custom_mac = custom_mac;
8414
8415   mp->mode = mode;
8416   mp->lb = lb;
8417
8418   if (custom_mac)
8419     clib_memcpy (mp->mac_address, mac_address, 6);
8420
8421   /* send it... */
8422   S (mp);
8423
8424   /* Wait for a reply... */
8425   W (ret);
8426   return ret;
8427 }
8428
8429 static int
8430 api_bond_delete (vat_main_t * vam)
8431 {
8432   unformat_input_t *i = vam->input;
8433   vl_api_bond_delete_t *mp;
8434   u32 sw_if_index = ~0;
8435   u8 sw_if_index_set = 0;
8436   int ret;
8437
8438   /* Parse args required to build the message */
8439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8440     {
8441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8442         sw_if_index_set = 1;
8443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8444         sw_if_index_set = 1;
8445       else
8446         break;
8447     }
8448
8449   if (sw_if_index_set == 0)
8450     {
8451       errmsg ("missing vpp interface name. ");
8452       return -99;
8453     }
8454
8455   /* Construct the API message */
8456   M (BOND_DELETE, mp);
8457
8458   mp->sw_if_index = ntohl (sw_if_index);
8459
8460   /* send it... */
8461   S (mp);
8462
8463   /* Wait for a reply... */
8464   W (ret);
8465   return ret;
8466 }
8467
8468 static int
8469 api_bond_enslave (vat_main_t * vam)
8470 {
8471   unformat_input_t *i = vam->input;
8472   vl_api_bond_enslave_t *mp;
8473   u32 bond_sw_if_index;
8474   int ret;
8475   u8 is_passive;
8476   u8 is_long_timeout;
8477   u32 bond_sw_if_index_is_set = 0;
8478   u32 sw_if_index;
8479   u8 sw_if_index_is_set = 0;
8480
8481   /* Parse args required to build the message */
8482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8483     {
8484       if (unformat (i, "sw_if_index %d", &sw_if_index))
8485         sw_if_index_is_set = 1;
8486       else if (unformat (i, "bond %u", &bond_sw_if_index))
8487         bond_sw_if_index_is_set = 1;
8488       else if (unformat (i, "passive %d", &is_passive))
8489         ;
8490       else if (unformat (i, "long-timeout %d", &is_long_timeout))
8491         ;
8492       else
8493         break;
8494     }
8495
8496   if (bond_sw_if_index_is_set == 0)
8497     {
8498       errmsg ("Missing bond sw_if_index. ");
8499       return -99;
8500     }
8501   if (sw_if_index_is_set == 0)
8502     {
8503       errmsg ("Missing slave sw_if_index. ");
8504       return -99;
8505     }
8506
8507   /* Construct the API message */
8508   M (BOND_ENSLAVE, mp);
8509
8510   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
8511   mp->sw_if_index = ntohl (sw_if_index);
8512   mp->is_long_timeout = is_long_timeout;
8513   mp->is_passive = is_passive;
8514
8515   /* send it... */
8516   S (mp);
8517
8518   /* Wait for a reply... */
8519   W (ret);
8520   return ret;
8521 }
8522
8523 static int
8524 api_bond_detach_slave (vat_main_t * vam)
8525 {
8526   unformat_input_t *i = vam->input;
8527   vl_api_bond_detach_slave_t *mp;
8528   u32 sw_if_index = ~0;
8529   u8 sw_if_index_set = 0;
8530   int ret;
8531
8532   /* Parse args required to build the message */
8533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8534     {
8535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8536         sw_if_index_set = 1;
8537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8538         sw_if_index_set = 1;
8539       else
8540         break;
8541     }
8542
8543   if (sw_if_index_set == 0)
8544     {
8545       errmsg ("missing vpp interface name. ");
8546       return -99;
8547     }
8548
8549   /* Construct the API message */
8550   M (BOND_DETACH_SLAVE, mp);
8551
8552   mp->sw_if_index = ntohl (sw_if_index);
8553
8554   /* send it... */
8555   S (mp);
8556
8557   /* Wait for a reply... */
8558   W (ret);
8559   return ret;
8560 }
8561
8562 static int
8563 api_ip_table_add_del (vat_main_t * vam)
8564 {
8565   unformat_input_t *i = vam->input;
8566   vl_api_ip_table_add_del_t *mp;
8567   u32 table_id = ~0;
8568   u8 is_ipv6 = 0;
8569   u8 is_add = 1;
8570   int ret = 0;
8571
8572   /* Parse args required to build the message */
8573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8574     {
8575       if (unformat (i, "ipv6"))
8576         is_ipv6 = 1;
8577       else if (unformat (i, "del"))
8578         is_add = 0;
8579       else if (unformat (i, "add"))
8580         is_add = 1;
8581       else if (unformat (i, "table %d", &table_id))
8582         ;
8583       else
8584         {
8585           clib_warning ("parse error '%U'", format_unformat_error, i);
8586           return -99;
8587         }
8588     }
8589
8590   if (~0 == table_id)
8591     {
8592       errmsg ("missing table-ID");
8593       return -99;
8594     }
8595
8596   /* Construct the API message */
8597   M (IP_TABLE_ADD_DEL, mp);
8598
8599   mp->table_id = ntohl (table_id);
8600   mp->is_ipv6 = is_ipv6;
8601   mp->is_add = is_add;
8602
8603   /* send it... */
8604   S (mp);
8605
8606   /* Wait for a reply... */
8607   W (ret);
8608
8609   return ret;
8610 }
8611
8612 static int
8613 api_ip_add_del_route (vat_main_t * vam)
8614 {
8615   unformat_input_t *i = vam->input;
8616   vl_api_ip_add_del_route_t *mp;
8617   u32 sw_if_index = ~0, vrf_id = 0;
8618   u8 is_ipv6 = 0;
8619   u8 is_local = 0, is_drop = 0;
8620   u8 is_unreach = 0, is_prohibit = 0;
8621   u8 is_add = 1;
8622   u32 next_hop_weight = 1;
8623   u8 is_multipath = 0;
8624   u8 address_set = 0;
8625   u8 address_length_set = 0;
8626   u32 next_hop_table_id = 0;
8627   u32 resolve_attempts = 0;
8628   u32 dst_address_length = 0;
8629   u8 next_hop_set = 0;
8630   ip4_address_t v4_dst_address, v4_next_hop_address;
8631   ip6_address_t v6_dst_address, v6_next_hop_address;
8632   int count = 1;
8633   int j;
8634   f64 before = 0;
8635   u32 random_add_del = 0;
8636   u32 *random_vector = 0;
8637   uword *random_hash;
8638   u32 random_seed = 0xdeaddabe;
8639   u32 classify_table_index = ~0;
8640   u8 is_classify = 0;
8641   u8 resolve_host = 0, resolve_attached = 0;
8642   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
8643   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8644   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8645
8646   memset (&v4_next_hop_address, 0, sizeof (ip4_address_t));
8647   memset (&v6_next_hop_address, 0, sizeof (ip6_address_t));
8648   /* Parse args required to build the message */
8649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8650     {
8651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8652         ;
8653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8654         ;
8655       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
8656         {
8657           address_set = 1;
8658           is_ipv6 = 0;
8659         }
8660       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
8661         {
8662           address_set = 1;
8663           is_ipv6 = 1;
8664         }
8665       else if (unformat (i, "/%d", &dst_address_length))
8666         {
8667           address_length_set = 1;
8668         }
8669
8670       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
8671                                          &v4_next_hop_address))
8672         {
8673           next_hop_set = 1;
8674         }
8675       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
8676                                          &v6_next_hop_address))
8677         {
8678           next_hop_set = 1;
8679         }
8680       else
8681         if (unformat
8682             (i, "via %U", api_unformat_sw_if_index, vam, &sw_if_index))
8683         {
8684           next_hop_set = 1;
8685         }
8686       else if (unformat (i, "via sw_if_index %d", &sw_if_index))
8687         {
8688           next_hop_set = 1;
8689         }
8690       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
8691         ;
8692       else if (unformat (i, "weight %d", &next_hop_weight))
8693         ;
8694       else if (unformat (i, "drop"))
8695         {
8696           is_drop = 1;
8697         }
8698       else if (unformat (i, "null-send-unreach"))
8699         {
8700           is_unreach = 1;
8701         }
8702       else if (unformat (i, "null-send-prohibit"))
8703         {
8704           is_prohibit = 1;
8705         }
8706       else if (unformat (i, "local"))
8707         {
8708           is_local = 1;
8709         }
8710       else if (unformat (i, "classify %d", &classify_table_index))
8711         {
8712           is_classify = 1;
8713         }
8714       else if (unformat (i, "del"))
8715         is_add = 0;
8716       else if (unformat (i, "add"))
8717         is_add = 1;
8718       else if (unformat (i, "resolve-via-host"))
8719         resolve_host = 1;
8720       else if (unformat (i, "resolve-via-attached"))
8721         resolve_attached = 1;
8722       else if (unformat (i, "multipath"))
8723         is_multipath = 1;
8724       else if (unformat (i, "vrf %d", &vrf_id))
8725         ;
8726       else if (unformat (i, "count %d", &count))
8727         ;
8728       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
8729         ;
8730       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8731         ;
8732       else if (unformat (i, "out-label %d", &next_hop_out_label))
8733         {
8734           vl_api_fib_mpls_label_t fib_label = {
8735             .label = ntohl (next_hop_out_label),
8736             .ttl = 64,
8737             .exp = 0,
8738           };
8739           vec_add1 (next_hop_out_label_stack, fib_label);
8740         }
8741       else if (unformat (i, "via via-label %d", &next_hop_via_label))
8742         ;
8743       else if (unformat (i, "random"))
8744         random_add_del = 1;
8745       else if (unformat (i, "seed %d", &random_seed))
8746         ;
8747       else
8748         {
8749           clib_warning ("parse error '%U'", format_unformat_error, i);
8750           return -99;
8751         }
8752     }
8753
8754   if (!next_hop_set && !is_drop && !is_local &&
8755       !is_classify && !is_unreach && !is_prohibit &&
8756       MPLS_LABEL_INVALID == next_hop_via_label)
8757     {
8758       errmsg
8759         ("next hop / local / drop / unreach / prohibit / classify not set");
8760       return -99;
8761     }
8762
8763   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
8764     {
8765       errmsg ("next hop and next-hop via label set");
8766       return -99;
8767     }
8768   if (address_set == 0)
8769     {
8770       errmsg ("missing addresses");
8771       return -99;
8772     }
8773
8774   if (address_length_set == 0)
8775     {
8776       errmsg ("missing address length");
8777       return -99;
8778     }
8779
8780   /* Generate a pile of unique, random routes */
8781   if (random_add_del)
8782     {
8783       u32 this_random_address;
8784       random_hash = hash_create (count, sizeof (uword));
8785
8786       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
8787       for (j = 0; j <= count; j++)
8788         {
8789           do
8790             {
8791               this_random_address = random_u32 (&random_seed);
8792               this_random_address =
8793                 clib_host_to_net_u32 (this_random_address);
8794             }
8795           while (hash_get (random_hash, this_random_address));
8796           vec_add1 (random_vector, this_random_address);
8797           hash_set (random_hash, this_random_address, 1);
8798         }
8799       hash_free (random_hash);
8800       v4_dst_address.as_u32 = random_vector[0];
8801     }
8802
8803   if (count > 1)
8804     {
8805       /* Turn on async mode */
8806       vam->async_mode = 1;
8807       vam->async_errors = 0;
8808       before = vat_time_now (vam);
8809     }
8810
8811   for (j = 0; j < count; j++)
8812     {
8813       /* Construct the API message */
8814       M2 (IP_ADD_DEL_ROUTE, mp, sizeof (vl_api_fib_mpls_label_t) *
8815           vec_len (next_hop_out_label_stack));
8816
8817       mp->next_hop_sw_if_index = ntohl (sw_if_index);
8818       mp->table_id = ntohl (vrf_id);
8819
8820       mp->is_add = is_add;
8821       mp->is_drop = is_drop;
8822       mp->is_unreach = is_unreach;
8823       mp->is_prohibit = is_prohibit;
8824       mp->is_ipv6 = is_ipv6;
8825       mp->is_local = is_local;
8826       mp->is_classify = is_classify;
8827       mp->is_multipath = is_multipath;
8828       mp->is_resolve_host = resolve_host;
8829       mp->is_resolve_attached = resolve_attached;
8830       mp->next_hop_weight = next_hop_weight;
8831       mp->dst_address_length = dst_address_length;
8832       mp->next_hop_table_id = ntohl (next_hop_table_id);
8833       mp->classify_table_index = ntohl (classify_table_index);
8834       mp->next_hop_via_label = ntohl (next_hop_via_label);
8835       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8836       if (0 != mp->next_hop_n_out_labels)
8837         {
8838           memcpy (mp->next_hop_out_label_stack,
8839                   next_hop_out_label_stack,
8840                   (vec_len (next_hop_out_label_stack) *
8841                    sizeof (vl_api_fib_mpls_label_t)));
8842           vec_free (next_hop_out_label_stack);
8843         }
8844
8845       if (is_ipv6)
8846         {
8847           clib_memcpy (mp->dst_address, &v6_dst_address,
8848                        sizeof (v6_dst_address));
8849           if (next_hop_set)
8850             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8851                          sizeof (v6_next_hop_address));
8852           increment_v6_address (&v6_dst_address);
8853         }
8854       else
8855         {
8856           clib_memcpy (mp->dst_address, &v4_dst_address,
8857                        sizeof (v4_dst_address));
8858           if (next_hop_set)
8859             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8860                          sizeof (v4_next_hop_address));
8861           if (random_add_del)
8862             v4_dst_address.as_u32 = random_vector[j + 1];
8863           else
8864             increment_v4_address (&v4_dst_address);
8865         }
8866       /* send it... */
8867       S (mp);
8868       /* If we receive SIGTERM, stop now... */
8869       if (vam->do_exit)
8870         break;
8871     }
8872
8873   /* When testing multiple add/del ops, use a control-ping to sync */
8874   if (count > 1)
8875     {
8876       vl_api_control_ping_t *mp_ping;
8877       f64 after;
8878       f64 timeout;
8879
8880       /* Shut off async mode */
8881       vam->async_mode = 0;
8882
8883       MPING (CONTROL_PING, mp_ping);
8884       S (mp_ping);
8885
8886       timeout = vat_time_now (vam) + 1.0;
8887       while (vat_time_now (vam) < timeout)
8888         if (vam->result_ready == 1)
8889           goto out;
8890       vam->retval = -99;
8891
8892     out:
8893       if (vam->retval == -99)
8894         errmsg ("timeout");
8895
8896       if (vam->async_errors > 0)
8897         {
8898           errmsg ("%d asynchronous errors", vam->async_errors);
8899           vam->retval = -98;
8900         }
8901       vam->async_errors = 0;
8902       after = vat_time_now (vam);
8903
8904       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8905       if (j > 0)
8906         count = j;
8907
8908       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8909              count, after - before, count / (after - before));
8910     }
8911   else
8912     {
8913       int ret;
8914
8915       /* Wait for a reply... */
8916       W (ret);
8917       return ret;
8918     }
8919
8920   /* Return the good/bad news */
8921   return (vam->retval);
8922 }
8923
8924 static int
8925 api_ip_mroute_add_del (vat_main_t * vam)
8926 {
8927   unformat_input_t *i = vam->input;
8928   vl_api_ip_mroute_add_del_t *mp;
8929   u32 sw_if_index = ~0, vrf_id = 0;
8930   u8 is_ipv6 = 0;
8931   u8 is_local = 0;
8932   u8 is_add = 1;
8933   u8 address_set = 0;
8934   u32 grp_address_length = 0;
8935   ip4_address_t v4_grp_address, v4_src_address;
8936   ip6_address_t v6_grp_address, v6_src_address;
8937   mfib_itf_flags_t iflags = 0;
8938   mfib_entry_flags_t eflags = 0;
8939   int ret;
8940
8941   /* Parse args required to build the message */
8942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (i, "sw_if_index %d", &sw_if_index))
8945         ;
8946       else if (unformat (i, "%U %U",
8947                          unformat_ip4_address, &v4_src_address,
8948                          unformat_ip4_address, &v4_grp_address))
8949         {
8950           grp_address_length = 64;
8951           address_set = 1;
8952           is_ipv6 = 0;
8953         }
8954       else if (unformat (i, "%U %U",
8955                          unformat_ip6_address, &v6_src_address,
8956                          unformat_ip6_address, &v6_grp_address))
8957         {
8958           grp_address_length = 256;
8959           address_set = 1;
8960           is_ipv6 = 1;
8961         }
8962       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8963         {
8964           memset (&v4_src_address, 0, sizeof (v4_src_address));
8965           grp_address_length = 32;
8966           address_set = 1;
8967           is_ipv6 = 0;
8968         }
8969       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8970         {
8971           memset (&v6_src_address, 0, sizeof (v6_src_address));
8972           grp_address_length = 128;
8973           address_set = 1;
8974           is_ipv6 = 1;
8975         }
8976       else if (unformat (i, "/%d", &grp_address_length))
8977         ;
8978       else if (unformat (i, "local"))
8979         {
8980           is_local = 1;
8981         }
8982       else if (unformat (i, "del"))
8983         is_add = 0;
8984       else if (unformat (i, "add"))
8985         is_add = 1;
8986       else if (unformat (i, "vrf %d", &vrf_id))
8987         ;
8988       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8989         ;
8990       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8991         ;
8992       else
8993         {
8994           clib_warning ("parse error '%U'", format_unformat_error, i);
8995           return -99;
8996         }
8997     }
8998
8999   if (address_set == 0)
9000     {
9001       errmsg ("missing addresses\n");
9002       return -99;
9003     }
9004
9005   /* Construct the API message */
9006   M (IP_MROUTE_ADD_DEL, mp);
9007
9008   mp->next_hop_sw_if_index = ntohl (sw_if_index);
9009   mp->table_id = ntohl (vrf_id);
9010
9011   mp->is_add = is_add;
9012   mp->is_ipv6 = is_ipv6;
9013   mp->is_local = is_local;
9014   mp->itf_flags = ntohl (iflags);
9015   mp->entry_flags = ntohl (eflags);
9016   mp->grp_address_length = grp_address_length;
9017   mp->grp_address_length = ntohs (mp->grp_address_length);
9018
9019   if (is_ipv6)
9020     {
9021       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
9022       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
9023     }
9024   else
9025     {
9026       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
9027       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
9028
9029     }
9030
9031   /* send it... */
9032   S (mp);
9033   /* Wait for a reply... */
9034   W (ret);
9035   return ret;
9036 }
9037
9038 static int
9039 api_mpls_table_add_del (vat_main_t * vam)
9040 {
9041   unformat_input_t *i = vam->input;
9042   vl_api_mpls_table_add_del_t *mp;
9043   u32 table_id = ~0;
9044   u8 is_add = 1;
9045   int ret = 0;
9046
9047   /* Parse args required to build the message */
9048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9049     {
9050       if (unformat (i, "table %d", &table_id))
9051         ;
9052       else if (unformat (i, "del"))
9053         is_add = 0;
9054       else if (unformat (i, "add"))
9055         is_add = 1;
9056       else
9057         {
9058           clib_warning ("parse error '%U'", format_unformat_error, i);
9059           return -99;
9060         }
9061     }
9062
9063   if (~0 == table_id)
9064     {
9065       errmsg ("missing table-ID");
9066       return -99;
9067     }
9068
9069   /* Construct the API message */
9070   M (MPLS_TABLE_ADD_DEL, mp);
9071
9072   mp->mt_table_id = ntohl (table_id);
9073   mp->mt_is_add = is_add;
9074
9075   /* send it... */
9076   S (mp);
9077
9078   /* Wait for a reply... */
9079   W (ret);
9080
9081   return ret;
9082 }
9083
9084 static int
9085 api_mpls_route_add_del (vat_main_t * vam)
9086 {
9087   unformat_input_t *i = vam->input;
9088   vl_api_mpls_route_add_del_t *mp;
9089   u32 sw_if_index = ~0, table_id = 0;
9090   u8 is_add = 1;
9091   u32 next_hop_weight = 1;
9092   u8 is_multipath = 0;
9093   u32 next_hop_table_id = 0;
9094   u8 next_hop_set = 0;
9095   ip4_address_t v4_next_hop_address = {
9096     .as_u32 = 0,
9097   };
9098   ip6_address_t v6_next_hop_address = { {0} };
9099   int count = 1;
9100   int j;
9101   f64 before = 0;
9102   u32 classify_table_index = ~0;
9103   u8 is_classify = 0;
9104   u8 resolve_host = 0, resolve_attached = 0;
9105   u8 is_interface_rx = 0;
9106   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9107   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9108   vl_api_fib_mpls_label_t *next_hop_out_label_stack = NULL;
9109   mpls_label_t local_label = MPLS_LABEL_INVALID;
9110   u8 is_eos = 0;
9111   dpo_proto_t next_hop_proto = DPO_PROTO_MPLS;
9112
9113   /* Parse args required to build the message */
9114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9115     {
9116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9117         ;
9118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9119         ;
9120       else if (unformat (i, "%d", &local_label))
9121         ;
9122       else if (unformat (i, "eos"))
9123         is_eos = 1;
9124       else if (unformat (i, "non-eos"))
9125         is_eos = 0;
9126       else if (unformat (i, "via %U", unformat_ip4_address,
9127                          &v4_next_hop_address))
9128         {
9129           next_hop_set = 1;
9130           next_hop_proto = DPO_PROTO_IP4;
9131         }
9132       else if (unformat (i, "via %U", unformat_ip6_address,
9133                          &v6_next_hop_address))
9134         {
9135           next_hop_set = 1;
9136           next_hop_proto = DPO_PROTO_IP6;
9137         }
9138       else if (unformat (i, "weight %d", &next_hop_weight))
9139         ;
9140       else if (unformat (i, "classify %d", &classify_table_index))
9141         {
9142           is_classify = 1;
9143         }
9144       else if (unformat (i, "del"))
9145         is_add = 0;
9146       else if (unformat (i, "add"))
9147         is_add = 1;
9148       else if (unformat (i, "resolve-via-host"))
9149         resolve_host = 1;
9150       else if (unformat (i, "resolve-via-attached"))
9151         resolve_attached = 1;
9152       else if (unformat (i, "multipath"))
9153         is_multipath = 1;
9154       else if (unformat (i, "count %d", &count))
9155         ;
9156       else if (unformat (i, "via lookup-in-ip4-table %d", &next_hop_table_id))
9157         {
9158           next_hop_set = 1;
9159           next_hop_proto = DPO_PROTO_IP4;
9160         }
9161       else if (unformat (i, "via lookup-in-ip6-table %d", &next_hop_table_id))
9162         {
9163           next_hop_set = 1;
9164           next_hop_proto = DPO_PROTO_IP6;
9165         }
9166       else
9167         if (unformat
9168             (i, "via l2-input-on %U", api_unformat_sw_if_index, vam,
9169              &sw_if_index))
9170         {
9171           next_hop_set = 1;
9172           next_hop_proto = DPO_PROTO_ETHERNET;
9173           is_interface_rx = 1;
9174         }
9175       else if (unformat (i, "via l2-input-on sw_if_index %d", &sw_if_index))
9176         {
9177           next_hop_set = 1;
9178           next_hop_proto = DPO_PROTO_ETHERNET;
9179           is_interface_rx = 1;
9180         }
9181       else if (unformat (i, "via next-hop-table %d", &next_hop_table_id))
9182         next_hop_set = 1;
9183       else if (unformat (i, "via via-label %d", &next_hop_via_label))
9184         next_hop_set = 1;
9185       else if (unformat (i, "out-label %d", &next_hop_out_label))
9186         {
9187           vl_api_fib_mpls_label_t fib_label = {
9188             .label = ntohl (next_hop_out_label),
9189             .ttl = 64,
9190             .exp = 0,
9191           };
9192           vec_add1 (next_hop_out_label_stack, fib_label);
9193         }
9194       else
9195         {
9196           clib_warning ("parse error '%U'", format_unformat_error, i);
9197           return -99;
9198         }
9199     }
9200
9201   if (!next_hop_set && !is_classify)
9202     {
9203       errmsg ("next hop / classify not set");
9204       return -99;
9205     }
9206
9207   if (MPLS_LABEL_INVALID == local_label)
9208     {
9209       errmsg ("missing label");
9210       return -99;
9211     }
9212
9213   if (count > 1)
9214     {
9215       /* Turn on async mode */
9216       vam->async_mode = 1;
9217       vam->async_errors = 0;
9218       before = vat_time_now (vam);
9219     }
9220
9221   for (j = 0; j < count; j++)
9222     {
9223       /* Construct the API message */
9224       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_mpls_label_t) *
9225           vec_len (next_hop_out_label_stack));
9226
9227       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
9228       mp->mr_table_id = ntohl (table_id);
9229
9230       mp->mr_is_add = is_add;
9231       mp->mr_next_hop_proto = next_hop_proto;
9232       mp->mr_is_classify = is_classify;
9233       mp->mr_is_multipath = is_multipath;
9234       mp->mr_is_resolve_host = resolve_host;
9235       mp->mr_is_resolve_attached = resolve_attached;
9236       mp->mr_is_interface_rx = is_interface_rx;
9237       mp->mr_next_hop_weight = next_hop_weight;
9238       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
9239       mp->mr_classify_table_index = ntohl (classify_table_index);
9240       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
9241       mp->mr_label = ntohl (local_label);
9242       mp->mr_eos = is_eos;
9243
9244       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
9245       if (0 != mp->mr_next_hop_n_out_labels)
9246         {
9247           memcpy (mp->mr_next_hop_out_label_stack,
9248                   next_hop_out_label_stack,
9249                   vec_len (next_hop_out_label_stack) *
9250                   sizeof (vl_api_fib_mpls_label_t));
9251           vec_free (next_hop_out_label_stack);
9252         }
9253
9254       if (next_hop_set)
9255         {
9256           if (DPO_PROTO_IP4 == next_hop_proto)
9257             {
9258               clib_memcpy (mp->mr_next_hop,
9259                            &v4_next_hop_address,
9260                            sizeof (v4_next_hop_address));
9261             }
9262           else if (DPO_PROTO_IP6 == next_hop_proto)
9263
9264             {
9265               clib_memcpy (mp->mr_next_hop,
9266                            &v6_next_hop_address,
9267                            sizeof (v6_next_hop_address));
9268             }
9269         }
9270       local_label++;
9271
9272       /* send it... */
9273       S (mp);
9274       /* If we receive SIGTERM, stop now... */
9275       if (vam->do_exit)
9276         break;
9277     }
9278
9279   /* When testing multiple add/del ops, use a control-ping to sync */
9280   if (count > 1)
9281     {
9282       vl_api_control_ping_t *mp_ping;
9283       f64 after;
9284       f64 timeout;
9285
9286       /* Shut off async mode */
9287       vam->async_mode = 0;
9288
9289       MPING (CONTROL_PING, mp_ping);
9290       S (mp_ping);
9291
9292       timeout = vat_time_now (vam) + 1.0;
9293       while (vat_time_now (vam) < timeout)
9294         if (vam->result_ready == 1)
9295           goto out;
9296       vam->retval = -99;
9297
9298     out:
9299       if (vam->retval == -99)
9300         errmsg ("timeout");
9301
9302       if (vam->async_errors > 0)
9303         {
9304           errmsg ("%d asynchronous errors", vam->async_errors);
9305           vam->retval = -98;
9306         }
9307       vam->async_errors = 0;
9308       after = vat_time_now (vam);
9309
9310       /* slim chance, but we might have eaten SIGTERM on the first iteration */
9311       if (j > 0)
9312         count = j;
9313
9314       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
9315              count, after - before, count / (after - before));
9316     }
9317   else
9318     {
9319       int ret;
9320
9321       /* Wait for a reply... */
9322       W (ret);
9323       return ret;
9324     }
9325
9326   /* Return the good/bad news */
9327   return (vam->retval);
9328 }
9329
9330 static int
9331 api_mpls_ip_bind_unbind (vat_main_t * vam)
9332 {
9333   unformat_input_t *i = vam->input;
9334   vl_api_mpls_ip_bind_unbind_t *mp;
9335   u32 ip_table_id = 0;
9336   u8 is_bind = 1;
9337   u8 is_ip4 = 1;
9338   ip4_address_t v4_address;
9339   ip6_address_t v6_address;
9340   u32 address_length;
9341   u8 address_set = 0;
9342   mpls_label_t local_label = MPLS_LABEL_INVALID;
9343   int ret;
9344
9345   /* Parse args required to build the message */
9346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9347     {
9348       if (unformat (i, "%U/%d", unformat_ip4_address,
9349                     &v4_address, &address_length))
9350         {
9351           is_ip4 = 1;
9352           address_set = 1;
9353         }
9354       else if (unformat (i, "%U/%d", unformat_ip6_address,
9355                          &v6_address, &address_length))
9356         {
9357           is_ip4 = 0;
9358           address_set = 1;
9359         }
9360       else if (unformat (i, "%d", &local_label))
9361         ;
9362       else if (unformat (i, "table-id %d", &ip_table_id))
9363         ;
9364       else if (unformat (i, "unbind"))
9365         is_bind = 0;
9366       else if (unformat (i, "bind"))
9367         is_bind = 1;
9368       else
9369         {
9370           clib_warning ("parse error '%U'", format_unformat_error, i);
9371           return -99;
9372         }
9373     }
9374
9375   if (!address_set)
9376     {
9377       errmsg ("IP address not set");
9378       return -99;
9379     }
9380
9381   if (MPLS_LABEL_INVALID == local_label)
9382     {
9383       errmsg ("missing label");
9384       return -99;
9385     }
9386
9387   /* Construct the API message */
9388   M (MPLS_IP_BIND_UNBIND, mp);
9389
9390   mp->mb_is_bind = is_bind;
9391   mp->mb_is_ip4 = is_ip4;
9392   mp->mb_ip_table_id = ntohl (ip_table_id);
9393   mp->mb_mpls_table_id = 0;
9394   mp->mb_label = ntohl (local_label);
9395   mp->mb_address_length = address_length;
9396
9397   if (is_ip4)
9398     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
9399   else
9400     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
9401
9402   /* send it... */
9403   S (mp);
9404
9405   /* Wait for a reply... */
9406   W (ret);
9407   return ret;
9408 }
9409
9410 static int
9411 api_sr_mpls_policy_add (vat_main_t * vam)
9412 {
9413   unformat_input_t *i = vam->input;
9414   vl_api_sr_mpls_policy_add_t *mp;
9415   u32 bsid = 0;
9416   u32 weight = 1;
9417   u8 type = 0;
9418   u8 n_segments = 0;
9419   u32 sid;
9420   u32 *segments = NULL;
9421   int ret;
9422
9423   /* Parse args required to build the message */
9424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9425     {
9426       if (unformat (i, "bsid %d", &bsid))
9427         ;
9428       else if (unformat (i, "weight %d", &weight))
9429         ;
9430       else if (unformat (i, "spray"))
9431         type = 1;
9432       else if (unformat (i, "next %d", &sid))
9433         {
9434           n_segments += 1;
9435           vec_add1 (segments, htonl (sid));
9436         }
9437       else
9438         {
9439           clib_warning ("parse error '%U'", format_unformat_error, i);
9440           return -99;
9441         }
9442     }
9443
9444   if (bsid == 0)
9445     {
9446       errmsg ("bsid not set");
9447       return -99;
9448     }
9449
9450   if (n_segments == 0)
9451     {
9452       errmsg ("no sid in segment stack");
9453       return -99;
9454     }
9455
9456   /* Construct the API message */
9457   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
9458
9459   mp->bsid = htonl (bsid);
9460   mp->weight = htonl (weight);
9461   mp->type = type;
9462   mp->n_segments = n_segments;
9463   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
9464   vec_free (segments);
9465
9466   /* send it... */
9467   S (mp);
9468
9469   /* Wait for a reply... */
9470   W (ret);
9471   return ret;
9472 }
9473
9474 static int
9475 api_sr_mpls_policy_del (vat_main_t * vam)
9476 {
9477   unformat_input_t *i = vam->input;
9478   vl_api_sr_mpls_policy_del_t *mp;
9479   u32 bsid = 0;
9480   int ret;
9481
9482   /* Parse args required to build the message */
9483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9484     {
9485       if (unformat (i, "bsid %d", &bsid))
9486         ;
9487       else
9488         {
9489           clib_warning ("parse error '%U'", format_unformat_error, i);
9490           return -99;
9491         }
9492     }
9493
9494   if (bsid == 0)
9495     {
9496       errmsg ("bsid not set");
9497       return -99;
9498     }
9499
9500   /* Construct the API message */
9501   M (SR_MPLS_POLICY_DEL, mp);
9502
9503   mp->bsid = htonl (bsid);
9504
9505   /* send it... */
9506   S (mp);
9507
9508   /* Wait for a reply... */
9509   W (ret);
9510   return ret;
9511 }
9512
9513 static int
9514 api_bier_table_add_del (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_bier_table_add_del_t *mp;
9518   u8 is_add = 1;
9519   u32 set = 0, sub_domain = 0, hdr_len = 3;
9520   mpls_label_t local_label = MPLS_LABEL_INVALID;
9521   int ret;
9522
9523   /* Parse args required to build the message */
9524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9525     {
9526       if (unformat (i, "sub-domain %d", &sub_domain))
9527         ;
9528       else if (unformat (i, "set %d", &set))
9529         ;
9530       else if (unformat (i, "label %d", &local_label))
9531         ;
9532       else if (unformat (i, "hdr-len %d", &hdr_len))
9533         ;
9534       else if (unformat (i, "add"))
9535         is_add = 1;
9536       else if (unformat (i, "del"))
9537         is_add = 0;
9538       else
9539         {
9540           clib_warning ("parse error '%U'", format_unformat_error, i);
9541           return -99;
9542         }
9543     }
9544
9545   if (MPLS_LABEL_INVALID == local_label)
9546     {
9547       errmsg ("missing label\n");
9548       return -99;
9549     }
9550
9551   /* Construct the API message */
9552   M (BIER_TABLE_ADD_DEL, mp);
9553
9554   mp->bt_is_add = is_add;
9555   mp->bt_label = ntohl (local_label);
9556   mp->bt_tbl_id.bt_set = set;
9557   mp->bt_tbl_id.bt_sub_domain = sub_domain;
9558   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
9559
9560   /* send it... */
9561   S (mp);
9562
9563   /* Wait for a reply... */
9564   W (ret);
9565
9566   return (ret);
9567 }
9568
9569 static int
9570 api_bier_route_add_del (vat_main_t * vam)
9571 {
9572   unformat_input_t *i = vam->input;
9573   vl_api_bier_route_add_del_t *mp;
9574   u8 is_add = 1;
9575   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
9576   ip4_address_t v4_next_hop_address;
9577   ip6_address_t v6_next_hop_address;
9578   u8 next_hop_set = 0;
9579   u8 next_hop_proto_is_ip4 = 1;
9580   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
9581   int ret;
9582
9583   /* Parse args required to build the message */
9584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9585     {
9586       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
9587         {
9588           next_hop_proto_is_ip4 = 1;
9589           next_hop_set = 1;
9590         }
9591       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
9592         {
9593           next_hop_proto_is_ip4 = 0;
9594           next_hop_set = 1;
9595         }
9596       if (unformat (i, "sub-domain %d", &sub_domain))
9597         ;
9598       else if (unformat (i, "set %d", &set))
9599         ;
9600       else if (unformat (i, "hdr-len %d", &hdr_len))
9601         ;
9602       else if (unformat (i, "bp %d", &bp))
9603         ;
9604       else if (unformat (i, "add"))
9605         is_add = 1;
9606       else if (unformat (i, "del"))
9607         is_add = 0;
9608       else if (unformat (i, "out-label %d", &next_hop_out_label))
9609         ;
9610       else
9611         {
9612           clib_warning ("parse error '%U'", format_unformat_error, i);
9613           return -99;
9614         }
9615     }
9616
9617   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
9618     {
9619       errmsg ("next hop / label set\n");
9620       return -99;
9621     }
9622   if (0 == bp)
9623     {
9624       errmsg ("bit=position not set\n");
9625       return -99;
9626     }
9627
9628   /* Construct the API message */
9629   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
9630
9631   mp->br_is_add = is_add;
9632   mp->br_tbl_id.bt_set = set;
9633   mp->br_tbl_id.bt_sub_domain = sub_domain;
9634   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
9635   mp->br_bp = ntohs (bp);
9636   mp->br_n_paths = 1;
9637   mp->br_paths[0].n_labels = 1;
9638   mp->br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
9639   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
9640
9641   if (next_hop_proto_is_ip4)
9642     {
9643       clib_memcpy (mp->br_paths[0].next_hop,
9644                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9645     }
9646   else
9647     {
9648       clib_memcpy (mp->br_paths[0].next_hop,
9649                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9650     }
9651
9652   /* send it... */
9653   S (mp);
9654
9655   /* Wait for a reply... */
9656   W (ret);
9657
9658   return (ret);
9659 }
9660
9661 static int
9662 api_proxy_arp_add_del (vat_main_t * vam)
9663 {
9664   unformat_input_t *i = vam->input;
9665   vl_api_proxy_arp_add_del_t *mp;
9666   u32 vrf_id = 0;
9667   u8 is_add = 1;
9668   ip4_address_t lo, hi;
9669   u8 range_set = 0;
9670   int ret;
9671
9672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9673     {
9674       if (unformat (i, "vrf %d", &vrf_id))
9675         ;
9676       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
9677                          unformat_ip4_address, &hi))
9678         range_set = 1;
9679       else if (unformat (i, "del"))
9680         is_add = 0;
9681       else
9682         {
9683           clib_warning ("parse error '%U'", format_unformat_error, i);
9684           return -99;
9685         }
9686     }
9687
9688   if (range_set == 0)
9689     {
9690       errmsg ("address range not set");
9691       return -99;
9692     }
9693
9694   M (PROXY_ARP_ADD_DEL, mp);
9695
9696   mp->proxy.vrf_id = ntohl (vrf_id);
9697   mp->is_add = is_add;
9698   clib_memcpy (mp->proxy.low_address, &lo, sizeof (mp->proxy.low_address));
9699   clib_memcpy (mp->proxy.hi_address, &hi, sizeof (mp->proxy.hi_address));
9700
9701   S (mp);
9702   W (ret);
9703   return ret;
9704 }
9705
9706 static int
9707 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
9708 {
9709   unformat_input_t *i = vam->input;
9710   vl_api_proxy_arp_intfc_enable_disable_t *mp;
9711   u32 sw_if_index;
9712   u8 enable = 1;
9713   u8 sw_if_index_set = 0;
9714   int ret;
9715
9716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9717     {
9718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9719         sw_if_index_set = 1;
9720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9721         sw_if_index_set = 1;
9722       else if (unformat (i, "enable"))
9723         enable = 1;
9724       else if (unformat (i, "disable"))
9725         enable = 0;
9726       else
9727         {
9728           clib_warning ("parse error '%U'", format_unformat_error, i);
9729           return -99;
9730         }
9731     }
9732
9733   if (sw_if_index_set == 0)
9734     {
9735       errmsg ("missing interface name or sw_if_index");
9736       return -99;
9737     }
9738
9739   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
9740
9741   mp->sw_if_index = ntohl (sw_if_index);
9742   mp->enable_disable = enable;
9743
9744   S (mp);
9745   W (ret);
9746   return ret;
9747 }
9748
9749 static int
9750 api_mpls_tunnel_add_del (vat_main_t * vam)
9751 {
9752   unformat_input_t *i = vam->input;
9753   vl_api_mpls_tunnel_add_del_t *mp;
9754
9755   u8 is_add = 1;
9756   u8 l2_only = 0;
9757   u32 sw_if_index = ~0;
9758   u32 next_hop_sw_if_index = ~0;
9759   u32 next_hop_proto_is_ip4 = 1;
9760
9761   u32 next_hop_table_id = 0;
9762   ip4_address_t v4_next_hop_address = {
9763     .as_u32 = 0,
9764   };
9765   ip6_address_t v6_next_hop_address = { {0} };
9766   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
9767   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
9768   int ret;
9769
9770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9771     {
9772       if (unformat (i, "add"))
9773         is_add = 1;
9774       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
9775         is_add = 0;
9776       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
9777         ;
9778       else if (unformat (i, "via %U",
9779                          unformat_ip4_address, &v4_next_hop_address))
9780         {
9781           next_hop_proto_is_ip4 = 1;
9782         }
9783       else if (unformat (i, "via %U",
9784                          unformat_ip6_address, &v6_next_hop_address))
9785         {
9786           next_hop_proto_is_ip4 = 0;
9787         }
9788       else if (unformat (i, "via-label %d", &next_hop_via_label))
9789         ;
9790       else if (unformat (i, "l2-only"))
9791         l2_only = 1;
9792       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
9793         ;
9794       else if (unformat (i, "out-label %d", &next_hop_out_label))
9795         vec_add1 (labels, ntohl (next_hop_out_label));
9796       else
9797         {
9798           clib_warning ("parse error '%U'", format_unformat_error, i);
9799           return -99;
9800         }
9801     }
9802
9803   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
9804
9805   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
9806   mp->mt_sw_if_index = ntohl (sw_if_index);
9807   mp->mt_is_add = is_add;
9808   mp->mt_l2_only = l2_only;
9809   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
9810   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
9811   mp->mt_next_hop_via_label = ntohl (next_hop_via_label);
9812
9813   mp->mt_next_hop_n_out_labels = vec_len (labels);
9814
9815   if (0 != mp->mt_next_hop_n_out_labels)
9816     {
9817       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
9818                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
9819       vec_free (labels);
9820     }
9821
9822   if (next_hop_proto_is_ip4)
9823     {
9824       clib_memcpy (mp->mt_next_hop,
9825                    &v4_next_hop_address, sizeof (v4_next_hop_address));
9826     }
9827   else
9828     {
9829       clib_memcpy (mp->mt_next_hop,
9830                    &v6_next_hop_address, sizeof (v6_next_hop_address));
9831     }
9832
9833   S (mp);
9834   W (ret);
9835   return ret;
9836 }
9837
9838 static int
9839 api_sw_interface_set_unnumbered (vat_main_t * vam)
9840 {
9841   unformat_input_t *i = vam->input;
9842   vl_api_sw_interface_set_unnumbered_t *mp;
9843   u32 sw_if_index;
9844   u32 unnum_sw_index = ~0;
9845   u8 is_add = 1;
9846   u8 sw_if_index_set = 0;
9847   int ret;
9848
9849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9850     {
9851       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9852         sw_if_index_set = 1;
9853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9854         sw_if_index_set = 1;
9855       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
9856         ;
9857       else if (unformat (i, "del"))
9858         is_add = 0;
9859       else
9860         {
9861           clib_warning ("parse error '%U'", format_unformat_error, i);
9862           return -99;
9863         }
9864     }
9865
9866   if (sw_if_index_set == 0)
9867     {
9868       errmsg ("missing interface name or sw_if_index");
9869       return -99;
9870     }
9871
9872   M (SW_INTERFACE_SET_UNNUMBERED, mp);
9873
9874   mp->sw_if_index = ntohl (sw_if_index);
9875   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
9876   mp->is_add = is_add;
9877
9878   S (mp);
9879   W (ret);
9880   return ret;
9881 }
9882
9883 static int
9884 api_ip_neighbor_add_del (vat_main_t * vam)
9885 {
9886   unformat_input_t *i = vam->input;
9887   vl_api_ip_neighbor_add_del_t *mp;
9888   u32 sw_if_index;
9889   u8 sw_if_index_set = 0;
9890   u8 is_add = 1;
9891   u8 is_static = 0;
9892   u8 is_no_fib_entry = 0;
9893   u8 mac_address[6];
9894   u8 mac_set = 0;
9895   u8 v4_address_set = 0;
9896   u8 v6_address_set = 0;
9897   ip4_address_t v4address;
9898   ip6_address_t v6address;
9899   int ret;
9900
9901   memset (mac_address, 0, sizeof (mac_address));
9902
9903   /* Parse args required to build the message */
9904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9905     {
9906       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
9907         {
9908           mac_set = 1;
9909         }
9910       else if (unformat (i, "del"))
9911         is_add = 0;
9912       else
9913         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9914         sw_if_index_set = 1;
9915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9916         sw_if_index_set = 1;
9917       else if (unformat (i, "is_static"))
9918         is_static = 1;
9919       else if (unformat (i, "no-fib-entry"))
9920         is_no_fib_entry = 1;
9921       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
9922         v4_address_set = 1;
9923       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
9924         v6_address_set = 1;
9925       else
9926         {
9927           clib_warning ("parse error '%U'", format_unformat_error, i);
9928           return -99;
9929         }
9930     }
9931
9932   if (sw_if_index_set == 0)
9933     {
9934       errmsg ("missing interface name or sw_if_index");
9935       return -99;
9936     }
9937   if (v4_address_set && v6_address_set)
9938     {
9939       errmsg ("both v4 and v6 addresses set");
9940       return -99;
9941     }
9942   if (!v4_address_set && !v6_address_set)
9943     {
9944       errmsg ("no address set");
9945       return -99;
9946     }
9947
9948   /* Construct the API message */
9949   M (IP_NEIGHBOR_ADD_DEL, mp);
9950
9951   mp->sw_if_index = ntohl (sw_if_index);
9952   mp->is_add = is_add;
9953   mp->is_static = is_static;
9954   mp->is_no_adj_fib = is_no_fib_entry;
9955   if (mac_set)
9956     clib_memcpy (mp->mac_address, mac_address, 6);
9957   if (v6_address_set)
9958     {
9959       mp->is_ipv6 = 1;
9960       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
9961     }
9962   else
9963     {
9964       /* mp->is_ipv6 = 0; via memset in M macro above */
9965       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9966     }
9967
9968   /* send it... */
9969   S (mp);
9970
9971   /* Wait for a reply, return good/bad news  */
9972   W (ret);
9973   return ret;
9974 }
9975
9976 static int
9977 api_create_vlan_subif (vat_main_t * vam)
9978 {
9979   unformat_input_t *i = vam->input;
9980   vl_api_create_vlan_subif_t *mp;
9981   u32 sw_if_index;
9982   u8 sw_if_index_set = 0;
9983   u32 vlan_id;
9984   u8 vlan_id_set = 0;
9985   int ret;
9986
9987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9988     {
9989       if (unformat (i, "sw_if_index %d", &sw_if_index))
9990         sw_if_index_set = 1;
9991       else
9992         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9993         sw_if_index_set = 1;
9994       else if (unformat (i, "vlan %d", &vlan_id))
9995         vlan_id_set = 1;
9996       else
9997         {
9998           clib_warning ("parse error '%U'", format_unformat_error, i);
9999           return -99;
10000         }
10001     }
10002
10003   if (sw_if_index_set == 0)
10004     {
10005       errmsg ("missing interface name or sw_if_index");
10006       return -99;
10007     }
10008
10009   if (vlan_id_set == 0)
10010     {
10011       errmsg ("missing vlan_id");
10012       return -99;
10013     }
10014   M (CREATE_VLAN_SUBIF, mp);
10015
10016   mp->sw_if_index = ntohl (sw_if_index);
10017   mp->vlan_id = ntohl (vlan_id);
10018
10019   S (mp);
10020   W (ret);
10021   return ret;
10022 }
10023
10024 #define foreach_create_subif_bit                \
10025 _(no_tags)                                      \
10026 _(one_tag)                                      \
10027 _(two_tags)                                     \
10028 _(dot1ad)                                       \
10029 _(exact_match)                                  \
10030 _(default_sub)                                  \
10031 _(outer_vlan_id_any)                            \
10032 _(inner_vlan_id_any)
10033
10034 static int
10035 api_create_subif (vat_main_t * vam)
10036 {
10037   unformat_input_t *i = vam->input;
10038   vl_api_create_subif_t *mp;
10039   u32 sw_if_index;
10040   u8 sw_if_index_set = 0;
10041   u32 sub_id;
10042   u8 sub_id_set = 0;
10043   u32 no_tags = 0;
10044   u32 one_tag = 0;
10045   u32 two_tags = 0;
10046   u32 dot1ad = 0;
10047   u32 exact_match = 0;
10048   u32 default_sub = 0;
10049   u32 outer_vlan_id_any = 0;
10050   u32 inner_vlan_id_any = 0;
10051   u32 tmp;
10052   u16 outer_vlan_id = 0;
10053   u16 inner_vlan_id = 0;
10054   int ret;
10055
10056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10057     {
10058       if (unformat (i, "sw_if_index %d", &sw_if_index))
10059         sw_if_index_set = 1;
10060       else
10061         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10062         sw_if_index_set = 1;
10063       else if (unformat (i, "sub_id %d", &sub_id))
10064         sub_id_set = 1;
10065       else if (unformat (i, "outer_vlan_id %d", &tmp))
10066         outer_vlan_id = tmp;
10067       else if (unformat (i, "inner_vlan_id %d", &tmp))
10068         inner_vlan_id = tmp;
10069
10070 #define _(a) else if (unformat (i, #a)) a = 1 ;
10071       foreach_create_subif_bit
10072 #undef _
10073         else
10074         {
10075           clib_warning ("parse error '%U'", format_unformat_error, i);
10076           return -99;
10077         }
10078     }
10079
10080   if (sw_if_index_set == 0)
10081     {
10082       errmsg ("missing interface name or sw_if_index");
10083       return -99;
10084     }
10085
10086   if (sub_id_set == 0)
10087     {
10088       errmsg ("missing sub_id");
10089       return -99;
10090     }
10091   M (CREATE_SUBIF, mp);
10092
10093   mp->sw_if_index = ntohl (sw_if_index);
10094   mp->sub_id = ntohl (sub_id);
10095
10096 #define _(a) mp->a = a;
10097   foreach_create_subif_bit;
10098 #undef _
10099
10100   mp->outer_vlan_id = ntohs (outer_vlan_id);
10101   mp->inner_vlan_id = ntohs (inner_vlan_id);
10102
10103   S (mp);
10104   W (ret);
10105   return ret;
10106 }
10107
10108 static int
10109 api_oam_add_del (vat_main_t * vam)
10110 {
10111   unformat_input_t *i = vam->input;
10112   vl_api_oam_add_del_t *mp;
10113   u32 vrf_id = 0;
10114   u8 is_add = 1;
10115   ip4_address_t src, dst;
10116   u8 src_set = 0;
10117   u8 dst_set = 0;
10118   int ret;
10119
10120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10121     {
10122       if (unformat (i, "vrf %d", &vrf_id))
10123         ;
10124       else if (unformat (i, "src %U", unformat_ip4_address, &src))
10125         src_set = 1;
10126       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
10127         dst_set = 1;
10128       else if (unformat (i, "del"))
10129         is_add = 0;
10130       else
10131         {
10132           clib_warning ("parse error '%U'", format_unformat_error, i);
10133           return -99;
10134         }
10135     }
10136
10137   if (src_set == 0)
10138     {
10139       errmsg ("missing src addr");
10140       return -99;
10141     }
10142
10143   if (dst_set == 0)
10144     {
10145       errmsg ("missing dst addr");
10146       return -99;
10147     }
10148
10149   M (OAM_ADD_DEL, mp);
10150
10151   mp->vrf_id = ntohl (vrf_id);
10152   mp->is_add = is_add;
10153   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
10154   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
10155
10156   S (mp);
10157   W (ret);
10158   return ret;
10159 }
10160
10161 static int
10162 api_reset_fib (vat_main_t * vam)
10163 {
10164   unformat_input_t *i = vam->input;
10165   vl_api_reset_fib_t *mp;
10166   u32 vrf_id = 0;
10167   u8 is_ipv6 = 0;
10168   u8 vrf_id_set = 0;
10169
10170   int ret;
10171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10172     {
10173       if (unformat (i, "vrf %d", &vrf_id))
10174         vrf_id_set = 1;
10175       else if (unformat (i, "ipv6"))
10176         is_ipv6 = 1;
10177       else
10178         {
10179           clib_warning ("parse error '%U'", format_unformat_error, i);
10180           return -99;
10181         }
10182     }
10183
10184   if (vrf_id_set == 0)
10185     {
10186       errmsg ("missing vrf id");
10187       return -99;
10188     }
10189
10190   M (RESET_FIB, mp);
10191
10192   mp->vrf_id = ntohl (vrf_id);
10193   mp->is_ipv6 = is_ipv6;
10194
10195   S (mp);
10196   W (ret);
10197   return ret;
10198 }
10199
10200 static int
10201 api_dhcp_proxy_config (vat_main_t * vam)
10202 {
10203   unformat_input_t *i = vam->input;
10204   vl_api_dhcp_proxy_config_t *mp;
10205   u32 rx_vrf_id = 0;
10206   u32 server_vrf_id = 0;
10207   u8 is_add = 1;
10208   u8 v4_address_set = 0;
10209   u8 v6_address_set = 0;
10210   ip4_address_t v4address;
10211   ip6_address_t v6address;
10212   u8 v4_src_address_set = 0;
10213   u8 v6_src_address_set = 0;
10214   ip4_address_t v4srcaddress;
10215   ip6_address_t v6srcaddress;
10216   int ret;
10217
10218   /* Parse args required to build the message */
10219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (i, "del"))
10222         is_add = 0;
10223       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
10224         ;
10225       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
10226         ;
10227       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
10228         v4_address_set = 1;
10229       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
10230         v6_address_set = 1;
10231       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
10232         v4_src_address_set = 1;
10233       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
10234         v6_src_address_set = 1;
10235       else
10236         break;
10237     }
10238
10239   if (v4_address_set && v6_address_set)
10240     {
10241       errmsg ("both v4 and v6 server addresses set");
10242       return -99;
10243     }
10244   if (!v4_address_set && !v6_address_set)
10245     {
10246       errmsg ("no server addresses set");
10247       return -99;
10248     }
10249
10250   if (v4_src_address_set && v6_src_address_set)
10251     {
10252       errmsg ("both v4 and v6  src addresses set");
10253       return -99;
10254     }
10255   if (!v4_src_address_set && !v6_src_address_set)
10256     {
10257       errmsg ("no src addresses set");
10258       return -99;
10259     }
10260
10261   if (!(v4_src_address_set && v4_address_set) &&
10262       !(v6_src_address_set && v6_address_set))
10263     {
10264       errmsg ("no matching server and src addresses set");
10265       return -99;
10266     }
10267
10268   /* Construct the API message */
10269   M (DHCP_PROXY_CONFIG, mp);
10270
10271   mp->is_add = is_add;
10272   mp->rx_vrf_id = ntohl (rx_vrf_id);
10273   mp->server_vrf_id = ntohl (server_vrf_id);
10274   if (v6_address_set)
10275     {
10276       mp->is_ipv6 = 1;
10277       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
10278       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
10279     }
10280   else
10281     {
10282       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
10283       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
10284     }
10285
10286   /* send it... */
10287   S (mp);
10288
10289   /* Wait for a reply, return good/bad news  */
10290   W (ret);
10291   return ret;
10292 }
10293
10294 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
10295 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
10296
10297 static void
10298 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
10299 {
10300   vat_main_t *vam = &vat_main;
10301   u32 i, count = mp->count;
10302   vl_api_dhcp_server_t *s;
10303
10304   if (mp->is_ipv6)
10305     print (vam->ofp,
10306            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10307            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10308            ntohl (mp->rx_vrf_id),
10309            format_ip6_address, mp->dhcp_src_address,
10310            mp->vss_type, mp->vss_vpn_ascii_id,
10311            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10312   else
10313     print (vam->ofp,
10314            "RX Table-ID %d, Source Address %U, VSS Type %d, "
10315            "VSS ASCII VPN-ID '%s', VSS RFC2685 VPN-ID (oui:id) %d:%d",
10316            ntohl (mp->rx_vrf_id),
10317            format_ip4_address, mp->dhcp_src_address,
10318            mp->vss_type, mp->vss_vpn_ascii_id,
10319            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
10320
10321   for (i = 0; i < count; i++)
10322     {
10323       s = &mp->servers[i];
10324
10325       if (mp->is_ipv6)
10326         print (vam->ofp,
10327                " Server Table-ID %d, Server Address %U",
10328                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
10329       else
10330         print (vam->ofp,
10331                " Server Table-ID %d, Server Address %U",
10332                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
10333     }
10334 }
10335
10336 static void vl_api_dhcp_proxy_details_t_handler_json
10337   (vl_api_dhcp_proxy_details_t * mp)
10338 {
10339   vat_main_t *vam = &vat_main;
10340   vat_json_node_t *node = NULL;
10341   u32 i, count = mp->count;
10342   struct in_addr ip4;
10343   struct in6_addr ip6;
10344   vl_api_dhcp_server_t *s;
10345
10346   if (VAT_JSON_ARRAY != vam->json_tree.type)
10347     {
10348       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10349       vat_json_init_array (&vam->json_tree);
10350     }
10351   node = vat_json_array_add (&vam->json_tree);
10352
10353   vat_json_init_object (node);
10354   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
10355   vat_json_object_add_bytes (node, "vss-type", &mp->vss_type,
10356                              sizeof (mp->vss_type));
10357   vat_json_object_add_string_copy (node, "vss-vpn-ascii-id",
10358                                    mp->vss_vpn_ascii_id);
10359   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
10360   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
10361
10362   if (mp->is_ipv6)
10363     {
10364       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
10365       vat_json_object_add_ip6 (node, "src_address", ip6);
10366     }
10367   else
10368     {
10369       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
10370       vat_json_object_add_ip4 (node, "src_address", ip4);
10371     }
10372
10373   for (i = 0; i < count; i++)
10374     {
10375       s = &mp->servers[i];
10376
10377       vat_json_object_add_uint (node, "server-table-id",
10378                                 ntohl (s->server_vrf_id));
10379
10380       if (mp->is_ipv6)
10381         {
10382           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
10383           vat_json_object_add_ip4 (node, "src_address", ip4);
10384         }
10385       else
10386         {
10387           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
10388           vat_json_object_add_ip6 (node, "server_address", ip6);
10389         }
10390     }
10391 }
10392
10393 static int
10394 api_dhcp_proxy_dump (vat_main_t * vam)
10395 {
10396   unformat_input_t *i = vam->input;
10397   vl_api_control_ping_t *mp_ping;
10398   vl_api_dhcp_proxy_dump_t *mp;
10399   u8 is_ipv6 = 0;
10400   int ret;
10401
10402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10403     {
10404       if (unformat (i, "ipv6"))
10405         is_ipv6 = 1;
10406       else
10407         {
10408           clib_warning ("parse error '%U'", format_unformat_error, i);
10409           return -99;
10410         }
10411     }
10412
10413   M (DHCP_PROXY_DUMP, mp);
10414
10415   mp->is_ip6 = is_ipv6;
10416   S (mp);
10417
10418   /* Use a control ping for synchronization */
10419   MPING (CONTROL_PING, mp_ping);
10420   S (mp_ping);
10421
10422   W (ret);
10423   return ret;
10424 }
10425
10426 static int
10427 api_dhcp_proxy_set_vss (vat_main_t * vam)
10428 {
10429   unformat_input_t *i = vam->input;
10430   vl_api_dhcp_proxy_set_vss_t *mp;
10431   u8 is_ipv6 = 0;
10432   u8 is_add = 1;
10433   u32 tbl_id = ~0;
10434   u8 vss_type = VSS_TYPE_DEFAULT;
10435   u8 *vpn_ascii_id = 0;
10436   u32 oui = 0;
10437   u32 fib_id = 0;
10438   int ret;
10439
10440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (i, "tbl_id %d", &tbl_id))
10443         ;
10444       else if (unformat (i, "vpn_ascii_id %s", &vpn_ascii_id))
10445         vss_type = VSS_TYPE_ASCII;
10446       else if (unformat (i, "fib_id %d", &fib_id))
10447         vss_type = VSS_TYPE_VPN_ID;
10448       else if (unformat (i, "oui %d", &oui))
10449         vss_type = VSS_TYPE_VPN_ID;
10450       else if (unformat (i, "ipv6"))
10451         is_ipv6 = 1;
10452       else if (unformat (i, "del"))
10453         is_add = 0;
10454       else
10455         break;
10456     }
10457
10458   if (tbl_id == ~0)
10459     {
10460       errmsg ("missing tbl_id ");
10461       vec_free (vpn_ascii_id);
10462       return -99;
10463     }
10464
10465   if ((vpn_ascii_id) && (vec_len (vpn_ascii_id) > 128))
10466     {
10467       errmsg ("vpn_ascii_id cannot be longer than 128 ");
10468       vec_free (vpn_ascii_id);
10469       return -99;
10470     }
10471
10472   M (DHCP_PROXY_SET_VSS, mp);
10473   mp->tbl_id = ntohl (tbl_id);
10474   mp->vss_type = vss_type;
10475   if (vpn_ascii_id)
10476     {
10477       clib_memcpy (mp->vpn_ascii_id, vpn_ascii_id, vec_len (vpn_ascii_id));
10478       mp->vpn_ascii_id[vec_len (vpn_ascii_id)] = 0;
10479     }
10480   mp->vpn_index = ntohl (fib_id);
10481   mp->oui = ntohl (oui);
10482   mp->is_ipv6 = is_ipv6;
10483   mp->is_add = is_add;
10484
10485   S (mp);
10486   W (ret);
10487
10488   vec_free (vpn_ascii_id);
10489   return ret;
10490 }
10491
10492 static int
10493 api_dhcp_client_config (vat_main_t * vam)
10494 {
10495   unformat_input_t *i = vam->input;
10496   vl_api_dhcp_client_config_t *mp;
10497   u32 sw_if_index;
10498   u8 sw_if_index_set = 0;
10499   u8 is_add = 1;
10500   u8 *hostname = 0;
10501   u8 disable_event = 0;
10502   int ret;
10503
10504   /* Parse args required to build the message */
10505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10506     {
10507       if (unformat (i, "del"))
10508         is_add = 0;
10509       else
10510         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10511         sw_if_index_set = 1;
10512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10513         sw_if_index_set = 1;
10514       else if (unformat (i, "hostname %s", &hostname))
10515         ;
10516       else if (unformat (i, "disable_event"))
10517         disable_event = 1;
10518       else
10519         break;
10520     }
10521
10522   if (sw_if_index_set == 0)
10523     {
10524       errmsg ("missing interface name or sw_if_index");
10525       return -99;
10526     }
10527
10528   if (vec_len (hostname) > 63)
10529     {
10530       errmsg ("hostname too long");
10531     }
10532   vec_add1 (hostname, 0);
10533
10534   /* Construct the API message */
10535   M (DHCP_CLIENT_CONFIG, mp);
10536
10537   mp->is_add = is_add;
10538   mp->client.sw_if_index = htonl (sw_if_index);
10539   clib_memcpy (mp->client.hostname, hostname, vec_len (hostname));
10540   vec_free (hostname);
10541   mp->client.want_dhcp_event = disable_event ? 0 : 1;
10542   mp->client.pid = htonl (getpid ());
10543
10544   /* send it... */
10545   S (mp);
10546
10547   /* Wait for a reply, return good/bad news  */
10548   W (ret);
10549   return ret;
10550 }
10551
10552 static int
10553 api_set_ip_flow_hash (vat_main_t * vam)
10554 {
10555   unformat_input_t *i = vam->input;
10556   vl_api_set_ip_flow_hash_t *mp;
10557   u32 vrf_id = 0;
10558   u8 is_ipv6 = 0;
10559   u8 vrf_id_set = 0;
10560   u8 src = 0;
10561   u8 dst = 0;
10562   u8 sport = 0;
10563   u8 dport = 0;
10564   u8 proto = 0;
10565   u8 reverse = 0;
10566   int ret;
10567
10568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10569     {
10570       if (unformat (i, "vrf %d", &vrf_id))
10571         vrf_id_set = 1;
10572       else if (unformat (i, "ipv6"))
10573         is_ipv6 = 1;
10574       else if (unformat (i, "src"))
10575         src = 1;
10576       else if (unformat (i, "dst"))
10577         dst = 1;
10578       else if (unformat (i, "sport"))
10579         sport = 1;
10580       else if (unformat (i, "dport"))
10581         dport = 1;
10582       else if (unformat (i, "proto"))
10583         proto = 1;
10584       else if (unformat (i, "reverse"))
10585         reverse = 1;
10586
10587       else
10588         {
10589           clib_warning ("parse error '%U'", format_unformat_error, i);
10590           return -99;
10591         }
10592     }
10593
10594   if (vrf_id_set == 0)
10595     {
10596       errmsg ("missing vrf id");
10597       return -99;
10598     }
10599
10600   M (SET_IP_FLOW_HASH, mp);
10601   mp->src = src;
10602   mp->dst = dst;
10603   mp->sport = sport;
10604   mp->dport = dport;
10605   mp->proto = proto;
10606   mp->reverse = reverse;
10607   mp->vrf_id = ntohl (vrf_id);
10608   mp->is_ipv6 = is_ipv6;
10609
10610   S (mp);
10611   W (ret);
10612   return ret;
10613 }
10614
10615 static int
10616 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
10617 {
10618   unformat_input_t *i = vam->input;
10619   vl_api_sw_interface_ip6_enable_disable_t *mp;
10620   u32 sw_if_index;
10621   u8 sw_if_index_set = 0;
10622   u8 enable = 0;
10623   int ret;
10624
10625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10626     {
10627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10628         sw_if_index_set = 1;
10629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10630         sw_if_index_set = 1;
10631       else if (unformat (i, "enable"))
10632         enable = 1;
10633       else if (unformat (i, "disable"))
10634         enable = 0;
10635       else
10636         {
10637           clib_warning ("parse error '%U'", format_unformat_error, i);
10638           return -99;
10639         }
10640     }
10641
10642   if (sw_if_index_set == 0)
10643     {
10644       errmsg ("missing interface name or sw_if_index");
10645       return -99;
10646     }
10647
10648   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
10649
10650   mp->sw_if_index = ntohl (sw_if_index);
10651   mp->enable = enable;
10652
10653   S (mp);
10654   W (ret);
10655   return ret;
10656 }
10657
10658 static int
10659 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
10660 {
10661   unformat_input_t *i = vam->input;
10662   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
10663   u32 sw_if_index;
10664   u8 sw_if_index_set = 0;
10665   u8 v6_address_set = 0;
10666   ip6_address_t v6address;
10667   int ret;
10668
10669   /* Parse args required to build the message */
10670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10671     {
10672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10673         sw_if_index_set = 1;
10674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10675         sw_if_index_set = 1;
10676       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10677         v6_address_set = 1;
10678       else
10679         break;
10680     }
10681
10682   if (sw_if_index_set == 0)
10683     {
10684       errmsg ("missing interface name or sw_if_index");
10685       return -99;
10686     }
10687   if (!v6_address_set)
10688     {
10689       errmsg ("no address set");
10690       return -99;
10691     }
10692
10693   /* Construct the API message */
10694   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
10695
10696   mp->sw_if_index = ntohl (sw_if_index);
10697   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10698
10699   /* send it... */
10700   S (mp);
10701
10702   /* Wait for a reply, return good/bad news  */
10703   W (ret);
10704   return ret;
10705 }
10706
10707 static int
10708 api_ip6nd_proxy_add_del (vat_main_t * vam)
10709 {
10710   unformat_input_t *i = vam->input;
10711   vl_api_ip6nd_proxy_add_del_t *mp;
10712   u32 sw_if_index = ~0;
10713   u8 v6_address_set = 0;
10714   ip6_address_t v6address;
10715   u8 is_del = 0;
10716   int ret;
10717
10718   /* Parse args required to build the message */
10719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10720     {
10721       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10722         ;
10723       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10724         ;
10725       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
10726         v6_address_set = 1;
10727       if (unformat (i, "del"))
10728         is_del = 1;
10729       else
10730         {
10731           clib_warning ("parse error '%U'", format_unformat_error, i);
10732           return -99;
10733         }
10734     }
10735
10736   if (sw_if_index == ~0)
10737     {
10738       errmsg ("missing interface name or sw_if_index");
10739       return -99;
10740     }
10741   if (!v6_address_set)
10742     {
10743       errmsg ("no address set");
10744       return -99;
10745     }
10746
10747   /* Construct the API message */
10748   M (IP6ND_PROXY_ADD_DEL, mp);
10749
10750   mp->is_del = is_del;
10751   mp->sw_if_index = ntohl (sw_if_index);
10752   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10753
10754   /* send it... */
10755   S (mp);
10756
10757   /* Wait for a reply, return good/bad news  */
10758   W (ret);
10759   return ret;
10760 }
10761
10762 static int
10763 api_ip6nd_proxy_dump (vat_main_t * vam)
10764 {
10765   vl_api_ip6nd_proxy_dump_t *mp;
10766   vl_api_control_ping_t *mp_ping;
10767   int ret;
10768
10769   M (IP6ND_PROXY_DUMP, mp);
10770
10771   S (mp);
10772
10773   /* Use a control ping for synchronization */
10774   MPING (CONTROL_PING, mp_ping);
10775   S (mp_ping);
10776
10777   W (ret);
10778   return ret;
10779 }
10780
10781 static void vl_api_ip6nd_proxy_details_t_handler
10782   (vl_api_ip6nd_proxy_details_t * mp)
10783 {
10784   vat_main_t *vam = &vat_main;
10785
10786   print (vam->ofp, "host %U sw_if_index %d",
10787          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
10788 }
10789
10790 static void vl_api_ip6nd_proxy_details_t_handler_json
10791   (vl_api_ip6nd_proxy_details_t * mp)
10792 {
10793   vat_main_t *vam = &vat_main;
10794   struct in6_addr ip6;
10795   vat_json_node_t *node = NULL;
10796
10797   if (VAT_JSON_ARRAY != vam->json_tree.type)
10798     {
10799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10800       vat_json_init_array (&vam->json_tree);
10801     }
10802   node = vat_json_array_add (&vam->json_tree);
10803
10804   vat_json_init_object (node);
10805   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10806
10807   clib_memcpy (&ip6, mp->address, sizeof (ip6));
10808   vat_json_object_add_ip6 (node, "host", ip6);
10809 }
10810
10811 static int
10812 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
10813 {
10814   unformat_input_t *i = vam->input;
10815   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
10816   u32 sw_if_index;
10817   u8 sw_if_index_set = 0;
10818   u32 address_length = 0;
10819   u8 v6_address_set = 0;
10820   ip6_address_t v6address;
10821   u8 use_default = 0;
10822   u8 no_advertise = 0;
10823   u8 off_link = 0;
10824   u8 no_autoconfig = 0;
10825   u8 no_onlink = 0;
10826   u8 is_no = 0;
10827   u32 val_lifetime = 0;
10828   u32 pref_lifetime = 0;
10829   int ret;
10830
10831   /* Parse args required to build the message */
10832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10833     {
10834       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10835         sw_if_index_set = 1;
10836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10837         sw_if_index_set = 1;
10838       else if (unformat (i, "%U/%d",
10839                          unformat_ip6_address, &v6address, &address_length))
10840         v6_address_set = 1;
10841       else if (unformat (i, "val_life %d", &val_lifetime))
10842         ;
10843       else if (unformat (i, "pref_life %d", &pref_lifetime))
10844         ;
10845       else if (unformat (i, "def"))
10846         use_default = 1;
10847       else if (unformat (i, "noadv"))
10848         no_advertise = 1;
10849       else if (unformat (i, "offl"))
10850         off_link = 1;
10851       else if (unformat (i, "noauto"))
10852         no_autoconfig = 1;
10853       else if (unformat (i, "nolink"))
10854         no_onlink = 1;
10855       else if (unformat (i, "isno"))
10856         is_no = 1;
10857       else
10858         {
10859           clib_warning ("parse error '%U'", format_unformat_error, i);
10860           return -99;
10861         }
10862     }
10863
10864   if (sw_if_index_set == 0)
10865     {
10866       errmsg ("missing interface name or sw_if_index");
10867       return -99;
10868     }
10869   if (!v6_address_set)
10870     {
10871       errmsg ("no address set");
10872       return -99;
10873     }
10874
10875   /* Construct the API message */
10876   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
10877
10878   mp->sw_if_index = ntohl (sw_if_index);
10879   clib_memcpy (mp->address, &v6address, sizeof (v6address));
10880   mp->address_length = address_length;
10881   mp->use_default = use_default;
10882   mp->no_advertise = no_advertise;
10883   mp->off_link = off_link;
10884   mp->no_autoconfig = no_autoconfig;
10885   mp->no_onlink = no_onlink;
10886   mp->is_no = is_no;
10887   mp->val_lifetime = ntohl (val_lifetime);
10888   mp->pref_lifetime = ntohl (pref_lifetime);
10889
10890   /* send it... */
10891   S (mp);
10892
10893   /* Wait for a reply, return good/bad news  */
10894   W (ret);
10895   return ret;
10896 }
10897
10898 static int
10899 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
10900 {
10901   unformat_input_t *i = vam->input;
10902   vl_api_sw_interface_ip6nd_ra_config_t *mp;
10903   u32 sw_if_index;
10904   u8 sw_if_index_set = 0;
10905   u8 suppress = 0;
10906   u8 managed = 0;
10907   u8 other = 0;
10908   u8 ll_option = 0;
10909   u8 send_unicast = 0;
10910   u8 cease = 0;
10911   u8 is_no = 0;
10912   u8 default_router = 0;
10913   u32 max_interval = 0;
10914   u32 min_interval = 0;
10915   u32 lifetime = 0;
10916   u32 initial_count = 0;
10917   u32 initial_interval = 0;
10918   int ret;
10919
10920
10921   /* Parse args required to build the message */
10922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10923     {
10924       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10925         sw_if_index_set = 1;
10926       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10927         sw_if_index_set = 1;
10928       else if (unformat (i, "maxint %d", &max_interval))
10929         ;
10930       else if (unformat (i, "minint %d", &min_interval))
10931         ;
10932       else if (unformat (i, "life %d", &lifetime))
10933         ;
10934       else if (unformat (i, "count %d", &initial_count))
10935         ;
10936       else if (unformat (i, "interval %d", &initial_interval))
10937         ;
10938       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10939         suppress = 1;
10940       else if (unformat (i, "managed"))
10941         managed = 1;
10942       else if (unformat (i, "other"))
10943         other = 1;
10944       else if (unformat (i, "ll"))
10945         ll_option = 1;
10946       else if (unformat (i, "send"))
10947         send_unicast = 1;
10948       else if (unformat (i, "cease"))
10949         cease = 1;
10950       else if (unformat (i, "isno"))
10951         is_no = 1;
10952       else if (unformat (i, "def"))
10953         default_router = 1;
10954       else
10955         {
10956           clib_warning ("parse error '%U'", format_unformat_error, i);
10957           return -99;
10958         }
10959     }
10960
10961   if (sw_if_index_set == 0)
10962     {
10963       errmsg ("missing interface name or sw_if_index");
10964       return -99;
10965     }
10966
10967   /* Construct the API message */
10968   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10969
10970   mp->sw_if_index = ntohl (sw_if_index);
10971   mp->max_interval = ntohl (max_interval);
10972   mp->min_interval = ntohl (min_interval);
10973   mp->lifetime = ntohl (lifetime);
10974   mp->initial_count = ntohl (initial_count);
10975   mp->initial_interval = ntohl (initial_interval);
10976   mp->suppress = suppress;
10977   mp->managed = managed;
10978   mp->other = other;
10979   mp->ll_option = ll_option;
10980   mp->send_unicast = send_unicast;
10981   mp->cease = cease;
10982   mp->is_no = is_no;
10983   mp->default_router = default_router;
10984
10985   /* send it... */
10986   S (mp);
10987
10988   /* Wait for a reply, return good/bad news  */
10989   W (ret);
10990   return ret;
10991 }
10992
10993 static int
10994 api_set_arp_neighbor_limit (vat_main_t * vam)
10995 {
10996   unformat_input_t *i = vam->input;
10997   vl_api_set_arp_neighbor_limit_t *mp;
10998   u32 arp_nbr_limit;
10999   u8 limit_set = 0;
11000   u8 is_ipv6 = 0;
11001   int ret;
11002
11003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
11006         limit_set = 1;
11007       else if (unformat (i, "ipv6"))
11008         is_ipv6 = 1;
11009       else
11010         {
11011           clib_warning ("parse error '%U'", format_unformat_error, i);
11012           return -99;
11013         }
11014     }
11015
11016   if (limit_set == 0)
11017     {
11018       errmsg ("missing limit value");
11019       return -99;
11020     }
11021
11022   M (SET_ARP_NEIGHBOR_LIMIT, mp);
11023
11024   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
11025   mp->is_ipv6 = is_ipv6;
11026
11027   S (mp);
11028   W (ret);
11029   return ret;
11030 }
11031
11032 static int
11033 api_l2_patch_add_del (vat_main_t * vam)
11034 {
11035   unformat_input_t *i = vam->input;
11036   vl_api_l2_patch_add_del_t *mp;
11037   u32 rx_sw_if_index;
11038   u8 rx_sw_if_index_set = 0;
11039   u32 tx_sw_if_index;
11040   u8 tx_sw_if_index_set = 0;
11041   u8 is_add = 1;
11042   int ret;
11043
11044   /* Parse args required to build the message */
11045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11046     {
11047       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
11048         rx_sw_if_index_set = 1;
11049       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
11050         tx_sw_if_index_set = 1;
11051       else if (unformat (i, "rx"))
11052         {
11053           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11054             {
11055               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11056                             &rx_sw_if_index))
11057                 rx_sw_if_index_set = 1;
11058             }
11059           else
11060             break;
11061         }
11062       else if (unformat (i, "tx"))
11063         {
11064           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11065             {
11066               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
11067                             &tx_sw_if_index))
11068                 tx_sw_if_index_set = 1;
11069             }
11070           else
11071             break;
11072         }
11073       else if (unformat (i, "del"))
11074         is_add = 0;
11075       else
11076         break;
11077     }
11078
11079   if (rx_sw_if_index_set == 0)
11080     {
11081       errmsg ("missing rx interface name or rx_sw_if_index");
11082       return -99;
11083     }
11084
11085   if (tx_sw_if_index_set == 0)
11086     {
11087       errmsg ("missing tx interface name or tx_sw_if_index");
11088       return -99;
11089     }
11090
11091   M (L2_PATCH_ADD_DEL, mp);
11092
11093   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
11094   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
11095   mp->is_add = is_add;
11096
11097   S (mp);
11098   W (ret);
11099   return ret;
11100 }
11101
11102 u8 is_del;
11103 u8 localsid_addr[16];
11104 u8 end_psp;
11105 u8 behavior;
11106 u32 sw_if_index;
11107 u32 vlan_index;
11108 u32 fib_table;
11109 u8 nh_addr[16];
11110
11111 static int
11112 api_sr_localsid_add_del (vat_main_t * vam)
11113 {
11114   unformat_input_t *i = vam->input;
11115   vl_api_sr_localsid_add_del_t *mp;
11116
11117   u8 is_del;
11118   ip6_address_t localsid;
11119   u8 end_psp = 0;
11120   u8 behavior = ~0;
11121   u32 sw_if_index;
11122   u32 fib_table = ~(u32) 0;
11123   ip6_address_t nh_addr6;
11124   ip4_address_t nh_addr4;
11125   memset (&nh_addr6, 0, sizeof (ip6_address_t));
11126   memset (&nh_addr4, 0, sizeof (ip4_address_t));
11127
11128   bool nexthop_set = 0;
11129
11130   int ret;
11131
11132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11133     {
11134       if (unformat (i, "del"))
11135         is_del = 1;
11136       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
11137       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
11138         nexthop_set = 1;
11139       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
11140         nexthop_set = 1;
11141       else if (unformat (i, "behavior %u", &behavior));
11142       else if (unformat (i, "sw_if_index %u", &sw_if_index));
11143       else if (unformat (i, "fib-table %u", &fib_table));
11144       else if (unformat (i, "end.psp %u", &behavior));
11145       else
11146         break;
11147     }
11148
11149   M (SR_LOCALSID_ADD_DEL, mp);
11150
11151   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
11152   if (nexthop_set)
11153     {
11154       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
11155       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
11156     }
11157   mp->behavior = behavior;
11158   mp->sw_if_index = ntohl (sw_if_index);
11159   mp->fib_table = ntohl (fib_table);
11160   mp->end_psp = end_psp;
11161   mp->is_del = is_del;
11162
11163   S (mp);
11164   W (ret);
11165   return ret;
11166 }
11167
11168 static int
11169 api_ioam_enable (vat_main_t * vam)
11170 {
11171   unformat_input_t *input = vam->input;
11172   vl_api_ioam_enable_t *mp;
11173   u32 id = 0;
11174   int has_trace_option = 0;
11175   int has_pot_option = 0;
11176   int has_seqno_option = 0;
11177   int has_analyse_option = 0;
11178   int ret;
11179
11180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11181     {
11182       if (unformat (input, "trace"))
11183         has_trace_option = 1;
11184       else if (unformat (input, "pot"))
11185         has_pot_option = 1;
11186       else if (unformat (input, "seqno"))
11187         has_seqno_option = 1;
11188       else if (unformat (input, "analyse"))
11189         has_analyse_option = 1;
11190       else
11191         break;
11192     }
11193   M (IOAM_ENABLE, mp);
11194   mp->id = htons (id);
11195   mp->seqno = has_seqno_option;
11196   mp->analyse = has_analyse_option;
11197   mp->pot_enable = has_pot_option;
11198   mp->trace_enable = has_trace_option;
11199
11200   S (mp);
11201   W (ret);
11202   return ret;
11203 }
11204
11205
11206 static int
11207 api_ioam_disable (vat_main_t * vam)
11208 {
11209   vl_api_ioam_disable_t *mp;
11210   int ret;
11211
11212   M (IOAM_DISABLE, mp);
11213   S (mp);
11214   W (ret);
11215   return ret;
11216 }
11217
11218 #define foreach_tcp_proto_field                 \
11219 _(src_port)                                     \
11220 _(dst_port)
11221
11222 #define foreach_udp_proto_field                 \
11223 _(src_port)                                     \
11224 _(dst_port)
11225
11226 #define foreach_ip4_proto_field                 \
11227 _(src_address)                                  \
11228 _(dst_address)                                  \
11229 _(tos)                                          \
11230 _(length)                                       \
11231 _(fragment_id)                                  \
11232 _(ttl)                                          \
11233 _(protocol)                                     \
11234 _(checksum)
11235
11236 typedef struct
11237 {
11238   u16 src_port, dst_port;
11239 } tcpudp_header_t;
11240
11241 #if VPP_API_TEST_BUILTIN == 0
11242 uword
11243 unformat_tcp_mask (unformat_input_t * input, va_list * args)
11244 {
11245   u8 **maskp = va_arg (*args, u8 **);
11246   u8 *mask = 0;
11247   u8 found_something = 0;
11248   tcp_header_t *tcp;
11249
11250 #define _(a) u8 a=0;
11251   foreach_tcp_proto_field;
11252 #undef _
11253
11254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11255     {
11256       if (0);
11257 #define _(a) else if (unformat (input, #a)) a=1;
11258       foreach_tcp_proto_field
11259 #undef _
11260         else
11261         break;
11262     }
11263
11264 #define _(a) found_something += a;
11265   foreach_tcp_proto_field;
11266 #undef _
11267
11268   if (found_something == 0)
11269     return 0;
11270
11271   vec_validate (mask, sizeof (*tcp) - 1);
11272
11273   tcp = (tcp_header_t *) mask;
11274
11275 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
11276   foreach_tcp_proto_field;
11277 #undef _
11278
11279   *maskp = mask;
11280   return 1;
11281 }
11282
11283 uword
11284 unformat_udp_mask (unformat_input_t * input, va_list * args)
11285 {
11286   u8 **maskp = va_arg (*args, u8 **);
11287   u8 *mask = 0;
11288   u8 found_something = 0;
11289   udp_header_t *udp;
11290
11291 #define _(a) u8 a=0;
11292   foreach_udp_proto_field;
11293 #undef _
11294
11295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11296     {
11297       if (0);
11298 #define _(a) else if (unformat (input, #a)) a=1;
11299       foreach_udp_proto_field
11300 #undef _
11301         else
11302         break;
11303     }
11304
11305 #define _(a) found_something += a;
11306   foreach_udp_proto_field;
11307 #undef _
11308
11309   if (found_something == 0)
11310     return 0;
11311
11312   vec_validate (mask, sizeof (*udp) - 1);
11313
11314   udp = (udp_header_t *) mask;
11315
11316 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
11317   foreach_udp_proto_field;
11318 #undef _
11319
11320   *maskp = mask;
11321   return 1;
11322 }
11323
11324 uword
11325 unformat_l4_mask (unformat_input_t * input, va_list * args)
11326 {
11327   u8 **maskp = va_arg (*args, u8 **);
11328   u16 src_port = 0, dst_port = 0;
11329   tcpudp_header_t *tcpudp;
11330
11331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11332     {
11333       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
11334         return 1;
11335       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
11336         return 1;
11337       else if (unformat (input, "src_port"))
11338         src_port = 0xFFFF;
11339       else if (unformat (input, "dst_port"))
11340         dst_port = 0xFFFF;
11341       else
11342         return 0;
11343     }
11344
11345   if (!src_port && !dst_port)
11346     return 0;
11347
11348   u8 *mask = 0;
11349   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
11350
11351   tcpudp = (tcpudp_header_t *) mask;
11352   tcpudp->src_port = src_port;
11353   tcpudp->dst_port = dst_port;
11354
11355   *maskp = mask;
11356
11357   return 1;
11358 }
11359
11360 uword
11361 unformat_ip4_mask (unformat_input_t * input, va_list * args)
11362 {
11363   u8 **maskp = va_arg (*args, u8 **);
11364   u8 *mask = 0;
11365   u8 found_something = 0;
11366   ip4_header_t *ip;
11367
11368 #define _(a) u8 a=0;
11369   foreach_ip4_proto_field;
11370 #undef _
11371   u8 version = 0;
11372   u8 hdr_length = 0;
11373
11374
11375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11376     {
11377       if (unformat (input, "version"))
11378         version = 1;
11379       else if (unformat (input, "hdr_length"))
11380         hdr_length = 1;
11381       else if (unformat (input, "src"))
11382         src_address = 1;
11383       else if (unformat (input, "dst"))
11384         dst_address = 1;
11385       else if (unformat (input, "proto"))
11386         protocol = 1;
11387
11388 #define _(a) else if (unformat (input, #a)) a=1;
11389       foreach_ip4_proto_field
11390 #undef _
11391         else
11392         break;
11393     }
11394
11395 #define _(a) found_something += a;
11396   foreach_ip4_proto_field;
11397 #undef _
11398
11399   if (found_something == 0)
11400     return 0;
11401
11402   vec_validate (mask, sizeof (*ip) - 1);
11403
11404   ip = (ip4_header_t *) mask;
11405
11406 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11407   foreach_ip4_proto_field;
11408 #undef _
11409
11410   ip->ip_version_and_header_length = 0;
11411
11412   if (version)
11413     ip->ip_version_and_header_length |= 0xF0;
11414
11415   if (hdr_length)
11416     ip->ip_version_and_header_length |= 0x0F;
11417
11418   *maskp = mask;
11419   return 1;
11420 }
11421
11422 #define foreach_ip6_proto_field                 \
11423 _(src_address)                                  \
11424 _(dst_address)                                  \
11425 _(payload_length)                               \
11426 _(hop_limit)                                    \
11427 _(protocol)
11428
11429 uword
11430 unformat_ip6_mask (unformat_input_t * input, va_list * args)
11431 {
11432   u8 **maskp = va_arg (*args, u8 **);
11433   u8 *mask = 0;
11434   u8 found_something = 0;
11435   ip6_header_t *ip;
11436   u32 ip_version_traffic_class_and_flow_label;
11437
11438 #define _(a) u8 a=0;
11439   foreach_ip6_proto_field;
11440 #undef _
11441   u8 version = 0;
11442   u8 traffic_class = 0;
11443   u8 flow_label = 0;
11444
11445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11446     {
11447       if (unformat (input, "version"))
11448         version = 1;
11449       else if (unformat (input, "traffic-class"))
11450         traffic_class = 1;
11451       else if (unformat (input, "flow-label"))
11452         flow_label = 1;
11453       else if (unformat (input, "src"))
11454         src_address = 1;
11455       else if (unformat (input, "dst"))
11456         dst_address = 1;
11457       else if (unformat (input, "proto"))
11458         protocol = 1;
11459
11460 #define _(a) else if (unformat (input, #a)) a=1;
11461       foreach_ip6_proto_field
11462 #undef _
11463         else
11464         break;
11465     }
11466
11467 #define _(a) found_something += a;
11468   foreach_ip6_proto_field;
11469 #undef _
11470
11471   if (found_something == 0)
11472     return 0;
11473
11474   vec_validate (mask, sizeof (*ip) - 1);
11475
11476   ip = (ip6_header_t *) mask;
11477
11478 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
11479   foreach_ip6_proto_field;
11480 #undef _
11481
11482   ip_version_traffic_class_and_flow_label = 0;
11483
11484   if (version)
11485     ip_version_traffic_class_and_flow_label |= 0xF0000000;
11486
11487   if (traffic_class)
11488     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
11489
11490   if (flow_label)
11491     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
11492
11493   ip->ip_version_traffic_class_and_flow_label =
11494     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11495
11496   *maskp = mask;
11497   return 1;
11498 }
11499
11500 uword
11501 unformat_l3_mask (unformat_input_t * input, va_list * args)
11502 {
11503   u8 **maskp = va_arg (*args, u8 **);
11504
11505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11506     {
11507       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
11508         return 1;
11509       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
11510         return 1;
11511       else
11512         break;
11513     }
11514   return 0;
11515 }
11516
11517 uword
11518 unformat_l2_mask (unformat_input_t * input, va_list * args)
11519 {
11520   u8 **maskp = va_arg (*args, u8 **);
11521   u8 *mask = 0;
11522   u8 src = 0;
11523   u8 dst = 0;
11524   u8 proto = 0;
11525   u8 tag1 = 0;
11526   u8 tag2 = 0;
11527   u8 ignore_tag1 = 0;
11528   u8 ignore_tag2 = 0;
11529   u8 cos1 = 0;
11530   u8 cos2 = 0;
11531   u8 dot1q = 0;
11532   u8 dot1ad = 0;
11533   int len = 14;
11534
11535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11536     {
11537       if (unformat (input, "src"))
11538         src = 1;
11539       else if (unformat (input, "dst"))
11540         dst = 1;
11541       else if (unformat (input, "proto"))
11542         proto = 1;
11543       else if (unformat (input, "tag1"))
11544         tag1 = 1;
11545       else if (unformat (input, "tag2"))
11546         tag2 = 1;
11547       else if (unformat (input, "ignore-tag1"))
11548         ignore_tag1 = 1;
11549       else if (unformat (input, "ignore-tag2"))
11550         ignore_tag2 = 1;
11551       else if (unformat (input, "cos1"))
11552         cos1 = 1;
11553       else if (unformat (input, "cos2"))
11554         cos2 = 1;
11555       else if (unformat (input, "dot1q"))
11556         dot1q = 1;
11557       else if (unformat (input, "dot1ad"))
11558         dot1ad = 1;
11559       else
11560         break;
11561     }
11562   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
11563        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11564     return 0;
11565
11566   if (tag1 || ignore_tag1 || cos1 || dot1q)
11567     len = 18;
11568   if (tag2 || ignore_tag2 || cos2 || dot1ad)
11569     len = 22;
11570
11571   vec_validate (mask, len - 1);
11572
11573   if (dst)
11574     memset (mask, 0xff, 6);
11575
11576   if (src)
11577     memset (mask + 6, 0xff, 6);
11578
11579   if (tag2 || dot1ad)
11580     {
11581       /* inner vlan tag */
11582       if (tag2)
11583         {
11584           mask[19] = 0xff;
11585           mask[18] = 0x0f;
11586         }
11587       if (cos2)
11588         mask[18] |= 0xe0;
11589       if (proto)
11590         mask[21] = mask[20] = 0xff;
11591       if (tag1)
11592         {
11593           mask[15] = 0xff;
11594           mask[14] = 0x0f;
11595         }
11596       if (cos1)
11597         mask[14] |= 0xe0;
11598       *maskp = mask;
11599       return 1;
11600     }
11601   if (tag1 | dot1q)
11602     {
11603       if (tag1)
11604         {
11605           mask[15] = 0xff;
11606           mask[14] = 0x0f;
11607         }
11608       if (cos1)
11609         mask[14] |= 0xe0;
11610       if (proto)
11611         mask[16] = mask[17] = 0xff;
11612
11613       *maskp = mask;
11614       return 1;
11615     }
11616   if (cos2)
11617     mask[18] |= 0xe0;
11618   if (cos1)
11619     mask[14] |= 0xe0;
11620   if (proto)
11621     mask[12] = mask[13] = 0xff;
11622
11623   *maskp = mask;
11624   return 1;
11625 }
11626
11627 uword
11628 unformat_classify_mask (unformat_input_t * input, va_list * args)
11629 {
11630   u8 **maskp = va_arg (*args, u8 **);
11631   u32 *skipp = va_arg (*args, u32 *);
11632   u32 *matchp = va_arg (*args, u32 *);
11633   u32 match;
11634   u8 *mask = 0;
11635   u8 *l2 = 0;
11636   u8 *l3 = 0;
11637   u8 *l4 = 0;
11638   int i;
11639
11640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11641     {
11642       if (unformat (input, "hex %U", unformat_hex_string, &mask))
11643         ;
11644       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
11645         ;
11646       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
11647         ;
11648       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
11649         ;
11650       else
11651         break;
11652     }
11653
11654   if (l4 && !l3)
11655     {
11656       vec_free (mask);
11657       vec_free (l2);
11658       vec_free (l4);
11659       return 0;
11660     }
11661
11662   if (mask || l2 || l3 || l4)
11663     {
11664       if (l2 || l3 || l4)
11665         {
11666           /* "With a free Ethernet header in every package" */
11667           if (l2 == 0)
11668             vec_validate (l2, 13);
11669           mask = l2;
11670           if (vec_len (l3))
11671             {
11672               vec_append (mask, l3);
11673               vec_free (l3);
11674             }
11675           if (vec_len (l4))
11676             {
11677               vec_append (mask, l4);
11678               vec_free (l4);
11679             }
11680         }
11681
11682       /* Scan forward looking for the first significant mask octet */
11683       for (i = 0; i < vec_len (mask); i++)
11684         if (mask[i])
11685           break;
11686
11687       /* compute (skip, match) params */
11688       *skipp = i / sizeof (u32x4);
11689       vec_delete (mask, *skipp * sizeof (u32x4), 0);
11690
11691       /* Pad mask to an even multiple of the vector size */
11692       while (vec_len (mask) % sizeof (u32x4))
11693         vec_add1 (mask, 0);
11694
11695       match = vec_len (mask) / sizeof (u32x4);
11696
11697       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
11698         {
11699           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
11700           if (*tmp || *(tmp + 1))
11701             break;
11702           match--;
11703         }
11704       if (match == 0)
11705         clib_warning ("BUG: match 0");
11706
11707       _vec_len (mask) = match * sizeof (u32x4);
11708
11709       *matchp = match;
11710       *maskp = mask;
11711
11712       return 1;
11713     }
11714
11715   return 0;
11716 }
11717 #endif /* VPP_API_TEST_BUILTIN */
11718
11719 #define foreach_l2_next                         \
11720 _(drop, DROP)                                   \
11721 _(ethernet, ETHERNET_INPUT)                     \
11722 _(ip4, IP4_INPUT)                               \
11723 _(ip6, IP6_INPUT)
11724
11725 uword
11726 unformat_l2_next_index (unformat_input_t * input, va_list * args)
11727 {
11728   u32 *miss_next_indexp = va_arg (*args, u32 *);
11729   u32 next_index = 0;
11730   u32 tmp;
11731
11732 #define _(n,N) \
11733   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
11734   foreach_l2_next;
11735 #undef _
11736
11737   if (unformat (input, "%d", &tmp))
11738     {
11739       next_index = tmp;
11740       goto out;
11741     }
11742
11743   return 0;
11744
11745 out:
11746   *miss_next_indexp = next_index;
11747   return 1;
11748 }
11749
11750 #define foreach_ip_next                         \
11751 _(drop, DROP)                                   \
11752 _(local, LOCAL)                                 \
11753 _(rewrite, REWRITE)
11754
11755 uword
11756 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
11757 {
11758   u32 *miss_next_indexp = va_arg (*args, u32 *);
11759   u32 next_index = 0;
11760   u32 tmp;
11761
11762 #define _(n,N) \
11763   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
11764   foreach_ip_next;
11765 #undef _
11766
11767   if (unformat (input, "%d", &tmp))
11768     {
11769       next_index = tmp;
11770       goto out;
11771     }
11772
11773   return 0;
11774
11775 out:
11776   *miss_next_indexp = next_index;
11777   return 1;
11778 }
11779
11780 #define foreach_acl_next                        \
11781 _(deny, DENY)
11782
11783 uword
11784 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
11785 {
11786   u32 *miss_next_indexp = va_arg (*args, u32 *);
11787   u32 next_index = 0;
11788   u32 tmp;
11789
11790 #define _(n,N) \
11791   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
11792   foreach_acl_next;
11793 #undef _
11794
11795   if (unformat (input, "permit"))
11796     {
11797       next_index = ~0;
11798       goto out;
11799     }
11800   else if (unformat (input, "%d", &tmp))
11801     {
11802       next_index = tmp;
11803       goto out;
11804     }
11805
11806   return 0;
11807
11808 out:
11809   *miss_next_indexp = next_index;
11810   return 1;
11811 }
11812
11813 uword
11814 unformat_policer_precolor (unformat_input_t * input, va_list * args)
11815 {
11816   u32 *r = va_arg (*args, u32 *);
11817
11818   if (unformat (input, "conform-color"))
11819     *r = POLICE_CONFORM;
11820   else if (unformat (input, "exceed-color"))
11821     *r = POLICE_EXCEED;
11822   else
11823     return 0;
11824
11825   return 1;
11826 }
11827
11828 static int
11829 api_classify_add_del_table (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   vl_api_classify_add_del_table_t *mp;
11833
11834   u32 nbuckets = 2;
11835   u32 skip = ~0;
11836   u32 match = ~0;
11837   int is_add = 1;
11838   int del_chain = 0;
11839   u32 table_index = ~0;
11840   u32 next_table_index = ~0;
11841   u32 miss_next_index = ~0;
11842   u32 memory_size = 32 << 20;
11843   u8 *mask = 0;
11844   u32 current_data_flag = 0;
11845   int current_data_offset = 0;
11846   int ret;
11847
11848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11849     {
11850       if (unformat (i, "del"))
11851         is_add = 0;
11852       else if (unformat (i, "del-chain"))
11853         {
11854           is_add = 0;
11855           del_chain = 1;
11856         }
11857       else if (unformat (i, "buckets %d", &nbuckets))
11858         ;
11859       else if (unformat (i, "memory_size %d", &memory_size))
11860         ;
11861       else if (unformat (i, "skip %d", &skip))
11862         ;
11863       else if (unformat (i, "match %d", &match))
11864         ;
11865       else if (unformat (i, "table %d", &table_index))
11866         ;
11867       else if (unformat (i, "mask %U", unformat_classify_mask,
11868                          &mask, &skip, &match))
11869         ;
11870       else if (unformat (i, "next-table %d", &next_table_index))
11871         ;
11872       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
11873                          &miss_next_index))
11874         ;
11875       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
11876                          &miss_next_index))
11877         ;
11878       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
11879                          &miss_next_index))
11880         ;
11881       else if (unformat (i, "current-data-flag %d", &current_data_flag))
11882         ;
11883       else if (unformat (i, "current-data-offset %d", &current_data_offset))
11884         ;
11885       else
11886         break;
11887     }
11888
11889   if (is_add && mask == 0)
11890     {
11891       errmsg ("Mask required");
11892       return -99;
11893     }
11894
11895   if (is_add && skip == ~0)
11896     {
11897       errmsg ("skip count required");
11898       return -99;
11899     }
11900
11901   if (is_add && match == ~0)
11902     {
11903       errmsg ("match count required");
11904       return -99;
11905     }
11906
11907   if (!is_add && table_index == ~0)
11908     {
11909       errmsg ("table index required for delete");
11910       return -99;
11911     }
11912
11913   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
11914
11915   mp->is_add = is_add;
11916   mp->del_chain = del_chain;
11917   mp->table_index = ntohl (table_index);
11918   mp->nbuckets = ntohl (nbuckets);
11919   mp->memory_size = ntohl (memory_size);
11920   mp->skip_n_vectors = ntohl (skip);
11921   mp->match_n_vectors = ntohl (match);
11922   mp->next_table_index = ntohl (next_table_index);
11923   mp->miss_next_index = ntohl (miss_next_index);
11924   mp->current_data_flag = ntohl (current_data_flag);
11925   mp->current_data_offset = ntohl (current_data_offset);
11926   mp->mask_len = ntohl (vec_len (mask));
11927   clib_memcpy (mp->mask, mask, vec_len (mask));
11928
11929   vec_free (mask);
11930
11931   S (mp);
11932   W (ret);
11933   return ret;
11934 }
11935
11936 #if VPP_API_TEST_BUILTIN == 0
11937 uword
11938 unformat_l4_match (unformat_input_t * input, va_list * args)
11939 {
11940   u8 **matchp = va_arg (*args, u8 **);
11941
11942   u8 *proto_header = 0;
11943   int src_port = 0;
11944   int dst_port = 0;
11945
11946   tcpudp_header_t h;
11947
11948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11949     {
11950       if (unformat (input, "src_port %d", &src_port))
11951         ;
11952       else if (unformat (input, "dst_port %d", &dst_port))
11953         ;
11954       else
11955         return 0;
11956     }
11957
11958   h.src_port = clib_host_to_net_u16 (src_port);
11959   h.dst_port = clib_host_to_net_u16 (dst_port);
11960   vec_validate (proto_header, sizeof (h) - 1);
11961   memcpy (proto_header, &h, sizeof (h));
11962
11963   *matchp = proto_header;
11964
11965   return 1;
11966 }
11967
11968 uword
11969 unformat_ip4_match (unformat_input_t * input, va_list * args)
11970 {
11971   u8 **matchp = va_arg (*args, u8 **);
11972   u8 *match = 0;
11973   ip4_header_t *ip;
11974   int version = 0;
11975   u32 version_val;
11976   int hdr_length = 0;
11977   u32 hdr_length_val;
11978   int src = 0, dst = 0;
11979   ip4_address_t src_val, dst_val;
11980   int proto = 0;
11981   u32 proto_val;
11982   int tos = 0;
11983   u32 tos_val;
11984   int length = 0;
11985   u32 length_val;
11986   int fragment_id = 0;
11987   u32 fragment_id_val;
11988   int ttl = 0;
11989   int ttl_val;
11990   int checksum = 0;
11991   u32 checksum_val;
11992
11993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11994     {
11995       if (unformat (input, "version %d", &version_val))
11996         version = 1;
11997       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11998         hdr_length = 1;
11999       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
12000         src = 1;
12001       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
12002         dst = 1;
12003       else if (unformat (input, "proto %d", &proto_val))
12004         proto = 1;
12005       else if (unformat (input, "tos %d", &tos_val))
12006         tos = 1;
12007       else if (unformat (input, "length %d", &length_val))
12008         length = 1;
12009       else if (unformat (input, "fragment_id %d", &fragment_id_val))
12010         fragment_id = 1;
12011       else if (unformat (input, "ttl %d", &ttl_val))
12012         ttl = 1;
12013       else if (unformat (input, "checksum %d", &checksum_val))
12014         checksum = 1;
12015       else
12016         break;
12017     }
12018
12019   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
12020       + ttl + checksum == 0)
12021     return 0;
12022
12023   /*
12024    * Aligned because we use the real comparison functions
12025    */
12026   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12027
12028   ip = (ip4_header_t *) match;
12029
12030   /* These are realistically matched in practice */
12031   if (src)
12032     ip->src_address.as_u32 = src_val.as_u32;
12033
12034   if (dst)
12035     ip->dst_address.as_u32 = dst_val.as_u32;
12036
12037   if (proto)
12038     ip->protocol = proto_val;
12039
12040
12041   /* These are not, but they're included for completeness */
12042   if (version)
12043     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
12044
12045   if (hdr_length)
12046     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
12047
12048   if (tos)
12049     ip->tos = tos_val;
12050
12051   if (length)
12052     ip->length = clib_host_to_net_u16 (length_val);
12053
12054   if (ttl)
12055     ip->ttl = ttl_val;
12056
12057   if (checksum)
12058     ip->checksum = clib_host_to_net_u16 (checksum_val);
12059
12060   *matchp = match;
12061   return 1;
12062 }
12063
12064 uword
12065 unformat_ip6_match (unformat_input_t * input, va_list * args)
12066 {
12067   u8 **matchp = va_arg (*args, u8 **);
12068   u8 *match = 0;
12069   ip6_header_t *ip;
12070   int version = 0;
12071   u32 version_val;
12072   u8 traffic_class = 0;
12073   u32 traffic_class_val = 0;
12074   u8 flow_label = 0;
12075   u8 flow_label_val;
12076   int src = 0, dst = 0;
12077   ip6_address_t src_val, dst_val;
12078   int proto = 0;
12079   u32 proto_val;
12080   int payload_length = 0;
12081   u32 payload_length_val;
12082   int hop_limit = 0;
12083   int hop_limit_val;
12084   u32 ip_version_traffic_class_and_flow_label;
12085
12086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12087     {
12088       if (unformat (input, "version %d", &version_val))
12089         version = 1;
12090       else if (unformat (input, "traffic_class %d", &traffic_class_val))
12091         traffic_class = 1;
12092       else if (unformat (input, "flow_label %d", &flow_label_val))
12093         flow_label = 1;
12094       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
12095         src = 1;
12096       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
12097         dst = 1;
12098       else if (unformat (input, "proto %d", &proto_val))
12099         proto = 1;
12100       else if (unformat (input, "payload_length %d", &payload_length_val))
12101         payload_length = 1;
12102       else if (unformat (input, "hop_limit %d", &hop_limit_val))
12103         hop_limit = 1;
12104       else
12105         break;
12106     }
12107
12108   if (version + traffic_class + flow_label + src + dst + proto +
12109       payload_length + hop_limit == 0)
12110     return 0;
12111
12112   /*
12113    * Aligned because we use the real comparison functions
12114    */
12115   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
12116
12117   ip = (ip6_header_t *) match;
12118
12119   if (src)
12120     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
12121
12122   if (dst)
12123     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
12124
12125   if (proto)
12126     ip->protocol = proto_val;
12127
12128   ip_version_traffic_class_and_flow_label = 0;
12129
12130   if (version)
12131     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
12132
12133   if (traffic_class)
12134     ip_version_traffic_class_and_flow_label |=
12135       (traffic_class_val & 0xFF) << 20;
12136
12137   if (flow_label)
12138     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
12139
12140   ip->ip_version_traffic_class_and_flow_label =
12141     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
12142
12143   if (payload_length)
12144     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
12145
12146   if (hop_limit)
12147     ip->hop_limit = hop_limit_val;
12148
12149   *matchp = match;
12150   return 1;
12151 }
12152
12153 uword
12154 unformat_l3_match (unformat_input_t * input, va_list * args)
12155 {
12156   u8 **matchp = va_arg (*args, u8 **);
12157
12158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12159     {
12160       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
12161         return 1;
12162       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
12163         return 1;
12164       else
12165         break;
12166     }
12167   return 0;
12168 }
12169
12170 uword
12171 unformat_vlan_tag (unformat_input_t * input, va_list * args)
12172 {
12173   u8 *tagp = va_arg (*args, u8 *);
12174   u32 tag;
12175
12176   if (unformat (input, "%d", &tag))
12177     {
12178       tagp[0] = (tag >> 8) & 0x0F;
12179       tagp[1] = tag & 0xFF;
12180       return 1;
12181     }
12182
12183   return 0;
12184 }
12185
12186 uword
12187 unformat_l2_match (unformat_input_t * input, va_list * args)
12188 {
12189   u8 **matchp = va_arg (*args, u8 **);
12190   u8 *match = 0;
12191   u8 src = 0;
12192   u8 src_val[6];
12193   u8 dst = 0;
12194   u8 dst_val[6];
12195   u8 proto = 0;
12196   u16 proto_val;
12197   u8 tag1 = 0;
12198   u8 tag1_val[2];
12199   u8 tag2 = 0;
12200   u8 tag2_val[2];
12201   int len = 14;
12202   u8 ignore_tag1 = 0;
12203   u8 ignore_tag2 = 0;
12204   u8 cos1 = 0;
12205   u8 cos2 = 0;
12206   u32 cos1_val = 0;
12207   u32 cos2_val = 0;
12208
12209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12210     {
12211       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
12212         src = 1;
12213       else
12214         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
12215         dst = 1;
12216       else if (unformat (input, "proto %U",
12217                          unformat_ethernet_type_host_byte_order, &proto_val))
12218         proto = 1;
12219       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
12220         tag1 = 1;
12221       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
12222         tag2 = 1;
12223       else if (unformat (input, "ignore-tag1"))
12224         ignore_tag1 = 1;
12225       else if (unformat (input, "ignore-tag2"))
12226         ignore_tag2 = 1;
12227       else if (unformat (input, "cos1 %d", &cos1_val))
12228         cos1 = 1;
12229       else if (unformat (input, "cos2 %d", &cos2_val))
12230         cos2 = 1;
12231       else
12232         break;
12233     }
12234   if ((src + dst + proto + tag1 + tag2 +
12235        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
12236     return 0;
12237
12238   if (tag1 || ignore_tag1 || cos1)
12239     len = 18;
12240   if (tag2 || ignore_tag2 || cos2)
12241     len = 22;
12242
12243   vec_validate_aligned (match, len - 1, sizeof (u32x4));
12244
12245   if (dst)
12246     clib_memcpy (match, dst_val, 6);
12247
12248   if (src)
12249     clib_memcpy (match + 6, src_val, 6);
12250
12251   if (tag2)
12252     {
12253       /* inner vlan tag */
12254       match[19] = tag2_val[1];
12255       match[18] = tag2_val[0];
12256       if (cos2)
12257         match[18] |= (cos2_val & 0x7) << 5;
12258       if (proto)
12259         {
12260           match[21] = proto_val & 0xff;
12261           match[20] = proto_val >> 8;
12262         }
12263       if (tag1)
12264         {
12265           match[15] = tag1_val[1];
12266           match[14] = tag1_val[0];
12267         }
12268       if (cos1)
12269         match[14] |= (cos1_val & 0x7) << 5;
12270       *matchp = match;
12271       return 1;
12272     }
12273   if (tag1)
12274     {
12275       match[15] = tag1_val[1];
12276       match[14] = tag1_val[0];
12277       if (proto)
12278         {
12279           match[17] = proto_val & 0xff;
12280           match[16] = proto_val >> 8;
12281         }
12282       if (cos1)
12283         match[14] |= (cos1_val & 0x7) << 5;
12284
12285       *matchp = match;
12286       return 1;
12287     }
12288   if (cos2)
12289     match[18] |= (cos2_val & 0x7) << 5;
12290   if (cos1)
12291     match[14] |= (cos1_val & 0x7) << 5;
12292   if (proto)
12293     {
12294       match[13] = proto_val & 0xff;
12295       match[12] = proto_val >> 8;
12296     }
12297
12298   *matchp = match;
12299   return 1;
12300 }
12301
12302 uword
12303 unformat_qos_source (unformat_input_t * input, va_list * args)
12304 {
12305   int *qs = va_arg (*args, int *);
12306
12307   if (unformat (input, "ip"))
12308     *qs = QOS_SOURCE_IP;
12309   else if (unformat (input, "mpls"))
12310     *qs = QOS_SOURCE_MPLS;
12311   else if (unformat (input, "ext"))
12312     *qs = QOS_SOURCE_EXT;
12313   else if (unformat (input, "vlan"))
12314     *qs = QOS_SOURCE_VLAN;
12315   else
12316     return 0;
12317
12318   return 1;
12319 }
12320 #endif
12321
12322 uword
12323 api_unformat_classify_match (unformat_input_t * input, va_list * args)
12324 {
12325   u8 **matchp = va_arg (*args, u8 **);
12326   u32 skip_n_vectors = va_arg (*args, u32);
12327   u32 match_n_vectors = va_arg (*args, u32);
12328
12329   u8 *match = 0;
12330   u8 *l2 = 0;
12331   u8 *l3 = 0;
12332   u8 *l4 = 0;
12333
12334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12335     {
12336       if (unformat (input, "hex %U", unformat_hex_string, &match))
12337         ;
12338       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
12339         ;
12340       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
12341         ;
12342       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
12343         ;
12344       else
12345         break;
12346     }
12347
12348   if (l4 && !l3)
12349     {
12350       vec_free (match);
12351       vec_free (l2);
12352       vec_free (l4);
12353       return 0;
12354     }
12355
12356   if (match || l2 || l3 || l4)
12357     {
12358       if (l2 || l3 || l4)
12359         {
12360           /* "Win a free Ethernet header in every packet" */
12361           if (l2 == 0)
12362             vec_validate_aligned (l2, 13, sizeof (u32x4));
12363           match = l2;
12364           if (vec_len (l3))
12365             {
12366               vec_append_aligned (match, l3, sizeof (u32x4));
12367               vec_free (l3);
12368             }
12369           if (vec_len (l4))
12370             {
12371               vec_append_aligned (match, l4, sizeof (u32x4));
12372               vec_free (l4);
12373             }
12374         }
12375
12376       /* Make sure the vector is big enough even if key is all 0's */
12377       vec_validate_aligned
12378         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
12379          sizeof (u32x4));
12380
12381       /* Set size, include skipped vectors */
12382       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
12383
12384       *matchp = match;
12385
12386       return 1;
12387     }
12388
12389   return 0;
12390 }
12391
12392 static int
12393 api_classify_add_del_session (vat_main_t * vam)
12394 {
12395   unformat_input_t *i = vam->input;
12396   vl_api_classify_add_del_session_t *mp;
12397   int is_add = 1;
12398   u32 table_index = ~0;
12399   u32 hit_next_index = ~0;
12400   u32 opaque_index = ~0;
12401   u8 *match = 0;
12402   i32 advance = 0;
12403   u32 skip_n_vectors = 0;
12404   u32 match_n_vectors = 0;
12405   u32 action = 0;
12406   u32 metadata = 0;
12407   int ret;
12408
12409   /*
12410    * Warning: you have to supply skip_n and match_n
12411    * because the API client cant simply look at the classify
12412    * table object.
12413    */
12414
12415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12416     {
12417       if (unformat (i, "del"))
12418         is_add = 0;
12419       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
12420                          &hit_next_index))
12421         ;
12422       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
12423                          &hit_next_index))
12424         ;
12425       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
12426                          &hit_next_index))
12427         ;
12428       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
12429         ;
12430       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
12431         ;
12432       else if (unformat (i, "opaque-index %d", &opaque_index))
12433         ;
12434       else if (unformat (i, "skip_n %d", &skip_n_vectors))
12435         ;
12436       else if (unformat (i, "match_n %d", &match_n_vectors))
12437         ;
12438       else if (unformat (i, "match %U", api_unformat_classify_match,
12439                          &match, skip_n_vectors, match_n_vectors))
12440         ;
12441       else if (unformat (i, "advance %d", &advance))
12442         ;
12443       else if (unformat (i, "table-index %d", &table_index))
12444         ;
12445       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
12446         action = 1;
12447       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
12448         action = 2;
12449       else if (unformat (i, "action %d", &action))
12450         ;
12451       else if (unformat (i, "metadata %d", &metadata))
12452         ;
12453       else
12454         break;
12455     }
12456
12457   if (table_index == ~0)
12458     {
12459       errmsg ("Table index required");
12460       return -99;
12461     }
12462
12463   if (is_add && match == 0)
12464     {
12465       errmsg ("Match value required");
12466       return -99;
12467     }
12468
12469   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
12470
12471   mp->is_add = is_add;
12472   mp->table_index = ntohl (table_index);
12473   mp->hit_next_index = ntohl (hit_next_index);
12474   mp->opaque_index = ntohl (opaque_index);
12475   mp->advance = ntohl (advance);
12476   mp->action = action;
12477   mp->metadata = ntohl (metadata);
12478   mp->match_len = ntohl (vec_len (match));
12479   clib_memcpy (mp->match, match, vec_len (match));
12480   vec_free (match);
12481
12482   S (mp);
12483   W (ret);
12484   return ret;
12485 }
12486
12487 static int
12488 api_classify_set_interface_ip_table (vat_main_t * vam)
12489 {
12490   unformat_input_t *i = vam->input;
12491   vl_api_classify_set_interface_ip_table_t *mp;
12492   u32 sw_if_index;
12493   int sw_if_index_set;
12494   u32 table_index = ~0;
12495   u8 is_ipv6 = 0;
12496   int ret;
12497
12498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12499     {
12500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12501         sw_if_index_set = 1;
12502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12503         sw_if_index_set = 1;
12504       else if (unformat (i, "table %d", &table_index))
12505         ;
12506       else
12507         {
12508           clib_warning ("parse error '%U'", format_unformat_error, i);
12509           return -99;
12510         }
12511     }
12512
12513   if (sw_if_index_set == 0)
12514     {
12515       errmsg ("missing interface name or sw_if_index");
12516       return -99;
12517     }
12518
12519
12520   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
12521
12522   mp->sw_if_index = ntohl (sw_if_index);
12523   mp->table_index = ntohl (table_index);
12524   mp->is_ipv6 = is_ipv6;
12525
12526   S (mp);
12527   W (ret);
12528   return ret;
12529 }
12530
12531 static int
12532 api_classify_set_interface_l2_tables (vat_main_t * vam)
12533 {
12534   unformat_input_t *i = vam->input;
12535   vl_api_classify_set_interface_l2_tables_t *mp;
12536   u32 sw_if_index;
12537   int sw_if_index_set;
12538   u32 ip4_table_index = ~0;
12539   u32 ip6_table_index = ~0;
12540   u32 other_table_index = ~0;
12541   u32 is_input = 1;
12542   int ret;
12543
12544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12545     {
12546       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12547         sw_if_index_set = 1;
12548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12549         sw_if_index_set = 1;
12550       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12551         ;
12552       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12553         ;
12554       else if (unformat (i, "other-table %d", &other_table_index))
12555         ;
12556       else if (unformat (i, "is-input %d", &is_input))
12557         ;
12558       else
12559         {
12560           clib_warning ("parse error '%U'", format_unformat_error, i);
12561           return -99;
12562         }
12563     }
12564
12565   if (sw_if_index_set == 0)
12566     {
12567       errmsg ("missing interface name or sw_if_index");
12568       return -99;
12569     }
12570
12571
12572   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
12573
12574   mp->sw_if_index = ntohl (sw_if_index);
12575   mp->ip4_table_index = ntohl (ip4_table_index);
12576   mp->ip6_table_index = ntohl (ip6_table_index);
12577   mp->other_table_index = ntohl (other_table_index);
12578   mp->is_input = (u8) is_input;
12579
12580   S (mp);
12581   W (ret);
12582   return ret;
12583 }
12584
12585 static int
12586 api_set_ipfix_exporter (vat_main_t * vam)
12587 {
12588   unformat_input_t *i = vam->input;
12589   vl_api_set_ipfix_exporter_t *mp;
12590   ip4_address_t collector_address;
12591   u8 collector_address_set = 0;
12592   u32 collector_port = ~0;
12593   ip4_address_t src_address;
12594   u8 src_address_set = 0;
12595   u32 vrf_id = ~0;
12596   u32 path_mtu = ~0;
12597   u32 template_interval = ~0;
12598   u8 udp_checksum = 0;
12599   int ret;
12600
12601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12602     {
12603       if (unformat (i, "collector_address %U", unformat_ip4_address,
12604                     &collector_address))
12605         collector_address_set = 1;
12606       else if (unformat (i, "collector_port %d", &collector_port))
12607         ;
12608       else if (unformat (i, "src_address %U", unformat_ip4_address,
12609                          &src_address))
12610         src_address_set = 1;
12611       else if (unformat (i, "vrf_id %d", &vrf_id))
12612         ;
12613       else if (unformat (i, "path_mtu %d", &path_mtu))
12614         ;
12615       else if (unformat (i, "template_interval %d", &template_interval))
12616         ;
12617       else if (unformat (i, "udp_checksum"))
12618         udp_checksum = 1;
12619       else
12620         break;
12621     }
12622
12623   if (collector_address_set == 0)
12624     {
12625       errmsg ("collector_address required");
12626       return -99;
12627     }
12628
12629   if (src_address_set == 0)
12630     {
12631       errmsg ("src_address required");
12632       return -99;
12633     }
12634
12635   M (SET_IPFIX_EXPORTER, mp);
12636
12637   memcpy (mp->collector_address, collector_address.data,
12638           sizeof (collector_address.data));
12639   mp->collector_port = htons ((u16) collector_port);
12640   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
12641   mp->vrf_id = htonl (vrf_id);
12642   mp->path_mtu = htonl (path_mtu);
12643   mp->template_interval = htonl (template_interval);
12644   mp->udp_checksum = udp_checksum;
12645
12646   S (mp);
12647   W (ret);
12648   return ret;
12649 }
12650
12651 static int
12652 api_set_ipfix_classify_stream (vat_main_t * vam)
12653 {
12654   unformat_input_t *i = vam->input;
12655   vl_api_set_ipfix_classify_stream_t *mp;
12656   u32 domain_id = 0;
12657   u32 src_port = UDP_DST_PORT_ipfix;
12658   int ret;
12659
12660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12661     {
12662       if (unformat (i, "domain %d", &domain_id))
12663         ;
12664       else if (unformat (i, "src_port %d", &src_port))
12665         ;
12666       else
12667         {
12668           errmsg ("unknown input `%U'", format_unformat_error, i);
12669           return -99;
12670         }
12671     }
12672
12673   M (SET_IPFIX_CLASSIFY_STREAM, mp);
12674
12675   mp->domain_id = htonl (domain_id);
12676   mp->src_port = htons ((u16) src_port);
12677
12678   S (mp);
12679   W (ret);
12680   return ret;
12681 }
12682
12683 static int
12684 api_ipfix_classify_table_add_del (vat_main_t * vam)
12685 {
12686   unformat_input_t *i = vam->input;
12687   vl_api_ipfix_classify_table_add_del_t *mp;
12688   int is_add = -1;
12689   u32 classify_table_index = ~0;
12690   u8 ip_version = 0;
12691   u8 transport_protocol = 255;
12692   int ret;
12693
12694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12695     {
12696       if (unformat (i, "add"))
12697         is_add = 1;
12698       else if (unformat (i, "del"))
12699         is_add = 0;
12700       else if (unformat (i, "table %d", &classify_table_index))
12701         ;
12702       else if (unformat (i, "ip4"))
12703         ip_version = 4;
12704       else if (unformat (i, "ip6"))
12705         ip_version = 6;
12706       else if (unformat (i, "tcp"))
12707         transport_protocol = 6;
12708       else if (unformat (i, "udp"))
12709         transport_protocol = 17;
12710       else
12711         {
12712           errmsg ("unknown input `%U'", format_unformat_error, i);
12713           return -99;
12714         }
12715     }
12716
12717   if (is_add == -1)
12718     {
12719       errmsg ("expecting: add|del");
12720       return -99;
12721     }
12722   if (classify_table_index == ~0)
12723     {
12724       errmsg ("classifier table not specified");
12725       return -99;
12726     }
12727   if (ip_version == 0)
12728     {
12729       errmsg ("IP version not specified");
12730       return -99;
12731     }
12732
12733   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
12734
12735   mp->is_add = is_add;
12736   mp->table_id = htonl (classify_table_index);
12737   mp->ip_version = ip_version;
12738   mp->transport_protocol = transport_protocol;
12739
12740   S (mp);
12741   W (ret);
12742   return ret;
12743 }
12744
12745 static int
12746 api_get_node_index (vat_main_t * vam)
12747 {
12748   unformat_input_t *i = vam->input;
12749   vl_api_get_node_index_t *mp;
12750   u8 *name = 0;
12751   int ret;
12752
12753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12754     {
12755       if (unformat (i, "node %s", &name))
12756         ;
12757       else
12758         break;
12759     }
12760   if (name == 0)
12761     {
12762       errmsg ("node name required");
12763       return -99;
12764     }
12765   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12766     {
12767       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12768       return -99;
12769     }
12770
12771   M (GET_NODE_INDEX, mp);
12772   clib_memcpy (mp->node_name, name, vec_len (name));
12773   vec_free (name);
12774
12775   S (mp);
12776   W (ret);
12777   return ret;
12778 }
12779
12780 static int
12781 api_get_next_index (vat_main_t * vam)
12782 {
12783   unformat_input_t *i = vam->input;
12784   vl_api_get_next_index_t *mp;
12785   u8 *node_name = 0, *next_node_name = 0;
12786   int ret;
12787
12788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12789     {
12790       if (unformat (i, "node-name %s", &node_name))
12791         ;
12792       else if (unformat (i, "next-node-name %s", &next_node_name))
12793         break;
12794     }
12795
12796   if (node_name == 0)
12797     {
12798       errmsg ("node name required");
12799       return -99;
12800     }
12801   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
12802     {
12803       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12804       return -99;
12805     }
12806
12807   if (next_node_name == 0)
12808     {
12809       errmsg ("next node name required");
12810       return -99;
12811     }
12812   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
12813     {
12814       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
12815       return -99;
12816     }
12817
12818   M (GET_NEXT_INDEX, mp);
12819   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
12820   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
12821   vec_free (node_name);
12822   vec_free (next_node_name);
12823
12824   S (mp);
12825   W (ret);
12826   return ret;
12827 }
12828
12829 static int
12830 api_add_node_next (vat_main_t * vam)
12831 {
12832   unformat_input_t *i = vam->input;
12833   vl_api_add_node_next_t *mp;
12834   u8 *name = 0;
12835   u8 *next = 0;
12836   int ret;
12837
12838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12839     {
12840       if (unformat (i, "node %s", &name))
12841         ;
12842       else if (unformat (i, "next %s", &next))
12843         ;
12844       else
12845         break;
12846     }
12847   if (name == 0)
12848     {
12849       errmsg ("node name required");
12850       return -99;
12851     }
12852   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
12853     {
12854       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
12855       return -99;
12856     }
12857   if (next == 0)
12858     {
12859       errmsg ("next node required");
12860       return -99;
12861     }
12862   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
12863     {
12864       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
12865       return -99;
12866     }
12867
12868   M (ADD_NODE_NEXT, mp);
12869   clib_memcpy (mp->node_name, name, vec_len (name));
12870   clib_memcpy (mp->next_name, next, vec_len (next));
12871   vec_free (name);
12872   vec_free (next);
12873
12874   S (mp);
12875   W (ret);
12876   return ret;
12877 }
12878
12879 static int
12880 api_l2tpv3_create_tunnel (vat_main_t * vam)
12881 {
12882   unformat_input_t *i = vam->input;
12883   ip6_address_t client_address, our_address;
12884   int client_address_set = 0;
12885   int our_address_set = 0;
12886   u32 local_session_id = 0;
12887   u32 remote_session_id = 0;
12888   u64 local_cookie = 0;
12889   u64 remote_cookie = 0;
12890   u8 l2_sublayer_present = 0;
12891   vl_api_l2tpv3_create_tunnel_t *mp;
12892   int ret;
12893
12894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12895     {
12896       if (unformat (i, "client_address %U", unformat_ip6_address,
12897                     &client_address))
12898         client_address_set = 1;
12899       else if (unformat (i, "our_address %U", unformat_ip6_address,
12900                          &our_address))
12901         our_address_set = 1;
12902       else if (unformat (i, "local_session_id %d", &local_session_id))
12903         ;
12904       else if (unformat (i, "remote_session_id %d", &remote_session_id))
12905         ;
12906       else if (unformat (i, "local_cookie %lld", &local_cookie))
12907         ;
12908       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
12909         ;
12910       else if (unformat (i, "l2-sublayer-present"))
12911         l2_sublayer_present = 1;
12912       else
12913         break;
12914     }
12915
12916   if (client_address_set == 0)
12917     {
12918       errmsg ("client_address required");
12919       return -99;
12920     }
12921
12922   if (our_address_set == 0)
12923     {
12924       errmsg ("our_address required");
12925       return -99;
12926     }
12927
12928   M (L2TPV3_CREATE_TUNNEL, mp);
12929
12930   clib_memcpy (mp->client_address, client_address.as_u8,
12931                sizeof (mp->client_address));
12932
12933   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
12934
12935   mp->local_session_id = ntohl (local_session_id);
12936   mp->remote_session_id = ntohl (remote_session_id);
12937   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
12938   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
12939   mp->l2_sublayer_present = l2_sublayer_present;
12940   mp->is_ipv6 = 1;
12941
12942   S (mp);
12943   W (ret);
12944   return ret;
12945 }
12946
12947 static int
12948 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
12949 {
12950   unformat_input_t *i = vam->input;
12951   u32 sw_if_index;
12952   u8 sw_if_index_set = 0;
12953   u64 new_local_cookie = 0;
12954   u64 new_remote_cookie = 0;
12955   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
12956   int ret;
12957
12958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12961         sw_if_index_set = 1;
12962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12963         sw_if_index_set = 1;
12964       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12965         ;
12966       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12967         ;
12968       else
12969         break;
12970     }
12971
12972   if (sw_if_index_set == 0)
12973     {
12974       errmsg ("missing interface name or sw_if_index");
12975       return -99;
12976     }
12977
12978   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12979
12980   mp->sw_if_index = ntohl (sw_if_index);
12981   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12982   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12983
12984   S (mp);
12985   W (ret);
12986   return ret;
12987 }
12988
12989 static int
12990 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12991 {
12992   unformat_input_t *i = vam->input;
12993   vl_api_l2tpv3_interface_enable_disable_t *mp;
12994   u32 sw_if_index;
12995   u8 sw_if_index_set = 0;
12996   u8 enable_disable = 1;
12997   int ret;
12998
12999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13000     {
13001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13002         sw_if_index_set = 1;
13003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13004         sw_if_index_set = 1;
13005       else if (unformat (i, "enable"))
13006         enable_disable = 1;
13007       else if (unformat (i, "disable"))
13008         enable_disable = 0;
13009       else
13010         break;
13011     }
13012
13013   if (sw_if_index_set == 0)
13014     {
13015       errmsg ("missing interface name or sw_if_index");
13016       return -99;
13017     }
13018
13019   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
13020
13021   mp->sw_if_index = ntohl (sw_if_index);
13022   mp->enable_disable = enable_disable;
13023
13024   S (mp);
13025   W (ret);
13026   return ret;
13027 }
13028
13029 static int
13030 api_l2tpv3_set_lookup_key (vat_main_t * vam)
13031 {
13032   unformat_input_t *i = vam->input;
13033   vl_api_l2tpv3_set_lookup_key_t *mp;
13034   u8 key = ~0;
13035   int ret;
13036
13037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13038     {
13039       if (unformat (i, "lookup_v6_src"))
13040         key = L2T_LOOKUP_SRC_ADDRESS;
13041       else if (unformat (i, "lookup_v6_dst"))
13042         key = L2T_LOOKUP_DST_ADDRESS;
13043       else if (unformat (i, "lookup_session_id"))
13044         key = L2T_LOOKUP_SESSION_ID;
13045       else
13046         break;
13047     }
13048
13049   if (key == (u8) ~ 0)
13050     {
13051       errmsg ("l2tp session lookup key unset");
13052       return -99;
13053     }
13054
13055   M (L2TPV3_SET_LOOKUP_KEY, mp);
13056
13057   mp->key = key;
13058
13059   S (mp);
13060   W (ret);
13061   return ret;
13062 }
13063
13064 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
13065   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13066 {
13067   vat_main_t *vam = &vat_main;
13068
13069   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
13070          format_ip6_address, mp->our_address,
13071          format_ip6_address, mp->client_address,
13072          clib_net_to_host_u32 (mp->sw_if_index));
13073
13074   print (vam->ofp,
13075          "   local cookies %016llx %016llx remote cookie %016llx",
13076          clib_net_to_host_u64 (mp->local_cookie[0]),
13077          clib_net_to_host_u64 (mp->local_cookie[1]),
13078          clib_net_to_host_u64 (mp->remote_cookie));
13079
13080   print (vam->ofp, "   local session-id %d remote session-id %d",
13081          clib_net_to_host_u32 (mp->local_session_id),
13082          clib_net_to_host_u32 (mp->remote_session_id));
13083
13084   print (vam->ofp, "   l2 specific sublayer %s\n",
13085          mp->l2_sublayer_present ? "preset" : "absent");
13086
13087 }
13088
13089 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
13090   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
13091 {
13092   vat_main_t *vam = &vat_main;
13093   vat_json_node_t *node = NULL;
13094   struct in6_addr addr;
13095
13096   if (VAT_JSON_ARRAY != vam->json_tree.type)
13097     {
13098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13099       vat_json_init_array (&vam->json_tree);
13100     }
13101   node = vat_json_array_add (&vam->json_tree);
13102
13103   vat_json_init_object (node);
13104
13105   clib_memcpy (&addr, mp->our_address, sizeof (addr));
13106   vat_json_object_add_ip6 (node, "our_address", addr);
13107   clib_memcpy (&addr, mp->client_address, sizeof (addr));
13108   vat_json_object_add_ip6 (node, "client_address", addr);
13109
13110   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
13111   vat_json_init_array (lc);
13112   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
13113   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
13114   vat_json_object_add_uint (node, "remote_cookie",
13115                             clib_net_to_host_u64 (mp->remote_cookie));
13116
13117   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
13118   vat_json_object_add_uint (node, "local_session_id",
13119                             clib_net_to_host_u32 (mp->local_session_id));
13120   vat_json_object_add_uint (node, "remote_session_id",
13121                             clib_net_to_host_u32 (mp->remote_session_id));
13122   vat_json_object_add_string_copy (node, "l2_sublayer",
13123                                    mp->l2_sublayer_present ? (u8 *) "present"
13124                                    : (u8 *) "absent");
13125 }
13126
13127 static int
13128 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
13129 {
13130   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
13131   vl_api_control_ping_t *mp_ping;
13132   int ret;
13133
13134   /* Get list of l2tpv3-tunnel interfaces */
13135   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
13136   S (mp);
13137
13138   /* Use a control ping for synchronization */
13139   MPING (CONTROL_PING, mp_ping);
13140   S (mp_ping);
13141
13142   W (ret);
13143   return ret;
13144 }
13145
13146
13147 static void vl_api_sw_interface_tap_details_t_handler
13148   (vl_api_sw_interface_tap_details_t * mp)
13149 {
13150   vat_main_t *vam = &vat_main;
13151
13152   print (vam->ofp, "%-16s %d",
13153          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
13154 }
13155
13156 static void vl_api_sw_interface_tap_details_t_handler_json
13157   (vl_api_sw_interface_tap_details_t * mp)
13158 {
13159   vat_main_t *vam = &vat_main;
13160   vat_json_node_t *node = NULL;
13161
13162   if (VAT_JSON_ARRAY != vam->json_tree.type)
13163     {
13164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13165       vat_json_init_array (&vam->json_tree);
13166     }
13167   node = vat_json_array_add (&vam->json_tree);
13168
13169   vat_json_init_object (node);
13170   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13171   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13172 }
13173
13174 static int
13175 api_sw_interface_tap_dump (vat_main_t * vam)
13176 {
13177   vl_api_sw_interface_tap_dump_t *mp;
13178   vl_api_control_ping_t *mp_ping;
13179   int ret;
13180
13181   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
13182   /* Get list of tap interfaces */
13183   M (SW_INTERFACE_TAP_DUMP, mp);
13184   S (mp);
13185
13186   /* Use a control ping for synchronization */
13187   MPING (CONTROL_PING, mp_ping);
13188   S (mp_ping);
13189
13190   W (ret);
13191   return ret;
13192 }
13193
13194 static void vl_api_sw_interface_tap_v2_details_t_handler
13195   (vl_api_sw_interface_tap_v2_details_t * mp)
13196 {
13197   vat_main_t *vam = &vat_main;
13198
13199   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
13200                     mp->host_ip4_prefix_len);
13201   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
13202                     mp->host_ip6_prefix_len);
13203
13204   print (vam->ofp,
13205          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s",
13206          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
13207          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
13208          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
13209          mp->host_bridge, ip4, ip6);
13210
13211   vec_free (ip4);
13212   vec_free (ip6);
13213 }
13214
13215 static void vl_api_sw_interface_tap_v2_details_t_handler_json
13216   (vl_api_sw_interface_tap_v2_details_t * mp)
13217 {
13218   vat_main_t *vam = &vat_main;
13219   vat_json_node_t *node = NULL;
13220
13221   if (VAT_JSON_ARRAY != vam->json_tree.type)
13222     {
13223       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13224       vat_json_init_array (&vam->json_tree);
13225     }
13226   node = vat_json_array_add (&vam->json_tree);
13227
13228   vat_json_init_object (node);
13229   vat_json_object_add_uint (node, "id", ntohl (mp->id));
13230   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13231   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
13232   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
13233   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
13234   vat_json_object_add_string_copy (node, "host_mac_addr",
13235                                    format (0, "%U", format_ethernet_address,
13236                                            &mp->host_mac_addr));
13237   vat_json_object_add_string_copy (node, "host_namespace",
13238                                    mp->host_namespace);
13239   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
13240   vat_json_object_add_string_copy (node, "host_ip4_addr",
13241                                    format (0, "%U/%d", format_ip4_address,
13242                                            mp->host_ip4_addr,
13243                                            mp->host_ip4_prefix_len));
13244   vat_json_object_add_string_copy (node, "host_ip6_addr",
13245                                    format (0, "%U/%d", format_ip6_address,
13246                                            mp->host_ip6_addr,
13247                                            mp->host_ip6_prefix_len));
13248
13249 }
13250
13251 static int
13252 api_sw_interface_tap_v2_dump (vat_main_t * vam)
13253 {
13254   vl_api_sw_interface_tap_v2_dump_t *mp;
13255   vl_api_control_ping_t *mp_ping;
13256   int ret;
13257
13258   print (vam->ofp,
13259          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
13260          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
13261          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
13262          "host_ip6_addr");
13263
13264   /* Get list of tap interfaces */
13265   M (SW_INTERFACE_TAP_V2_DUMP, mp);
13266   S (mp);
13267
13268   /* Use a control ping for synchronization */
13269   MPING (CONTROL_PING, mp_ping);
13270   S (mp_ping);
13271
13272   W (ret);
13273   return ret;
13274 }
13275
13276 static int
13277 api_vxlan_offload_rx (vat_main_t * vam)
13278 {
13279   unformat_input_t *line_input = vam->input;
13280   vl_api_vxlan_offload_rx_t *mp;
13281   u32 hw_if_index = ~0, rx_if_index = ~0;
13282   u8 is_add = 1;
13283   int ret;
13284
13285   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13286     {
13287       if (unformat (line_input, "del"))
13288         is_add = 0;
13289       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
13290                          &hw_if_index))
13291         ;
13292       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
13293         ;
13294       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
13295                          &rx_if_index))
13296         ;
13297       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
13298         ;
13299       else
13300         {
13301           errmsg ("parse error '%U'", format_unformat_error, line_input);
13302           return -99;
13303         }
13304     }
13305
13306   if (hw_if_index == ~0)
13307     {
13308       errmsg ("no hw interface");
13309       return -99;
13310     }
13311
13312   if (rx_if_index == ~0)
13313     {
13314       errmsg ("no rx tunnel");
13315       return -99;
13316     }
13317
13318   M (VXLAN_OFFLOAD_RX, mp);
13319
13320   mp->hw_if_index = ntohl (hw_if_index);
13321   mp->sw_if_index = ntohl (rx_if_index);
13322   mp->enable = is_add;
13323
13324   S (mp);
13325   W (ret);
13326   return ret;
13327 }
13328
13329 static uword unformat_vxlan_decap_next
13330   (unformat_input_t * input, va_list * args)
13331 {
13332   u32 *result = va_arg (*args, u32 *);
13333   u32 tmp;
13334
13335   if (unformat (input, "l2"))
13336     *result = VXLAN_INPUT_NEXT_L2_INPUT;
13337   else if (unformat (input, "%d", &tmp))
13338     *result = tmp;
13339   else
13340     return 0;
13341   return 1;
13342 }
13343
13344 static int
13345 api_vxlan_add_del_tunnel (vat_main_t * vam)
13346 {
13347   unformat_input_t *line_input = vam->input;
13348   vl_api_vxlan_add_del_tunnel_t *mp;
13349   ip46_address_t src, dst;
13350   u8 is_add = 1;
13351   u8 ipv4_set = 0, ipv6_set = 0;
13352   u8 src_set = 0;
13353   u8 dst_set = 0;
13354   u8 grp_set = 0;
13355   u32 instance = ~0;
13356   u32 mcast_sw_if_index = ~0;
13357   u32 encap_vrf_id = 0;
13358   u32 decap_next_index = ~0;
13359   u32 vni = 0;
13360   int ret;
13361
13362   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13363   memset (&src, 0, sizeof src);
13364   memset (&dst, 0, sizeof dst);
13365
13366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13367     {
13368       if (unformat (line_input, "del"))
13369         is_add = 0;
13370       else if (unformat (line_input, "instance %d", &instance))
13371         ;
13372       else
13373         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13374         {
13375           ipv4_set = 1;
13376           src_set = 1;
13377         }
13378       else
13379         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13380         {
13381           ipv4_set = 1;
13382           dst_set = 1;
13383         }
13384       else
13385         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13386         {
13387           ipv6_set = 1;
13388           src_set = 1;
13389         }
13390       else
13391         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13392         {
13393           ipv6_set = 1;
13394           dst_set = 1;
13395         }
13396       else if (unformat (line_input, "group %U %U",
13397                          unformat_ip4_address, &dst.ip4,
13398                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13399         {
13400           grp_set = dst_set = 1;
13401           ipv4_set = 1;
13402         }
13403       else if (unformat (line_input, "group %U",
13404                          unformat_ip4_address, &dst.ip4))
13405         {
13406           grp_set = dst_set = 1;
13407           ipv4_set = 1;
13408         }
13409       else if (unformat (line_input, "group %U %U",
13410                          unformat_ip6_address, &dst.ip6,
13411                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13412         {
13413           grp_set = dst_set = 1;
13414           ipv6_set = 1;
13415         }
13416       else if (unformat (line_input, "group %U",
13417                          unformat_ip6_address, &dst.ip6))
13418         {
13419           grp_set = dst_set = 1;
13420           ipv6_set = 1;
13421         }
13422       else
13423         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13424         ;
13425       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13426         ;
13427       else if (unformat (line_input, "decap-next %U",
13428                          unformat_vxlan_decap_next, &decap_next_index))
13429         ;
13430       else if (unformat (line_input, "vni %d", &vni))
13431         ;
13432       else
13433         {
13434           errmsg ("parse error '%U'", format_unformat_error, line_input);
13435           return -99;
13436         }
13437     }
13438
13439   if (src_set == 0)
13440     {
13441       errmsg ("tunnel src address not specified");
13442       return -99;
13443     }
13444   if (dst_set == 0)
13445     {
13446       errmsg ("tunnel dst address not specified");
13447       return -99;
13448     }
13449
13450   if (grp_set && !ip46_address_is_multicast (&dst))
13451     {
13452       errmsg ("tunnel group address not multicast");
13453       return -99;
13454     }
13455   if (grp_set && mcast_sw_if_index == ~0)
13456     {
13457       errmsg ("tunnel nonexistent multicast device");
13458       return -99;
13459     }
13460   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13461     {
13462       errmsg ("tunnel dst address must be unicast");
13463       return -99;
13464     }
13465
13466
13467   if (ipv4_set && ipv6_set)
13468     {
13469       errmsg ("both IPv4 and IPv6 addresses specified");
13470       return -99;
13471     }
13472
13473   if ((vni == 0) || (vni >> 24))
13474     {
13475       errmsg ("vni not specified or out of range");
13476       return -99;
13477     }
13478
13479   M (VXLAN_ADD_DEL_TUNNEL, mp);
13480
13481   if (ipv6_set)
13482     {
13483       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
13484       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
13485     }
13486   else
13487     {
13488       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
13489       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
13490     }
13491
13492   mp->instance = htonl (instance);
13493   mp->encap_vrf_id = ntohl (encap_vrf_id);
13494   mp->decap_next_index = ntohl (decap_next_index);
13495   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13496   mp->vni = ntohl (vni);
13497   mp->is_add = is_add;
13498   mp->is_ipv6 = ipv6_set;
13499
13500   S (mp);
13501   W (ret);
13502   return ret;
13503 }
13504
13505 static void vl_api_vxlan_tunnel_details_t_handler
13506   (vl_api_vxlan_tunnel_details_t * mp)
13507 {
13508   vat_main_t *vam = &vat_main;
13509   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13510   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13511
13512   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
13513          ntohl (mp->sw_if_index),
13514          ntohl (mp->instance),
13515          format_ip46_address, &src, IP46_TYPE_ANY,
13516          format_ip46_address, &dst, IP46_TYPE_ANY,
13517          ntohl (mp->encap_vrf_id),
13518          ntohl (mp->decap_next_index), ntohl (mp->vni),
13519          ntohl (mp->mcast_sw_if_index));
13520 }
13521
13522 static void vl_api_vxlan_tunnel_details_t_handler_json
13523   (vl_api_vxlan_tunnel_details_t * mp)
13524 {
13525   vat_main_t *vam = &vat_main;
13526   vat_json_node_t *node = NULL;
13527
13528   if (VAT_JSON_ARRAY != vam->json_tree.type)
13529     {
13530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13531       vat_json_init_array (&vam->json_tree);
13532     }
13533   node = vat_json_array_add (&vam->json_tree);
13534
13535   vat_json_init_object (node);
13536   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13537
13538   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
13539
13540   if (mp->is_ipv6)
13541     {
13542       struct in6_addr ip6;
13543
13544       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13545       vat_json_object_add_ip6 (node, "src_address", ip6);
13546       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13547       vat_json_object_add_ip6 (node, "dst_address", ip6);
13548     }
13549   else
13550     {
13551       struct in_addr ip4;
13552
13553       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13554       vat_json_object_add_ip4 (node, "src_address", ip4);
13555       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13556       vat_json_object_add_ip4 (node, "dst_address", ip4);
13557     }
13558   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13559   vat_json_object_add_uint (node, "decap_next_index",
13560                             ntohl (mp->decap_next_index));
13561   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13562   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13563   vat_json_object_add_uint (node, "mcast_sw_if_index",
13564                             ntohl (mp->mcast_sw_if_index));
13565 }
13566
13567 static int
13568 api_vxlan_tunnel_dump (vat_main_t * vam)
13569 {
13570   unformat_input_t *i = vam->input;
13571   vl_api_vxlan_tunnel_dump_t *mp;
13572   vl_api_control_ping_t *mp_ping;
13573   u32 sw_if_index;
13574   u8 sw_if_index_set = 0;
13575   int ret;
13576
13577   /* Parse args required to build the message */
13578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat (i, "sw_if_index %d", &sw_if_index))
13581         sw_if_index_set = 1;
13582       else
13583         break;
13584     }
13585
13586   if (sw_if_index_set == 0)
13587     {
13588       sw_if_index = ~0;
13589     }
13590
13591   if (!vam->json_output)
13592     {
13593       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
13594              "sw_if_index", "instance", "src_address", "dst_address",
13595              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13596     }
13597
13598   /* Get list of vxlan-tunnel interfaces */
13599   M (VXLAN_TUNNEL_DUMP, mp);
13600
13601   mp->sw_if_index = htonl (sw_if_index);
13602
13603   S (mp);
13604
13605   /* Use a control ping for synchronization */
13606   MPING (CONTROL_PING, mp_ping);
13607   S (mp_ping);
13608
13609   W (ret);
13610   return ret;
13611 }
13612
13613 static uword unformat_geneve_decap_next
13614   (unformat_input_t * input, va_list * args)
13615 {
13616   u32 *result = va_arg (*args, u32 *);
13617   u32 tmp;
13618
13619   if (unformat (input, "l2"))
13620     *result = GENEVE_INPUT_NEXT_L2_INPUT;
13621   else if (unformat (input, "%d", &tmp))
13622     *result = tmp;
13623   else
13624     return 0;
13625   return 1;
13626 }
13627
13628 static int
13629 api_geneve_add_del_tunnel (vat_main_t * vam)
13630 {
13631   unformat_input_t *line_input = vam->input;
13632   vl_api_geneve_add_del_tunnel_t *mp;
13633   ip46_address_t src, dst;
13634   u8 is_add = 1;
13635   u8 ipv4_set = 0, ipv6_set = 0;
13636   u8 src_set = 0;
13637   u8 dst_set = 0;
13638   u8 grp_set = 0;
13639   u32 mcast_sw_if_index = ~0;
13640   u32 encap_vrf_id = 0;
13641   u32 decap_next_index = ~0;
13642   u32 vni = 0;
13643   int ret;
13644
13645   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13646   memset (&src, 0, sizeof src);
13647   memset (&dst, 0, sizeof dst);
13648
13649   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13650     {
13651       if (unformat (line_input, "del"))
13652         is_add = 0;
13653       else
13654         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
13655         {
13656           ipv4_set = 1;
13657           src_set = 1;
13658         }
13659       else
13660         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
13661         {
13662           ipv4_set = 1;
13663           dst_set = 1;
13664         }
13665       else
13666         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
13667         {
13668           ipv6_set = 1;
13669           src_set = 1;
13670         }
13671       else
13672         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
13673         {
13674           ipv6_set = 1;
13675           dst_set = 1;
13676         }
13677       else if (unformat (line_input, "group %U %U",
13678                          unformat_ip4_address, &dst.ip4,
13679                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13680         {
13681           grp_set = dst_set = 1;
13682           ipv4_set = 1;
13683         }
13684       else if (unformat (line_input, "group %U",
13685                          unformat_ip4_address, &dst.ip4))
13686         {
13687           grp_set = dst_set = 1;
13688           ipv4_set = 1;
13689         }
13690       else if (unformat (line_input, "group %U %U",
13691                          unformat_ip6_address, &dst.ip6,
13692                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13693         {
13694           grp_set = dst_set = 1;
13695           ipv6_set = 1;
13696         }
13697       else if (unformat (line_input, "group %U",
13698                          unformat_ip6_address, &dst.ip6))
13699         {
13700           grp_set = dst_set = 1;
13701           ipv6_set = 1;
13702         }
13703       else
13704         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13705         ;
13706       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13707         ;
13708       else if (unformat (line_input, "decap-next %U",
13709                          unformat_geneve_decap_next, &decap_next_index))
13710         ;
13711       else if (unformat (line_input, "vni %d", &vni))
13712         ;
13713       else
13714         {
13715           errmsg ("parse error '%U'", format_unformat_error, line_input);
13716           return -99;
13717         }
13718     }
13719
13720   if (src_set == 0)
13721     {
13722       errmsg ("tunnel src address not specified");
13723       return -99;
13724     }
13725   if (dst_set == 0)
13726     {
13727       errmsg ("tunnel dst address not specified");
13728       return -99;
13729     }
13730
13731   if (grp_set && !ip46_address_is_multicast (&dst))
13732     {
13733       errmsg ("tunnel group address not multicast");
13734       return -99;
13735     }
13736   if (grp_set && mcast_sw_if_index == ~0)
13737     {
13738       errmsg ("tunnel nonexistent multicast device");
13739       return -99;
13740     }
13741   if (grp_set == 0 && ip46_address_is_multicast (&dst))
13742     {
13743       errmsg ("tunnel dst address must be unicast");
13744       return -99;
13745     }
13746
13747
13748   if (ipv4_set && ipv6_set)
13749     {
13750       errmsg ("both IPv4 and IPv6 addresses specified");
13751       return -99;
13752     }
13753
13754   if ((vni == 0) || (vni >> 24))
13755     {
13756       errmsg ("vni not specified or out of range");
13757       return -99;
13758     }
13759
13760   M (GENEVE_ADD_DEL_TUNNEL, mp);
13761
13762   if (ipv6_set)
13763     {
13764       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
13765       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
13766     }
13767   else
13768     {
13769       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
13770       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
13771     }
13772   mp->encap_vrf_id = ntohl (encap_vrf_id);
13773   mp->decap_next_index = ntohl (decap_next_index);
13774   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13775   mp->vni = ntohl (vni);
13776   mp->is_add = is_add;
13777   mp->is_ipv6 = ipv6_set;
13778
13779   S (mp);
13780   W (ret);
13781   return ret;
13782 }
13783
13784 static void vl_api_geneve_tunnel_details_t_handler
13785   (vl_api_geneve_tunnel_details_t * mp)
13786 {
13787   vat_main_t *vam = &vat_main;
13788   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
13789   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
13790
13791   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
13792          ntohl (mp->sw_if_index),
13793          format_ip46_address, &src, IP46_TYPE_ANY,
13794          format_ip46_address, &dst, IP46_TYPE_ANY,
13795          ntohl (mp->encap_vrf_id),
13796          ntohl (mp->decap_next_index), ntohl (mp->vni),
13797          ntohl (mp->mcast_sw_if_index));
13798 }
13799
13800 static void vl_api_geneve_tunnel_details_t_handler_json
13801   (vl_api_geneve_tunnel_details_t * mp)
13802 {
13803   vat_main_t *vam = &vat_main;
13804   vat_json_node_t *node = NULL;
13805
13806   if (VAT_JSON_ARRAY != vam->json_tree.type)
13807     {
13808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13809       vat_json_init_array (&vam->json_tree);
13810     }
13811   node = vat_json_array_add (&vam->json_tree);
13812
13813   vat_json_init_object (node);
13814   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13815   if (mp->is_ipv6)
13816     {
13817       struct in6_addr ip6;
13818
13819       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
13820       vat_json_object_add_ip6 (node, "src_address", ip6);
13821       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
13822       vat_json_object_add_ip6 (node, "dst_address", ip6);
13823     }
13824   else
13825     {
13826       struct in_addr ip4;
13827
13828       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
13829       vat_json_object_add_ip4 (node, "src_address", ip4);
13830       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
13831       vat_json_object_add_ip4 (node, "dst_address", ip4);
13832     }
13833   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13834   vat_json_object_add_uint (node, "decap_next_index",
13835                             ntohl (mp->decap_next_index));
13836   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13837   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13838   vat_json_object_add_uint (node, "mcast_sw_if_index",
13839                             ntohl (mp->mcast_sw_if_index));
13840 }
13841
13842 static int
13843 api_geneve_tunnel_dump (vat_main_t * vam)
13844 {
13845   unformat_input_t *i = vam->input;
13846   vl_api_geneve_tunnel_dump_t *mp;
13847   vl_api_control_ping_t *mp_ping;
13848   u32 sw_if_index;
13849   u8 sw_if_index_set = 0;
13850   int ret;
13851
13852   /* Parse args required to build the message */
13853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13854     {
13855       if (unformat (i, "sw_if_index %d", &sw_if_index))
13856         sw_if_index_set = 1;
13857       else
13858         break;
13859     }
13860
13861   if (sw_if_index_set == 0)
13862     {
13863       sw_if_index = ~0;
13864     }
13865
13866   if (!vam->json_output)
13867     {
13868       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
13869              "sw_if_index", "local_address", "remote_address",
13870              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
13871     }
13872
13873   /* Get list of geneve-tunnel interfaces */
13874   M (GENEVE_TUNNEL_DUMP, mp);
13875
13876   mp->sw_if_index = htonl (sw_if_index);
13877
13878   S (mp);
13879
13880   /* Use a control ping for synchronization */
13881   M (CONTROL_PING, mp_ping);
13882   S (mp_ping);
13883
13884   W (ret);
13885   return ret;
13886 }
13887
13888 static int
13889 api_gre_add_del_tunnel (vat_main_t * vam)
13890 {
13891   unformat_input_t *line_input = vam->input;
13892   vl_api_gre_add_del_tunnel_t *mp;
13893   ip4_address_t src4, dst4;
13894   ip6_address_t src6, dst6;
13895   u8 is_add = 1;
13896   u8 ipv4_set = 0;
13897   u8 ipv6_set = 0;
13898   u8 t_type = GRE_TUNNEL_TYPE_L3;
13899   u8 src_set = 0;
13900   u8 dst_set = 0;
13901   u32 outer_fib_id = 0;
13902   u32 session_id = 0;
13903   u32 instance = ~0;
13904   int ret;
13905
13906   memset (&src4, 0, sizeof src4);
13907   memset (&dst4, 0, sizeof dst4);
13908   memset (&src6, 0, sizeof src6);
13909   memset (&dst6, 0, sizeof dst6);
13910
13911   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13912     {
13913       if (unformat (line_input, "del"))
13914         is_add = 0;
13915       else if (unformat (line_input, "instance %d", &instance))
13916         ;
13917       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
13918         {
13919           src_set = 1;
13920           ipv4_set = 1;
13921         }
13922       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
13923         {
13924           dst_set = 1;
13925           ipv4_set = 1;
13926         }
13927       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
13928         {
13929           src_set = 1;
13930           ipv6_set = 1;
13931         }
13932       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
13933         {
13934           dst_set = 1;
13935           ipv6_set = 1;
13936         }
13937       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
13938         ;
13939       else if (unformat (line_input, "teb"))
13940         t_type = GRE_TUNNEL_TYPE_TEB;
13941       else if (unformat (line_input, "erspan %d", &session_id))
13942         t_type = GRE_TUNNEL_TYPE_ERSPAN;
13943       else
13944         {
13945           errmsg ("parse error '%U'", format_unformat_error, line_input);
13946           return -99;
13947         }
13948     }
13949
13950   if (src_set == 0)
13951     {
13952       errmsg ("tunnel src address not specified");
13953       return -99;
13954     }
13955   if (dst_set == 0)
13956     {
13957       errmsg ("tunnel dst address not specified");
13958       return -99;
13959     }
13960   if (ipv4_set && ipv6_set)
13961     {
13962       errmsg ("both IPv4 and IPv6 addresses specified");
13963       return -99;
13964     }
13965
13966
13967   M (GRE_ADD_DEL_TUNNEL, mp);
13968
13969   if (ipv4_set)
13970     {
13971       clib_memcpy (&mp->src_address, &src4, 4);
13972       clib_memcpy (&mp->dst_address, &dst4, 4);
13973     }
13974   else
13975     {
13976       clib_memcpy (&mp->src_address, &src6, 16);
13977       clib_memcpy (&mp->dst_address, &dst6, 16);
13978     }
13979   mp->instance = htonl (instance);
13980   mp->outer_fib_id = htonl (outer_fib_id);
13981   mp->is_add = is_add;
13982   mp->session_id = htons ((u16) session_id);
13983   mp->tunnel_type = t_type;
13984   mp->is_ipv6 = ipv6_set;
13985
13986   S (mp);
13987   W (ret);
13988   return ret;
13989 }
13990
13991 static void vl_api_gre_tunnel_details_t_handler
13992   (vl_api_gre_tunnel_details_t * mp)
13993 {
13994   vat_main_t *vam = &vat_main;
13995   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
13996   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
13997
13998   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
13999          ntohl (mp->sw_if_index),
14000          ntohl (mp->instance),
14001          format_ip46_address, &src, IP46_TYPE_ANY,
14002          format_ip46_address, &dst, IP46_TYPE_ANY,
14003          mp->tunnel_type, ntohl (mp->outer_fib_id), ntohl (mp->session_id));
14004 }
14005
14006 static void vl_api_gre_tunnel_details_t_handler_json
14007   (vl_api_gre_tunnel_details_t * mp)
14008 {
14009   vat_main_t *vam = &vat_main;
14010   vat_json_node_t *node = NULL;
14011   struct in_addr ip4;
14012   struct in6_addr ip6;
14013
14014   if (VAT_JSON_ARRAY != vam->json_tree.type)
14015     {
14016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14017       vat_json_init_array (&vam->json_tree);
14018     }
14019   node = vat_json_array_add (&vam->json_tree);
14020
14021   vat_json_init_object (node);
14022   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14023   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
14024   if (!mp->is_ipv6)
14025     {
14026       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14027       vat_json_object_add_ip4 (node, "src_address", ip4);
14028       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14029       vat_json_object_add_ip4 (node, "dst_address", ip4);
14030     }
14031   else
14032     {
14033       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
14034       vat_json_object_add_ip6 (node, "src_address", ip6);
14035       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
14036       vat_json_object_add_ip6 (node, "dst_address", ip6);
14037     }
14038   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel_type);
14039   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
14040   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
14041   vat_json_object_add_uint (node, "session_id", mp->session_id);
14042 }
14043
14044 static int
14045 api_gre_tunnel_dump (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_gre_tunnel_dump_t *mp;
14049   vl_api_control_ping_t *mp_ping;
14050   u32 sw_if_index;
14051   u8 sw_if_index_set = 0;
14052   int ret;
14053
14054   /* Parse args required to build the message */
14055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14056     {
14057       if (unformat (i, "sw_if_index %d", &sw_if_index))
14058         sw_if_index_set = 1;
14059       else
14060         break;
14061     }
14062
14063   if (sw_if_index_set == 0)
14064     {
14065       sw_if_index = ~0;
14066     }
14067
14068   if (!vam->json_output)
14069     {
14070       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
14071              "sw_if_index", "instance", "src_address", "dst_address",
14072              "tunnel_type", "outer_fib_id", "session_id");
14073     }
14074
14075   /* Get list of gre-tunnel interfaces */
14076   M (GRE_TUNNEL_DUMP, mp);
14077
14078   mp->sw_if_index = htonl (sw_if_index);
14079
14080   S (mp);
14081
14082   /* Use a control ping for synchronization */
14083   MPING (CONTROL_PING, mp_ping);
14084   S (mp_ping);
14085
14086   W (ret);
14087   return ret;
14088 }
14089
14090 static int
14091 api_l2_fib_clear_table (vat_main_t * vam)
14092 {
14093 //  unformat_input_t * i = vam->input;
14094   vl_api_l2_fib_clear_table_t *mp;
14095   int ret;
14096
14097   M (L2_FIB_CLEAR_TABLE, mp);
14098
14099   S (mp);
14100   W (ret);
14101   return ret;
14102 }
14103
14104 static int
14105 api_l2_interface_efp_filter (vat_main_t * vam)
14106 {
14107   unformat_input_t *i = vam->input;
14108   vl_api_l2_interface_efp_filter_t *mp;
14109   u32 sw_if_index;
14110   u8 enable = 1;
14111   u8 sw_if_index_set = 0;
14112   int ret;
14113
14114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14115     {
14116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14117         sw_if_index_set = 1;
14118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14119         sw_if_index_set = 1;
14120       else if (unformat (i, "enable"))
14121         enable = 1;
14122       else if (unformat (i, "disable"))
14123         enable = 0;
14124       else
14125         {
14126           clib_warning ("parse error '%U'", format_unformat_error, i);
14127           return -99;
14128         }
14129     }
14130
14131   if (sw_if_index_set == 0)
14132     {
14133       errmsg ("missing sw_if_index");
14134       return -99;
14135     }
14136
14137   M (L2_INTERFACE_EFP_FILTER, mp);
14138
14139   mp->sw_if_index = ntohl (sw_if_index);
14140   mp->enable_disable = enable;
14141
14142   S (mp);
14143   W (ret);
14144   return ret;
14145 }
14146
14147 #define foreach_vtr_op                          \
14148 _("disable",  L2_VTR_DISABLED)                  \
14149 _("push-1",  L2_VTR_PUSH_1)                     \
14150 _("push-2",  L2_VTR_PUSH_2)                     \
14151 _("pop-1",  L2_VTR_POP_1)                       \
14152 _("pop-2",  L2_VTR_POP_2)                       \
14153 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
14154 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
14155 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
14156 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
14157
14158 static int
14159 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
14160 {
14161   unformat_input_t *i = vam->input;
14162   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
14163   u32 sw_if_index;
14164   u8 sw_if_index_set = 0;
14165   u8 vtr_op_set = 0;
14166   u32 vtr_op = 0;
14167   u32 push_dot1q = 1;
14168   u32 tag1 = ~0;
14169   u32 tag2 = ~0;
14170   int ret;
14171
14172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14173     {
14174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14175         sw_if_index_set = 1;
14176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14177         sw_if_index_set = 1;
14178       else if (unformat (i, "vtr_op %d", &vtr_op))
14179         vtr_op_set = 1;
14180 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
14181       foreach_vtr_op
14182 #undef _
14183         else if (unformat (i, "push_dot1q %d", &push_dot1q))
14184         ;
14185       else if (unformat (i, "tag1 %d", &tag1))
14186         ;
14187       else if (unformat (i, "tag2 %d", &tag2))
14188         ;
14189       else
14190         {
14191           clib_warning ("parse error '%U'", format_unformat_error, i);
14192           return -99;
14193         }
14194     }
14195
14196   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
14197     {
14198       errmsg ("missing vtr operation or sw_if_index");
14199       return -99;
14200     }
14201
14202   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
14203   mp->sw_if_index = ntohl (sw_if_index);
14204   mp->vtr_op = ntohl (vtr_op);
14205   mp->push_dot1q = ntohl (push_dot1q);
14206   mp->tag1 = ntohl (tag1);
14207   mp->tag2 = ntohl (tag2);
14208
14209   S (mp);
14210   W (ret);
14211   return ret;
14212 }
14213
14214 static int
14215 api_create_vhost_user_if (vat_main_t * vam)
14216 {
14217   unformat_input_t *i = vam->input;
14218   vl_api_create_vhost_user_if_t *mp;
14219   u8 *file_name;
14220   u8 is_server = 0;
14221   u8 file_name_set = 0;
14222   u32 custom_dev_instance = ~0;
14223   u8 hwaddr[6];
14224   u8 use_custom_mac = 0;
14225   u8 disable_mrg_rxbuf = 0;
14226   u8 disable_indirect_desc = 0;
14227   u8 *tag = 0;
14228   int ret;
14229
14230   /* Shut up coverity */
14231   memset (hwaddr, 0, sizeof (hwaddr));
14232
14233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14234     {
14235       if (unformat (i, "socket %s", &file_name))
14236         {
14237           file_name_set = 1;
14238         }
14239       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14240         ;
14241       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
14242         use_custom_mac = 1;
14243       else if (unformat (i, "server"))
14244         is_server = 1;
14245       else if (unformat (i, "disable_mrg_rxbuf"))
14246         disable_mrg_rxbuf = 1;
14247       else if (unformat (i, "disable_indirect_desc"))
14248         disable_indirect_desc = 1;
14249       else if (unformat (i, "tag %s", &tag))
14250         ;
14251       else
14252         break;
14253     }
14254
14255   if (file_name_set == 0)
14256     {
14257       errmsg ("missing socket file name");
14258       return -99;
14259     }
14260
14261   if (vec_len (file_name) > 255)
14262     {
14263       errmsg ("socket file name too long");
14264       return -99;
14265     }
14266   vec_add1 (file_name, 0);
14267
14268   M (CREATE_VHOST_USER_IF, mp);
14269
14270   mp->is_server = is_server;
14271   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
14272   mp->disable_indirect_desc = disable_indirect_desc;
14273   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14274   vec_free (file_name);
14275   if (custom_dev_instance != ~0)
14276     {
14277       mp->renumber = 1;
14278       mp->custom_dev_instance = ntohl (custom_dev_instance);
14279     }
14280
14281   mp->use_custom_mac = use_custom_mac;
14282   clib_memcpy (mp->mac_address, hwaddr, 6);
14283   if (tag)
14284     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
14285   vec_free (tag);
14286
14287   S (mp);
14288   W (ret);
14289   return ret;
14290 }
14291
14292 static int
14293 api_modify_vhost_user_if (vat_main_t * vam)
14294 {
14295   unformat_input_t *i = vam->input;
14296   vl_api_modify_vhost_user_if_t *mp;
14297   u8 *file_name;
14298   u8 is_server = 0;
14299   u8 file_name_set = 0;
14300   u32 custom_dev_instance = ~0;
14301   u8 sw_if_index_set = 0;
14302   u32 sw_if_index = (u32) ~ 0;
14303   int ret;
14304
14305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14306     {
14307       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14308         sw_if_index_set = 1;
14309       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14310         sw_if_index_set = 1;
14311       else if (unformat (i, "socket %s", &file_name))
14312         {
14313           file_name_set = 1;
14314         }
14315       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
14316         ;
14317       else if (unformat (i, "server"))
14318         is_server = 1;
14319       else
14320         break;
14321     }
14322
14323   if (sw_if_index_set == 0)
14324     {
14325       errmsg ("missing sw_if_index or interface name");
14326       return -99;
14327     }
14328
14329   if (file_name_set == 0)
14330     {
14331       errmsg ("missing socket file name");
14332       return -99;
14333     }
14334
14335   if (vec_len (file_name) > 255)
14336     {
14337       errmsg ("socket file name too long");
14338       return -99;
14339     }
14340   vec_add1 (file_name, 0);
14341
14342   M (MODIFY_VHOST_USER_IF, mp);
14343
14344   mp->sw_if_index = ntohl (sw_if_index);
14345   mp->is_server = is_server;
14346   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
14347   vec_free (file_name);
14348   if (custom_dev_instance != ~0)
14349     {
14350       mp->renumber = 1;
14351       mp->custom_dev_instance = ntohl (custom_dev_instance);
14352     }
14353
14354   S (mp);
14355   W (ret);
14356   return ret;
14357 }
14358
14359 static int
14360 api_delete_vhost_user_if (vat_main_t * vam)
14361 {
14362   unformat_input_t *i = vam->input;
14363   vl_api_delete_vhost_user_if_t *mp;
14364   u32 sw_if_index = ~0;
14365   u8 sw_if_index_set = 0;
14366   int ret;
14367
14368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14369     {
14370       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14371         sw_if_index_set = 1;
14372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14373         sw_if_index_set = 1;
14374       else
14375         break;
14376     }
14377
14378   if (sw_if_index_set == 0)
14379     {
14380       errmsg ("missing sw_if_index or interface name");
14381       return -99;
14382     }
14383
14384
14385   M (DELETE_VHOST_USER_IF, mp);
14386
14387   mp->sw_if_index = ntohl (sw_if_index);
14388
14389   S (mp);
14390   W (ret);
14391   return ret;
14392 }
14393
14394 static void vl_api_sw_interface_vhost_user_details_t_handler
14395   (vl_api_sw_interface_vhost_user_details_t * mp)
14396 {
14397   vat_main_t *vam = &vat_main;
14398
14399   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
14400          (char *) mp->interface_name,
14401          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
14402          clib_net_to_host_u64 (mp->features), mp->is_server,
14403          ntohl (mp->num_regions), (char *) mp->sock_filename);
14404   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
14405 }
14406
14407 static void vl_api_sw_interface_vhost_user_details_t_handler_json
14408   (vl_api_sw_interface_vhost_user_details_t * mp)
14409 {
14410   vat_main_t *vam = &vat_main;
14411   vat_json_node_t *node = NULL;
14412
14413   if (VAT_JSON_ARRAY != vam->json_tree.type)
14414     {
14415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14416       vat_json_init_array (&vam->json_tree);
14417     }
14418   node = vat_json_array_add (&vam->json_tree);
14419
14420   vat_json_init_object (node);
14421   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14422   vat_json_object_add_string_copy (node, "interface_name",
14423                                    mp->interface_name);
14424   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
14425                             ntohl (mp->virtio_net_hdr_sz));
14426   vat_json_object_add_uint (node, "features",
14427                             clib_net_to_host_u64 (mp->features));
14428   vat_json_object_add_uint (node, "is_server", mp->is_server);
14429   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
14430   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
14431   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
14432 }
14433
14434 static int
14435 api_sw_interface_vhost_user_dump (vat_main_t * vam)
14436 {
14437   vl_api_sw_interface_vhost_user_dump_t *mp;
14438   vl_api_control_ping_t *mp_ping;
14439   int ret;
14440   print (vam->ofp,
14441          "Interface name            idx hdr_sz features server regions filename");
14442
14443   /* Get list of vhost-user interfaces */
14444   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
14445   S (mp);
14446
14447   /* Use a control ping for synchronization */
14448   MPING (CONTROL_PING, mp_ping);
14449   S (mp_ping);
14450
14451   W (ret);
14452   return ret;
14453 }
14454
14455 static int
14456 api_show_version (vat_main_t * vam)
14457 {
14458   vl_api_show_version_t *mp;
14459   int ret;
14460
14461   M (SHOW_VERSION, mp);
14462
14463   S (mp);
14464   W (ret);
14465   return ret;
14466 }
14467
14468
14469 static int
14470 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
14471 {
14472   unformat_input_t *line_input = vam->input;
14473   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
14474   ip4_address_t local4, remote4;
14475   ip6_address_t local6, remote6;
14476   u8 is_add = 1;
14477   u8 ipv4_set = 0, ipv6_set = 0;
14478   u8 local_set = 0;
14479   u8 remote_set = 0;
14480   u8 grp_set = 0;
14481   u32 mcast_sw_if_index = ~0;
14482   u32 encap_vrf_id = 0;
14483   u32 decap_vrf_id = 0;
14484   u8 protocol = ~0;
14485   u32 vni;
14486   u8 vni_set = 0;
14487   int ret;
14488
14489   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
14490   memset (&local4, 0, sizeof local4);
14491   memset (&remote4, 0, sizeof remote4);
14492   memset (&local6, 0, sizeof local6);
14493   memset (&remote6, 0, sizeof remote6);
14494
14495   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14496     {
14497       if (unformat (line_input, "del"))
14498         is_add = 0;
14499       else if (unformat (line_input, "local %U",
14500                          unformat_ip4_address, &local4))
14501         {
14502           local_set = 1;
14503           ipv4_set = 1;
14504         }
14505       else if (unformat (line_input, "remote %U",
14506                          unformat_ip4_address, &remote4))
14507         {
14508           remote_set = 1;
14509           ipv4_set = 1;
14510         }
14511       else if (unformat (line_input, "local %U",
14512                          unformat_ip6_address, &local6))
14513         {
14514           local_set = 1;
14515           ipv6_set = 1;
14516         }
14517       else if (unformat (line_input, "remote %U",
14518                          unformat_ip6_address, &remote6))
14519         {
14520           remote_set = 1;
14521           ipv6_set = 1;
14522         }
14523       else if (unformat (line_input, "group %U %U",
14524                          unformat_ip4_address, &remote4,
14525                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14526         {
14527           grp_set = remote_set = 1;
14528           ipv4_set = 1;
14529         }
14530       else if (unformat (line_input, "group %U",
14531                          unformat_ip4_address, &remote4))
14532         {
14533           grp_set = remote_set = 1;
14534           ipv4_set = 1;
14535         }
14536       else if (unformat (line_input, "group %U %U",
14537                          unformat_ip6_address, &remote6,
14538                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
14539         {
14540           grp_set = remote_set = 1;
14541           ipv6_set = 1;
14542         }
14543       else if (unformat (line_input, "group %U",
14544                          unformat_ip6_address, &remote6))
14545         {
14546           grp_set = remote_set = 1;
14547           ipv6_set = 1;
14548         }
14549       else
14550         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
14551         ;
14552       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
14553         ;
14554       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
14555         ;
14556       else if (unformat (line_input, "vni %d", &vni))
14557         vni_set = 1;
14558       else if (unformat (line_input, "next-ip4"))
14559         protocol = 1;
14560       else if (unformat (line_input, "next-ip6"))
14561         protocol = 2;
14562       else if (unformat (line_input, "next-ethernet"))
14563         protocol = 3;
14564       else if (unformat (line_input, "next-nsh"))
14565         protocol = 4;
14566       else
14567         {
14568           errmsg ("parse error '%U'", format_unformat_error, line_input);
14569           return -99;
14570         }
14571     }
14572
14573   if (local_set == 0)
14574     {
14575       errmsg ("tunnel local address not specified");
14576       return -99;
14577     }
14578   if (remote_set == 0)
14579     {
14580       errmsg ("tunnel remote address not specified");
14581       return -99;
14582     }
14583   if (grp_set && mcast_sw_if_index == ~0)
14584     {
14585       errmsg ("tunnel nonexistent multicast device");
14586       return -99;
14587     }
14588   if (ipv4_set && ipv6_set)
14589     {
14590       errmsg ("both IPv4 and IPv6 addresses specified");
14591       return -99;
14592     }
14593
14594   if (vni_set == 0)
14595     {
14596       errmsg ("vni not specified");
14597       return -99;
14598     }
14599
14600   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
14601
14602
14603   if (ipv6_set)
14604     {
14605       clib_memcpy (&mp->local, &local6, sizeof (local6));
14606       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
14607     }
14608   else
14609     {
14610       clib_memcpy (&mp->local, &local4, sizeof (local4));
14611       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
14612     }
14613
14614   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
14615   mp->encap_vrf_id = ntohl (encap_vrf_id);
14616   mp->decap_vrf_id = ntohl (decap_vrf_id);
14617   mp->protocol = protocol;
14618   mp->vni = ntohl (vni);
14619   mp->is_add = is_add;
14620   mp->is_ipv6 = ipv6_set;
14621
14622   S (mp);
14623   W (ret);
14624   return ret;
14625 }
14626
14627 static void vl_api_vxlan_gpe_tunnel_details_t_handler
14628   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14629 {
14630   vat_main_t *vam = &vat_main;
14631   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
14632   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
14633
14634   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
14635          ntohl (mp->sw_if_index),
14636          format_ip46_address, &local, IP46_TYPE_ANY,
14637          format_ip46_address, &remote, IP46_TYPE_ANY,
14638          ntohl (mp->vni), mp->protocol,
14639          ntohl (mp->mcast_sw_if_index),
14640          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
14641 }
14642
14643
14644 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
14645   (vl_api_vxlan_gpe_tunnel_details_t * mp)
14646 {
14647   vat_main_t *vam = &vat_main;
14648   vat_json_node_t *node = NULL;
14649   struct in_addr ip4;
14650   struct in6_addr ip6;
14651
14652   if (VAT_JSON_ARRAY != vam->json_tree.type)
14653     {
14654       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14655       vat_json_init_array (&vam->json_tree);
14656     }
14657   node = vat_json_array_add (&vam->json_tree);
14658
14659   vat_json_init_object (node);
14660   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14661   if (mp->is_ipv6)
14662     {
14663       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
14664       vat_json_object_add_ip6 (node, "local", ip6);
14665       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
14666       vat_json_object_add_ip6 (node, "remote", ip6);
14667     }
14668   else
14669     {
14670       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
14671       vat_json_object_add_ip4 (node, "local", ip4);
14672       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
14673       vat_json_object_add_ip4 (node, "remote", ip4);
14674     }
14675   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
14676   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
14677   vat_json_object_add_uint (node, "mcast_sw_if_index",
14678                             ntohl (mp->mcast_sw_if_index));
14679   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
14680   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
14681   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
14682 }
14683
14684 static int
14685 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
14686 {
14687   unformat_input_t *i = vam->input;
14688   vl_api_vxlan_gpe_tunnel_dump_t *mp;
14689   vl_api_control_ping_t *mp_ping;
14690   u32 sw_if_index;
14691   u8 sw_if_index_set = 0;
14692   int ret;
14693
14694   /* Parse args required to build the message */
14695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14696     {
14697       if (unformat (i, "sw_if_index %d", &sw_if_index))
14698         sw_if_index_set = 1;
14699       else
14700         break;
14701     }
14702
14703   if (sw_if_index_set == 0)
14704     {
14705       sw_if_index = ~0;
14706     }
14707
14708   if (!vam->json_output)
14709     {
14710       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
14711              "sw_if_index", "local", "remote", "vni",
14712              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
14713     }
14714
14715   /* Get list of vxlan-tunnel interfaces */
14716   M (VXLAN_GPE_TUNNEL_DUMP, mp);
14717
14718   mp->sw_if_index = htonl (sw_if_index);
14719
14720   S (mp);
14721
14722   /* Use a control ping for synchronization */
14723   MPING (CONTROL_PING, mp_ping);
14724   S (mp_ping);
14725
14726   W (ret);
14727   return ret;
14728 }
14729
14730 static void vl_api_l2_fib_table_details_t_handler
14731   (vl_api_l2_fib_table_details_t * mp)
14732 {
14733   vat_main_t *vam = &vat_main;
14734
14735   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
14736          "       %d       %d     %d",
14737          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
14738          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
14739          mp->bvi_mac);
14740 }
14741
14742 static void vl_api_l2_fib_table_details_t_handler_json
14743   (vl_api_l2_fib_table_details_t * mp)
14744 {
14745   vat_main_t *vam = &vat_main;
14746   vat_json_node_t *node = NULL;
14747
14748   if (VAT_JSON_ARRAY != vam->json_tree.type)
14749     {
14750       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14751       vat_json_init_array (&vam->json_tree);
14752     }
14753   node = vat_json_array_add (&vam->json_tree);
14754
14755   vat_json_init_object (node);
14756   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
14757   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
14758   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14759   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
14760   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
14761   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
14762 }
14763
14764 static int
14765 api_l2_fib_table_dump (vat_main_t * vam)
14766 {
14767   unformat_input_t *i = vam->input;
14768   vl_api_l2_fib_table_dump_t *mp;
14769   vl_api_control_ping_t *mp_ping;
14770   u32 bd_id;
14771   u8 bd_id_set = 0;
14772   int ret;
14773
14774   /* Parse args required to build the message */
14775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14776     {
14777       if (unformat (i, "bd_id %d", &bd_id))
14778         bd_id_set = 1;
14779       else
14780         break;
14781     }
14782
14783   if (bd_id_set == 0)
14784     {
14785       errmsg ("missing bridge domain");
14786       return -99;
14787     }
14788
14789   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
14790
14791   /* Get list of l2 fib entries */
14792   M (L2_FIB_TABLE_DUMP, mp);
14793
14794   mp->bd_id = ntohl (bd_id);
14795   S (mp);
14796
14797   /* Use a control ping for synchronization */
14798   MPING (CONTROL_PING, mp_ping);
14799   S (mp_ping);
14800
14801   W (ret);
14802   return ret;
14803 }
14804
14805
14806 static int
14807 api_interface_name_renumber (vat_main_t * vam)
14808 {
14809   unformat_input_t *line_input = vam->input;
14810   vl_api_interface_name_renumber_t *mp;
14811   u32 sw_if_index = ~0;
14812   u32 new_show_dev_instance = ~0;
14813   int ret;
14814
14815   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14816     {
14817       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
14818                     &sw_if_index))
14819         ;
14820       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14821         ;
14822       else if (unformat (line_input, "new_show_dev_instance %d",
14823                          &new_show_dev_instance))
14824         ;
14825       else
14826         break;
14827     }
14828
14829   if (sw_if_index == ~0)
14830     {
14831       errmsg ("missing interface name or sw_if_index");
14832       return -99;
14833     }
14834
14835   if (new_show_dev_instance == ~0)
14836     {
14837       errmsg ("missing new_show_dev_instance");
14838       return -99;
14839     }
14840
14841   M (INTERFACE_NAME_RENUMBER, mp);
14842
14843   mp->sw_if_index = ntohl (sw_if_index);
14844   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
14845
14846   S (mp);
14847   W (ret);
14848   return ret;
14849 }
14850
14851 static int
14852 api_ip_probe_neighbor (vat_main_t * vam)
14853 {
14854   unformat_input_t *i = vam->input;
14855   vl_api_ip_probe_neighbor_t *mp;
14856   u8 int_set = 0;
14857   u8 adr_set = 0;
14858   u8 is_ipv6 = 0;
14859   u8 dst_adr[16];
14860   u32 sw_if_index;
14861   int ret;
14862
14863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14864     {
14865       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14866         int_set = 1;
14867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14868         int_set = 1;
14869       else if (unformat (i, "address %U", unformat_ip4_address, dst_adr))
14870         adr_set = 1;
14871       else if (unformat (i, "address %U", unformat_ip6_address, dst_adr))
14872         {
14873           adr_set = 1;
14874           is_ipv6 = 1;
14875         }
14876       else
14877         break;
14878     }
14879
14880   if (int_set == 0)
14881     {
14882       errmsg ("missing interface");
14883       return -99;
14884     }
14885
14886   if (adr_set == 0)
14887     {
14888       errmsg ("missing addresses");
14889       return -99;
14890     }
14891
14892   M (IP_PROBE_NEIGHBOR, mp);
14893
14894   mp->sw_if_index = ntohl (sw_if_index);
14895   mp->is_ipv6 = is_ipv6;
14896   clib_memcpy (mp->dst_address, dst_adr, sizeof (dst_adr));
14897
14898   S (mp);
14899   W (ret);
14900   return ret;
14901 }
14902
14903 static int
14904 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
14905 {
14906   unformat_input_t *i = vam->input;
14907   vl_api_ip_scan_neighbor_enable_disable_t *mp;
14908   u8 mode = IP_SCAN_V46_NEIGHBORS;
14909   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
14910   int ret;
14911
14912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14913     {
14914       if (unformat (i, "ip4"))
14915         mode = IP_SCAN_V4_NEIGHBORS;
14916       else if (unformat (i, "ip6"))
14917         mode = IP_SCAN_V6_NEIGHBORS;
14918       if (unformat (i, "both"))
14919         mode = IP_SCAN_V46_NEIGHBORS;
14920       else if (unformat (i, "disable"))
14921         mode = IP_SCAN_DISABLED;
14922       else if (unformat (i, "interval %d", &interval))
14923         ;
14924       else if (unformat (i, "max-time %d", &time))
14925         ;
14926       else if (unformat (i, "max-update %d", &update))
14927         ;
14928       else if (unformat (i, "delay %d", &delay))
14929         ;
14930       else if (unformat (i, "stale %d", &stale))
14931         ;
14932       else
14933         break;
14934     }
14935
14936   if (interval > 255)
14937     {
14938       errmsg ("interval cannot exceed 255 minutes.");
14939       return -99;
14940     }
14941   if (time > 255)
14942     {
14943       errmsg ("max-time cannot exceed 255 usec.");
14944       return -99;
14945     }
14946   if (update > 255)
14947     {
14948       errmsg ("max-update cannot exceed 255.");
14949       return -99;
14950     }
14951   if (delay > 255)
14952     {
14953       errmsg ("delay cannot exceed 255 msec.");
14954       return -99;
14955     }
14956   if (stale > 255)
14957     {
14958       errmsg ("stale cannot exceed 255 minutes.");
14959       return -99;
14960     }
14961
14962   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
14963   mp->mode = mode;
14964   mp->scan_interval = interval;
14965   mp->max_proc_time = time;
14966   mp->max_update = update;
14967   mp->scan_int_delay = delay;
14968   mp->stale_threshold = stale;
14969
14970   S (mp);
14971   W (ret);
14972   return ret;
14973 }
14974
14975 static int
14976 api_want_ip4_arp_events (vat_main_t * vam)
14977 {
14978   unformat_input_t *line_input = vam->input;
14979   vl_api_want_ip4_arp_events_t *mp;
14980   ip4_address_t address;
14981   int address_set = 0;
14982   u32 enable_disable = 1;
14983   int ret;
14984
14985   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14986     {
14987       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
14988         address_set = 1;
14989       else if (unformat (line_input, "del"))
14990         enable_disable = 0;
14991       else
14992         break;
14993     }
14994
14995   if (address_set == 0)
14996     {
14997       errmsg ("missing addresses");
14998       return -99;
14999     }
15000
15001   M (WANT_IP4_ARP_EVENTS, mp);
15002   mp->enable_disable = enable_disable;
15003   mp->pid = htonl (getpid ());
15004   mp->address = address.as_u32;
15005
15006   S (mp);
15007   W (ret);
15008   return ret;
15009 }
15010
15011 static int
15012 api_want_ip6_nd_events (vat_main_t * vam)
15013 {
15014   unformat_input_t *line_input = vam->input;
15015   vl_api_want_ip6_nd_events_t *mp;
15016   ip6_address_t address;
15017   int address_set = 0;
15018   u32 enable_disable = 1;
15019   int ret;
15020
15021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
15024         address_set = 1;
15025       else if (unformat (line_input, "del"))
15026         enable_disable = 0;
15027       else
15028         break;
15029     }
15030
15031   if (address_set == 0)
15032     {
15033       errmsg ("missing addresses");
15034       return -99;
15035     }
15036
15037   M (WANT_IP6_ND_EVENTS, mp);
15038   mp->enable_disable = enable_disable;
15039   mp->pid = htonl (getpid ());
15040   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
15041
15042   S (mp);
15043   W (ret);
15044   return ret;
15045 }
15046
15047 static int
15048 api_want_l2_macs_events (vat_main_t * vam)
15049 {
15050   unformat_input_t *line_input = vam->input;
15051   vl_api_want_l2_macs_events_t *mp;
15052   u8 enable_disable = 1;
15053   u32 scan_delay = 0;
15054   u32 max_macs_in_event = 0;
15055   u32 learn_limit = 0;
15056   int ret;
15057
15058   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15059     {
15060       if (unformat (line_input, "learn-limit %d", &learn_limit))
15061         ;
15062       else if (unformat (line_input, "scan-delay %d", &scan_delay))
15063         ;
15064       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
15065         ;
15066       else if (unformat (line_input, "disable"))
15067         enable_disable = 0;
15068       else
15069         break;
15070     }
15071
15072   M (WANT_L2_MACS_EVENTS, mp);
15073   mp->enable_disable = enable_disable;
15074   mp->pid = htonl (getpid ());
15075   mp->learn_limit = htonl (learn_limit);
15076   mp->scan_delay = (u8) scan_delay;
15077   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
15078   S (mp);
15079   W (ret);
15080   return ret;
15081 }
15082
15083 static int
15084 api_input_acl_set_interface (vat_main_t * vam)
15085 {
15086   unformat_input_t *i = vam->input;
15087   vl_api_input_acl_set_interface_t *mp;
15088   u32 sw_if_index;
15089   int sw_if_index_set;
15090   u32 ip4_table_index = ~0;
15091   u32 ip6_table_index = ~0;
15092   u32 l2_table_index = ~0;
15093   u8 is_add = 1;
15094   int ret;
15095
15096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15097     {
15098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15099         sw_if_index_set = 1;
15100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15101         sw_if_index_set = 1;
15102       else if (unformat (i, "del"))
15103         is_add = 0;
15104       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15105         ;
15106       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15107         ;
15108       else if (unformat (i, "l2-table %d", &l2_table_index))
15109         ;
15110       else
15111         {
15112           clib_warning ("parse error '%U'", format_unformat_error, i);
15113           return -99;
15114         }
15115     }
15116
15117   if (sw_if_index_set == 0)
15118     {
15119       errmsg ("missing interface name or sw_if_index");
15120       return -99;
15121     }
15122
15123   M (INPUT_ACL_SET_INTERFACE, mp);
15124
15125   mp->sw_if_index = ntohl (sw_if_index);
15126   mp->ip4_table_index = ntohl (ip4_table_index);
15127   mp->ip6_table_index = ntohl (ip6_table_index);
15128   mp->l2_table_index = ntohl (l2_table_index);
15129   mp->is_add = is_add;
15130
15131   S (mp);
15132   W (ret);
15133   return ret;
15134 }
15135
15136 static int
15137 api_output_acl_set_interface (vat_main_t * vam)
15138 {
15139   unformat_input_t *i = vam->input;
15140   vl_api_output_acl_set_interface_t *mp;
15141   u32 sw_if_index;
15142   int sw_if_index_set;
15143   u32 ip4_table_index = ~0;
15144   u32 ip6_table_index = ~0;
15145   u32 l2_table_index = ~0;
15146   u8 is_add = 1;
15147   int ret;
15148
15149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15150     {
15151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15152         sw_if_index_set = 1;
15153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15154         sw_if_index_set = 1;
15155       else if (unformat (i, "del"))
15156         is_add = 0;
15157       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15158         ;
15159       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15160         ;
15161       else if (unformat (i, "l2-table %d", &l2_table_index))
15162         ;
15163       else
15164         {
15165           clib_warning ("parse error '%U'", format_unformat_error, i);
15166           return -99;
15167         }
15168     }
15169
15170   if (sw_if_index_set == 0)
15171     {
15172       errmsg ("missing interface name or sw_if_index");
15173       return -99;
15174     }
15175
15176   M (OUTPUT_ACL_SET_INTERFACE, mp);
15177
15178   mp->sw_if_index = ntohl (sw_if_index);
15179   mp->ip4_table_index = ntohl (ip4_table_index);
15180   mp->ip6_table_index = ntohl (ip6_table_index);
15181   mp->l2_table_index = ntohl (l2_table_index);
15182   mp->is_add = is_add;
15183
15184   S (mp);
15185   W (ret);
15186   return ret;
15187 }
15188
15189 static int
15190 api_ip_address_dump (vat_main_t * vam)
15191 {
15192   unformat_input_t *i = vam->input;
15193   vl_api_ip_address_dump_t *mp;
15194   vl_api_control_ping_t *mp_ping;
15195   u32 sw_if_index = ~0;
15196   u8 sw_if_index_set = 0;
15197   u8 ipv4_set = 0;
15198   u8 ipv6_set = 0;
15199   int ret;
15200
15201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15202     {
15203       if (unformat (i, "sw_if_index %d", &sw_if_index))
15204         sw_if_index_set = 1;
15205       else
15206         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15207         sw_if_index_set = 1;
15208       else if (unformat (i, "ipv4"))
15209         ipv4_set = 1;
15210       else if (unformat (i, "ipv6"))
15211         ipv6_set = 1;
15212       else
15213         break;
15214     }
15215
15216   if (ipv4_set && ipv6_set)
15217     {
15218       errmsg ("ipv4 and ipv6 flags cannot be both set");
15219       return -99;
15220     }
15221
15222   if ((!ipv4_set) && (!ipv6_set))
15223     {
15224       errmsg ("no ipv4 nor ipv6 flag set");
15225       return -99;
15226     }
15227
15228   if (sw_if_index_set == 0)
15229     {
15230       errmsg ("missing interface name or sw_if_index");
15231       return -99;
15232     }
15233
15234   vam->current_sw_if_index = sw_if_index;
15235   vam->is_ipv6 = ipv6_set;
15236
15237   M (IP_ADDRESS_DUMP, mp);
15238   mp->sw_if_index = ntohl (sw_if_index);
15239   mp->is_ipv6 = ipv6_set;
15240   S (mp);
15241
15242   /* Use a control ping for synchronization */
15243   MPING (CONTROL_PING, mp_ping);
15244   S (mp_ping);
15245
15246   W (ret);
15247   return ret;
15248 }
15249
15250 static int
15251 api_ip_dump (vat_main_t * vam)
15252 {
15253   vl_api_ip_dump_t *mp;
15254   vl_api_control_ping_t *mp_ping;
15255   unformat_input_t *in = vam->input;
15256   int ipv4_set = 0;
15257   int ipv6_set = 0;
15258   int is_ipv6;
15259   int i;
15260   int ret;
15261
15262   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
15263     {
15264       if (unformat (in, "ipv4"))
15265         ipv4_set = 1;
15266       else if (unformat (in, "ipv6"))
15267         ipv6_set = 1;
15268       else
15269         break;
15270     }
15271
15272   if (ipv4_set && ipv6_set)
15273     {
15274       errmsg ("ipv4 and ipv6 flags cannot be both set");
15275       return -99;
15276     }
15277
15278   if ((!ipv4_set) && (!ipv6_set))
15279     {
15280       errmsg ("no ipv4 nor ipv6 flag set");
15281       return -99;
15282     }
15283
15284   is_ipv6 = ipv6_set;
15285   vam->is_ipv6 = is_ipv6;
15286
15287   /* free old data */
15288   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
15289     {
15290       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
15291     }
15292   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
15293
15294   M (IP_DUMP, mp);
15295   mp->is_ipv6 = ipv6_set;
15296   S (mp);
15297
15298   /* Use a control ping for synchronization */
15299   MPING (CONTROL_PING, mp_ping);
15300   S (mp_ping);
15301
15302   W (ret);
15303   return ret;
15304 }
15305
15306 static int
15307 api_ipsec_spd_add_del (vat_main_t * vam)
15308 {
15309   unformat_input_t *i = vam->input;
15310   vl_api_ipsec_spd_add_del_t *mp;
15311   u32 spd_id = ~0;
15312   u8 is_add = 1;
15313   int ret;
15314
15315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15316     {
15317       if (unformat (i, "spd_id %d", &spd_id))
15318         ;
15319       else if (unformat (i, "del"))
15320         is_add = 0;
15321       else
15322         {
15323           clib_warning ("parse error '%U'", format_unformat_error, i);
15324           return -99;
15325         }
15326     }
15327   if (spd_id == ~0)
15328     {
15329       errmsg ("spd_id must be set");
15330       return -99;
15331     }
15332
15333   M (IPSEC_SPD_ADD_DEL, mp);
15334
15335   mp->spd_id = ntohl (spd_id);
15336   mp->is_add = is_add;
15337
15338   S (mp);
15339   W (ret);
15340   return ret;
15341 }
15342
15343 static int
15344 api_ipsec_interface_add_del_spd (vat_main_t * vam)
15345 {
15346   unformat_input_t *i = vam->input;
15347   vl_api_ipsec_interface_add_del_spd_t *mp;
15348   u32 sw_if_index;
15349   u8 sw_if_index_set = 0;
15350   u32 spd_id = (u32) ~ 0;
15351   u8 is_add = 1;
15352   int ret;
15353
15354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15355     {
15356       if (unformat (i, "del"))
15357         is_add = 0;
15358       else if (unformat (i, "spd_id %d", &spd_id))
15359         ;
15360       else
15361         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15362         sw_if_index_set = 1;
15363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15364         sw_if_index_set = 1;
15365       else
15366         {
15367           clib_warning ("parse error '%U'", format_unformat_error, i);
15368           return -99;
15369         }
15370
15371     }
15372
15373   if (spd_id == (u32) ~ 0)
15374     {
15375       errmsg ("spd_id must be set");
15376       return -99;
15377     }
15378
15379   if (sw_if_index_set == 0)
15380     {
15381       errmsg ("missing interface name or sw_if_index");
15382       return -99;
15383     }
15384
15385   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
15386
15387   mp->spd_id = ntohl (spd_id);
15388   mp->sw_if_index = ntohl (sw_if_index);
15389   mp->is_add = is_add;
15390
15391   S (mp);
15392   W (ret);
15393   return ret;
15394 }
15395
15396 static int
15397 api_ipsec_spd_add_del_entry (vat_main_t * vam)
15398 {
15399   unformat_input_t *i = vam->input;
15400   vl_api_ipsec_spd_add_del_entry_t *mp;
15401   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
15402   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
15403   i32 priority = 0;
15404   u32 rport_start = 0, rport_stop = (u32) ~ 0;
15405   u32 lport_start = 0, lport_stop = (u32) ~ 0;
15406   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
15407   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
15408   int ret;
15409
15410   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
15411   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
15412   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
15413   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
15414   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
15415   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
15416
15417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15418     {
15419       if (unformat (i, "del"))
15420         is_add = 0;
15421       if (unformat (i, "outbound"))
15422         is_outbound = 1;
15423       if (unformat (i, "inbound"))
15424         is_outbound = 0;
15425       else if (unformat (i, "spd_id %d", &spd_id))
15426         ;
15427       else if (unformat (i, "sa_id %d", &sa_id))
15428         ;
15429       else if (unformat (i, "priority %d", &priority))
15430         ;
15431       else if (unformat (i, "protocol %d", &protocol))
15432         ;
15433       else if (unformat (i, "lport_start %d", &lport_start))
15434         ;
15435       else if (unformat (i, "lport_stop %d", &lport_stop))
15436         ;
15437       else if (unformat (i, "rport_start %d", &rport_start))
15438         ;
15439       else if (unformat (i, "rport_stop %d", &rport_stop))
15440         ;
15441       else
15442         if (unformat
15443             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
15444         {
15445           is_ipv6 = 0;
15446           is_ip_any = 0;
15447         }
15448       else
15449         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
15450         {
15451           is_ipv6 = 0;
15452           is_ip_any = 0;
15453         }
15454       else
15455         if (unformat
15456             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
15457         {
15458           is_ipv6 = 0;
15459           is_ip_any = 0;
15460         }
15461       else
15462         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
15463         {
15464           is_ipv6 = 0;
15465           is_ip_any = 0;
15466         }
15467       else
15468         if (unformat
15469             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
15470         {
15471           is_ipv6 = 1;
15472           is_ip_any = 0;
15473         }
15474       else
15475         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
15476         {
15477           is_ipv6 = 1;
15478           is_ip_any = 0;
15479         }
15480       else
15481         if (unformat
15482             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
15483         {
15484           is_ipv6 = 1;
15485           is_ip_any = 0;
15486         }
15487       else
15488         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
15489         {
15490           is_ipv6 = 1;
15491           is_ip_any = 0;
15492         }
15493       else
15494         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
15495         {
15496           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
15497             {
15498               clib_warning ("unsupported action: 'resolve'");
15499               return -99;
15500             }
15501         }
15502       else
15503         {
15504           clib_warning ("parse error '%U'", format_unformat_error, i);
15505           return -99;
15506         }
15507
15508     }
15509
15510   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
15511
15512   mp->spd_id = ntohl (spd_id);
15513   mp->priority = ntohl (priority);
15514   mp->is_outbound = is_outbound;
15515
15516   mp->is_ipv6 = is_ipv6;
15517   if (is_ipv6 || is_ip_any)
15518     {
15519       clib_memcpy (mp->remote_address_start, &raddr6_start,
15520                    sizeof (ip6_address_t));
15521       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
15522                    sizeof (ip6_address_t));
15523       clib_memcpy (mp->local_address_start, &laddr6_start,
15524                    sizeof (ip6_address_t));
15525       clib_memcpy (mp->local_address_stop, &laddr6_stop,
15526                    sizeof (ip6_address_t));
15527     }
15528   else
15529     {
15530       clib_memcpy (mp->remote_address_start, &raddr4_start,
15531                    sizeof (ip4_address_t));
15532       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
15533                    sizeof (ip4_address_t));
15534       clib_memcpy (mp->local_address_start, &laddr4_start,
15535                    sizeof (ip4_address_t));
15536       clib_memcpy (mp->local_address_stop, &laddr4_stop,
15537                    sizeof (ip4_address_t));
15538     }
15539   mp->protocol = (u8) protocol;
15540   mp->local_port_start = ntohs ((u16) lport_start);
15541   mp->local_port_stop = ntohs ((u16) lport_stop);
15542   mp->remote_port_start = ntohs ((u16) rport_start);
15543   mp->remote_port_stop = ntohs ((u16) rport_stop);
15544   mp->policy = (u8) policy;
15545   mp->sa_id = ntohl (sa_id);
15546   mp->is_add = is_add;
15547   mp->is_ip_any = is_ip_any;
15548   S (mp);
15549   W (ret);
15550   return ret;
15551 }
15552
15553 static int
15554 api_ipsec_sad_add_del_entry (vat_main_t * vam)
15555 {
15556   unformat_input_t *i = vam->input;
15557   vl_api_ipsec_sad_add_del_entry_t *mp;
15558   u32 sad_id = 0, spi = 0;
15559   u8 *ck = 0, *ik = 0;
15560   u8 is_add = 1;
15561
15562   u8 protocol = IPSEC_PROTOCOL_AH;
15563   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
15564   u32 crypto_alg = 0, integ_alg = 0;
15565   ip4_address_t tun_src4;
15566   ip4_address_t tun_dst4;
15567   ip6_address_t tun_src6;
15568   ip6_address_t tun_dst6;
15569   int ret;
15570
15571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15572     {
15573       if (unformat (i, "del"))
15574         is_add = 0;
15575       else if (unformat (i, "sad_id %d", &sad_id))
15576         ;
15577       else if (unformat (i, "spi %d", &spi))
15578         ;
15579       else if (unformat (i, "esp"))
15580         protocol = IPSEC_PROTOCOL_ESP;
15581       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
15582         {
15583           is_tunnel = 1;
15584           is_tunnel_ipv6 = 0;
15585         }
15586       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
15587         {
15588           is_tunnel = 1;
15589           is_tunnel_ipv6 = 0;
15590         }
15591       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
15592         {
15593           is_tunnel = 1;
15594           is_tunnel_ipv6 = 1;
15595         }
15596       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
15597         {
15598           is_tunnel = 1;
15599           is_tunnel_ipv6 = 1;
15600         }
15601       else
15602         if (unformat
15603             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15604         {
15605           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15606             {
15607               clib_warning ("unsupported crypto-alg: '%U'",
15608                             format_ipsec_crypto_alg, crypto_alg);
15609               return -99;
15610             }
15611         }
15612       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15613         ;
15614       else
15615         if (unformat
15616             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15617         {
15618           if (integ_alg >= IPSEC_INTEG_N_ALG)
15619             {
15620               clib_warning ("unsupported integ-alg: '%U'",
15621                             format_ipsec_integ_alg, integ_alg);
15622               return -99;
15623             }
15624         }
15625       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15626         ;
15627       else
15628         {
15629           clib_warning ("parse error '%U'", format_unformat_error, i);
15630           return -99;
15631         }
15632
15633     }
15634
15635   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
15636
15637   mp->sad_id = ntohl (sad_id);
15638   mp->is_add = is_add;
15639   mp->protocol = protocol;
15640   mp->spi = ntohl (spi);
15641   mp->is_tunnel = is_tunnel;
15642   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
15643   mp->crypto_algorithm = crypto_alg;
15644   mp->integrity_algorithm = integ_alg;
15645   mp->crypto_key_length = vec_len (ck);
15646   mp->integrity_key_length = vec_len (ik);
15647
15648   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15649     mp->crypto_key_length = sizeof (mp->crypto_key);
15650
15651   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15652     mp->integrity_key_length = sizeof (mp->integrity_key);
15653
15654   if (ck)
15655     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15656   if (ik)
15657     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15658
15659   if (is_tunnel)
15660     {
15661       if (is_tunnel_ipv6)
15662         {
15663           clib_memcpy (mp->tunnel_src_address, &tun_src6,
15664                        sizeof (ip6_address_t));
15665           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
15666                        sizeof (ip6_address_t));
15667         }
15668       else
15669         {
15670           clib_memcpy (mp->tunnel_src_address, &tun_src4,
15671                        sizeof (ip4_address_t));
15672           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
15673                        sizeof (ip4_address_t));
15674         }
15675     }
15676
15677   S (mp);
15678   W (ret);
15679   return ret;
15680 }
15681
15682 static int
15683 api_ipsec_sa_set_key (vat_main_t * vam)
15684 {
15685   unformat_input_t *i = vam->input;
15686   vl_api_ipsec_sa_set_key_t *mp;
15687   u32 sa_id;
15688   u8 *ck = 0, *ik = 0;
15689   int ret;
15690
15691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15692     {
15693       if (unformat (i, "sa_id %d", &sa_id))
15694         ;
15695       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
15696         ;
15697       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
15698         ;
15699       else
15700         {
15701           clib_warning ("parse error '%U'", format_unformat_error, i);
15702           return -99;
15703         }
15704     }
15705
15706   M (IPSEC_SA_SET_KEY, mp);
15707
15708   mp->sa_id = ntohl (sa_id);
15709   mp->crypto_key_length = vec_len (ck);
15710   mp->integrity_key_length = vec_len (ik);
15711
15712   if (mp->crypto_key_length > sizeof (mp->crypto_key))
15713     mp->crypto_key_length = sizeof (mp->crypto_key);
15714
15715   if (mp->integrity_key_length > sizeof (mp->integrity_key))
15716     mp->integrity_key_length = sizeof (mp->integrity_key);
15717
15718   if (ck)
15719     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
15720   if (ik)
15721     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
15722
15723   S (mp);
15724   W (ret);
15725   return ret;
15726 }
15727
15728 static int
15729 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
15730 {
15731   unformat_input_t *i = vam->input;
15732   vl_api_ipsec_tunnel_if_add_del_t *mp;
15733   u32 local_spi = 0, remote_spi = 0;
15734   u32 crypto_alg = 0, integ_alg = 0;
15735   u8 *lck = NULL, *rck = NULL;
15736   u8 *lik = NULL, *rik = NULL;
15737   ip4_address_t local_ip = { {0} };
15738   ip4_address_t remote_ip = { {0} };
15739   u8 is_add = 1;
15740   u8 esn = 0;
15741   u8 anti_replay = 0;
15742   u8 renumber = 0;
15743   u32 instance = ~0;
15744   int ret;
15745
15746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15747     {
15748       if (unformat (i, "del"))
15749         is_add = 0;
15750       else if (unformat (i, "esn"))
15751         esn = 1;
15752       else if (unformat (i, "anti_replay"))
15753         anti_replay = 1;
15754       else if (unformat (i, "local_spi %d", &local_spi))
15755         ;
15756       else if (unformat (i, "remote_spi %d", &remote_spi))
15757         ;
15758       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
15759         ;
15760       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
15761         ;
15762       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
15763         ;
15764       else
15765         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
15766         ;
15767       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
15768         ;
15769       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
15770         ;
15771       else
15772         if (unformat
15773             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
15774         {
15775           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
15776             {
15777               errmsg ("unsupported crypto-alg: '%U'\n",
15778                       format_ipsec_crypto_alg, crypto_alg);
15779               return -99;
15780             }
15781         }
15782       else
15783         if (unformat
15784             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
15785         {
15786           if (integ_alg >= IPSEC_INTEG_N_ALG)
15787             {
15788               errmsg ("unsupported integ-alg: '%U'\n",
15789                       format_ipsec_integ_alg, integ_alg);
15790               return -99;
15791             }
15792         }
15793       else if (unformat (i, "instance %u", &instance))
15794         renumber = 1;
15795       else
15796         {
15797           errmsg ("parse error '%U'\n", format_unformat_error, i);
15798           return -99;
15799         }
15800     }
15801
15802   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
15803
15804   mp->is_add = is_add;
15805   mp->esn = esn;
15806   mp->anti_replay = anti_replay;
15807
15808   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
15809   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
15810
15811   mp->local_spi = htonl (local_spi);
15812   mp->remote_spi = htonl (remote_spi);
15813   mp->crypto_alg = (u8) crypto_alg;
15814
15815   mp->local_crypto_key_len = 0;
15816   if (lck)
15817     {
15818       mp->local_crypto_key_len = vec_len (lck);
15819       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
15820         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
15821       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
15822     }
15823
15824   mp->remote_crypto_key_len = 0;
15825   if (rck)
15826     {
15827       mp->remote_crypto_key_len = vec_len (rck);
15828       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
15829         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
15830       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
15831     }
15832
15833   mp->integ_alg = (u8) integ_alg;
15834
15835   mp->local_integ_key_len = 0;
15836   if (lik)
15837     {
15838       mp->local_integ_key_len = vec_len (lik);
15839       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
15840         mp->local_integ_key_len = sizeof (mp->local_integ_key);
15841       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
15842     }
15843
15844   mp->remote_integ_key_len = 0;
15845   if (rik)
15846     {
15847       mp->remote_integ_key_len = vec_len (rik);
15848       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
15849         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
15850       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
15851     }
15852
15853   if (renumber)
15854     {
15855       mp->renumber = renumber;
15856       mp->show_instance = ntohl (instance);
15857     }
15858
15859   S (mp);
15860   W (ret);
15861   return ret;
15862 }
15863
15864 static void
15865 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
15866 {
15867   vat_main_t *vam = &vat_main;
15868
15869   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
15870          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
15871          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
15872          "tunnel_src_addr %U tunnel_dst_addr %U "
15873          "salt %u seq_outbound %lu last_seq_inbound %lu "
15874          "replay_window %lu total_data_size %lu\n",
15875          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
15876          mp->protocol,
15877          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
15878          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
15879          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
15880          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15881          mp->tunnel_src_addr,
15882          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
15883          mp->tunnel_dst_addr,
15884          ntohl (mp->salt),
15885          clib_net_to_host_u64 (mp->seq_outbound),
15886          clib_net_to_host_u64 (mp->last_seq_inbound),
15887          clib_net_to_host_u64 (mp->replay_window),
15888          clib_net_to_host_u64 (mp->total_data_size));
15889 }
15890
15891 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
15892 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
15893
15894 static void vl_api_ipsec_sa_details_t_handler_json
15895   (vl_api_ipsec_sa_details_t * mp)
15896 {
15897   vat_main_t *vam = &vat_main;
15898   vat_json_node_t *node = NULL;
15899   struct in_addr src_ip4, dst_ip4;
15900   struct in6_addr src_ip6, dst_ip6;
15901
15902   if (VAT_JSON_ARRAY != vam->json_tree.type)
15903     {
15904       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15905       vat_json_init_array (&vam->json_tree);
15906     }
15907   node = vat_json_array_add (&vam->json_tree);
15908
15909   vat_json_init_object (node);
15910   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
15911   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15912   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
15913   vat_json_object_add_uint (node, "proto", mp->protocol);
15914   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
15915   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
15916   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
15917   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
15918   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
15919   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
15920   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
15921                              mp->crypto_key_len);
15922   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
15923                              mp->integ_key_len);
15924   if (mp->is_tunnel_ip6)
15925     {
15926       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
15927       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
15928       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
15929       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
15930     }
15931   else
15932     {
15933       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
15934       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
15935       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
15936       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
15937     }
15938   vat_json_object_add_uint (node, "replay_window",
15939                             clib_net_to_host_u64 (mp->replay_window));
15940   vat_json_object_add_uint (node, "total_data_size",
15941                             clib_net_to_host_u64 (mp->total_data_size));
15942
15943 }
15944
15945 static int
15946 api_ipsec_sa_dump (vat_main_t * vam)
15947 {
15948   unformat_input_t *i = vam->input;
15949   vl_api_ipsec_sa_dump_t *mp;
15950   vl_api_control_ping_t *mp_ping;
15951   u32 sa_id = ~0;
15952   int ret;
15953
15954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15955     {
15956       if (unformat (i, "sa_id %d", &sa_id))
15957         ;
15958       else
15959         {
15960           clib_warning ("parse error '%U'", format_unformat_error, i);
15961           return -99;
15962         }
15963     }
15964
15965   M (IPSEC_SA_DUMP, mp);
15966
15967   mp->sa_id = ntohl (sa_id);
15968
15969   S (mp);
15970
15971   /* Use a control ping for synchronization */
15972   M (CONTROL_PING, mp_ping);
15973   S (mp_ping);
15974
15975   W (ret);
15976   return ret;
15977 }
15978
15979 static int
15980 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
15981 {
15982   unformat_input_t *i = vam->input;
15983   vl_api_ipsec_tunnel_if_set_key_t *mp;
15984   u32 sw_if_index = ~0;
15985   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
15986   u8 *key = 0;
15987   u32 alg = ~0;
15988   int ret;
15989
15990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15991     {
15992       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15993         ;
15994       else
15995         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
15996         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
15997       else
15998         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
15999         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
16000       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
16001         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
16002       else
16003         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
16004         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
16005       else if (unformat (i, "%U", unformat_hex_string, &key))
16006         ;
16007       else
16008         {
16009           clib_warning ("parse error '%U'", format_unformat_error, i);
16010           return -99;
16011         }
16012     }
16013
16014   if (sw_if_index == ~0)
16015     {
16016       errmsg ("interface must be specified");
16017       return -99;
16018     }
16019
16020   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
16021     {
16022       errmsg ("key type must be specified");
16023       return -99;
16024     }
16025
16026   if (alg == ~0)
16027     {
16028       errmsg ("algorithm must be specified");
16029       return -99;
16030     }
16031
16032   if (vec_len (key) == 0)
16033     {
16034       errmsg ("key must be specified");
16035       return -99;
16036     }
16037
16038   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
16039
16040   mp->sw_if_index = htonl (sw_if_index);
16041   mp->alg = alg;
16042   mp->key_type = key_type;
16043   mp->key_len = vec_len (key);
16044   clib_memcpy (mp->key, key, vec_len (key));
16045
16046   S (mp);
16047   W (ret);
16048
16049   return ret;
16050 }
16051
16052 static int
16053 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
16054 {
16055   unformat_input_t *i = vam->input;
16056   vl_api_ipsec_tunnel_if_set_sa_t *mp;
16057   u32 sw_if_index = ~0;
16058   u32 sa_id = ~0;
16059   u8 is_outbound = (u8) ~ 0;
16060   int ret;
16061
16062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16063     {
16064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16065         ;
16066       else if (unformat (i, "sa_id %d", &sa_id))
16067         ;
16068       else if (unformat (i, "outbound"))
16069         is_outbound = 1;
16070       else if (unformat (i, "inbound"))
16071         is_outbound = 0;
16072       else
16073         {
16074           clib_warning ("parse error '%U'", format_unformat_error, i);
16075           return -99;
16076         }
16077     }
16078
16079   if (sw_if_index == ~0)
16080     {
16081       errmsg ("interface must be specified");
16082       return -99;
16083     }
16084
16085   if (sa_id == ~0)
16086     {
16087       errmsg ("SA ID must be specified");
16088       return -99;
16089     }
16090
16091   M (IPSEC_TUNNEL_IF_SET_SA, mp);
16092
16093   mp->sw_if_index = htonl (sw_if_index);
16094   mp->sa_id = htonl (sa_id);
16095   mp->is_outbound = is_outbound;
16096
16097   S (mp);
16098   W (ret);
16099
16100   return ret;
16101 }
16102
16103 static int
16104 api_ikev2_profile_add_del (vat_main_t * vam)
16105 {
16106   unformat_input_t *i = vam->input;
16107   vl_api_ikev2_profile_add_del_t *mp;
16108   u8 is_add = 1;
16109   u8 *name = 0;
16110   int ret;
16111
16112   const char *valid_chars = "a-zA-Z0-9_";
16113
16114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16115     {
16116       if (unformat (i, "del"))
16117         is_add = 0;
16118       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16119         vec_add1 (name, 0);
16120       else
16121         {
16122           errmsg ("parse error '%U'", format_unformat_error, i);
16123           return -99;
16124         }
16125     }
16126
16127   if (!vec_len (name))
16128     {
16129       errmsg ("profile name must be specified");
16130       return -99;
16131     }
16132
16133   if (vec_len (name) > 64)
16134     {
16135       errmsg ("profile name too long");
16136       return -99;
16137     }
16138
16139   M (IKEV2_PROFILE_ADD_DEL, mp);
16140
16141   clib_memcpy (mp->name, name, vec_len (name));
16142   mp->is_add = is_add;
16143   vec_free (name);
16144
16145   S (mp);
16146   W (ret);
16147   return ret;
16148 }
16149
16150 static int
16151 api_ikev2_profile_set_auth (vat_main_t * vam)
16152 {
16153   unformat_input_t *i = vam->input;
16154   vl_api_ikev2_profile_set_auth_t *mp;
16155   u8 *name = 0;
16156   u8 *data = 0;
16157   u32 auth_method = 0;
16158   u8 is_hex = 0;
16159   int ret;
16160
16161   const char *valid_chars = "a-zA-Z0-9_";
16162
16163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16164     {
16165       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16166         vec_add1 (name, 0);
16167       else if (unformat (i, "auth_method %U",
16168                          unformat_ikev2_auth_method, &auth_method))
16169         ;
16170       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
16171         is_hex = 1;
16172       else if (unformat (i, "auth_data %v", &data))
16173         ;
16174       else
16175         {
16176           errmsg ("parse error '%U'", format_unformat_error, i);
16177           return -99;
16178         }
16179     }
16180
16181   if (!vec_len (name))
16182     {
16183       errmsg ("profile name must be specified");
16184       return -99;
16185     }
16186
16187   if (vec_len (name) > 64)
16188     {
16189       errmsg ("profile name too long");
16190       return -99;
16191     }
16192
16193   if (!vec_len (data))
16194     {
16195       errmsg ("auth_data must be specified");
16196       return -99;
16197     }
16198
16199   if (!auth_method)
16200     {
16201       errmsg ("auth_method must be specified");
16202       return -99;
16203     }
16204
16205   M (IKEV2_PROFILE_SET_AUTH, mp);
16206
16207   mp->is_hex = is_hex;
16208   mp->auth_method = (u8) auth_method;
16209   mp->data_len = vec_len (data);
16210   clib_memcpy (mp->name, name, vec_len (name));
16211   clib_memcpy (mp->data, data, vec_len (data));
16212   vec_free (name);
16213   vec_free (data);
16214
16215   S (mp);
16216   W (ret);
16217   return ret;
16218 }
16219
16220 static int
16221 api_ikev2_profile_set_id (vat_main_t * vam)
16222 {
16223   unformat_input_t *i = vam->input;
16224   vl_api_ikev2_profile_set_id_t *mp;
16225   u8 *name = 0;
16226   u8 *data = 0;
16227   u8 is_local = 0;
16228   u32 id_type = 0;
16229   ip4_address_t ip4;
16230   int ret;
16231
16232   const char *valid_chars = "a-zA-Z0-9_";
16233
16234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16235     {
16236       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16237         vec_add1 (name, 0);
16238       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
16239         ;
16240       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
16241         {
16242           data = vec_new (u8, 4);
16243           clib_memcpy (data, ip4.as_u8, 4);
16244         }
16245       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
16246         ;
16247       else if (unformat (i, "id_data %v", &data))
16248         ;
16249       else if (unformat (i, "local"))
16250         is_local = 1;
16251       else if (unformat (i, "remote"))
16252         is_local = 0;
16253       else
16254         {
16255           errmsg ("parse error '%U'", format_unformat_error, i);
16256           return -99;
16257         }
16258     }
16259
16260   if (!vec_len (name))
16261     {
16262       errmsg ("profile name must be specified");
16263       return -99;
16264     }
16265
16266   if (vec_len (name) > 64)
16267     {
16268       errmsg ("profile name too long");
16269       return -99;
16270     }
16271
16272   if (!vec_len (data))
16273     {
16274       errmsg ("id_data must be specified");
16275       return -99;
16276     }
16277
16278   if (!id_type)
16279     {
16280       errmsg ("id_type must be specified");
16281       return -99;
16282     }
16283
16284   M (IKEV2_PROFILE_SET_ID, mp);
16285
16286   mp->is_local = is_local;
16287   mp->id_type = (u8) id_type;
16288   mp->data_len = vec_len (data);
16289   clib_memcpy (mp->name, name, vec_len (name));
16290   clib_memcpy (mp->data, data, vec_len (data));
16291   vec_free (name);
16292   vec_free (data);
16293
16294   S (mp);
16295   W (ret);
16296   return ret;
16297 }
16298
16299 static int
16300 api_ikev2_profile_set_ts (vat_main_t * vam)
16301 {
16302   unformat_input_t *i = vam->input;
16303   vl_api_ikev2_profile_set_ts_t *mp;
16304   u8 *name = 0;
16305   u8 is_local = 0;
16306   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
16307   ip4_address_t start_addr, end_addr;
16308
16309   const char *valid_chars = "a-zA-Z0-9_";
16310   int ret;
16311
16312   start_addr.as_u32 = 0;
16313   end_addr.as_u32 = (u32) ~ 0;
16314
16315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16316     {
16317       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
16318         vec_add1 (name, 0);
16319       else if (unformat (i, "protocol %d", &proto))
16320         ;
16321       else if (unformat (i, "start_port %d", &start_port))
16322         ;
16323       else if (unformat (i, "end_port %d", &end_port))
16324         ;
16325       else
16326         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
16327         ;
16328       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
16329         ;
16330       else if (unformat (i, "local"))
16331         is_local = 1;
16332       else if (unformat (i, "remote"))
16333         is_local = 0;
16334       else
16335         {
16336           errmsg ("parse error '%U'", format_unformat_error, i);
16337           return -99;
16338         }
16339     }
16340
16341   if (!vec_len (name))
16342     {
16343       errmsg ("profile name must be specified");
16344       return -99;
16345     }
16346
16347   if (vec_len (name) > 64)
16348     {
16349       errmsg ("profile name too long");
16350       return -99;
16351     }
16352
16353   M (IKEV2_PROFILE_SET_TS, mp);
16354
16355   mp->is_local = is_local;
16356   mp->proto = (u8) proto;
16357   mp->start_port = (u16) start_port;
16358   mp->end_port = (u16) end_port;
16359   mp->start_addr = start_addr.as_u32;
16360   mp->end_addr = end_addr.as_u32;
16361   clib_memcpy (mp->name, name, vec_len (name));
16362   vec_free (name);
16363
16364   S (mp);
16365   W (ret);
16366   return ret;
16367 }
16368
16369 static int
16370 api_ikev2_set_local_key (vat_main_t * vam)
16371 {
16372   unformat_input_t *i = vam->input;
16373   vl_api_ikev2_set_local_key_t *mp;
16374   u8 *file = 0;
16375   int ret;
16376
16377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (i, "file %v", &file))
16380         vec_add1 (file, 0);
16381       else
16382         {
16383           errmsg ("parse error '%U'", format_unformat_error, i);
16384           return -99;
16385         }
16386     }
16387
16388   if (!vec_len (file))
16389     {
16390       errmsg ("RSA key file must be specified");
16391       return -99;
16392     }
16393
16394   if (vec_len (file) > 256)
16395     {
16396       errmsg ("file name too long");
16397       return -99;
16398     }
16399
16400   M (IKEV2_SET_LOCAL_KEY, mp);
16401
16402   clib_memcpy (mp->key_file, file, vec_len (file));
16403   vec_free (file);
16404
16405   S (mp);
16406   W (ret);
16407   return ret;
16408 }
16409
16410 static int
16411 api_ikev2_set_responder (vat_main_t * vam)
16412 {
16413   unformat_input_t *i = vam->input;
16414   vl_api_ikev2_set_responder_t *mp;
16415   int ret;
16416   u8 *name = 0;
16417   u32 sw_if_index = ~0;
16418   ip4_address_t address;
16419
16420   const char *valid_chars = "a-zA-Z0-9_";
16421
16422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16423     {
16424       if (unformat
16425           (i, "%U interface %d address %U", unformat_token, valid_chars,
16426            &name, &sw_if_index, unformat_ip4_address, &address))
16427         vec_add1 (name, 0);
16428       else
16429         {
16430           errmsg ("parse error '%U'", format_unformat_error, i);
16431           return -99;
16432         }
16433     }
16434
16435   if (!vec_len (name))
16436     {
16437       errmsg ("profile name must be specified");
16438       return -99;
16439     }
16440
16441   if (vec_len (name) > 64)
16442     {
16443       errmsg ("profile name too long");
16444       return -99;
16445     }
16446
16447   M (IKEV2_SET_RESPONDER, mp);
16448
16449   clib_memcpy (mp->name, name, vec_len (name));
16450   vec_free (name);
16451
16452   mp->sw_if_index = sw_if_index;
16453   clib_memcpy (mp->address, &address, sizeof (address));
16454
16455   S (mp);
16456   W (ret);
16457   return ret;
16458 }
16459
16460 static int
16461 api_ikev2_set_ike_transforms (vat_main_t * vam)
16462 {
16463   unformat_input_t *i = vam->input;
16464   vl_api_ikev2_set_ike_transforms_t *mp;
16465   int ret;
16466   u8 *name = 0;
16467   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16468
16469   const char *valid_chars = "a-zA-Z0-9_";
16470
16471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16472     {
16473       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16474                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16475         vec_add1 (name, 0);
16476       else
16477         {
16478           errmsg ("parse error '%U'", format_unformat_error, i);
16479           return -99;
16480         }
16481     }
16482
16483   if (!vec_len (name))
16484     {
16485       errmsg ("profile name must be specified");
16486       return -99;
16487     }
16488
16489   if (vec_len (name) > 64)
16490     {
16491       errmsg ("profile name too long");
16492       return -99;
16493     }
16494
16495   M (IKEV2_SET_IKE_TRANSFORMS, mp);
16496
16497   clib_memcpy (mp->name, name, vec_len (name));
16498   vec_free (name);
16499   mp->crypto_alg = crypto_alg;
16500   mp->crypto_key_size = crypto_key_size;
16501   mp->integ_alg = integ_alg;
16502   mp->dh_group = dh_group;
16503
16504   S (mp);
16505   W (ret);
16506   return ret;
16507 }
16508
16509
16510 static int
16511 api_ikev2_set_esp_transforms (vat_main_t * vam)
16512 {
16513   unformat_input_t *i = vam->input;
16514   vl_api_ikev2_set_esp_transforms_t *mp;
16515   int ret;
16516   u8 *name = 0;
16517   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
16518
16519   const char *valid_chars = "a-zA-Z0-9_";
16520
16521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16522     {
16523       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
16524                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
16525         vec_add1 (name, 0);
16526       else
16527         {
16528           errmsg ("parse error '%U'", format_unformat_error, i);
16529           return -99;
16530         }
16531     }
16532
16533   if (!vec_len (name))
16534     {
16535       errmsg ("profile name must be specified");
16536       return -99;
16537     }
16538
16539   if (vec_len (name) > 64)
16540     {
16541       errmsg ("profile name too long");
16542       return -99;
16543     }
16544
16545   M (IKEV2_SET_ESP_TRANSFORMS, mp);
16546
16547   clib_memcpy (mp->name, name, vec_len (name));
16548   vec_free (name);
16549   mp->crypto_alg = crypto_alg;
16550   mp->crypto_key_size = crypto_key_size;
16551   mp->integ_alg = integ_alg;
16552   mp->dh_group = dh_group;
16553
16554   S (mp);
16555   W (ret);
16556   return ret;
16557 }
16558
16559 static int
16560 api_ikev2_set_sa_lifetime (vat_main_t * vam)
16561 {
16562   unformat_input_t *i = vam->input;
16563   vl_api_ikev2_set_sa_lifetime_t *mp;
16564   int ret;
16565   u8 *name = 0;
16566   u64 lifetime, lifetime_maxdata;
16567   u32 lifetime_jitter, handover;
16568
16569   const char *valid_chars = "a-zA-Z0-9_";
16570
16571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16572     {
16573       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
16574                     &lifetime, &lifetime_jitter, &handover,
16575                     &lifetime_maxdata))
16576         vec_add1 (name, 0);
16577       else
16578         {
16579           errmsg ("parse error '%U'", format_unformat_error, i);
16580           return -99;
16581         }
16582     }
16583
16584   if (!vec_len (name))
16585     {
16586       errmsg ("profile name must be specified");
16587       return -99;
16588     }
16589
16590   if (vec_len (name) > 64)
16591     {
16592       errmsg ("profile name too long");
16593       return -99;
16594     }
16595
16596   M (IKEV2_SET_SA_LIFETIME, mp);
16597
16598   clib_memcpy (mp->name, name, vec_len (name));
16599   vec_free (name);
16600   mp->lifetime = lifetime;
16601   mp->lifetime_jitter = lifetime_jitter;
16602   mp->handover = handover;
16603   mp->lifetime_maxdata = lifetime_maxdata;
16604
16605   S (mp);
16606   W (ret);
16607   return ret;
16608 }
16609
16610 static int
16611 api_ikev2_initiate_sa_init (vat_main_t * vam)
16612 {
16613   unformat_input_t *i = vam->input;
16614   vl_api_ikev2_initiate_sa_init_t *mp;
16615   int ret;
16616   u8 *name = 0;
16617
16618   const char *valid_chars = "a-zA-Z0-9_";
16619
16620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16621     {
16622       if (unformat (i, "%U", unformat_token, valid_chars, &name))
16623         vec_add1 (name, 0);
16624       else
16625         {
16626           errmsg ("parse error '%U'", format_unformat_error, i);
16627           return -99;
16628         }
16629     }
16630
16631   if (!vec_len (name))
16632     {
16633       errmsg ("profile name must be specified");
16634       return -99;
16635     }
16636
16637   if (vec_len (name) > 64)
16638     {
16639       errmsg ("profile name too long");
16640       return -99;
16641     }
16642
16643   M (IKEV2_INITIATE_SA_INIT, mp);
16644
16645   clib_memcpy (mp->name, name, vec_len (name));
16646   vec_free (name);
16647
16648   S (mp);
16649   W (ret);
16650   return ret;
16651 }
16652
16653 static int
16654 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
16655 {
16656   unformat_input_t *i = vam->input;
16657   vl_api_ikev2_initiate_del_ike_sa_t *mp;
16658   int ret;
16659   u64 ispi;
16660
16661
16662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16663     {
16664       if (unformat (i, "%lx", &ispi))
16665         ;
16666       else
16667         {
16668           errmsg ("parse error '%U'", format_unformat_error, i);
16669           return -99;
16670         }
16671     }
16672
16673   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
16674
16675   mp->ispi = ispi;
16676
16677   S (mp);
16678   W (ret);
16679   return ret;
16680 }
16681
16682 static int
16683 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
16684 {
16685   unformat_input_t *i = vam->input;
16686   vl_api_ikev2_initiate_del_child_sa_t *mp;
16687   int ret;
16688   u32 ispi;
16689
16690
16691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16692     {
16693       if (unformat (i, "%x", &ispi))
16694         ;
16695       else
16696         {
16697           errmsg ("parse error '%U'", format_unformat_error, i);
16698           return -99;
16699         }
16700     }
16701
16702   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
16703
16704   mp->ispi = ispi;
16705
16706   S (mp);
16707   W (ret);
16708   return ret;
16709 }
16710
16711 static int
16712 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
16713 {
16714   unformat_input_t *i = vam->input;
16715   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
16716   int ret;
16717   u32 ispi;
16718
16719
16720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16721     {
16722       if (unformat (i, "%x", &ispi))
16723         ;
16724       else
16725         {
16726           errmsg ("parse error '%U'", format_unformat_error, i);
16727           return -99;
16728         }
16729     }
16730
16731   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
16732
16733   mp->ispi = ispi;
16734
16735   S (mp);
16736   W (ret);
16737   return ret;
16738 }
16739
16740 static int
16741 api_get_first_msg_id (vat_main_t * vam)
16742 {
16743   vl_api_get_first_msg_id_t *mp;
16744   unformat_input_t *i = vam->input;
16745   u8 *name;
16746   u8 name_set = 0;
16747   int ret;
16748
16749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16750     {
16751       if (unformat (i, "client %s", &name))
16752         name_set = 1;
16753       else
16754         break;
16755     }
16756
16757   if (name_set == 0)
16758     {
16759       errmsg ("missing client name");
16760       return -99;
16761     }
16762   vec_add1 (name, 0);
16763
16764   if (vec_len (name) > 63)
16765     {
16766       errmsg ("client name too long");
16767       return -99;
16768     }
16769
16770   M (GET_FIRST_MSG_ID, mp);
16771   clib_memcpy (mp->name, name, vec_len (name));
16772   S (mp);
16773   W (ret);
16774   return ret;
16775 }
16776
16777 static int
16778 api_cop_interface_enable_disable (vat_main_t * vam)
16779 {
16780   unformat_input_t *line_input = vam->input;
16781   vl_api_cop_interface_enable_disable_t *mp;
16782   u32 sw_if_index = ~0;
16783   u8 enable_disable = 1;
16784   int ret;
16785
16786   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16787     {
16788       if (unformat (line_input, "disable"))
16789         enable_disable = 0;
16790       if (unformat (line_input, "enable"))
16791         enable_disable = 1;
16792       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16793                          vam, &sw_if_index))
16794         ;
16795       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16796         ;
16797       else
16798         break;
16799     }
16800
16801   if (sw_if_index == ~0)
16802     {
16803       errmsg ("missing interface name or sw_if_index");
16804       return -99;
16805     }
16806
16807   /* Construct the API message */
16808   M (COP_INTERFACE_ENABLE_DISABLE, mp);
16809   mp->sw_if_index = ntohl (sw_if_index);
16810   mp->enable_disable = enable_disable;
16811
16812   /* send it... */
16813   S (mp);
16814   /* Wait for the reply */
16815   W (ret);
16816   return ret;
16817 }
16818
16819 static int
16820 api_cop_whitelist_enable_disable (vat_main_t * vam)
16821 {
16822   unformat_input_t *line_input = vam->input;
16823   vl_api_cop_whitelist_enable_disable_t *mp;
16824   u32 sw_if_index = ~0;
16825   u8 ip4 = 0, ip6 = 0, default_cop = 0;
16826   u32 fib_id = 0;
16827   int ret;
16828
16829   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16830     {
16831       if (unformat (line_input, "ip4"))
16832         ip4 = 1;
16833       else if (unformat (line_input, "ip6"))
16834         ip6 = 1;
16835       else if (unformat (line_input, "default"))
16836         default_cop = 1;
16837       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
16838                          vam, &sw_if_index))
16839         ;
16840       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
16841         ;
16842       else if (unformat (line_input, "fib-id %d", &fib_id))
16843         ;
16844       else
16845         break;
16846     }
16847
16848   if (sw_if_index == ~0)
16849     {
16850       errmsg ("missing interface name or sw_if_index");
16851       return -99;
16852     }
16853
16854   /* Construct the API message */
16855   M (COP_WHITELIST_ENABLE_DISABLE, mp);
16856   mp->sw_if_index = ntohl (sw_if_index);
16857   mp->fib_id = ntohl (fib_id);
16858   mp->ip4 = ip4;
16859   mp->ip6 = ip6;
16860   mp->default_cop = default_cop;
16861
16862   /* send it... */
16863   S (mp);
16864   /* Wait for the reply */
16865   W (ret);
16866   return ret;
16867 }
16868
16869 static int
16870 api_get_node_graph (vat_main_t * vam)
16871 {
16872   vl_api_get_node_graph_t *mp;
16873   int ret;
16874
16875   M (GET_NODE_GRAPH, mp);
16876
16877   /* send it... */
16878   S (mp);
16879   /* Wait for the reply */
16880   W (ret);
16881   return ret;
16882 }
16883
16884 /* *INDENT-OFF* */
16885 /** Used for parsing LISP eids */
16886 typedef CLIB_PACKED(struct{
16887   u8 addr[16];   /**< eid address */
16888   u32 len;       /**< prefix length if IP */
16889   u8 type;      /**< type of eid */
16890 }) lisp_eid_vat_t;
16891 /* *INDENT-ON* */
16892
16893 static uword
16894 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
16895 {
16896   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
16897
16898   memset (a, 0, sizeof (a[0]));
16899
16900   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
16901     {
16902       a->type = 0;              /* ipv4 type */
16903     }
16904   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
16905     {
16906       a->type = 1;              /* ipv6 type */
16907     }
16908   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
16909     {
16910       a->type = 2;              /* mac type */
16911     }
16912   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
16913     {
16914       a->type = 3;              /* NSH type */
16915       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
16916       nsh->spi = clib_host_to_net_u32 (nsh->spi);
16917     }
16918   else
16919     {
16920       return 0;
16921     }
16922
16923   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
16924     {
16925       return 0;
16926     }
16927
16928   return 1;
16929 }
16930
16931 static int
16932 lisp_eid_size_vat (u8 type)
16933 {
16934   switch (type)
16935     {
16936     case 0:
16937       return 4;
16938     case 1:
16939       return 16;
16940     case 2:
16941       return 6;
16942     case 3:
16943       return 5;
16944     }
16945   return 0;
16946 }
16947
16948 static void
16949 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
16950 {
16951   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
16952 }
16953
16954 static int
16955 api_one_add_del_locator_set (vat_main_t * vam)
16956 {
16957   unformat_input_t *input = vam->input;
16958   vl_api_one_add_del_locator_set_t *mp;
16959   u8 is_add = 1;
16960   u8 *locator_set_name = NULL;
16961   u8 locator_set_name_set = 0;
16962   vl_api_local_locator_t locator, *locators = 0;
16963   u32 sw_if_index, priority, weight;
16964   u32 data_len = 0;
16965
16966   int ret;
16967   /* Parse args required to build the message */
16968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16969     {
16970       if (unformat (input, "del"))
16971         {
16972           is_add = 0;
16973         }
16974       else if (unformat (input, "locator-set %s", &locator_set_name))
16975         {
16976           locator_set_name_set = 1;
16977         }
16978       else if (unformat (input, "sw_if_index %u p %u w %u",
16979                          &sw_if_index, &priority, &weight))
16980         {
16981           locator.sw_if_index = htonl (sw_if_index);
16982           locator.priority = priority;
16983           locator.weight = weight;
16984           vec_add1 (locators, locator);
16985         }
16986       else
16987         if (unformat
16988             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
16989              &sw_if_index, &priority, &weight))
16990         {
16991           locator.sw_if_index = htonl (sw_if_index);
16992           locator.priority = priority;
16993           locator.weight = weight;
16994           vec_add1 (locators, locator);
16995         }
16996       else
16997         break;
16998     }
16999
17000   if (locator_set_name_set == 0)
17001     {
17002       errmsg ("missing locator-set name");
17003       vec_free (locators);
17004       return -99;
17005     }
17006
17007   if (vec_len (locator_set_name) > 64)
17008     {
17009       errmsg ("locator-set name too long");
17010       vec_free (locator_set_name);
17011       vec_free (locators);
17012       return -99;
17013     }
17014   vec_add1 (locator_set_name, 0);
17015
17016   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
17017
17018   /* Construct the API message */
17019   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
17020
17021   mp->is_add = is_add;
17022   clib_memcpy (mp->locator_set_name, locator_set_name,
17023                vec_len (locator_set_name));
17024   vec_free (locator_set_name);
17025
17026   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
17027   if (locators)
17028     clib_memcpy (mp->locators, locators, data_len);
17029   vec_free (locators);
17030
17031   /* send it... */
17032   S (mp);
17033
17034   /* Wait for a reply... */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
17040
17041 static int
17042 api_one_add_del_locator (vat_main_t * vam)
17043 {
17044   unformat_input_t *input = vam->input;
17045   vl_api_one_add_del_locator_t *mp;
17046   u32 tmp_if_index = ~0;
17047   u32 sw_if_index = ~0;
17048   u8 sw_if_index_set = 0;
17049   u8 sw_if_index_if_name_set = 0;
17050   u32 priority = ~0;
17051   u8 priority_set = 0;
17052   u32 weight = ~0;
17053   u8 weight_set = 0;
17054   u8 is_add = 1;
17055   u8 *locator_set_name = NULL;
17056   u8 locator_set_name_set = 0;
17057   int ret;
17058
17059   /* Parse args required to build the message */
17060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17061     {
17062       if (unformat (input, "del"))
17063         {
17064           is_add = 0;
17065         }
17066       else if (unformat (input, "locator-set %s", &locator_set_name))
17067         {
17068           locator_set_name_set = 1;
17069         }
17070       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
17071                          &tmp_if_index))
17072         {
17073           sw_if_index_if_name_set = 1;
17074           sw_if_index = tmp_if_index;
17075         }
17076       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
17077         {
17078           sw_if_index_set = 1;
17079           sw_if_index = tmp_if_index;
17080         }
17081       else if (unformat (input, "p %d", &priority))
17082         {
17083           priority_set = 1;
17084         }
17085       else if (unformat (input, "w %d", &weight))
17086         {
17087           weight_set = 1;
17088         }
17089       else
17090         break;
17091     }
17092
17093   if (locator_set_name_set == 0)
17094     {
17095       errmsg ("missing locator-set name");
17096       return -99;
17097     }
17098
17099   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
17100     {
17101       errmsg ("missing sw_if_index");
17102       vec_free (locator_set_name);
17103       return -99;
17104     }
17105
17106   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
17107     {
17108       errmsg ("cannot use both params interface name and sw_if_index");
17109       vec_free (locator_set_name);
17110       return -99;
17111     }
17112
17113   if (priority_set == 0)
17114     {
17115       errmsg ("missing locator-set priority");
17116       vec_free (locator_set_name);
17117       return -99;
17118     }
17119
17120   if (weight_set == 0)
17121     {
17122       errmsg ("missing locator-set weight");
17123       vec_free (locator_set_name);
17124       return -99;
17125     }
17126
17127   if (vec_len (locator_set_name) > 64)
17128     {
17129       errmsg ("locator-set name too long");
17130       vec_free (locator_set_name);
17131       return -99;
17132     }
17133   vec_add1 (locator_set_name, 0);
17134
17135   /* Construct the API message */
17136   M (ONE_ADD_DEL_LOCATOR, mp);
17137
17138   mp->is_add = is_add;
17139   mp->sw_if_index = ntohl (sw_if_index);
17140   mp->priority = priority;
17141   mp->weight = weight;
17142   clib_memcpy (mp->locator_set_name, locator_set_name,
17143                vec_len (locator_set_name));
17144   vec_free (locator_set_name);
17145
17146   /* send it... */
17147   S (mp);
17148
17149   /* Wait for a reply... */
17150   W (ret);
17151   return ret;
17152 }
17153
17154 #define api_lisp_add_del_locator api_one_add_del_locator
17155
17156 uword
17157 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
17158 {
17159   u32 *key_id = va_arg (*args, u32 *);
17160   u8 *s = 0;
17161
17162   if (unformat (input, "%s", &s))
17163     {
17164       if (!strcmp ((char *) s, "sha1"))
17165         key_id[0] = HMAC_SHA_1_96;
17166       else if (!strcmp ((char *) s, "sha256"))
17167         key_id[0] = HMAC_SHA_256_128;
17168       else
17169         {
17170           clib_warning ("invalid key_id: '%s'", s);
17171           key_id[0] = HMAC_NO_KEY;
17172         }
17173     }
17174   else
17175     return 0;
17176
17177   vec_free (s);
17178   return 1;
17179 }
17180
17181 static int
17182 api_one_add_del_local_eid (vat_main_t * vam)
17183 {
17184   unformat_input_t *input = vam->input;
17185   vl_api_one_add_del_local_eid_t *mp;
17186   u8 is_add = 1;
17187   u8 eid_set = 0;
17188   lisp_eid_vat_t _eid, *eid = &_eid;
17189   u8 *locator_set_name = 0;
17190   u8 locator_set_name_set = 0;
17191   u32 vni = 0;
17192   u16 key_id = 0;
17193   u8 *key = 0;
17194   int ret;
17195
17196   /* Parse args required to build the message */
17197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17198     {
17199       if (unformat (input, "del"))
17200         {
17201           is_add = 0;
17202         }
17203       else if (unformat (input, "vni %d", &vni))
17204         {
17205           ;
17206         }
17207       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17208         {
17209           eid_set = 1;
17210         }
17211       else if (unformat (input, "locator-set %s", &locator_set_name))
17212         {
17213           locator_set_name_set = 1;
17214         }
17215       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
17216         ;
17217       else if (unformat (input, "secret-key %_%v%_", &key))
17218         ;
17219       else
17220         break;
17221     }
17222
17223   if (locator_set_name_set == 0)
17224     {
17225       errmsg ("missing locator-set name");
17226       return -99;
17227     }
17228
17229   if (0 == eid_set)
17230     {
17231       errmsg ("EID address not set!");
17232       vec_free (locator_set_name);
17233       return -99;
17234     }
17235
17236   if (key && (0 == key_id))
17237     {
17238       errmsg ("invalid key_id!");
17239       return -99;
17240     }
17241
17242   if (vec_len (key) > 64)
17243     {
17244       errmsg ("key too long");
17245       vec_free (key);
17246       return -99;
17247     }
17248
17249   if (vec_len (locator_set_name) > 64)
17250     {
17251       errmsg ("locator-set name too long");
17252       vec_free (locator_set_name);
17253       return -99;
17254     }
17255   vec_add1 (locator_set_name, 0);
17256
17257   /* Construct the API message */
17258   M (ONE_ADD_DEL_LOCAL_EID, mp);
17259
17260   mp->is_add = is_add;
17261   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17262   mp->eid_type = eid->type;
17263   mp->prefix_len = eid->len;
17264   mp->vni = clib_host_to_net_u32 (vni);
17265   mp->key_id = clib_host_to_net_u16 (key_id);
17266   clib_memcpy (mp->locator_set_name, locator_set_name,
17267                vec_len (locator_set_name));
17268   clib_memcpy (mp->key, key, vec_len (key));
17269
17270   vec_free (locator_set_name);
17271   vec_free (key);
17272
17273   /* send it... */
17274   S (mp);
17275
17276   /* Wait for a reply... */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
17282
17283 static int
17284 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
17285 {
17286   u32 dp_table = 0, vni = 0;;
17287   unformat_input_t *input = vam->input;
17288   vl_api_gpe_add_del_fwd_entry_t *mp;
17289   u8 is_add = 1;
17290   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
17291   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
17292   u8 rmt_eid_set = 0, lcl_eid_set = 0;
17293   u32 action = ~0, w;
17294   ip4_address_t rmt_rloc4, lcl_rloc4;
17295   ip6_address_t rmt_rloc6, lcl_rloc6;
17296   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
17297   int ret;
17298
17299   memset (&rloc, 0, sizeof (rloc));
17300
17301   /* Parse args required to build the message */
17302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17303     {
17304       if (unformat (input, "del"))
17305         is_add = 0;
17306       else if (unformat (input, "add"))
17307         is_add = 1;
17308       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
17309         {
17310           rmt_eid_set = 1;
17311         }
17312       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
17313         {
17314           lcl_eid_set = 1;
17315         }
17316       else if (unformat (input, "vrf %d", &dp_table))
17317         ;
17318       else if (unformat (input, "bd %d", &dp_table))
17319         ;
17320       else if (unformat (input, "vni %d", &vni))
17321         ;
17322       else if (unformat (input, "w %d", &w))
17323         {
17324           if (!curr_rloc)
17325             {
17326               errmsg ("No RLOC configured for setting priority/weight!");
17327               return -99;
17328             }
17329           curr_rloc->weight = w;
17330         }
17331       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
17332                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
17333         {
17334           rloc.is_ip4 = 1;
17335
17336           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
17337           rloc.weight = 0;
17338           vec_add1 (lcl_locs, rloc);
17339
17340           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
17341           vec_add1 (rmt_locs, rloc);
17342           /* weight saved in rmt loc */
17343           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17344         }
17345       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
17346                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
17347         {
17348           rloc.is_ip4 = 0;
17349           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
17350           rloc.weight = 0;
17351           vec_add1 (lcl_locs, rloc);
17352
17353           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
17354           vec_add1 (rmt_locs, rloc);
17355           /* weight saved in rmt loc */
17356           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
17357         }
17358       else if (unformat (input, "action %d", &action))
17359         {
17360           ;
17361         }
17362       else
17363         {
17364           clib_warning ("parse error '%U'", format_unformat_error, input);
17365           return -99;
17366         }
17367     }
17368
17369   if (!rmt_eid_set)
17370     {
17371       errmsg ("remote eid addresses not set");
17372       return -99;
17373     }
17374
17375   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
17376     {
17377       errmsg ("eid types don't match");
17378       return -99;
17379     }
17380
17381   if (0 == rmt_locs && (u32) ~ 0 == action)
17382     {
17383       errmsg ("action not set for negative mapping");
17384       return -99;
17385     }
17386
17387   /* Construct the API message */
17388   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
17389       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
17390
17391   mp->is_add = is_add;
17392   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
17393   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
17394   mp->eid_type = rmt_eid->type;
17395   mp->dp_table = clib_host_to_net_u32 (dp_table);
17396   mp->vni = clib_host_to_net_u32 (vni);
17397   mp->rmt_len = rmt_eid->len;
17398   mp->lcl_len = lcl_eid->len;
17399   mp->action = action;
17400
17401   if (0 != rmt_locs && 0 != lcl_locs)
17402     {
17403       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
17404       clib_memcpy (mp->locs, lcl_locs,
17405                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
17406
17407       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
17408       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
17409                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
17410     }
17411   vec_free (lcl_locs);
17412   vec_free (rmt_locs);
17413
17414   /* send it... */
17415   S (mp);
17416
17417   /* Wait for a reply... */
17418   W (ret);
17419   return ret;
17420 }
17421
17422 static int
17423 api_one_add_del_map_server (vat_main_t * vam)
17424 {
17425   unformat_input_t *input = vam->input;
17426   vl_api_one_add_del_map_server_t *mp;
17427   u8 is_add = 1;
17428   u8 ipv4_set = 0;
17429   u8 ipv6_set = 0;
17430   ip4_address_t ipv4;
17431   ip6_address_t ipv6;
17432   int ret;
17433
17434   /* Parse args required to build the message */
17435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17436     {
17437       if (unformat (input, "del"))
17438         {
17439           is_add = 0;
17440         }
17441       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17442         {
17443           ipv4_set = 1;
17444         }
17445       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17446         {
17447           ipv6_set = 1;
17448         }
17449       else
17450         break;
17451     }
17452
17453   if (ipv4_set && ipv6_set)
17454     {
17455       errmsg ("both eid v4 and v6 addresses set");
17456       return -99;
17457     }
17458
17459   if (!ipv4_set && !ipv6_set)
17460     {
17461       errmsg ("eid addresses not set");
17462       return -99;
17463     }
17464
17465   /* Construct the API message */
17466   M (ONE_ADD_DEL_MAP_SERVER, mp);
17467
17468   mp->is_add = is_add;
17469   if (ipv6_set)
17470     {
17471       mp->is_ipv6 = 1;
17472       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17473     }
17474   else
17475     {
17476       mp->is_ipv6 = 0;
17477       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17478     }
17479
17480   /* send it... */
17481   S (mp);
17482
17483   /* Wait for a reply... */
17484   W (ret);
17485   return ret;
17486 }
17487
17488 #define api_lisp_add_del_map_server api_one_add_del_map_server
17489
17490 static int
17491 api_one_add_del_map_resolver (vat_main_t * vam)
17492 {
17493   unformat_input_t *input = vam->input;
17494   vl_api_one_add_del_map_resolver_t *mp;
17495   u8 is_add = 1;
17496   u8 ipv4_set = 0;
17497   u8 ipv6_set = 0;
17498   ip4_address_t ipv4;
17499   ip6_address_t ipv6;
17500   int ret;
17501
17502   /* Parse args required to build the message */
17503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17504     {
17505       if (unformat (input, "del"))
17506         {
17507           is_add = 0;
17508         }
17509       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
17510         {
17511           ipv4_set = 1;
17512         }
17513       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
17514         {
17515           ipv6_set = 1;
17516         }
17517       else
17518         break;
17519     }
17520
17521   if (ipv4_set && ipv6_set)
17522     {
17523       errmsg ("both eid v4 and v6 addresses set");
17524       return -99;
17525     }
17526
17527   if (!ipv4_set && !ipv6_set)
17528     {
17529       errmsg ("eid addresses not set");
17530       return -99;
17531     }
17532
17533   /* Construct the API message */
17534   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
17535
17536   mp->is_add = is_add;
17537   if (ipv6_set)
17538     {
17539       mp->is_ipv6 = 1;
17540       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
17541     }
17542   else
17543     {
17544       mp->is_ipv6 = 0;
17545       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
17546     }
17547
17548   /* send it... */
17549   S (mp);
17550
17551   /* Wait for a reply... */
17552   W (ret);
17553   return ret;
17554 }
17555
17556 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
17557
17558 static int
17559 api_lisp_gpe_enable_disable (vat_main_t * vam)
17560 {
17561   unformat_input_t *input = vam->input;
17562   vl_api_gpe_enable_disable_t *mp;
17563   u8 is_set = 0;
17564   u8 is_en = 1;
17565   int ret;
17566
17567   /* Parse args required to build the message */
17568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17569     {
17570       if (unformat (input, "enable"))
17571         {
17572           is_set = 1;
17573           is_en = 1;
17574         }
17575       else if (unformat (input, "disable"))
17576         {
17577           is_set = 1;
17578           is_en = 0;
17579         }
17580       else
17581         break;
17582     }
17583
17584   if (is_set == 0)
17585     {
17586       errmsg ("Value not set");
17587       return -99;
17588     }
17589
17590   /* Construct the API message */
17591   M (GPE_ENABLE_DISABLE, mp);
17592
17593   mp->is_en = is_en;
17594
17595   /* send it... */
17596   S (mp);
17597
17598   /* Wait for a reply... */
17599   W (ret);
17600   return ret;
17601 }
17602
17603 static int
17604 api_one_rloc_probe_enable_disable (vat_main_t * vam)
17605 {
17606   unformat_input_t *input = vam->input;
17607   vl_api_one_rloc_probe_enable_disable_t *mp;
17608   u8 is_set = 0;
17609   u8 is_en = 0;
17610   int ret;
17611
17612   /* Parse args required to build the message */
17613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17614     {
17615       if (unformat (input, "enable"))
17616         {
17617           is_set = 1;
17618           is_en = 1;
17619         }
17620       else if (unformat (input, "disable"))
17621         is_set = 1;
17622       else
17623         break;
17624     }
17625
17626   if (!is_set)
17627     {
17628       errmsg ("Value not set");
17629       return -99;
17630     }
17631
17632   /* Construct the API message */
17633   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
17634
17635   mp->is_enabled = is_en;
17636
17637   /* send it... */
17638   S (mp);
17639
17640   /* Wait for a reply... */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
17646
17647 static int
17648 api_one_map_register_enable_disable (vat_main_t * vam)
17649 {
17650   unformat_input_t *input = vam->input;
17651   vl_api_one_map_register_enable_disable_t *mp;
17652   u8 is_set = 0;
17653   u8 is_en = 0;
17654   int ret;
17655
17656   /* Parse args required to build the message */
17657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17658     {
17659       if (unformat (input, "enable"))
17660         {
17661           is_set = 1;
17662           is_en = 1;
17663         }
17664       else if (unformat (input, "disable"))
17665         is_set = 1;
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_MAP_REGISTER_ENABLE_DISABLE, mp);
17678
17679   mp->is_enabled = is_en;
17680
17681   /* send it... */
17682   S (mp);
17683
17684   /* Wait for a reply... */
17685   W (ret);
17686   return ret;
17687 }
17688
17689 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
17690
17691 static int
17692 api_one_enable_disable (vat_main_t * vam)
17693 {
17694   unformat_input_t *input = vam->input;
17695   vl_api_one_enable_disable_t *mp;
17696   u8 is_set = 0;
17697   u8 is_en = 0;
17698   int ret;
17699
17700   /* Parse args required to build the message */
17701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17702     {
17703       if (unformat (input, "enable"))
17704         {
17705           is_set = 1;
17706           is_en = 1;
17707         }
17708       else if (unformat (input, "disable"))
17709         {
17710           is_set = 1;
17711         }
17712       else
17713         break;
17714     }
17715
17716   if (!is_set)
17717     {
17718       errmsg ("Value not set");
17719       return -99;
17720     }
17721
17722   /* Construct the API message */
17723   M (ONE_ENABLE_DISABLE, mp);
17724
17725   mp->is_en = is_en;
17726
17727   /* send it... */
17728   S (mp);
17729
17730   /* Wait for a reply... */
17731   W (ret);
17732   return ret;
17733 }
17734
17735 #define api_lisp_enable_disable api_one_enable_disable
17736
17737 static int
17738 api_one_enable_disable_xtr_mode (vat_main_t * vam)
17739 {
17740   unformat_input_t *input = vam->input;
17741   vl_api_one_enable_disable_xtr_mode_t *mp;
17742   u8 is_set = 0;
17743   u8 is_en = 0;
17744   int ret;
17745
17746   /* Parse args required to build the message */
17747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17748     {
17749       if (unformat (input, "enable"))
17750         {
17751           is_set = 1;
17752           is_en = 1;
17753         }
17754       else if (unformat (input, "disable"))
17755         {
17756           is_set = 1;
17757         }
17758       else
17759         break;
17760     }
17761
17762   if (!is_set)
17763     {
17764       errmsg ("Value not set");
17765       return -99;
17766     }
17767
17768   /* Construct the API message */
17769   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
17770
17771   mp->is_en = is_en;
17772
17773   /* send it... */
17774   S (mp);
17775
17776   /* Wait for a reply... */
17777   W (ret);
17778   return ret;
17779 }
17780
17781 static int
17782 api_one_show_xtr_mode (vat_main_t * vam)
17783 {
17784   vl_api_one_show_xtr_mode_t *mp;
17785   int ret;
17786
17787   /* Construct the API message */
17788   M (ONE_SHOW_XTR_MODE, mp);
17789
17790   /* send it... */
17791   S (mp);
17792
17793   /* Wait for a reply... */
17794   W (ret);
17795   return ret;
17796 }
17797
17798 static int
17799 api_one_enable_disable_pitr_mode (vat_main_t * vam)
17800 {
17801   unformat_input_t *input = vam->input;
17802   vl_api_one_enable_disable_pitr_mode_t *mp;
17803   u8 is_set = 0;
17804   u8 is_en = 0;
17805   int ret;
17806
17807   /* Parse args required to build the message */
17808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17809     {
17810       if (unformat (input, "enable"))
17811         {
17812           is_set = 1;
17813           is_en = 1;
17814         }
17815       else if (unformat (input, "disable"))
17816         {
17817           is_set = 1;
17818         }
17819       else
17820         break;
17821     }
17822
17823   if (!is_set)
17824     {
17825       errmsg ("Value not set");
17826       return -99;
17827     }
17828
17829   /* Construct the API message */
17830   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
17831
17832   mp->is_en = is_en;
17833
17834   /* send it... */
17835   S (mp);
17836
17837   /* Wait for a reply... */
17838   W (ret);
17839   return ret;
17840 }
17841
17842 static int
17843 api_one_show_pitr_mode (vat_main_t * vam)
17844 {
17845   vl_api_one_show_pitr_mode_t *mp;
17846   int ret;
17847
17848   /* Construct the API message */
17849   M (ONE_SHOW_PITR_MODE, mp);
17850
17851   /* send it... */
17852   S (mp);
17853
17854   /* Wait for a reply... */
17855   W (ret);
17856   return ret;
17857 }
17858
17859 static int
17860 api_one_enable_disable_petr_mode (vat_main_t * vam)
17861 {
17862   unformat_input_t *input = vam->input;
17863   vl_api_one_enable_disable_petr_mode_t *mp;
17864   u8 is_set = 0;
17865   u8 is_en = 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, "enable"))
17872         {
17873           is_set = 1;
17874           is_en = 1;
17875         }
17876       else if (unformat (input, "disable"))
17877         {
17878           is_set = 1;
17879         }
17880       else
17881         break;
17882     }
17883
17884   if (!is_set)
17885     {
17886       errmsg ("Value not set");
17887       return -99;
17888     }
17889
17890   /* Construct the API message */
17891   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
17892
17893   mp->is_en = is_en;
17894
17895   /* send it... */
17896   S (mp);
17897
17898   /* Wait for a reply... */
17899   W (ret);
17900   return ret;
17901 }
17902
17903 static int
17904 api_one_show_petr_mode (vat_main_t * vam)
17905 {
17906   vl_api_one_show_petr_mode_t *mp;
17907   int ret;
17908
17909   /* Construct the API message */
17910   M (ONE_SHOW_PETR_MODE, mp);
17911
17912   /* send it... */
17913   S (mp);
17914
17915   /* Wait for a reply... */
17916   W (ret);
17917   return ret;
17918 }
17919
17920 static int
17921 api_show_one_map_register_state (vat_main_t * vam)
17922 {
17923   vl_api_show_one_map_register_state_t *mp;
17924   int ret;
17925
17926   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
17927
17928   /* send */
17929   S (mp);
17930
17931   /* wait for reply */
17932   W (ret);
17933   return ret;
17934 }
17935
17936 #define api_show_lisp_map_register_state api_show_one_map_register_state
17937
17938 static int
17939 api_show_one_rloc_probe_state (vat_main_t * vam)
17940 {
17941   vl_api_show_one_rloc_probe_state_t *mp;
17942   int ret;
17943
17944   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
17945
17946   /* send */
17947   S (mp);
17948
17949   /* wait for reply */
17950   W (ret);
17951   return ret;
17952 }
17953
17954 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
17955
17956 static int
17957 api_one_add_del_ndp_entry (vat_main_t * vam)
17958 {
17959   vl_api_one_add_del_ndp_entry_t *mp;
17960   unformat_input_t *input = vam->input;
17961   u8 is_add = 1;
17962   u8 mac_set = 0;
17963   u8 bd_set = 0;
17964   u8 ip_set = 0;
17965   u8 mac[6] = { 0, };
17966   u8 ip6[16] = { 0, };
17967   u32 bd = ~0;
17968   int ret;
17969
17970   /* Parse args required to build the message */
17971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17972     {
17973       if (unformat (input, "del"))
17974         is_add = 0;
17975       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
17976         mac_set = 1;
17977       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
17978         ip_set = 1;
17979       else if (unformat (input, "bd %d", &bd))
17980         bd_set = 1;
17981       else
17982         {
17983           errmsg ("parse error '%U'", format_unformat_error, input);
17984           return -99;
17985         }
17986     }
17987
17988   if (!bd_set || !ip_set || (!mac_set && is_add))
17989     {
17990       errmsg ("Missing BD, IP or MAC!");
17991       return -99;
17992     }
17993
17994   M (ONE_ADD_DEL_NDP_ENTRY, mp);
17995   mp->is_add = is_add;
17996   clib_memcpy (mp->mac, mac, 6);
17997   mp->bd = clib_host_to_net_u32 (bd);
17998   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
17999
18000   /* send */
18001   S (mp);
18002
18003   /* wait for reply */
18004   W (ret);
18005   return ret;
18006 }
18007
18008 static int
18009 api_one_add_del_l2_arp_entry (vat_main_t * vam)
18010 {
18011   vl_api_one_add_del_l2_arp_entry_t *mp;
18012   unformat_input_t *input = vam->input;
18013   u8 is_add = 1;
18014   u8 mac_set = 0;
18015   u8 bd_set = 0;
18016   u8 ip_set = 0;
18017   u8 mac[6] = { 0, };
18018   u32 ip4 = 0, bd = ~0;
18019   int ret;
18020
18021   /* Parse args required to build the message */
18022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18023     {
18024       if (unformat (input, "del"))
18025         is_add = 0;
18026       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
18027         mac_set = 1;
18028       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
18029         ip_set = 1;
18030       else if (unformat (input, "bd %d", &bd))
18031         bd_set = 1;
18032       else
18033         {
18034           errmsg ("parse error '%U'", format_unformat_error, input);
18035           return -99;
18036         }
18037     }
18038
18039   if (!bd_set || !ip_set || (!mac_set && is_add))
18040     {
18041       errmsg ("Missing BD, IP or MAC!");
18042       return -99;
18043     }
18044
18045   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
18046   mp->is_add = is_add;
18047   clib_memcpy (mp->mac, mac, 6);
18048   mp->bd = clib_host_to_net_u32 (bd);
18049   mp->ip4 = ip4;
18050
18051   /* send */
18052   S (mp);
18053
18054   /* wait for reply */
18055   W (ret);
18056   return ret;
18057 }
18058
18059 static int
18060 api_one_ndp_bd_get (vat_main_t * vam)
18061 {
18062   vl_api_one_ndp_bd_get_t *mp;
18063   int ret;
18064
18065   M (ONE_NDP_BD_GET, mp);
18066
18067   /* send */
18068   S (mp);
18069
18070   /* wait for reply */
18071   W (ret);
18072   return ret;
18073 }
18074
18075 static int
18076 api_one_ndp_entries_get (vat_main_t * vam)
18077 {
18078   vl_api_one_ndp_entries_get_t *mp;
18079   unformat_input_t *input = vam->input;
18080   u8 bd_set = 0;
18081   u32 bd = ~0;
18082   int ret;
18083
18084   /* Parse args required to build the message */
18085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (input, "bd %d", &bd))
18088         bd_set = 1;
18089       else
18090         {
18091           errmsg ("parse error '%U'", format_unformat_error, input);
18092           return -99;
18093         }
18094     }
18095
18096   if (!bd_set)
18097     {
18098       errmsg ("Expected bridge domain!");
18099       return -99;
18100     }
18101
18102   M (ONE_NDP_ENTRIES_GET, mp);
18103   mp->bd = clib_host_to_net_u32 (bd);
18104
18105   /* send */
18106   S (mp);
18107
18108   /* wait for reply */
18109   W (ret);
18110   return ret;
18111 }
18112
18113 static int
18114 api_one_l2_arp_bd_get (vat_main_t * vam)
18115 {
18116   vl_api_one_l2_arp_bd_get_t *mp;
18117   int ret;
18118
18119   M (ONE_L2_ARP_BD_GET, mp);
18120
18121   /* send */
18122   S (mp);
18123
18124   /* wait for reply */
18125   W (ret);
18126   return ret;
18127 }
18128
18129 static int
18130 api_one_l2_arp_entries_get (vat_main_t * vam)
18131 {
18132   vl_api_one_l2_arp_entries_get_t *mp;
18133   unformat_input_t *input = vam->input;
18134   u8 bd_set = 0;
18135   u32 bd = ~0;
18136   int ret;
18137
18138   /* Parse args required to build the message */
18139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18140     {
18141       if (unformat (input, "bd %d", &bd))
18142         bd_set = 1;
18143       else
18144         {
18145           errmsg ("parse error '%U'", format_unformat_error, input);
18146           return -99;
18147         }
18148     }
18149
18150   if (!bd_set)
18151     {
18152       errmsg ("Expected bridge domain!");
18153       return -99;
18154     }
18155
18156   M (ONE_L2_ARP_ENTRIES_GET, mp);
18157   mp->bd = clib_host_to_net_u32 (bd);
18158
18159   /* send */
18160   S (mp);
18161
18162   /* wait for reply */
18163   W (ret);
18164   return ret;
18165 }
18166
18167 static int
18168 api_one_stats_enable_disable (vat_main_t * vam)
18169 {
18170   vl_api_one_stats_enable_disable_t *mp;
18171   unformat_input_t *input = vam->input;
18172   u8 is_set = 0;
18173   u8 is_en = 0;
18174   int ret;
18175
18176   /* Parse args required to build the message */
18177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18178     {
18179       if (unformat (input, "enable"))
18180         {
18181           is_set = 1;
18182           is_en = 1;
18183         }
18184       else if (unformat (input, "disable"))
18185         {
18186           is_set = 1;
18187         }
18188       else
18189         break;
18190     }
18191
18192   if (!is_set)
18193     {
18194       errmsg ("Value not set");
18195       return -99;
18196     }
18197
18198   M (ONE_STATS_ENABLE_DISABLE, mp);
18199   mp->is_en = is_en;
18200
18201   /* send */
18202   S (mp);
18203
18204   /* wait for reply */
18205   W (ret);
18206   return ret;
18207 }
18208
18209 static int
18210 api_show_one_stats_enable_disable (vat_main_t * vam)
18211 {
18212   vl_api_show_one_stats_enable_disable_t *mp;
18213   int ret;
18214
18215   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
18216
18217   /* send */
18218   S (mp);
18219
18220   /* wait for reply */
18221   W (ret);
18222   return ret;
18223 }
18224
18225 static int
18226 api_show_one_map_request_mode (vat_main_t * vam)
18227 {
18228   vl_api_show_one_map_request_mode_t *mp;
18229   int ret;
18230
18231   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
18232
18233   /* send */
18234   S (mp);
18235
18236   /* wait for reply */
18237   W (ret);
18238   return ret;
18239 }
18240
18241 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
18242
18243 static int
18244 api_one_map_request_mode (vat_main_t * vam)
18245 {
18246   unformat_input_t *input = vam->input;
18247   vl_api_one_map_request_mode_t *mp;
18248   u8 mode = 0;
18249   int ret;
18250
18251   /* Parse args required to build the message */
18252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18253     {
18254       if (unformat (input, "dst-only"))
18255         mode = 0;
18256       else if (unformat (input, "src-dst"))
18257         mode = 1;
18258       else
18259         {
18260           errmsg ("parse error '%U'", format_unformat_error, input);
18261           return -99;
18262         }
18263     }
18264
18265   M (ONE_MAP_REQUEST_MODE, mp);
18266
18267   mp->mode = mode;
18268
18269   /* send */
18270   S (mp);
18271
18272   /* wait for reply */
18273   W (ret);
18274   return ret;
18275 }
18276
18277 #define api_lisp_map_request_mode api_one_map_request_mode
18278
18279 /**
18280  * Enable/disable ONE proxy ITR.
18281  *
18282  * @param vam vpp API test context
18283  * @return return code
18284  */
18285 static int
18286 api_one_pitr_set_locator_set (vat_main_t * vam)
18287 {
18288   u8 ls_name_set = 0;
18289   unformat_input_t *input = vam->input;
18290   vl_api_one_pitr_set_locator_set_t *mp;
18291   u8 is_add = 1;
18292   u8 *ls_name = 0;
18293   int ret;
18294
18295   /* Parse args required to build the message */
18296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18297     {
18298       if (unformat (input, "del"))
18299         is_add = 0;
18300       else if (unformat (input, "locator-set %s", &ls_name))
18301         ls_name_set = 1;
18302       else
18303         {
18304           errmsg ("parse error '%U'", format_unformat_error, input);
18305           return -99;
18306         }
18307     }
18308
18309   if (!ls_name_set)
18310     {
18311       errmsg ("locator-set name not set!");
18312       return -99;
18313     }
18314
18315   M (ONE_PITR_SET_LOCATOR_SET, mp);
18316
18317   mp->is_add = is_add;
18318   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18319   vec_free (ls_name);
18320
18321   /* send */
18322   S (mp);
18323
18324   /* wait for reply */
18325   W (ret);
18326   return ret;
18327 }
18328
18329 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
18330
18331 static int
18332 api_one_nsh_set_locator_set (vat_main_t * vam)
18333 {
18334   u8 ls_name_set = 0;
18335   unformat_input_t *input = vam->input;
18336   vl_api_one_nsh_set_locator_set_t *mp;
18337   u8 is_add = 1;
18338   u8 *ls_name = 0;
18339   int ret;
18340
18341   /* Parse args required to build the message */
18342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18343     {
18344       if (unformat (input, "del"))
18345         is_add = 0;
18346       else if (unformat (input, "ls %s", &ls_name))
18347         ls_name_set = 1;
18348       else
18349         {
18350           errmsg ("parse error '%U'", format_unformat_error, input);
18351           return -99;
18352         }
18353     }
18354
18355   if (!ls_name_set && is_add)
18356     {
18357       errmsg ("locator-set name not set!");
18358       return -99;
18359     }
18360
18361   M (ONE_NSH_SET_LOCATOR_SET, mp);
18362
18363   mp->is_add = is_add;
18364   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
18365   vec_free (ls_name);
18366
18367   /* send */
18368   S (mp);
18369
18370   /* wait for reply */
18371   W (ret);
18372   return ret;
18373 }
18374
18375 static int
18376 api_show_one_pitr (vat_main_t * vam)
18377 {
18378   vl_api_show_one_pitr_t *mp;
18379   int ret;
18380
18381   if (!vam->json_output)
18382     {
18383       print (vam->ofp, "%=20s", "lisp status:");
18384     }
18385
18386   M (SHOW_ONE_PITR, mp);
18387   /* send it... */
18388   S (mp);
18389
18390   /* Wait for a reply... */
18391   W (ret);
18392   return ret;
18393 }
18394
18395 #define api_show_lisp_pitr api_show_one_pitr
18396
18397 static int
18398 api_one_use_petr (vat_main_t * vam)
18399 {
18400   unformat_input_t *input = vam->input;
18401   vl_api_one_use_petr_t *mp;
18402   u8 is_add = 0;
18403   ip_address_t ip;
18404   int ret;
18405
18406   memset (&ip, 0, sizeof (ip));
18407
18408   /* Parse args required to build the message */
18409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18410     {
18411       if (unformat (input, "disable"))
18412         is_add = 0;
18413       else
18414         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
18415         {
18416           is_add = 1;
18417           ip_addr_version (&ip) = IP4;
18418         }
18419       else
18420         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
18421         {
18422           is_add = 1;
18423           ip_addr_version (&ip) = IP6;
18424         }
18425       else
18426         {
18427           errmsg ("parse error '%U'", format_unformat_error, input);
18428           return -99;
18429         }
18430     }
18431
18432   M (ONE_USE_PETR, mp);
18433
18434   mp->is_add = is_add;
18435   if (is_add)
18436     {
18437       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
18438       if (mp->is_ip4)
18439         clib_memcpy (mp->address, &ip, 4);
18440       else
18441         clib_memcpy (mp->address, &ip, 16);
18442     }
18443
18444   /* send */
18445   S (mp);
18446
18447   /* wait for reply */
18448   W (ret);
18449   return ret;
18450 }
18451
18452 #define api_lisp_use_petr api_one_use_petr
18453
18454 static int
18455 api_show_one_nsh_mapping (vat_main_t * vam)
18456 {
18457   vl_api_show_one_use_petr_t *mp;
18458   int ret;
18459
18460   if (!vam->json_output)
18461     {
18462       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
18463     }
18464
18465   M (SHOW_ONE_NSH_MAPPING, mp);
18466   /* send it... */
18467   S (mp);
18468
18469   /* Wait for a reply... */
18470   W (ret);
18471   return ret;
18472 }
18473
18474 static int
18475 api_show_one_use_petr (vat_main_t * vam)
18476 {
18477   vl_api_show_one_use_petr_t *mp;
18478   int ret;
18479
18480   if (!vam->json_output)
18481     {
18482       print (vam->ofp, "%=20s", "Proxy-ETR status:");
18483     }
18484
18485   M (SHOW_ONE_USE_PETR, mp);
18486   /* send it... */
18487   S (mp);
18488
18489   /* Wait for a reply... */
18490   W (ret);
18491   return ret;
18492 }
18493
18494 #define api_show_lisp_use_petr api_show_one_use_petr
18495
18496 /**
18497  * Add/delete mapping between vni and vrf
18498  */
18499 static int
18500 api_one_eid_table_add_del_map (vat_main_t * vam)
18501 {
18502   unformat_input_t *input = vam->input;
18503   vl_api_one_eid_table_add_del_map_t *mp;
18504   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
18505   u32 vni, vrf, bd_index;
18506   int ret;
18507
18508   /* Parse args required to build the message */
18509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18510     {
18511       if (unformat (input, "del"))
18512         is_add = 0;
18513       else if (unformat (input, "vrf %d", &vrf))
18514         vrf_set = 1;
18515       else if (unformat (input, "bd_index %d", &bd_index))
18516         bd_index_set = 1;
18517       else if (unformat (input, "vni %d", &vni))
18518         vni_set = 1;
18519       else
18520         break;
18521     }
18522
18523   if (!vni_set || (!vrf_set && !bd_index_set))
18524     {
18525       errmsg ("missing arguments!");
18526       return -99;
18527     }
18528
18529   if (vrf_set && bd_index_set)
18530     {
18531       errmsg ("error: both vrf and bd entered!");
18532       return -99;
18533     }
18534
18535   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
18536
18537   mp->is_add = is_add;
18538   mp->vni = htonl (vni);
18539   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
18540   mp->is_l2 = bd_index_set;
18541
18542   /* send */
18543   S (mp);
18544
18545   /* wait for reply */
18546   W (ret);
18547   return ret;
18548 }
18549
18550 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
18551
18552 uword
18553 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
18554 {
18555   u32 *action = va_arg (*args, u32 *);
18556   u8 *s = 0;
18557
18558   if (unformat (input, "%s", &s))
18559     {
18560       if (!strcmp ((char *) s, "no-action"))
18561         action[0] = 0;
18562       else if (!strcmp ((char *) s, "natively-forward"))
18563         action[0] = 1;
18564       else if (!strcmp ((char *) s, "send-map-request"))
18565         action[0] = 2;
18566       else if (!strcmp ((char *) s, "drop"))
18567         action[0] = 3;
18568       else
18569         {
18570           clib_warning ("invalid action: '%s'", s);
18571           action[0] = 3;
18572         }
18573     }
18574   else
18575     return 0;
18576
18577   vec_free (s);
18578   return 1;
18579 }
18580
18581 /**
18582  * Add/del remote mapping to/from ONE control plane
18583  *
18584  * @param vam vpp API test context
18585  * @return return code
18586  */
18587 static int
18588 api_one_add_del_remote_mapping (vat_main_t * vam)
18589 {
18590   unformat_input_t *input = vam->input;
18591   vl_api_one_add_del_remote_mapping_t *mp;
18592   u32 vni = 0;
18593   lisp_eid_vat_t _eid, *eid = &_eid;
18594   lisp_eid_vat_t _seid, *seid = &_seid;
18595   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
18596   u32 action = ~0, p, w, data_len;
18597   ip4_address_t rloc4;
18598   ip6_address_t rloc6;
18599   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
18600   int ret;
18601
18602   memset (&rloc, 0, sizeof (rloc));
18603
18604   /* Parse args required to build the message */
18605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18606     {
18607       if (unformat (input, "del-all"))
18608         {
18609           del_all = 1;
18610         }
18611       else if (unformat (input, "del"))
18612         {
18613           is_add = 0;
18614         }
18615       else if (unformat (input, "add"))
18616         {
18617           is_add = 1;
18618         }
18619       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
18620         {
18621           eid_set = 1;
18622         }
18623       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
18624         {
18625           seid_set = 1;
18626         }
18627       else if (unformat (input, "vni %d", &vni))
18628         {
18629           ;
18630         }
18631       else if (unformat (input, "p %d w %d", &p, &w))
18632         {
18633           if (!curr_rloc)
18634             {
18635               errmsg ("No RLOC configured for setting priority/weight!");
18636               return -99;
18637             }
18638           curr_rloc->priority = p;
18639           curr_rloc->weight = w;
18640         }
18641       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
18642         {
18643           rloc.is_ip4 = 1;
18644           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
18645           vec_add1 (rlocs, rloc);
18646           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18647         }
18648       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
18649         {
18650           rloc.is_ip4 = 0;
18651           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
18652           vec_add1 (rlocs, rloc);
18653           curr_rloc = &rlocs[vec_len (rlocs) - 1];
18654         }
18655       else if (unformat (input, "action %U",
18656                          unformat_negative_mapping_action, &action))
18657         {
18658           ;
18659         }
18660       else
18661         {
18662           clib_warning ("parse error '%U'", format_unformat_error, input);
18663           return -99;
18664         }
18665     }
18666
18667   if (0 == eid_set)
18668     {
18669       errmsg ("missing params!");
18670       return -99;
18671     }
18672
18673   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
18674     {
18675       errmsg ("no action set for negative map-reply!");
18676       return -99;
18677     }
18678
18679   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
18680
18681   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
18682   mp->is_add = is_add;
18683   mp->vni = htonl (vni);
18684   mp->action = (u8) action;
18685   mp->is_src_dst = seid_set;
18686   mp->eid_len = eid->len;
18687   mp->seid_len = seid->len;
18688   mp->del_all = del_all;
18689   mp->eid_type = eid->type;
18690   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
18691   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
18692
18693   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
18694   clib_memcpy (mp->rlocs, rlocs, data_len);
18695   vec_free (rlocs);
18696
18697   /* send it... */
18698   S (mp);
18699
18700   /* Wait for a reply... */
18701   W (ret);
18702   return ret;
18703 }
18704
18705 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
18706
18707 /**
18708  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
18709  * forwarding entries in data-plane accordingly.
18710  *
18711  * @param vam vpp API test context
18712  * @return return code
18713  */
18714 static int
18715 api_one_add_del_adjacency (vat_main_t * vam)
18716 {
18717   unformat_input_t *input = vam->input;
18718   vl_api_one_add_del_adjacency_t *mp;
18719   u32 vni = 0;
18720   ip4_address_t leid4, reid4;
18721   ip6_address_t leid6, reid6;
18722   u8 reid_mac[6] = { 0 };
18723   u8 leid_mac[6] = { 0 };
18724   u8 reid_type, leid_type;
18725   u32 leid_len = 0, reid_len = 0, len;
18726   u8 is_add = 1;
18727   int ret;
18728
18729   leid_type = reid_type = (u8) ~ 0;
18730
18731   /* Parse args required to build the message */
18732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18733     {
18734       if (unformat (input, "del"))
18735         {
18736           is_add = 0;
18737         }
18738       else if (unformat (input, "add"))
18739         {
18740           is_add = 1;
18741         }
18742       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
18743                          &reid4, &len))
18744         {
18745           reid_type = 0;        /* ipv4 */
18746           reid_len = len;
18747         }
18748       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
18749                          &reid6, &len))
18750         {
18751           reid_type = 1;        /* ipv6 */
18752           reid_len = len;
18753         }
18754       else if (unformat (input, "reid %U", unformat_ethernet_address,
18755                          reid_mac))
18756         {
18757           reid_type = 2;        /* mac */
18758         }
18759       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
18760                          &leid4, &len))
18761         {
18762           leid_type = 0;        /* ipv4 */
18763           leid_len = len;
18764         }
18765       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
18766                          &leid6, &len))
18767         {
18768           leid_type = 1;        /* ipv6 */
18769           leid_len = len;
18770         }
18771       else if (unformat (input, "leid %U", unformat_ethernet_address,
18772                          leid_mac))
18773         {
18774           leid_type = 2;        /* mac */
18775         }
18776       else if (unformat (input, "vni %d", &vni))
18777         {
18778           ;
18779         }
18780       else
18781         {
18782           errmsg ("parse error '%U'", format_unformat_error, input);
18783           return -99;
18784         }
18785     }
18786
18787   if ((u8) ~ 0 == reid_type)
18788     {
18789       errmsg ("missing params!");
18790       return -99;
18791     }
18792
18793   if (leid_type != reid_type)
18794     {
18795       errmsg ("remote and local EIDs are of different types!");
18796       return -99;
18797     }
18798
18799   M (ONE_ADD_DEL_ADJACENCY, mp);
18800   mp->is_add = is_add;
18801   mp->vni = htonl (vni);
18802   mp->leid_len = leid_len;
18803   mp->reid_len = reid_len;
18804   mp->eid_type = reid_type;
18805
18806   switch (mp->eid_type)
18807     {
18808     case 0:
18809       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
18810       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
18811       break;
18812     case 1:
18813       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
18814       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
18815       break;
18816     case 2:
18817       clib_memcpy (mp->leid, leid_mac, 6);
18818       clib_memcpy (mp->reid, reid_mac, 6);
18819       break;
18820     default:
18821       errmsg ("unknown EID type %d!", mp->eid_type);
18822       return 0;
18823     }
18824
18825   /* send it... */
18826   S (mp);
18827
18828   /* Wait for a reply... */
18829   W (ret);
18830   return ret;
18831 }
18832
18833 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
18834
18835 uword
18836 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
18837 {
18838   u32 *mode = va_arg (*args, u32 *);
18839
18840   if (unformat (input, "lisp"))
18841     *mode = 0;
18842   else if (unformat (input, "vxlan"))
18843     *mode = 1;
18844   else
18845     return 0;
18846
18847   return 1;
18848 }
18849
18850 static int
18851 api_gpe_get_encap_mode (vat_main_t * vam)
18852 {
18853   vl_api_gpe_get_encap_mode_t *mp;
18854   int ret;
18855
18856   /* Construct the API message */
18857   M (GPE_GET_ENCAP_MODE, mp);
18858
18859   /* send it... */
18860   S (mp);
18861
18862   /* Wait for a reply... */
18863   W (ret);
18864   return ret;
18865 }
18866
18867 static int
18868 api_gpe_set_encap_mode (vat_main_t * vam)
18869 {
18870   unformat_input_t *input = vam->input;
18871   vl_api_gpe_set_encap_mode_t *mp;
18872   int ret;
18873   u32 mode = 0;
18874
18875   /* Parse args required to build the message */
18876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18877     {
18878       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
18879         ;
18880       else
18881         break;
18882     }
18883
18884   /* Construct the API message */
18885   M (GPE_SET_ENCAP_MODE, mp);
18886
18887   mp->mode = mode;
18888
18889   /* send it... */
18890   S (mp);
18891
18892   /* Wait for a reply... */
18893   W (ret);
18894   return ret;
18895 }
18896
18897 static int
18898 api_lisp_gpe_add_del_iface (vat_main_t * vam)
18899 {
18900   unformat_input_t *input = vam->input;
18901   vl_api_gpe_add_del_iface_t *mp;
18902   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
18903   u32 dp_table = 0, vni = 0;
18904   int ret;
18905
18906   /* Parse args required to build the message */
18907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18908     {
18909       if (unformat (input, "up"))
18910         {
18911           action_set = 1;
18912           is_add = 1;
18913         }
18914       else if (unformat (input, "down"))
18915         {
18916           action_set = 1;
18917           is_add = 0;
18918         }
18919       else if (unformat (input, "table_id %d", &dp_table))
18920         {
18921           dp_table_set = 1;
18922         }
18923       else if (unformat (input, "bd_id %d", &dp_table))
18924         {
18925           dp_table_set = 1;
18926           is_l2 = 1;
18927         }
18928       else if (unformat (input, "vni %d", &vni))
18929         {
18930           vni_set = 1;
18931         }
18932       else
18933         break;
18934     }
18935
18936   if (action_set == 0)
18937     {
18938       errmsg ("Action not set");
18939       return -99;
18940     }
18941   if (dp_table_set == 0 || vni_set == 0)
18942     {
18943       errmsg ("vni and dp_table must be set");
18944       return -99;
18945     }
18946
18947   /* Construct the API message */
18948   M (GPE_ADD_DEL_IFACE, mp);
18949
18950   mp->is_add = is_add;
18951   mp->dp_table = clib_host_to_net_u32 (dp_table);
18952   mp->is_l2 = is_l2;
18953   mp->vni = clib_host_to_net_u32 (vni);
18954
18955   /* send it... */
18956   S (mp);
18957
18958   /* Wait for a reply... */
18959   W (ret);
18960   return ret;
18961 }
18962
18963 static int
18964 api_one_map_register_fallback_threshold (vat_main_t * vam)
18965 {
18966   unformat_input_t *input = vam->input;
18967   vl_api_one_map_register_fallback_threshold_t *mp;
18968   u32 value = 0;
18969   u8 is_set = 0;
18970   int ret;
18971
18972   /* Parse args required to build the message */
18973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18974     {
18975       if (unformat (input, "%u", &value))
18976         is_set = 1;
18977       else
18978         {
18979           clib_warning ("parse error '%U'", format_unformat_error, input);
18980           return -99;
18981         }
18982     }
18983
18984   if (!is_set)
18985     {
18986       errmsg ("fallback threshold value is missing!");
18987       return -99;
18988     }
18989
18990   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
18991   mp->value = clib_host_to_net_u32 (value);
18992
18993   /* send it... */
18994   S (mp);
18995
18996   /* Wait for a reply... */
18997   W (ret);
18998   return ret;
18999 }
19000
19001 static int
19002 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
19003 {
19004   vl_api_show_one_map_register_fallback_threshold_t *mp;
19005   int ret;
19006
19007   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
19008
19009   /* send it... */
19010   S (mp);
19011
19012   /* Wait for a reply... */
19013   W (ret);
19014   return ret;
19015 }
19016
19017 uword
19018 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
19019 {
19020   u32 *proto = va_arg (*args, u32 *);
19021
19022   if (unformat (input, "udp"))
19023     *proto = 1;
19024   else if (unformat (input, "api"))
19025     *proto = 2;
19026   else
19027     return 0;
19028
19029   return 1;
19030 }
19031
19032 static int
19033 api_one_set_transport_protocol (vat_main_t * vam)
19034 {
19035   unformat_input_t *input = vam->input;
19036   vl_api_one_set_transport_protocol_t *mp;
19037   u8 is_set = 0;
19038   u32 protocol = 0;
19039   int ret;
19040
19041   /* Parse args required to build the message */
19042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19043     {
19044       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
19045         is_set = 1;
19046       else
19047         {
19048           clib_warning ("parse error '%U'", format_unformat_error, input);
19049           return -99;
19050         }
19051     }
19052
19053   if (!is_set)
19054     {
19055       errmsg ("Transport protocol missing!");
19056       return -99;
19057     }
19058
19059   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
19060   mp->protocol = (u8) protocol;
19061
19062   /* send it... */
19063   S (mp);
19064
19065   /* Wait for a reply... */
19066   W (ret);
19067   return ret;
19068 }
19069
19070 static int
19071 api_one_get_transport_protocol (vat_main_t * vam)
19072 {
19073   vl_api_one_get_transport_protocol_t *mp;
19074   int ret;
19075
19076   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
19077
19078   /* send it... */
19079   S (mp);
19080
19081   /* Wait for a reply... */
19082   W (ret);
19083   return ret;
19084 }
19085
19086 static int
19087 api_one_map_register_set_ttl (vat_main_t * vam)
19088 {
19089   unformat_input_t *input = vam->input;
19090   vl_api_one_map_register_set_ttl_t *mp;
19091   u32 ttl = 0;
19092   u8 is_set = 0;
19093   int ret;
19094
19095   /* Parse args required to build the message */
19096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19097     {
19098       if (unformat (input, "%u", &ttl))
19099         is_set = 1;
19100       else
19101         {
19102           clib_warning ("parse error '%U'", format_unformat_error, input);
19103           return -99;
19104         }
19105     }
19106
19107   if (!is_set)
19108     {
19109       errmsg ("TTL value missing!");
19110       return -99;
19111     }
19112
19113   M (ONE_MAP_REGISTER_SET_TTL, mp);
19114   mp->ttl = clib_host_to_net_u32 (ttl);
19115
19116   /* send it... */
19117   S (mp);
19118
19119   /* Wait for a reply... */
19120   W (ret);
19121   return ret;
19122 }
19123
19124 static int
19125 api_show_one_map_register_ttl (vat_main_t * vam)
19126 {
19127   vl_api_show_one_map_register_ttl_t *mp;
19128   int ret;
19129
19130   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
19131
19132   /* send it... */
19133   S (mp);
19134
19135   /* Wait for a reply... */
19136   W (ret);
19137   return ret;
19138 }
19139
19140 /**
19141  * Add/del map request itr rlocs from ONE control plane and updates
19142  *
19143  * @param vam vpp API test context
19144  * @return return code
19145  */
19146 static int
19147 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
19148 {
19149   unformat_input_t *input = vam->input;
19150   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
19151   u8 *locator_set_name = 0;
19152   u8 locator_set_name_set = 0;
19153   u8 is_add = 1;
19154   int ret;
19155
19156   /* Parse args required to build the message */
19157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19158     {
19159       if (unformat (input, "del"))
19160         {
19161           is_add = 0;
19162         }
19163       else if (unformat (input, "%_%v%_", &locator_set_name))
19164         {
19165           locator_set_name_set = 1;
19166         }
19167       else
19168         {
19169           clib_warning ("parse error '%U'", format_unformat_error, input);
19170           return -99;
19171         }
19172     }
19173
19174   if (is_add && !locator_set_name_set)
19175     {
19176       errmsg ("itr-rloc is not set!");
19177       return -99;
19178     }
19179
19180   if (is_add && vec_len (locator_set_name) > 64)
19181     {
19182       errmsg ("itr-rloc locator-set name too long");
19183       vec_free (locator_set_name);
19184       return -99;
19185     }
19186
19187   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
19188   mp->is_add = is_add;
19189   if (is_add)
19190     {
19191       clib_memcpy (mp->locator_set_name, locator_set_name,
19192                    vec_len (locator_set_name));
19193     }
19194   else
19195     {
19196       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
19197     }
19198   vec_free (locator_set_name);
19199
19200   /* send it... */
19201   S (mp);
19202
19203   /* Wait for a reply... */
19204   W (ret);
19205   return ret;
19206 }
19207
19208 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
19209
19210 static int
19211 api_one_locator_dump (vat_main_t * vam)
19212 {
19213   unformat_input_t *input = vam->input;
19214   vl_api_one_locator_dump_t *mp;
19215   vl_api_control_ping_t *mp_ping;
19216   u8 is_index_set = 0, is_name_set = 0;
19217   u8 *ls_name = 0;
19218   u32 ls_index = ~0;
19219   int ret;
19220
19221   /* Parse args required to build the message */
19222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19223     {
19224       if (unformat (input, "ls_name %_%v%_", &ls_name))
19225         {
19226           is_name_set = 1;
19227         }
19228       else if (unformat (input, "ls_index %d", &ls_index))
19229         {
19230           is_index_set = 1;
19231         }
19232       else
19233         {
19234           errmsg ("parse error '%U'", format_unformat_error, input);
19235           return -99;
19236         }
19237     }
19238
19239   if (!is_index_set && !is_name_set)
19240     {
19241       errmsg ("error: expected one of index or name!");
19242       return -99;
19243     }
19244
19245   if (is_index_set && is_name_set)
19246     {
19247       errmsg ("error: only one param expected!");
19248       return -99;
19249     }
19250
19251   if (vec_len (ls_name) > 62)
19252     {
19253       errmsg ("error: locator set name too long!");
19254       return -99;
19255     }
19256
19257   if (!vam->json_output)
19258     {
19259       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
19260     }
19261
19262   M (ONE_LOCATOR_DUMP, mp);
19263   mp->is_index_set = is_index_set;
19264
19265   if (is_index_set)
19266     mp->ls_index = clib_host_to_net_u32 (ls_index);
19267   else
19268     {
19269       vec_add1 (ls_name, 0);
19270       strncpy ((char *) mp->ls_name, (char *) ls_name,
19271                sizeof (mp->ls_name) - 1);
19272     }
19273
19274   /* send it... */
19275   S (mp);
19276
19277   /* Use a control ping for synchronization */
19278   MPING (CONTROL_PING, mp_ping);
19279   S (mp_ping);
19280
19281   /* Wait for a reply... */
19282   W (ret);
19283   return ret;
19284 }
19285
19286 #define api_lisp_locator_dump api_one_locator_dump
19287
19288 static int
19289 api_one_locator_set_dump (vat_main_t * vam)
19290 {
19291   vl_api_one_locator_set_dump_t *mp;
19292   vl_api_control_ping_t *mp_ping;
19293   unformat_input_t *input = vam->input;
19294   u8 filter = 0;
19295   int ret;
19296
19297   /* Parse args required to build the message */
19298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19299     {
19300       if (unformat (input, "local"))
19301         {
19302           filter = 1;
19303         }
19304       else if (unformat (input, "remote"))
19305         {
19306           filter = 2;
19307         }
19308       else
19309         {
19310           errmsg ("parse error '%U'", format_unformat_error, input);
19311           return -99;
19312         }
19313     }
19314
19315   if (!vam->json_output)
19316     {
19317       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
19318     }
19319
19320   M (ONE_LOCATOR_SET_DUMP, mp);
19321
19322   mp->filter = filter;
19323
19324   /* send it... */
19325   S (mp);
19326
19327   /* Use a control ping for synchronization */
19328   MPING (CONTROL_PING, mp_ping);
19329   S (mp_ping);
19330
19331   /* Wait for a reply... */
19332   W (ret);
19333   return ret;
19334 }
19335
19336 #define api_lisp_locator_set_dump api_one_locator_set_dump
19337
19338 static int
19339 api_one_eid_table_map_dump (vat_main_t * vam)
19340 {
19341   u8 is_l2 = 0;
19342   u8 mode_set = 0;
19343   unformat_input_t *input = vam->input;
19344   vl_api_one_eid_table_map_dump_t *mp;
19345   vl_api_control_ping_t *mp_ping;
19346   int ret;
19347
19348   /* Parse args required to build the message */
19349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19350     {
19351       if (unformat (input, "l2"))
19352         {
19353           is_l2 = 1;
19354           mode_set = 1;
19355         }
19356       else if (unformat (input, "l3"))
19357         {
19358           is_l2 = 0;
19359           mode_set = 1;
19360         }
19361       else
19362         {
19363           errmsg ("parse error '%U'", format_unformat_error, input);
19364           return -99;
19365         }
19366     }
19367
19368   if (!mode_set)
19369     {
19370       errmsg ("expected one of 'l2' or 'l3' parameter!");
19371       return -99;
19372     }
19373
19374   if (!vam->json_output)
19375     {
19376       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
19377     }
19378
19379   M (ONE_EID_TABLE_MAP_DUMP, mp);
19380   mp->is_l2 = is_l2;
19381
19382   /* send it... */
19383   S (mp);
19384
19385   /* Use a control ping for synchronization */
19386   MPING (CONTROL_PING, mp_ping);
19387   S (mp_ping);
19388
19389   /* Wait for a reply... */
19390   W (ret);
19391   return ret;
19392 }
19393
19394 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
19395
19396 static int
19397 api_one_eid_table_vni_dump (vat_main_t * vam)
19398 {
19399   vl_api_one_eid_table_vni_dump_t *mp;
19400   vl_api_control_ping_t *mp_ping;
19401   int ret;
19402
19403   if (!vam->json_output)
19404     {
19405       print (vam->ofp, "VNI");
19406     }
19407
19408   M (ONE_EID_TABLE_VNI_DUMP, mp);
19409
19410   /* send it... */
19411   S (mp);
19412
19413   /* Use a control ping for synchronization */
19414   MPING (CONTROL_PING, mp_ping);
19415   S (mp_ping);
19416
19417   /* Wait for a reply... */
19418   W (ret);
19419   return ret;
19420 }
19421
19422 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
19423
19424 static int
19425 api_one_eid_table_dump (vat_main_t * vam)
19426 {
19427   unformat_input_t *i = vam->input;
19428   vl_api_one_eid_table_dump_t *mp;
19429   vl_api_control_ping_t *mp_ping;
19430   struct in_addr ip4;
19431   struct in6_addr ip6;
19432   u8 mac[6];
19433   u8 eid_type = ~0, eid_set = 0;
19434   u32 prefix_length = ~0, t, vni = 0;
19435   u8 filter = 0;
19436   int ret;
19437   lisp_nsh_api_t nsh;
19438
19439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19440     {
19441       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
19442         {
19443           eid_set = 1;
19444           eid_type = 0;
19445           prefix_length = t;
19446         }
19447       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
19448         {
19449           eid_set = 1;
19450           eid_type = 1;
19451           prefix_length = t;
19452         }
19453       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
19454         {
19455           eid_set = 1;
19456           eid_type = 2;
19457         }
19458       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
19459         {
19460           eid_set = 1;
19461           eid_type = 3;
19462         }
19463       else if (unformat (i, "vni %d", &t))
19464         {
19465           vni = t;
19466         }
19467       else if (unformat (i, "local"))
19468         {
19469           filter = 1;
19470         }
19471       else if (unformat (i, "remote"))
19472         {
19473           filter = 2;
19474         }
19475       else
19476         {
19477           errmsg ("parse error '%U'", format_unformat_error, i);
19478           return -99;
19479         }
19480     }
19481
19482   if (!vam->json_output)
19483     {
19484       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
19485              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
19486     }
19487
19488   M (ONE_EID_TABLE_DUMP, mp);
19489
19490   mp->filter = filter;
19491   if (eid_set)
19492     {
19493       mp->eid_set = 1;
19494       mp->vni = htonl (vni);
19495       mp->eid_type = eid_type;
19496       switch (eid_type)
19497         {
19498         case 0:
19499           mp->prefix_length = prefix_length;
19500           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
19501           break;
19502         case 1:
19503           mp->prefix_length = prefix_length;
19504           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
19505           break;
19506         case 2:
19507           clib_memcpy (mp->eid, mac, sizeof (mac));
19508           break;
19509         case 3:
19510           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
19511           break;
19512         default:
19513           errmsg ("unknown EID type %d!", eid_type);
19514           return -99;
19515         }
19516     }
19517
19518   /* send it... */
19519   S (mp);
19520
19521   /* Use a control ping for synchronization */
19522   MPING (CONTROL_PING, mp_ping);
19523   S (mp_ping);
19524
19525   /* Wait for a reply... */
19526   W (ret);
19527   return ret;
19528 }
19529
19530 #define api_lisp_eid_table_dump api_one_eid_table_dump
19531
19532 static int
19533 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
19534 {
19535   unformat_input_t *i = vam->input;
19536   vl_api_gpe_fwd_entries_get_t *mp;
19537   u8 vni_set = 0;
19538   u32 vni = ~0;
19539   int ret;
19540
19541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19542     {
19543       if (unformat (i, "vni %d", &vni))
19544         {
19545           vni_set = 1;
19546         }
19547       else
19548         {
19549           errmsg ("parse error '%U'", format_unformat_error, i);
19550           return -99;
19551         }
19552     }
19553
19554   if (!vni_set)
19555     {
19556       errmsg ("vni not set!");
19557       return -99;
19558     }
19559
19560   if (!vam->json_output)
19561     {
19562       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
19563              "leid", "reid");
19564     }
19565
19566   M (GPE_FWD_ENTRIES_GET, mp);
19567   mp->vni = clib_host_to_net_u32 (vni);
19568
19569   /* send it... */
19570   S (mp);
19571
19572   /* Wait for a reply... */
19573   W (ret);
19574   return ret;
19575 }
19576
19577 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
19578 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
19579 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
19580 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
19581 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
19582 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
19583 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
19584 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
19585
19586 static int
19587 api_one_adjacencies_get (vat_main_t * vam)
19588 {
19589   unformat_input_t *i = vam->input;
19590   vl_api_one_adjacencies_get_t *mp;
19591   u8 vni_set = 0;
19592   u32 vni = ~0;
19593   int ret;
19594
19595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19596     {
19597       if (unformat (i, "vni %d", &vni))
19598         {
19599           vni_set = 1;
19600         }
19601       else
19602         {
19603           errmsg ("parse error '%U'", format_unformat_error, i);
19604           return -99;
19605         }
19606     }
19607
19608   if (!vni_set)
19609     {
19610       errmsg ("vni not set!");
19611       return -99;
19612     }
19613
19614   if (!vam->json_output)
19615     {
19616       print (vam->ofp, "%s %40s", "leid", "reid");
19617     }
19618
19619   M (ONE_ADJACENCIES_GET, mp);
19620   mp->vni = clib_host_to_net_u32 (vni);
19621
19622   /* send it... */
19623   S (mp);
19624
19625   /* Wait for a reply... */
19626   W (ret);
19627   return ret;
19628 }
19629
19630 #define api_lisp_adjacencies_get api_one_adjacencies_get
19631
19632 static int
19633 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
19634 {
19635   unformat_input_t *i = vam->input;
19636   vl_api_gpe_native_fwd_rpaths_get_t *mp;
19637   int ret;
19638   u8 ip_family_set = 0, is_ip4 = 1;
19639
19640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19641     {
19642       if (unformat (i, "ip4"))
19643         {
19644           ip_family_set = 1;
19645           is_ip4 = 1;
19646         }
19647       else if (unformat (i, "ip6"))
19648         {
19649           ip_family_set = 1;
19650           is_ip4 = 0;
19651         }
19652       else
19653         {
19654           errmsg ("parse error '%U'", format_unformat_error, i);
19655           return -99;
19656         }
19657     }
19658
19659   if (!ip_family_set)
19660     {
19661       errmsg ("ip family not set!");
19662       return -99;
19663     }
19664
19665   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
19666   mp->is_ip4 = is_ip4;
19667
19668   /* send it... */
19669   S (mp);
19670
19671   /* Wait for a reply... */
19672   W (ret);
19673   return ret;
19674 }
19675
19676 static int
19677 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
19678 {
19679   vl_api_gpe_fwd_entry_vnis_get_t *mp;
19680   int ret;
19681
19682   if (!vam->json_output)
19683     {
19684       print (vam->ofp, "VNIs");
19685     }
19686
19687   M (GPE_FWD_ENTRY_VNIS_GET, mp);
19688
19689   /* send it... */
19690   S (mp);
19691
19692   /* Wait for a reply... */
19693   W (ret);
19694   return ret;
19695 }
19696
19697 static int
19698 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
19699 {
19700   unformat_input_t *i = vam->input;
19701   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
19702   int ret = 0;
19703   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
19704   struct in_addr ip4;
19705   struct in6_addr ip6;
19706   u32 table_id = 0, nh_sw_if_index = ~0;
19707
19708   memset (&ip4, 0, sizeof (ip4));
19709   memset (&ip6, 0, sizeof (ip6));
19710
19711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19712     {
19713       if (unformat (i, "del"))
19714         is_add = 0;
19715       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
19716                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19717         {
19718           ip_set = 1;
19719           is_ip4 = 1;
19720         }
19721       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
19722                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
19723         {
19724           ip_set = 1;
19725           is_ip4 = 0;
19726         }
19727       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
19728         {
19729           ip_set = 1;
19730           is_ip4 = 1;
19731           nh_sw_if_index = ~0;
19732         }
19733       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
19734         {
19735           ip_set = 1;
19736           is_ip4 = 0;
19737           nh_sw_if_index = ~0;
19738         }
19739       else if (unformat (i, "table %d", &table_id))
19740         ;
19741       else
19742         {
19743           errmsg ("parse error '%U'", format_unformat_error, i);
19744           return -99;
19745         }
19746     }
19747
19748   if (!ip_set)
19749     {
19750       errmsg ("nh addr not set!");
19751       return -99;
19752     }
19753
19754   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
19755   mp->is_add = is_add;
19756   mp->table_id = clib_host_to_net_u32 (table_id);
19757   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
19758   mp->is_ip4 = is_ip4;
19759   if (is_ip4)
19760     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
19761   else
19762     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
19763
19764   /* send it... */
19765   S (mp);
19766
19767   /* Wait for a reply... */
19768   W (ret);
19769   return ret;
19770 }
19771
19772 static int
19773 api_one_map_server_dump (vat_main_t * vam)
19774 {
19775   vl_api_one_map_server_dump_t *mp;
19776   vl_api_control_ping_t *mp_ping;
19777   int ret;
19778
19779   if (!vam->json_output)
19780     {
19781       print (vam->ofp, "%=20s", "Map server");
19782     }
19783
19784   M (ONE_MAP_SERVER_DUMP, mp);
19785   /* send it... */
19786   S (mp);
19787
19788   /* Use a control ping for synchronization */
19789   MPING (CONTROL_PING, mp_ping);
19790   S (mp_ping);
19791
19792   /* Wait for a reply... */
19793   W (ret);
19794   return ret;
19795 }
19796
19797 #define api_lisp_map_server_dump api_one_map_server_dump
19798
19799 static int
19800 api_one_map_resolver_dump (vat_main_t * vam)
19801 {
19802   vl_api_one_map_resolver_dump_t *mp;
19803   vl_api_control_ping_t *mp_ping;
19804   int ret;
19805
19806   if (!vam->json_output)
19807     {
19808       print (vam->ofp, "%=20s", "Map resolver");
19809     }
19810
19811   M (ONE_MAP_RESOLVER_DUMP, mp);
19812   /* send it... */
19813   S (mp);
19814
19815   /* Use a control ping for synchronization */
19816   MPING (CONTROL_PING, mp_ping);
19817   S (mp_ping);
19818
19819   /* Wait for a reply... */
19820   W (ret);
19821   return ret;
19822 }
19823
19824 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
19825
19826 static int
19827 api_one_stats_flush (vat_main_t * vam)
19828 {
19829   vl_api_one_stats_flush_t *mp;
19830   int ret = 0;
19831
19832   M (ONE_STATS_FLUSH, mp);
19833   S (mp);
19834   W (ret);
19835   return ret;
19836 }
19837
19838 static int
19839 api_one_stats_dump (vat_main_t * vam)
19840 {
19841   vl_api_one_stats_dump_t *mp;
19842   vl_api_control_ping_t *mp_ping;
19843   int ret;
19844
19845   M (ONE_STATS_DUMP, mp);
19846   /* send it... */
19847   S (mp);
19848
19849   /* Use a control ping for synchronization */
19850   MPING (CONTROL_PING, mp_ping);
19851   S (mp_ping);
19852
19853   /* Wait for a reply... */
19854   W (ret);
19855   return ret;
19856 }
19857
19858 static int
19859 api_show_one_status (vat_main_t * vam)
19860 {
19861   vl_api_show_one_status_t *mp;
19862   int ret;
19863
19864   if (!vam->json_output)
19865     {
19866       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
19867     }
19868
19869   M (SHOW_ONE_STATUS, mp);
19870   /* send it... */
19871   S (mp);
19872   /* Wait for a reply... */
19873   W (ret);
19874   return ret;
19875 }
19876
19877 #define api_show_lisp_status api_show_one_status
19878
19879 static int
19880 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
19881 {
19882   vl_api_gpe_fwd_entry_path_dump_t *mp;
19883   vl_api_control_ping_t *mp_ping;
19884   unformat_input_t *i = vam->input;
19885   u32 fwd_entry_index = ~0;
19886   int ret;
19887
19888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19889     {
19890       if (unformat (i, "index %d", &fwd_entry_index))
19891         ;
19892       else
19893         break;
19894     }
19895
19896   if (~0 == fwd_entry_index)
19897     {
19898       errmsg ("no index specified!");
19899       return -99;
19900     }
19901
19902   if (!vam->json_output)
19903     {
19904       print (vam->ofp, "first line");
19905     }
19906
19907   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
19908
19909   /* send it... */
19910   S (mp);
19911   /* Use a control ping for synchronization */
19912   MPING (CONTROL_PING, mp_ping);
19913   S (mp_ping);
19914
19915   /* Wait for a reply... */
19916   W (ret);
19917   return ret;
19918 }
19919
19920 static int
19921 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
19922 {
19923   vl_api_one_get_map_request_itr_rlocs_t *mp;
19924   int ret;
19925
19926   if (!vam->json_output)
19927     {
19928       print (vam->ofp, "%=20s", "itr-rlocs:");
19929     }
19930
19931   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
19932   /* send it... */
19933   S (mp);
19934   /* Wait for a reply... */
19935   W (ret);
19936   return ret;
19937 }
19938
19939 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
19940
19941 static int
19942 api_af_packet_create (vat_main_t * vam)
19943 {
19944   unformat_input_t *i = vam->input;
19945   vl_api_af_packet_create_t *mp;
19946   u8 *host_if_name = 0;
19947   u8 hw_addr[6];
19948   u8 random_hw_addr = 1;
19949   int ret;
19950
19951   memset (hw_addr, 0, sizeof (hw_addr));
19952
19953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19954     {
19955       if (unformat (i, "name %s", &host_if_name))
19956         vec_add1 (host_if_name, 0);
19957       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19958         random_hw_addr = 0;
19959       else
19960         break;
19961     }
19962
19963   if (!vec_len (host_if_name))
19964     {
19965       errmsg ("host-interface name must be specified");
19966       return -99;
19967     }
19968
19969   if (vec_len (host_if_name) > 64)
19970     {
19971       errmsg ("host-interface name too long");
19972       return -99;
19973     }
19974
19975   M (AF_PACKET_CREATE, mp);
19976
19977   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
19978   clib_memcpy (mp->hw_addr, hw_addr, 6);
19979   mp->use_random_hw_addr = random_hw_addr;
19980   vec_free (host_if_name);
19981
19982   S (mp);
19983
19984   /* *INDENT-OFF* */
19985   W2 (ret,
19986       ({
19987         if (ret == 0)
19988           fprintf (vam->ofp ? vam->ofp : stderr,
19989                    " new sw_if_index = %d\n", vam->sw_if_index);
19990       }));
19991   /* *INDENT-ON* */
19992   return ret;
19993 }
19994
19995 static int
19996 api_af_packet_delete (vat_main_t * vam)
19997 {
19998   unformat_input_t *i = vam->input;
19999   vl_api_af_packet_delete_t *mp;
20000   u8 *host_if_name = 0;
20001   int ret;
20002
20003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20004     {
20005       if (unformat (i, "name %s", &host_if_name))
20006         vec_add1 (host_if_name, 0);
20007       else
20008         break;
20009     }
20010
20011   if (!vec_len (host_if_name))
20012     {
20013       errmsg ("host-interface name must be specified");
20014       return -99;
20015     }
20016
20017   if (vec_len (host_if_name) > 64)
20018     {
20019       errmsg ("host-interface name too long");
20020       return -99;
20021     }
20022
20023   M (AF_PACKET_DELETE, mp);
20024
20025   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
20026   vec_free (host_if_name);
20027
20028   S (mp);
20029   W (ret);
20030   return ret;
20031 }
20032
20033 static void vl_api_af_packet_details_t_handler
20034   (vl_api_af_packet_details_t * mp)
20035 {
20036   vat_main_t *vam = &vat_main;
20037
20038   print (vam->ofp, "%-16s %d",
20039          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
20040 }
20041
20042 static void vl_api_af_packet_details_t_handler_json
20043   (vl_api_af_packet_details_t * mp)
20044 {
20045   vat_main_t *vam = &vat_main;
20046   vat_json_node_t *node = NULL;
20047
20048   if (VAT_JSON_ARRAY != vam->json_tree.type)
20049     {
20050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20051       vat_json_init_array (&vam->json_tree);
20052     }
20053   node = vat_json_array_add (&vam->json_tree);
20054
20055   vat_json_init_object (node);
20056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20057   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
20058 }
20059
20060 static int
20061 api_af_packet_dump (vat_main_t * vam)
20062 {
20063   vl_api_af_packet_dump_t *mp;
20064   vl_api_control_ping_t *mp_ping;
20065   int ret;
20066
20067   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
20068   /* Get list of tap interfaces */
20069   M (AF_PACKET_DUMP, mp);
20070   S (mp);
20071
20072   /* Use a control ping for synchronization */
20073   MPING (CONTROL_PING, mp_ping);
20074   S (mp_ping);
20075
20076   W (ret);
20077   return ret;
20078 }
20079
20080 static int
20081 api_policer_add_del (vat_main_t * vam)
20082 {
20083   unformat_input_t *i = vam->input;
20084   vl_api_policer_add_del_t *mp;
20085   u8 is_add = 1;
20086   u8 *name = 0;
20087   u32 cir = 0;
20088   u32 eir = 0;
20089   u64 cb = 0;
20090   u64 eb = 0;
20091   u8 rate_type = 0;
20092   u8 round_type = 0;
20093   u8 type = 0;
20094   u8 color_aware = 0;
20095   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
20096   int ret;
20097
20098   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
20099   conform_action.dscp = 0;
20100   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
20101   exceed_action.dscp = 0;
20102   violate_action.action_type = SSE2_QOS_ACTION_DROP;
20103   violate_action.dscp = 0;
20104
20105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20106     {
20107       if (unformat (i, "del"))
20108         is_add = 0;
20109       else if (unformat (i, "name %s", &name))
20110         vec_add1 (name, 0);
20111       else if (unformat (i, "cir %u", &cir))
20112         ;
20113       else if (unformat (i, "eir %u", &eir))
20114         ;
20115       else if (unformat (i, "cb %u", &cb))
20116         ;
20117       else if (unformat (i, "eb %u", &eb))
20118         ;
20119       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
20120                          &rate_type))
20121         ;
20122       else if (unformat (i, "round_type %U", unformat_policer_round_type,
20123                          &round_type))
20124         ;
20125       else if (unformat (i, "type %U", unformat_policer_type, &type))
20126         ;
20127       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
20128                          &conform_action))
20129         ;
20130       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
20131                          &exceed_action))
20132         ;
20133       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
20134                          &violate_action))
20135         ;
20136       else if (unformat (i, "color-aware"))
20137         color_aware = 1;
20138       else
20139         break;
20140     }
20141
20142   if (!vec_len (name))
20143     {
20144       errmsg ("policer name must be specified");
20145       return -99;
20146     }
20147
20148   if (vec_len (name) > 64)
20149     {
20150       errmsg ("policer name too long");
20151       return -99;
20152     }
20153
20154   M (POLICER_ADD_DEL, mp);
20155
20156   clib_memcpy (mp->name, name, vec_len (name));
20157   vec_free (name);
20158   mp->is_add = is_add;
20159   mp->cir = ntohl (cir);
20160   mp->eir = ntohl (eir);
20161   mp->cb = clib_net_to_host_u64 (cb);
20162   mp->eb = clib_net_to_host_u64 (eb);
20163   mp->rate_type = rate_type;
20164   mp->round_type = round_type;
20165   mp->type = type;
20166   mp->conform_action_type = conform_action.action_type;
20167   mp->conform_dscp = conform_action.dscp;
20168   mp->exceed_action_type = exceed_action.action_type;
20169   mp->exceed_dscp = exceed_action.dscp;
20170   mp->violate_action_type = violate_action.action_type;
20171   mp->violate_dscp = violate_action.dscp;
20172   mp->color_aware = color_aware;
20173
20174   S (mp);
20175   W (ret);
20176   return ret;
20177 }
20178
20179 static int
20180 api_policer_dump (vat_main_t * vam)
20181 {
20182   unformat_input_t *i = vam->input;
20183   vl_api_policer_dump_t *mp;
20184   vl_api_control_ping_t *mp_ping;
20185   u8 *match_name = 0;
20186   u8 match_name_valid = 0;
20187   int ret;
20188
20189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20190     {
20191       if (unformat (i, "name %s", &match_name))
20192         {
20193           vec_add1 (match_name, 0);
20194           match_name_valid = 1;
20195         }
20196       else
20197         break;
20198     }
20199
20200   M (POLICER_DUMP, mp);
20201   mp->match_name_valid = match_name_valid;
20202   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
20203   vec_free (match_name);
20204   /* send it... */
20205   S (mp);
20206
20207   /* Use a control ping for synchronization */
20208   MPING (CONTROL_PING, mp_ping);
20209   S (mp_ping);
20210
20211   /* Wait for a reply... */
20212   W (ret);
20213   return ret;
20214 }
20215
20216 static int
20217 api_policer_classify_set_interface (vat_main_t * vam)
20218 {
20219   unformat_input_t *i = vam->input;
20220   vl_api_policer_classify_set_interface_t *mp;
20221   u32 sw_if_index;
20222   int sw_if_index_set;
20223   u32 ip4_table_index = ~0;
20224   u32 ip6_table_index = ~0;
20225   u32 l2_table_index = ~0;
20226   u8 is_add = 1;
20227   int ret;
20228
20229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20230     {
20231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20232         sw_if_index_set = 1;
20233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20234         sw_if_index_set = 1;
20235       else if (unformat (i, "del"))
20236         is_add = 0;
20237       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20238         ;
20239       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20240         ;
20241       else if (unformat (i, "l2-table %d", &l2_table_index))
20242         ;
20243       else
20244         {
20245           clib_warning ("parse error '%U'", format_unformat_error, i);
20246           return -99;
20247         }
20248     }
20249
20250   if (sw_if_index_set == 0)
20251     {
20252       errmsg ("missing interface name or sw_if_index");
20253       return -99;
20254     }
20255
20256   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
20257
20258   mp->sw_if_index = ntohl (sw_if_index);
20259   mp->ip4_table_index = ntohl (ip4_table_index);
20260   mp->ip6_table_index = ntohl (ip6_table_index);
20261   mp->l2_table_index = ntohl (l2_table_index);
20262   mp->is_add = is_add;
20263
20264   S (mp);
20265   W (ret);
20266   return ret;
20267 }
20268
20269 static int
20270 api_policer_classify_dump (vat_main_t * vam)
20271 {
20272   unformat_input_t *i = vam->input;
20273   vl_api_policer_classify_dump_t *mp;
20274   vl_api_control_ping_t *mp_ping;
20275   u8 type = POLICER_CLASSIFY_N_TABLES;
20276   int ret;
20277
20278   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
20279     ;
20280   else
20281     {
20282       errmsg ("classify table type must be specified");
20283       return -99;
20284     }
20285
20286   if (!vam->json_output)
20287     {
20288       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20289     }
20290
20291   M (POLICER_CLASSIFY_DUMP, mp);
20292   mp->type = type;
20293   /* send it... */
20294   S (mp);
20295
20296   /* Use a control ping for synchronization */
20297   MPING (CONTROL_PING, mp_ping);
20298   S (mp_ping);
20299
20300   /* Wait for a reply... */
20301   W (ret);
20302   return ret;
20303 }
20304
20305 static int
20306 api_netmap_create (vat_main_t * vam)
20307 {
20308   unformat_input_t *i = vam->input;
20309   vl_api_netmap_create_t *mp;
20310   u8 *if_name = 0;
20311   u8 hw_addr[6];
20312   u8 random_hw_addr = 1;
20313   u8 is_pipe = 0;
20314   u8 is_master = 0;
20315   int ret;
20316
20317   memset (hw_addr, 0, sizeof (hw_addr));
20318
20319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20320     {
20321       if (unformat (i, "name %s", &if_name))
20322         vec_add1 (if_name, 0);
20323       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
20324         random_hw_addr = 0;
20325       else if (unformat (i, "pipe"))
20326         is_pipe = 1;
20327       else if (unformat (i, "master"))
20328         is_master = 1;
20329       else if (unformat (i, "slave"))
20330         is_master = 0;
20331       else
20332         break;
20333     }
20334
20335   if (!vec_len (if_name))
20336     {
20337       errmsg ("interface name must be specified");
20338       return -99;
20339     }
20340
20341   if (vec_len (if_name) > 64)
20342     {
20343       errmsg ("interface name too long");
20344       return -99;
20345     }
20346
20347   M (NETMAP_CREATE, mp);
20348
20349   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20350   clib_memcpy (mp->hw_addr, hw_addr, 6);
20351   mp->use_random_hw_addr = random_hw_addr;
20352   mp->is_pipe = is_pipe;
20353   mp->is_master = is_master;
20354   vec_free (if_name);
20355
20356   S (mp);
20357   W (ret);
20358   return ret;
20359 }
20360
20361 static int
20362 api_netmap_delete (vat_main_t * vam)
20363 {
20364   unformat_input_t *i = vam->input;
20365   vl_api_netmap_delete_t *mp;
20366   u8 *if_name = 0;
20367   int ret;
20368
20369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20370     {
20371       if (unformat (i, "name %s", &if_name))
20372         vec_add1 (if_name, 0);
20373       else
20374         break;
20375     }
20376
20377   if (!vec_len (if_name))
20378     {
20379       errmsg ("interface name must be specified");
20380       return -99;
20381     }
20382
20383   if (vec_len (if_name) > 64)
20384     {
20385       errmsg ("interface name too long");
20386       return -99;
20387     }
20388
20389   M (NETMAP_DELETE, mp);
20390
20391   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
20392   vec_free (if_name);
20393
20394   S (mp);
20395   W (ret);
20396   return ret;
20397 }
20398
20399 static void
20400 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
20401 {
20402   if (fp->afi == IP46_TYPE_IP6)
20403     print (vam->ofp,
20404            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20405            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20406            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20407            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20408            format_ip6_address, fp->next_hop);
20409   else if (fp->afi == IP46_TYPE_IP4)
20410     print (vam->ofp,
20411            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20412            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20413            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20414            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20415            format_ip4_address, fp->next_hop);
20416 }
20417
20418 static void
20419 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
20420                                  vl_api_fib_path_t * fp)
20421 {
20422   struct in_addr ip4;
20423   struct in6_addr ip6;
20424
20425   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20426   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20427   vat_json_object_add_uint (node, "is_local", fp->is_local);
20428   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20429   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20430   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20431   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20432   if (fp->afi == IP46_TYPE_IP4)
20433     {
20434       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20435       vat_json_object_add_ip4 (node, "next_hop", ip4);
20436     }
20437   else if (fp->afi == IP46_TYPE_IP6)
20438     {
20439       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20440       vat_json_object_add_ip6 (node, "next_hop", ip6);
20441     }
20442 }
20443
20444 static void
20445 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
20446 {
20447   vat_main_t *vam = &vat_main;
20448   int count = ntohl (mp->mt_count);
20449   vl_api_fib_path_t *fp;
20450   i32 i;
20451
20452   print (vam->ofp, "[%d]: sw_if_index %d via:",
20453          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
20454   fp = mp->mt_paths;
20455   for (i = 0; i < count; i++)
20456     {
20457       vl_api_mpls_fib_path_print (vam, fp);
20458       fp++;
20459     }
20460
20461   print (vam->ofp, "");
20462 }
20463
20464 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
20465 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
20466
20467 static void
20468 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
20469 {
20470   vat_main_t *vam = &vat_main;
20471   vat_json_node_t *node = NULL;
20472   int count = ntohl (mp->mt_count);
20473   vl_api_fib_path_t *fp;
20474   i32 i;
20475
20476   if (VAT_JSON_ARRAY != vam->json_tree.type)
20477     {
20478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20479       vat_json_init_array (&vam->json_tree);
20480     }
20481   node = vat_json_array_add (&vam->json_tree);
20482
20483   vat_json_init_object (node);
20484   vat_json_object_add_uint (node, "tunnel_index",
20485                             ntohl (mp->mt_tunnel_index));
20486   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
20487
20488   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
20489
20490   fp = mp->mt_paths;
20491   for (i = 0; i < count; i++)
20492     {
20493       vl_api_mpls_fib_path_json_print (node, fp);
20494       fp++;
20495     }
20496 }
20497
20498 static int
20499 api_mpls_tunnel_dump (vat_main_t * vam)
20500 {
20501   vl_api_mpls_tunnel_dump_t *mp;
20502   vl_api_control_ping_t *mp_ping;
20503   u32 sw_if_index = ~0;
20504   int ret;
20505
20506   /* Parse args required to build the message */
20507   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
20508     {
20509       if (unformat (vam->input, "sw_if_index %d", &sw_if_index))
20510         ;
20511     }
20512
20513   print (vam->ofp, "  sw_if_index %d", sw_if_index);
20514
20515   M (MPLS_TUNNEL_DUMP, mp);
20516   mp->sw_if_index = htonl (sw_if_index);
20517   S (mp);
20518
20519   /* Use a control ping for synchronization */
20520   MPING (CONTROL_PING, mp_ping);
20521   S (mp_ping);
20522
20523   W (ret);
20524   return ret;
20525 }
20526
20527 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
20528 #define vl_api_mpls_fib_details_t_print vl_noop_handler
20529
20530
20531 static void
20532 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
20533 {
20534   vat_main_t *vam = &vat_main;
20535   int count = ntohl (mp->count);
20536   vl_api_fib_path_t *fp;
20537   int i;
20538
20539   print (vam->ofp,
20540          "table-id %d, label %u, ess_bit %u",
20541          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
20542   fp = mp->path;
20543   for (i = 0; i < count; i++)
20544     {
20545       vl_api_mpls_fib_path_print (vam, fp);
20546       fp++;
20547     }
20548 }
20549
20550 static void vl_api_mpls_fib_details_t_handler_json
20551   (vl_api_mpls_fib_details_t * mp)
20552 {
20553   vat_main_t *vam = &vat_main;
20554   int count = ntohl (mp->count);
20555   vat_json_node_t *node = NULL;
20556   vl_api_fib_path_t *fp;
20557   int i;
20558
20559   if (VAT_JSON_ARRAY != vam->json_tree.type)
20560     {
20561       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20562       vat_json_init_array (&vam->json_tree);
20563     }
20564   node = vat_json_array_add (&vam->json_tree);
20565
20566   vat_json_init_object (node);
20567   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20568   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
20569   vat_json_object_add_uint (node, "label", ntohl (mp->label));
20570   vat_json_object_add_uint (node, "path_count", count);
20571   fp = mp->path;
20572   for (i = 0; i < count; i++)
20573     {
20574       vl_api_mpls_fib_path_json_print (node, fp);
20575       fp++;
20576     }
20577 }
20578
20579 static int
20580 api_mpls_fib_dump (vat_main_t * vam)
20581 {
20582   vl_api_mpls_fib_dump_t *mp;
20583   vl_api_control_ping_t *mp_ping;
20584   int ret;
20585
20586   M (MPLS_FIB_DUMP, mp);
20587   S (mp);
20588
20589   /* Use a control ping for synchronization */
20590   MPING (CONTROL_PING, mp_ping);
20591   S (mp_ping);
20592
20593   W (ret);
20594   return ret;
20595 }
20596
20597 #define vl_api_ip_fib_details_t_endian vl_noop_handler
20598 #define vl_api_ip_fib_details_t_print vl_noop_handler
20599
20600 static void
20601 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
20602 {
20603   vat_main_t *vam = &vat_main;
20604   int count = ntohl (mp->count);
20605   vl_api_fib_path_t *fp;
20606   int i;
20607
20608   print (vam->ofp,
20609          "table-id %d, prefix %U/%d stats-index %d",
20610          ntohl (mp->table_id), format_ip4_address, mp->address,
20611          mp->address_length, ntohl (mp->stats_index));
20612   fp = mp->path;
20613   for (i = 0; i < count; i++)
20614     {
20615       if (fp->afi == IP46_TYPE_IP6)
20616         print (vam->ofp,
20617                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20618                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20619                "next_hop_table %d",
20620                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20621                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20622                format_ip6_address, fp->next_hop, ntohl (fp->table_id));
20623       else if (fp->afi == IP46_TYPE_IP4)
20624         print (vam->ofp,
20625                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20626                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U, "
20627                "next_hop_table %d",
20628                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20629                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20630                format_ip4_address, fp->next_hop, ntohl (fp->table_id));
20631       fp++;
20632     }
20633 }
20634
20635 static void vl_api_ip_fib_details_t_handler_json
20636   (vl_api_ip_fib_details_t * mp)
20637 {
20638   vat_main_t *vam = &vat_main;
20639   int count = ntohl (mp->count);
20640   vat_json_node_t *node = NULL;
20641   struct in_addr ip4;
20642   struct in6_addr ip6;
20643   vl_api_fib_path_t *fp;
20644   int i;
20645
20646   if (VAT_JSON_ARRAY != vam->json_tree.type)
20647     {
20648       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20649       vat_json_init_array (&vam->json_tree);
20650     }
20651   node = vat_json_array_add (&vam->json_tree);
20652
20653   vat_json_init_object (node);
20654   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20655   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
20656   vat_json_object_add_ip4 (node, "prefix", ip4);
20657   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20658   vat_json_object_add_uint (node, "path_count", count);
20659   fp = mp->path;
20660   for (i = 0; i < count; i++)
20661     {
20662       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20663       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20664       vat_json_object_add_uint (node, "is_local", fp->is_local);
20665       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20666       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20667       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20668       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20669       if (fp->afi == IP46_TYPE_IP4)
20670         {
20671           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20672           vat_json_object_add_ip4 (node, "next_hop", ip4);
20673         }
20674       else if (fp->afi == IP46_TYPE_IP6)
20675         {
20676           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20677           vat_json_object_add_ip6 (node, "next_hop", ip6);
20678         }
20679     }
20680 }
20681
20682 static int
20683 api_ip_fib_dump (vat_main_t * vam)
20684 {
20685   vl_api_ip_fib_dump_t *mp;
20686   vl_api_control_ping_t *mp_ping;
20687   int ret;
20688
20689   M (IP_FIB_DUMP, mp);
20690   S (mp);
20691
20692   /* Use a control ping for synchronization */
20693   MPING (CONTROL_PING, mp_ping);
20694   S (mp_ping);
20695
20696   W (ret);
20697   return ret;
20698 }
20699
20700 static int
20701 api_ip_mfib_dump (vat_main_t * vam)
20702 {
20703   vl_api_ip_mfib_dump_t *mp;
20704   vl_api_control_ping_t *mp_ping;
20705   int ret;
20706
20707   M (IP_MFIB_DUMP, mp);
20708   S (mp);
20709
20710   /* Use a control ping for synchronization */
20711   MPING (CONTROL_PING, mp_ping);
20712   S (mp_ping);
20713
20714   W (ret);
20715   return ret;
20716 }
20717
20718 static void vl_api_ip_neighbor_details_t_handler
20719   (vl_api_ip_neighbor_details_t * mp)
20720 {
20721   vat_main_t *vam = &vat_main;
20722
20723   print (vam->ofp, "%c %U %U",
20724          (mp->is_static) ? 'S' : 'D',
20725          format_ethernet_address, &mp->mac_address,
20726          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
20727          &mp->ip_address);
20728 }
20729
20730 static void vl_api_ip_neighbor_details_t_handler_json
20731   (vl_api_ip_neighbor_details_t * mp)
20732 {
20733
20734   vat_main_t *vam = &vat_main;
20735   vat_json_node_t *node;
20736   struct in_addr ip4;
20737   struct in6_addr ip6;
20738
20739   if (VAT_JSON_ARRAY != vam->json_tree.type)
20740     {
20741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20742       vat_json_init_array (&vam->json_tree);
20743     }
20744   node = vat_json_array_add (&vam->json_tree);
20745
20746   vat_json_init_object (node);
20747   vat_json_object_add_string_copy (node, "flag",
20748                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
20749                                    "dynamic");
20750
20751   vat_json_object_add_string_copy (node, "link_layer",
20752                                    format (0, "%U", format_ethernet_address,
20753                                            &mp->mac_address));
20754
20755   if (mp->is_ipv6)
20756     {
20757       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
20758       vat_json_object_add_ip6 (node, "ip_address", ip6);
20759     }
20760   else
20761     {
20762       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
20763       vat_json_object_add_ip4 (node, "ip_address", ip4);
20764     }
20765 }
20766
20767 static int
20768 api_ip_neighbor_dump (vat_main_t * vam)
20769 {
20770   unformat_input_t *i = vam->input;
20771   vl_api_ip_neighbor_dump_t *mp;
20772   vl_api_control_ping_t *mp_ping;
20773   u8 is_ipv6 = 0;
20774   u32 sw_if_index = ~0;
20775   int ret;
20776
20777   /* Parse args required to build the message */
20778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20779     {
20780       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20781         ;
20782       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20783         ;
20784       else if (unformat (i, "ip6"))
20785         is_ipv6 = 1;
20786       else
20787         break;
20788     }
20789
20790   if (sw_if_index == ~0)
20791     {
20792       errmsg ("missing interface name or sw_if_index");
20793       return -99;
20794     }
20795
20796   M (IP_NEIGHBOR_DUMP, mp);
20797   mp->is_ipv6 = (u8) is_ipv6;
20798   mp->sw_if_index = ntohl (sw_if_index);
20799   S (mp);
20800
20801   /* Use a control ping for synchronization */
20802   MPING (CONTROL_PING, mp_ping);
20803   S (mp_ping);
20804
20805   W (ret);
20806   return ret;
20807 }
20808
20809 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
20810 #define vl_api_ip6_fib_details_t_print vl_noop_handler
20811
20812 static void
20813 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
20814 {
20815   vat_main_t *vam = &vat_main;
20816   int count = ntohl (mp->count);
20817   vl_api_fib_path_t *fp;
20818   int i;
20819
20820   print (vam->ofp,
20821          "table-id %d, prefix %U/%d stats-index %d",
20822          ntohl (mp->table_id), format_ip6_address, mp->address,
20823          mp->address_length, ntohl (mp->stats_index));
20824   fp = mp->path;
20825   for (i = 0; i < count; i++)
20826     {
20827       if (fp->afi == IP46_TYPE_IP6)
20828         print (vam->ofp,
20829                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20830                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20831                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20832                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20833                format_ip6_address, fp->next_hop);
20834       else if (fp->afi == IP46_TYPE_IP4)
20835         print (vam->ofp,
20836                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
20837                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
20838                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
20839                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
20840                format_ip4_address, fp->next_hop);
20841       fp++;
20842     }
20843 }
20844
20845 static void vl_api_ip6_fib_details_t_handler_json
20846   (vl_api_ip6_fib_details_t * mp)
20847 {
20848   vat_main_t *vam = &vat_main;
20849   int count = ntohl (mp->count);
20850   vat_json_node_t *node = NULL;
20851   struct in_addr ip4;
20852   struct in6_addr ip6;
20853   vl_api_fib_path_t *fp;
20854   int i;
20855
20856   if (VAT_JSON_ARRAY != vam->json_tree.type)
20857     {
20858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20859       vat_json_init_array (&vam->json_tree);
20860     }
20861   node = vat_json_array_add (&vam->json_tree);
20862
20863   vat_json_init_object (node);
20864   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
20865   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
20866   vat_json_object_add_ip6 (node, "prefix", ip6);
20867   vat_json_object_add_uint (node, "mask_length", mp->address_length);
20868   vat_json_object_add_uint (node, "path_count", count);
20869   fp = mp->path;
20870   for (i = 0; i < count; i++)
20871     {
20872       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
20873       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
20874       vat_json_object_add_uint (node, "is_local", fp->is_local);
20875       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
20876       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
20877       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
20878       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
20879       if (fp->afi == IP46_TYPE_IP4)
20880         {
20881           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
20882           vat_json_object_add_ip4 (node, "next_hop", ip4);
20883         }
20884       else if (fp->afi == IP46_TYPE_IP6)
20885         {
20886           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
20887           vat_json_object_add_ip6 (node, "next_hop", ip6);
20888         }
20889     }
20890 }
20891
20892 static int
20893 api_ip6_fib_dump (vat_main_t * vam)
20894 {
20895   vl_api_ip6_fib_dump_t *mp;
20896   vl_api_control_ping_t *mp_ping;
20897   int ret;
20898
20899   M (IP6_FIB_DUMP, mp);
20900   S (mp);
20901
20902   /* Use a control ping for synchronization */
20903   MPING (CONTROL_PING, mp_ping);
20904   S (mp_ping);
20905
20906   W (ret);
20907   return ret;
20908 }
20909
20910 static int
20911 api_ip6_mfib_dump (vat_main_t * vam)
20912 {
20913   vl_api_ip6_mfib_dump_t *mp;
20914   vl_api_control_ping_t *mp_ping;
20915   int ret;
20916
20917   M (IP6_MFIB_DUMP, mp);
20918   S (mp);
20919
20920   /* Use a control ping for synchronization */
20921   MPING (CONTROL_PING, mp_ping);
20922   S (mp_ping);
20923
20924   W (ret);
20925   return ret;
20926 }
20927
20928 int
20929 api_classify_table_ids (vat_main_t * vam)
20930 {
20931   vl_api_classify_table_ids_t *mp;
20932   int ret;
20933
20934   /* Construct the API message */
20935   M (CLASSIFY_TABLE_IDS, mp);
20936   mp->context = 0;
20937
20938   S (mp);
20939   W (ret);
20940   return ret;
20941 }
20942
20943 int
20944 api_classify_table_by_interface (vat_main_t * vam)
20945 {
20946   unformat_input_t *input = vam->input;
20947   vl_api_classify_table_by_interface_t *mp;
20948
20949   u32 sw_if_index = ~0;
20950   int ret;
20951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20952     {
20953       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20954         ;
20955       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20956         ;
20957       else
20958         break;
20959     }
20960   if (sw_if_index == ~0)
20961     {
20962       errmsg ("missing interface name or sw_if_index");
20963       return -99;
20964     }
20965
20966   /* Construct the API message */
20967   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
20968   mp->context = 0;
20969   mp->sw_if_index = ntohl (sw_if_index);
20970
20971   S (mp);
20972   W (ret);
20973   return ret;
20974 }
20975
20976 int
20977 api_classify_table_info (vat_main_t * vam)
20978 {
20979   unformat_input_t *input = vam->input;
20980   vl_api_classify_table_info_t *mp;
20981
20982   u32 table_id = ~0;
20983   int ret;
20984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20985     {
20986       if (unformat (input, "table_id %d", &table_id))
20987         ;
20988       else
20989         break;
20990     }
20991   if (table_id == ~0)
20992     {
20993       errmsg ("missing table id");
20994       return -99;
20995     }
20996
20997   /* Construct the API message */
20998   M (CLASSIFY_TABLE_INFO, mp);
20999   mp->context = 0;
21000   mp->table_id = ntohl (table_id);
21001
21002   S (mp);
21003   W (ret);
21004   return ret;
21005 }
21006
21007 int
21008 api_classify_session_dump (vat_main_t * vam)
21009 {
21010   unformat_input_t *input = vam->input;
21011   vl_api_classify_session_dump_t *mp;
21012   vl_api_control_ping_t *mp_ping;
21013
21014   u32 table_id = ~0;
21015   int ret;
21016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21017     {
21018       if (unformat (input, "table_id %d", &table_id))
21019         ;
21020       else
21021         break;
21022     }
21023   if (table_id == ~0)
21024     {
21025       errmsg ("missing table id");
21026       return -99;
21027     }
21028
21029   /* Construct the API message */
21030   M (CLASSIFY_SESSION_DUMP, mp);
21031   mp->context = 0;
21032   mp->table_id = ntohl (table_id);
21033   S (mp);
21034
21035   /* Use a control ping for synchronization */
21036   MPING (CONTROL_PING, mp_ping);
21037   S (mp_ping);
21038
21039   W (ret);
21040   return ret;
21041 }
21042
21043 static void
21044 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
21045 {
21046   vat_main_t *vam = &vat_main;
21047
21048   print (vam->ofp, "collector_address %U, collector_port %d, "
21049          "src_address %U, vrf_id %d, path_mtu %u, "
21050          "template_interval %u, udp_checksum %d",
21051          format_ip4_address, mp->collector_address,
21052          ntohs (mp->collector_port),
21053          format_ip4_address, mp->src_address,
21054          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
21055          ntohl (mp->template_interval), mp->udp_checksum);
21056
21057   vam->retval = 0;
21058   vam->result_ready = 1;
21059 }
21060
21061 static void
21062   vl_api_ipfix_exporter_details_t_handler_json
21063   (vl_api_ipfix_exporter_details_t * mp)
21064 {
21065   vat_main_t *vam = &vat_main;
21066   vat_json_node_t node;
21067   struct in_addr collector_address;
21068   struct in_addr src_address;
21069
21070   vat_json_init_object (&node);
21071   clib_memcpy (&collector_address, &mp->collector_address,
21072                sizeof (collector_address));
21073   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
21074   vat_json_object_add_uint (&node, "collector_port",
21075                             ntohs (mp->collector_port));
21076   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
21077   vat_json_object_add_ip4 (&node, "src_address", src_address);
21078   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
21079   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
21080   vat_json_object_add_uint (&node, "template_interval",
21081                             ntohl (mp->template_interval));
21082   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
21083
21084   vat_json_print (vam->ofp, &node);
21085   vat_json_free (&node);
21086   vam->retval = 0;
21087   vam->result_ready = 1;
21088 }
21089
21090 int
21091 api_ipfix_exporter_dump (vat_main_t * vam)
21092 {
21093   vl_api_ipfix_exporter_dump_t *mp;
21094   int ret;
21095
21096   /* Construct the API message */
21097   M (IPFIX_EXPORTER_DUMP, mp);
21098   mp->context = 0;
21099
21100   S (mp);
21101   W (ret);
21102   return ret;
21103 }
21104
21105 static int
21106 api_ipfix_classify_stream_dump (vat_main_t * vam)
21107 {
21108   vl_api_ipfix_classify_stream_dump_t *mp;
21109   int ret;
21110
21111   /* Construct the API message */
21112   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
21113   mp->context = 0;
21114
21115   S (mp);
21116   W (ret);
21117   return ret;
21118   /* NOTREACHED */
21119   return 0;
21120 }
21121
21122 static void
21123   vl_api_ipfix_classify_stream_details_t_handler
21124   (vl_api_ipfix_classify_stream_details_t * mp)
21125 {
21126   vat_main_t *vam = &vat_main;
21127   print (vam->ofp, "domain_id %d, src_port %d",
21128          ntohl (mp->domain_id), ntohs (mp->src_port));
21129   vam->retval = 0;
21130   vam->result_ready = 1;
21131 }
21132
21133 static void
21134   vl_api_ipfix_classify_stream_details_t_handler_json
21135   (vl_api_ipfix_classify_stream_details_t * mp)
21136 {
21137   vat_main_t *vam = &vat_main;
21138   vat_json_node_t node;
21139
21140   vat_json_init_object (&node);
21141   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
21142   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
21143
21144   vat_json_print (vam->ofp, &node);
21145   vat_json_free (&node);
21146   vam->retval = 0;
21147   vam->result_ready = 1;
21148 }
21149
21150 static int
21151 api_ipfix_classify_table_dump (vat_main_t * vam)
21152 {
21153   vl_api_ipfix_classify_table_dump_t *mp;
21154   vl_api_control_ping_t *mp_ping;
21155   int ret;
21156
21157   if (!vam->json_output)
21158     {
21159       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
21160              "transport_protocol");
21161     }
21162
21163   /* Construct the API message */
21164   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
21165
21166   /* send it... */
21167   S (mp);
21168
21169   /* Use a control ping for synchronization */
21170   MPING (CONTROL_PING, mp_ping);
21171   S (mp_ping);
21172
21173   W (ret);
21174   return ret;
21175 }
21176
21177 static void
21178   vl_api_ipfix_classify_table_details_t_handler
21179   (vl_api_ipfix_classify_table_details_t * mp)
21180 {
21181   vat_main_t *vam = &vat_main;
21182   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
21183          mp->transport_protocol);
21184 }
21185
21186 static void
21187   vl_api_ipfix_classify_table_details_t_handler_json
21188   (vl_api_ipfix_classify_table_details_t * mp)
21189 {
21190   vat_json_node_t *node = NULL;
21191   vat_main_t *vam = &vat_main;
21192
21193   if (VAT_JSON_ARRAY != vam->json_tree.type)
21194     {
21195       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21196       vat_json_init_array (&vam->json_tree);
21197     }
21198
21199   node = vat_json_array_add (&vam->json_tree);
21200   vat_json_init_object (node);
21201
21202   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
21203   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
21204   vat_json_object_add_uint (node, "transport_protocol",
21205                             mp->transport_protocol);
21206 }
21207
21208 static int
21209 api_sw_interface_span_enable_disable (vat_main_t * vam)
21210 {
21211   unformat_input_t *i = vam->input;
21212   vl_api_sw_interface_span_enable_disable_t *mp;
21213   u32 src_sw_if_index = ~0;
21214   u32 dst_sw_if_index = ~0;
21215   u8 state = 3;
21216   int ret;
21217   u8 is_l2 = 0;
21218
21219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21220     {
21221       if (unformat
21222           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
21223         ;
21224       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
21225         ;
21226       else
21227         if (unformat
21228             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
21229         ;
21230       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
21231         ;
21232       else if (unformat (i, "disable"))
21233         state = 0;
21234       else if (unformat (i, "rx"))
21235         state = 1;
21236       else if (unformat (i, "tx"))
21237         state = 2;
21238       else if (unformat (i, "both"))
21239         state = 3;
21240       else if (unformat (i, "l2"))
21241         is_l2 = 1;
21242       else
21243         break;
21244     }
21245
21246   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
21247
21248   mp->sw_if_index_from = htonl (src_sw_if_index);
21249   mp->sw_if_index_to = htonl (dst_sw_if_index);
21250   mp->state = state;
21251   mp->is_l2 = is_l2;
21252
21253   S (mp);
21254   W (ret);
21255   return ret;
21256 }
21257
21258 static void
21259 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
21260                                             * mp)
21261 {
21262   vat_main_t *vam = &vat_main;
21263   u8 *sw_if_from_name = 0;
21264   u8 *sw_if_to_name = 0;
21265   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21266   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21267   char *states[] = { "none", "rx", "tx", "both" };
21268   hash_pair_t *p;
21269
21270   /* *INDENT-OFF* */
21271   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21272   ({
21273     if ((u32) p->value[0] == sw_if_index_from)
21274       {
21275         sw_if_from_name = (u8 *)(p->key);
21276         if (sw_if_to_name)
21277           break;
21278       }
21279     if ((u32) p->value[0] == sw_if_index_to)
21280       {
21281         sw_if_to_name = (u8 *)(p->key);
21282         if (sw_if_from_name)
21283           break;
21284       }
21285   }));
21286   /* *INDENT-ON* */
21287   print (vam->ofp, "%20s => %20s (%s) %s",
21288          sw_if_from_name, sw_if_to_name, states[mp->state],
21289          mp->is_l2 ? "l2" : "device");
21290 }
21291
21292 static void
21293   vl_api_sw_interface_span_details_t_handler_json
21294   (vl_api_sw_interface_span_details_t * mp)
21295 {
21296   vat_main_t *vam = &vat_main;
21297   vat_json_node_t *node = NULL;
21298   u8 *sw_if_from_name = 0;
21299   u8 *sw_if_to_name = 0;
21300   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
21301   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
21302   hash_pair_t *p;
21303
21304   /* *INDENT-OFF* */
21305   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
21306   ({
21307     if ((u32) p->value[0] == sw_if_index_from)
21308       {
21309         sw_if_from_name = (u8 *)(p->key);
21310         if (sw_if_to_name)
21311           break;
21312       }
21313     if ((u32) p->value[0] == sw_if_index_to)
21314       {
21315         sw_if_to_name = (u8 *)(p->key);
21316         if (sw_if_from_name)
21317           break;
21318       }
21319   }));
21320   /* *INDENT-ON* */
21321
21322   if (VAT_JSON_ARRAY != vam->json_tree.type)
21323     {
21324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21325       vat_json_init_array (&vam->json_tree);
21326     }
21327   node = vat_json_array_add (&vam->json_tree);
21328
21329   vat_json_init_object (node);
21330   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
21331   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
21332   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
21333   if (0 != sw_if_to_name)
21334     {
21335       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
21336     }
21337   vat_json_object_add_uint (node, "state", mp->state);
21338   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
21339 }
21340
21341 static int
21342 api_sw_interface_span_dump (vat_main_t * vam)
21343 {
21344   unformat_input_t *input = vam->input;
21345   vl_api_sw_interface_span_dump_t *mp;
21346   vl_api_control_ping_t *mp_ping;
21347   u8 is_l2 = 0;
21348   int ret;
21349
21350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21351     {
21352       if (unformat (input, "l2"))
21353         is_l2 = 1;
21354       else
21355         break;
21356     }
21357
21358   M (SW_INTERFACE_SPAN_DUMP, mp);
21359   mp->is_l2 = is_l2;
21360   S (mp);
21361
21362   /* Use a control ping for synchronization */
21363   MPING (CONTROL_PING, mp_ping);
21364   S (mp_ping);
21365
21366   W (ret);
21367   return ret;
21368 }
21369
21370 int
21371 api_pg_create_interface (vat_main_t * vam)
21372 {
21373   unformat_input_t *input = vam->input;
21374   vl_api_pg_create_interface_t *mp;
21375
21376   u32 if_id = ~0;
21377   int ret;
21378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21379     {
21380       if (unformat (input, "if_id %d", &if_id))
21381         ;
21382       else
21383         break;
21384     }
21385   if (if_id == ~0)
21386     {
21387       errmsg ("missing pg interface index");
21388       return -99;
21389     }
21390
21391   /* Construct the API message */
21392   M (PG_CREATE_INTERFACE, mp);
21393   mp->context = 0;
21394   mp->interface_id = ntohl (if_id);
21395
21396   S (mp);
21397   W (ret);
21398   return ret;
21399 }
21400
21401 int
21402 api_pg_capture (vat_main_t * vam)
21403 {
21404   unformat_input_t *input = vam->input;
21405   vl_api_pg_capture_t *mp;
21406
21407   u32 if_id = ~0;
21408   u8 enable = 1;
21409   u32 count = 1;
21410   u8 pcap_file_set = 0;
21411   u8 *pcap_file = 0;
21412   int ret;
21413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21414     {
21415       if (unformat (input, "if_id %d", &if_id))
21416         ;
21417       else if (unformat (input, "pcap %s", &pcap_file))
21418         pcap_file_set = 1;
21419       else if (unformat (input, "count %d", &count))
21420         ;
21421       else if (unformat (input, "disable"))
21422         enable = 0;
21423       else
21424         break;
21425     }
21426   if (if_id == ~0)
21427     {
21428       errmsg ("missing pg interface index");
21429       return -99;
21430     }
21431   if (pcap_file_set > 0)
21432     {
21433       if (vec_len (pcap_file) > 255)
21434         {
21435           errmsg ("pcap file name is too long");
21436           return -99;
21437         }
21438     }
21439
21440   u32 name_len = vec_len (pcap_file);
21441   /* Construct the API message */
21442   M (PG_CAPTURE, mp);
21443   mp->context = 0;
21444   mp->interface_id = ntohl (if_id);
21445   mp->is_enabled = enable;
21446   mp->count = ntohl (count);
21447   mp->pcap_name_length = ntohl (name_len);
21448   if (pcap_file_set != 0)
21449     {
21450       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
21451     }
21452   vec_free (pcap_file);
21453
21454   S (mp);
21455   W (ret);
21456   return ret;
21457 }
21458
21459 int
21460 api_pg_enable_disable (vat_main_t * vam)
21461 {
21462   unformat_input_t *input = vam->input;
21463   vl_api_pg_enable_disable_t *mp;
21464
21465   u8 enable = 1;
21466   u8 stream_name_set = 0;
21467   u8 *stream_name = 0;
21468   int ret;
21469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21470     {
21471       if (unformat (input, "stream %s", &stream_name))
21472         stream_name_set = 1;
21473       else if (unformat (input, "disable"))
21474         enable = 0;
21475       else
21476         break;
21477     }
21478
21479   if (stream_name_set > 0)
21480     {
21481       if (vec_len (stream_name) > 255)
21482         {
21483           errmsg ("stream name too long");
21484           return -99;
21485         }
21486     }
21487
21488   u32 name_len = vec_len (stream_name);
21489   /* Construct the API message */
21490   M (PG_ENABLE_DISABLE, mp);
21491   mp->context = 0;
21492   mp->is_enabled = enable;
21493   if (stream_name_set != 0)
21494     {
21495       mp->stream_name_length = ntohl (name_len);
21496       clib_memcpy (mp->stream_name, stream_name, name_len);
21497     }
21498   vec_free (stream_name);
21499
21500   S (mp);
21501   W (ret);
21502   return ret;
21503 }
21504
21505 int
21506 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
21507 {
21508   unformat_input_t *input = vam->input;
21509   vl_api_ip_source_and_port_range_check_add_del_t *mp;
21510
21511   u16 *low_ports = 0;
21512   u16 *high_ports = 0;
21513   u16 this_low;
21514   u16 this_hi;
21515   ip4_address_t ip4_addr;
21516   ip6_address_t ip6_addr;
21517   u32 length;
21518   u32 tmp, tmp2;
21519   u8 prefix_set = 0;
21520   u32 vrf_id = ~0;
21521   u8 is_add = 1;
21522   u8 is_ipv6 = 0;
21523   int ret;
21524
21525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21526     {
21527       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
21528         {
21529           prefix_set = 1;
21530         }
21531       else
21532         if (unformat
21533             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
21534         {
21535           prefix_set = 1;
21536           is_ipv6 = 1;
21537         }
21538       else if (unformat (input, "vrf %d", &vrf_id))
21539         ;
21540       else if (unformat (input, "del"))
21541         is_add = 0;
21542       else if (unformat (input, "port %d", &tmp))
21543         {
21544           if (tmp == 0 || tmp > 65535)
21545             {
21546               errmsg ("port %d out of range", tmp);
21547               return -99;
21548             }
21549           this_low = tmp;
21550           this_hi = this_low + 1;
21551           vec_add1 (low_ports, this_low);
21552           vec_add1 (high_ports, this_hi);
21553         }
21554       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
21555         {
21556           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
21557             {
21558               errmsg ("incorrect range parameters");
21559               return -99;
21560             }
21561           this_low = tmp;
21562           /* Note: in debug CLI +1 is added to high before
21563              passing to real fn that does "the work"
21564              (ip_source_and_port_range_check_add_del).
21565              This fn is a wrapper around the binary API fn a
21566              control plane will call, which expects this increment
21567              to have occurred. Hence letting the binary API control
21568              plane fn do the increment for consistency between VAT
21569              and other control planes.
21570            */
21571           this_hi = tmp2;
21572           vec_add1 (low_ports, this_low);
21573           vec_add1 (high_ports, this_hi);
21574         }
21575       else
21576         break;
21577     }
21578
21579   if (prefix_set == 0)
21580     {
21581       errmsg ("<address>/<mask> not specified");
21582       return -99;
21583     }
21584
21585   if (vrf_id == ~0)
21586     {
21587       errmsg ("VRF ID required, not specified");
21588       return -99;
21589     }
21590
21591   if (vrf_id == 0)
21592     {
21593       errmsg
21594         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21595       return -99;
21596     }
21597
21598   if (vec_len (low_ports) == 0)
21599     {
21600       errmsg ("At least one port or port range required");
21601       return -99;
21602     }
21603
21604   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
21605
21606   mp->is_add = is_add;
21607
21608   if (is_ipv6)
21609     {
21610       mp->is_ipv6 = 1;
21611       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
21612     }
21613   else
21614     {
21615       mp->is_ipv6 = 0;
21616       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
21617     }
21618
21619   mp->mask_length = length;
21620   mp->number_of_ranges = vec_len (low_ports);
21621
21622   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
21623   vec_free (low_ports);
21624
21625   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
21626   vec_free (high_ports);
21627
21628   mp->vrf_id = ntohl (vrf_id);
21629
21630   S (mp);
21631   W (ret);
21632   return ret;
21633 }
21634
21635 int
21636 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
21637 {
21638   unformat_input_t *input = vam->input;
21639   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
21640   u32 sw_if_index = ~0;
21641   int vrf_set = 0;
21642   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
21643   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
21644   u8 is_add = 1;
21645   int ret;
21646
21647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
21648     {
21649       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21650         ;
21651       else if (unformat (input, "sw_if_index %d", &sw_if_index))
21652         ;
21653       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
21654         vrf_set = 1;
21655       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
21656         vrf_set = 1;
21657       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
21658         vrf_set = 1;
21659       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
21660         vrf_set = 1;
21661       else if (unformat (input, "del"))
21662         is_add = 0;
21663       else
21664         break;
21665     }
21666
21667   if (sw_if_index == ~0)
21668     {
21669       errmsg ("Interface required but not specified");
21670       return -99;
21671     }
21672
21673   if (vrf_set == 0)
21674     {
21675       errmsg ("VRF ID required but not specified");
21676       return -99;
21677     }
21678
21679   if (tcp_out_vrf_id == 0
21680       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
21681     {
21682       errmsg
21683         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
21684       return -99;
21685     }
21686
21687   /* Construct the API message */
21688   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
21689
21690   mp->sw_if_index = ntohl (sw_if_index);
21691   mp->is_add = is_add;
21692   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
21693   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
21694   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
21695   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
21696
21697   /* send it... */
21698   S (mp);
21699
21700   /* Wait for a reply... */
21701   W (ret);
21702   return ret;
21703 }
21704
21705 static int
21706 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
21707 {
21708   unformat_input_t *i = vam->input;
21709   vl_api_ipsec_gre_add_del_tunnel_t *mp;
21710   u32 local_sa_id = 0;
21711   u32 remote_sa_id = 0;
21712   ip4_address_t src_address;
21713   ip4_address_t dst_address;
21714   u8 is_add = 1;
21715   int ret;
21716
21717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21718     {
21719       if (unformat (i, "local_sa %d", &local_sa_id))
21720         ;
21721       else if (unformat (i, "remote_sa %d", &remote_sa_id))
21722         ;
21723       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
21724         ;
21725       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
21726         ;
21727       else if (unformat (i, "del"))
21728         is_add = 0;
21729       else
21730         {
21731           clib_warning ("parse error '%U'", format_unformat_error, i);
21732           return -99;
21733         }
21734     }
21735
21736   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
21737
21738   mp->local_sa_id = ntohl (local_sa_id);
21739   mp->remote_sa_id = ntohl (remote_sa_id);
21740   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
21741   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
21742   mp->is_add = is_add;
21743
21744   S (mp);
21745   W (ret);
21746   return ret;
21747 }
21748
21749 static int
21750 api_punt (vat_main_t * vam)
21751 {
21752   unformat_input_t *i = vam->input;
21753   vl_api_punt_t *mp;
21754   u32 ipv = ~0;
21755   u32 protocol = ~0;
21756   u32 port = ~0;
21757   int is_add = 1;
21758   int ret;
21759
21760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21761     {
21762       if (unformat (i, "ip %d", &ipv))
21763         ;
21764       else if (unformat (i, "protocol %d", &protocol))
21765         ;
21766       else if (unformat (i, "port %d", &port))
21767         ;
21768       else if (unformat (i, "del"))
21769         is_add = 0;
21770       else
21771         {
21772           clib_warning ("parse error '%U'", format_unformat_error, i);
21773           return -99;
21774         }
21775     }
21776
21777   M (PUNT, mp);
21778
21779   mp->is_add = (u8) is_add;
21780   mp->ipv = (u8) ipv;
21781   mp->l4_protocol = (u8) protocol;
21782   mp->l4_port = htons ((u16) port);
21783
21784   S (mp);
21785   W (ret);
21786   return ret;
21787 }
21788
21789 static void vl_api_ipsec_gre_tunnel_details_t_handler
21790   (vl_api_ipsec_gre_tunnel_details_t * mp)
21791 {
21792   vat_main_t *vam = &vat_main;
21793
21794   print (vam->ofp, "%11d%15U%15U%14d%14d",
21795          ntohl (mp->sw_if_index),
21796          format_ip4_address, &mp->src_address,
21797          format_ip4_address, &mp->dst_address,
21798          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
21799 }
21800
21801 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
21802   (vl_api_ipsec_gre_tunnel_details_t * mp)
21803 {
21804   vat_main_t *vam = &vat_main;
21805   vat_json_node_t *node = NULL;
21806   struct in_addr ip4;
21807
21808   if (VAT_JSON_ARRAY != vam->json_tree.type)
21809     {
21810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21811       vat_json_init_array (&vam->json_tree);
21812     }
21813   node = vat_json_array_add (&vam->json_tree);
21814
21815   vat_json_init_object (node);
21816   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
21817   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
21818   vat_json_object_add_ip4 (node, "src_address", ip4);
21819   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
21820   vat_json_object_add_ip4 (node, "dst_address", ip4);
21821   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
21822   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
21823 }
21824
21825 static int
21826 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
21827 {
21828   unformat_input_t *i = vam->input;
21829   vl_api_ipsec_gre_tunnel_dump_t *mp;
21830   vl_api_control_ping_t *mp_ping;
21831   u32 sw_if_index;
21832   u8 sw_if_index_set = 0;
21833   int ret;
21834
21835   /* Parse args required to build the message */
21836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21837     {
21838       if (unformat (i, "sw_if_index %d", &sw_if_index))
21839         sw_if_index_set = 1;
21840       else
21841         break;
21842     }
21843
21844   if (sw_if_index_set == 0)
21845     {
21846       sw_if_index = ~0;
21847     }
21848
21849   if (!vam->json_output)
21850     {
21851       print (vam->ofp, "%11s%15s%15s%14s%14s",
21852              "sw_if_index", "src_address", "dst_address",
21853              "local_sa_id", "remote_sa_id");
21854     }
21855
21856   /* Get list of gre-tunnel interfaces */
21857   M (IPSEC_GRE_TUNNEL_DUMP, mp);
21858
21859   mp->sw_if_index = htonl (sw_if_index);
21860
21861   S (mp);
21862
21863   /* Use a control ping for synchronization */
21864   MPING (CONTROL_PING, mp_ping);
21865   S (mp_ping);
21866
21867   W (ret);
21868   return ret;
21869 }
21870
21871 static int
21872 api_delete_subif (vat_main_t * vam)
21873 {
21874   unformat_input_t *i = vam->input;
21875   vl_api_delete_subif_t *mp;
21876   u32 sw_if_index = ~0;
21877   int ret;
21878
21879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21880     {
21881       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21882         ;
21883       if (unformat (i, "sw_if_index %d", &sw_if_index))
21884         ;
21885       else
21886         break;
21887     }
21888
21889   if (sw_if_index == ~0)
21890     {
21891       errmsg ("missing sw_if_index");
21892       return -99;
21893     }
21894
21895   /* Construct the API message */
21896   M (DELETE_SUBIF, mp);
21897   mp->sw_if_index = ntohl (sw_if_index);
21898
21899   S (mp);
21900   W (ret);
21901   return ret;
21902 }
21903
21904 #define foreach_pbb_vtr_op      \
21905 _("disable",  L2_VTR_DISABLED)  \
21906 _("pop",  L2_VTR_POP_2)         \
21907 _("push",  L2_VTR_PUSH_2)
21908
21909 static int
21910 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
21911 {
21912   unformat_input_t *i = vam->input;
21913   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
21914   u32 sw_if_index = ~0, vtr_op = ~0;
21915   u16 outer_tag = ~0;
21916   u8 dmac[6], smac[6];
21917   u8 dmac_set = 0, smac_set = 0;
21918   u16 vlanid = 0;
21919   u32 sid = ~0;
21920   u32 tmp;
21921   int ret;
21922
21923   /* Shut up coverity */
21924   memset (dmac, 0, sizeof (dmac));
21925   memset (smac, 0, sizeof (smac));
21926
21927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21928     {
21929       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21930         ;
21931       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21932         ;
21933       else if (unformat (i, "vtr_op %d", &vtr_op))
21934         ;
21935 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
21936       foreach_pbb_vtr_op
21937 #undef _
21938         else if (unformat (i, "translate_pbb_stag"))
21939         {
21940           if (unformat (i, "%d", &tmp))
21941             {
21942               vtr_op = L2_VTR_TRANSLATE_2_1;
21943               outer_tag = tmp;
21944             }
21945           else
21946             {
21947               errmsg
21948                 ("translate_pbb_stag operation requires outer tag definition");
21949               return -99;
21950             }
21951         }
21952       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
21953         dmac_set++;
21954       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
21955         smac_set++;
21956       else if (unformat (i, "sid %d", &sid))
21957         ;
21958       else if (unformat (i, "vlanid %d", &tmp))
21959         vlanid = tmp;
21960       else
21961         {
21962           clib_warning ("parse error '%U'", format_unformat_error, i);
21963           return -99;
21964         }
21965     }
21966
21967   if ((sw_if_index == ~0) || (vtr_op == ~0))
21968     {
21969       errmsg ("missing sw_if_index or vtr operation");
21970       return -99;
21971     }
21972   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
21973       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
21974     {
21975       errmsg
21976         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
21977       return -99;
21978     }
21979
21980   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
21981   mp->sw_if_index = ntohl (sw_if_index);
21982   mp->vtr_op = ntohl (vtr_op);
21983   mp->outer_tag = ntohs (outer_tag);
21984   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
21985   clib_memcpy (mp->b_smac, smac, sizeof (smac));
21986   mp->b_vlanid = ntohs (vlanid);
21987   mp->i_sid = ntohl (sid);
21988
21989   S (mp);
21990   W (ret);
21991   return ret;
21992 }
21993
21994 static int
21995 api_flow_classify_set_interface (vat_main_t * vam)
21996 {
21997   unformat_input_t *i = vam->input;
21998   vl_api_flow_classify_set_interface_t *mp;
21999   u32 sw_if_index;
22000   int sw_if_index_set;
22001   u32 ip4_table_index = ~0;
22002   u32 ip6_table_index = ~0;
22003   u8 is_add = 1;
22004   int ret;
22005
22006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22007     {
22008       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22009         sw_if_index_set = 1;
22010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22011         sw_if_index_set = 1;
22012       else if (unformat (i, "del"))
22013         is_add = 0;
22014       else if (unformat (i, "ip4-table %d", &ip4_table_index))
22015         ;
22016       else if (unformat (i, "ip6-table %d", &ip6_table_index))
22017         ;
22018       else
22019         {
22020           clib_warning ("parse error '%U'", format_unformat_error, i);
22021           return -99;
22022         }
22023     }
22024
22025   if (sw_if_index_set == 0)
22026     {
22027       errmsg ("missing interface name or sw_if_index");
22028       return -99;
22029     }
22030
22031   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
22032
22033   mp->sw_if_index = ntohl (sw_if_index);
22034   mp->ip4_table_index = ntohl (ip4_table_index);
22035   mp->ip6_table_index = ntohl (ip6_table_index);
22036   mp->is_add = is_add;
22037
22038   S (mp);
22039   W (ret);
22040   return ret;
22041 }
22042
22043 static int
22044 api_flow_classify_dump (vat_main_t * vam)
22045 {
22046   unformat_input_t *i = vam->input;
22047   vl_api_flow_classify_dump_t *mp;
22048   vl_api_control_ping_t *mp_ping;
22049   u8 type = FLOW_CLASSIFY_N_TABLES;
22050   int ret;
22051
22052   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
22053     ;
22054   else
22055     {
22056       errmsg ("classify table type must be specified");
22057       return -99;
22058     }
22059
22060   if (!vam->json_output)
22061     {
22062       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
22063     }
22064
22065   M (FLOW_CLASSIFY_DUMP, mp);
22066   mp->type = type;
22067   /* send it... */
22068   S (mp);
22069
22070   /* Use a control ping for synchronization */
22071   MPING (CONTROL_PING, mp_ping);
22072   S (mp_ping);
22073
22074   /* Wait for a reply... */
22075   W (ret);
22076   return ret;
22077 }
22078
22079 static int
22080 api_feature_enable_disable (vat_main_t * vam)
22081 {
22082   unformat_input_t *i = vam->input;
22083   vl_api_feature_enable_disable_t *mp;
22084   u8 *arc_name = 0;
22085   u8 *feature_name = 0;
22086   u32 sw_if_index = ~0;
22087   u8 enable = 1;
22088   int ret;
22089
22090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22091     {
22092       if (unformat (i, "arc_name %s", &arc_name))
22093         ;
22094       else if (unformat (i, "feature_name %s", &feature_name))
22095         ;
22096       else
22097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22098         ;
22099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22100         ;
22101       else if (unformat (i, "disable"))
22102         enable = 0;
22103       else
22104         break;
22105     }
22106
22107   if (arc_name == 0)
22108     {
22109       errmsg ("missing arc name");
22110       return -99;
22111     }
22112   if (vec_len (arc_name) > 63)
22113     {
22114       errmsg ("arc name too long");
22115     }
22116
22117   if (feature_name == 0)
22118     {
22119       errmsg ("missing feature name");
22120       return -99;
22121     }
22122   if (vec_len (feature_name) > 63)
22123     {
22124       errmsg ("feature name too long");
22125     }
22126
22127   if (sw_if_index == ~0)
22128     {
22129       errmsg ("missing interface name or sw_if_index");
22130       return -99;
22131     }
22132
22133   /* Construct the API message */
22134   M (FEATURE_ENABLE_DISABLE, mp);
22135   mp->sw_if_index = ntohl (sw_if_index);
22136   mp->enable = enable;
22137   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
22138   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
22139   vec_free (arc_name);
22140   vec_free (feature_name);
22141
22142   S (mp);
22143   W (ret);
22144   return ret;
22145 }
22146
22147 static int
22148 api_sw_interface_tag_add_del (vat_main_t * vam)
22149 {
22150   unformat_input_t *i = vam->input;
22151   vl_api_sw_interface_tag_add_del_t *mp;
22152   u32 sw_if_index = ~0;
22153   u8 *tag = 0;
22154   u8 enable = 1;
22155   int ret;
22156
22157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22158     {
22159       if (unformat (i, "tag %s", &tag))
22160         ;
22161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22162         ;
22163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22164         ;
22165       else if (unformat (i, "del"))
22166         enable = 0;
22167       else
22168         break;
22169     }
22170
22171   if (sw_if_index == ~0)
22172     {
22173       errmsg ("missing interface name or sw_if_index");
22174       return -99;
22175     }
22176
22177   if (enable && (tag == 0))
22178     {
22179       errmsg ("no tag specified");
22180       return -99;
22181     }
22182
22183   /* Construct the API message */
22184   M (SW_INTERFACE_TAG_ADD_DEL, mp);
22185   mp->sw_if_index = ntohl (sw_if_index);
22186   mp->is_add = enable;
22187   if (enable)
22188     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
22189   vec_free (tag);
22190
22191   S (mp);
22192   W (ret);
22193   return ret;
22194 }
22195
22196 static void vl_api_l2_xconnect_details_t_handler
22197   (vl_api_l2_xconnect_details_t * mp)
22198 {
22199   vat_main_t *vam = &vat_main;
22200
22201   print (vam->ofp, "%15d%15d",
22202          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
22203 }
22204
22205 static void vl_api_l2_xconnect_details_t_handler_json
22206   (vl_api_l2_xconnect_details_t * mp)
22207 {
22208   vat_main_t *vam = &vat_main;
22209   vat_json_node_t *node = NULL;
22210
22211   if (VAT_JSON_ARRAY != vam->json_tree.type)
22212     {
22213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22214       vat_json_init_array (&vam->json_tree);
22215     }
22216   node = vat_json_array_add (&vam->json_tree);
22217
22218   vat_json_init_object (node);
22219   vat_json_object_add_uint (node, "rx_sw_if_index",
22220                             ntohl (mp->rx_sw_if_index));
22221   vat_json_object_add_uint (node, "tx_sw_if_index",
22222                             ntohl (mp->tx_sw_if_index));
22223 }
22224
22225 static int
22226 api_l2_xconnect_dump (vat_main_t * vam)
22227 {
22228   vl_api_l2_xconnect_dump_t *mp;
22229   vl_api_control_ping_t *mp_ping;
22230   int ret;
22231
22232   if (!vam->json_output)
22233     {
22234       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
22235     }
22236
22237   M (L2_XCONNECT_DUMP, mp);
22238
22239   S (mp);
22240
22241   /* Use a control ping for synchronization */
22242   MPING (CONTROL_PING, mp_ping);
22243   S (mp_ping);
22244
22245   W (ret);
22246   return ret;
22247 }
22248
22249 static int
22250 api_hw_interface_set_mtu (vat_main_t * vam)
22251 {
22252   unformat_input_t *i = vam->input;
22253   vl_api_hw_interface_set_mtu_t *mp;
22254   u32 sw_if_index = ~0;
22255   u32 mtu = 0;
22256   int ret;
22257
22258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22259     {
22260       if (unformat (i, "mtu %d", &mtu))
22261         ;
22262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22263         ;
22264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22265         ;
22266       else
22267         break;
22268     }
22269
22270   if (sw_if_index == ~0)
22271     {
22272       errmsg ("missing interface name or sw_if_index");
22273       return -99;
22274     }
22275
22276   if (mtu == 0)
22277     {
22278       errmsg ("no mtu specified");
22279       return -99;
22280     }
22281
22282   /* Construct the API message */
22283   M (HW_INTERFACE_SET_MTU, mp);
22284   mp->sw_if_index = ntohl (sw_if_index);
22285   mp->mtu = ntohs ((u16) mtu);
22286
22287   S (mp);
22288   W (ret);
22289   return ret;
22290 }
22291
22292 static int
22293 api_p2p_ethernet_add (vat_main_t * vam)
22294 {
22295   unformat_input_t *i = vam->input;
22296   vl_api_p2p_ethernet_add_t *mp;
22297   u32 parent_if_index = ~0;
22298   u32 sub_id = ~0;
22299   u8 remote_mac[6];
22300   u8 mac_set = 0;
22301   int ret;
22302
22303   memset (remote_mac, 0, sizeof (remote_mac));
22304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22305     {
22306       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22307         ;
22308       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22309         ;
22310       else
22311         if (unformat
22312             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22313         mac_set++;
22314       else if (unformat (i, "sub_id %d", &sub_id))
22315         ;
22316       else
22317         {
22318           clib_warning ("parse error '%U'", format_unformat_error, i);
22319           return -99;
22320         }
22321     }
22322
22323   if (parent_if_index == ~0)
22324     {
22325       errmsg ("missing interface name or sw_if_index");
22326       return -99;
22327     }
22328   if (mac_set == 0)
22329     {
22330       errmsg ("missing remote mac address");
22331       return -99;
22332     }
22333   if (sub_id == ~0)
22334     {
22335       errmsg ("missing sub-interface id");
22336       return -99;
22337     }
22338
22339   M (P2P_ETHERNET_ADD, mp);
22340   mp->parent_if_index = ntohl (parent_if_index);
22341   mp->subif_id = ntohl (sub_id);
22342   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22343
22344   S (mp);
22345   W (ret);
22346   return ret;
22347 }
22348
22349 static int
22350 api_p2p_ethernet_del (vat_main_t * vam)
22351 {
22352   unformat_input_t *i = vam->input;
22353   vl_api_p2p_ethernet_del_t *mp;
22354   u32 parent_if_index = ~0;
22355   u8 remote_mac[6];
22356   u8 mac_set = 0;
22357   int ret;
22358
22359   memset (remote_mac, 0, sizeof (remote_mac));
22360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22361     {
22362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
22363         ;
22364       else if (unformat (i, "sw_if_index %d", &parent_if_index))
22365         ;
22366       else
22367         if (unformat
22368             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
22369         mac_set++;
22370       else
22371         {
22372           clib_warning ("parse error '%U'", format_unformat_error, i);
22373           return -99;
22374         }
22375     }
22376
22377   if (parent_if_index == ~0)
22378     {
22379       errmsg ("missing interface name or sw_if_index");
22380       return -99;
22381     }
22382   if (mac_set == 0)
22383     {
22384       errmsg ("missing remote mac address");
22385       return -99;
22386     }
22387
22388   M (P2P_ETHERNET_DEL, mp);
22389   mp->parent_if_index = ntohl (parent_if_index);
22390   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
22391
22392   S (mp);
22393   W (ret);
22394   return ret;
22395 }
22396
22397 static int
22398 api_lldp_config (vat_main_t * vam)
22399 {
22400   unformat_input_t *i = vam->input;
22401   vl_api_lldp_config_t *mp;
22402   int tx_hold = 0;
22403   int tx_interval = 0;
22404   u8 *sys_name = NULL;
22405   int ret;
22406
22407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22408     {
22409       if (unformat (i, "system-name %s", &sys_name))
22410         ;
22411       else if (unformat (i, "tx-hold %d", &tx_hold))
22412         ;
22413       else if (unformat (i, "tx-interval %d", &tx_interval))
22414         ;
22415       else
22416         {
22417           clib_warning ("parse error '%U'", format_unformat_error, i);
22418           return -99;
22419         }
22420     }
22421
22422   vec_add1 (sys_name, 0);
22423
22424   M (LLDP_CONFIG, mp);
22425   mp->tx_hold = htonl (tx_hold);
22426   mp->tx_interval = htonl (tx_interval);
22427   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
22428   vec_free (sys_name);
22429
22430   S (mp);
22431   W (ret);
22432   return ret;
22433 }
22434
22435 static int
22436 api_sw_interface_set_lldp (vat_main_t * vam)
22437 {
22438   unformat_input_t *i = vam->input;
22439   vl_api_sw_interface_set_lldp_t *mp;
22440   u32 sw_if_index = ~0;
22441   u32 enable = 1;
22442   u8 *port_desc = NULL, *mgmt_oid = NULL;
22443   ip4_address_t ip4_addr;
22444   ip6_address_t ip6_addr;
22445   int ret;
22446
22447   memset (&ip4_addr, 0, sizeof (ip4_addr));
22448   memset (&ip6_addr, 0, sizeof (ip6_addr));
22449
22450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22451     {
22452       if (unformat (i, "disable"))
22453         enable = 0;
22454       else
22455         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
22456         ;
22457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22458         ;
22459       else if (unformat (i, "port-desc %s", &port_desc))
22460         ;
22461       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
22462         ;
22463       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
22464         ;
22465       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
22466         ;
22467       else
22468         break;
22469     }
22470
22471   if (sw_if_index == ~0)
22472     {
22473       errmsg ("missing interface name or sw_if_index");
22474       return -99;
22475     }
22476
22477   /* Construct the API message */
22478   vec_add1 (port_desc, 0);
22479   vec_add1 (mgmt_oid, 0);
22480   M (SW_INTERFACE_SET_LLDP, mp);
22481   mp->sw_if_index = ntohl (sw_if_index);
22482   mp->enable = enable;
22483   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
22484   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
22485   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
22486   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
22487   vec_free (port_desc);
22488   vec_free (mgmt_oid);
22489
22490   S (mp);
22491   W (ret);
22492   return ret;
22493 }
22494
22495 static int
22496 api_tcp_configure_src_addresses (vat_main_t * vam)
22497 {
22498   vl_api_tcp_configure_src_addresses_t *mp;
22499   unformat_input_t *i = vam->input;
22500   ip4_address_t v4first, v4last;
22501   ip6_address_t v6first, v6last;
22502   u8 range_set = 0;
22503   u32 vrf_id = 0;
22504   int ret;
22505
22506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22507     {
22508       if (unformat (i, "%U - %U",
22509                     unformat_ip4_address, &v4first,
22510                     unformat_ip4_address, &v4last))
22511         {
22512           if (range_set)
22513             {
22514               errmsg ("one range per message (range already set)");
22515               return -99;
22516             }
22517           range_set = 1;
22518         }
22519       else if (unformat (i, "%U - %U",
22520                          unformat_ip6_address, &v6first,
22521                          unformat_ip6_address, &v6last))
22522         {
22523           if (range_set)
22524             {
22525               errmsg ("one range per message (range already set)");
22526               return -99;
22527             }
22528           range_set = 2;
22529         }
22530       else if (unformat (i, "vrf %d", &vrf_id))
22531         ;
22532       else
22533         break;
22534     }
22535
22536   if (range_set == 0)
22537     {
22538       errmsg ("address range not set");
22539       return -99;
22540     }
22541
22542   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
22543   mp->vrf_id = ntohl (vrf_id);
22544   /* ipv6? */
22545   if (range_set == 2)
22546     {
22547       mp->is_ipv6 = 1;
22548       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
22549       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
22550     }
22551   else
22552     {
22553       mp->is_ipv6 = 0;
22554       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
22555       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
22556     }
22557   S (mp);
22558   W (ret);
22559   return ret;
22560 }
22561
22562 static void vl_api_app_namespace_add_del_reply_t_handler
22563   (vl_api_app_namespace_add_del_reply_t * mp)
22564 {
22565   vat_main_t *vam = &vat_main;
22566   i32 retval = ntohl (mp->retval);
22567   if (vam->async_mode)
22568     {
22569       vam->async_errors += (retval < 0);
22570     }
22571   else
22572     {
22573       vam->retval = retval;
22574       if (retval == 0)
22575         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
22576       vam->result_ready = 1;
22577     }
22578 }
22579
22580 static void vl_api_app_namespace_add_del_reply_t_handler_json
22581   (vl_api_app_namespace_add_del_reply_t * mp)
22582 {
22583   vat_main_t *vam = &vat_main;
22584   vat_json_node_t node;
22585
22586   vat_json_init_object (&node);
22587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
22588   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
22589
22590   vat_json_print (vam->ofp, &node);
22591   vat_json_free (&node);
22592
22593   vam->retval = ntohl (mp->retval);
22594   vam->result_ready = 1;
22595 }
22596
22597 static int
22598 api_app_namespace_add_del (vat_main_t * vam)
22599 {
22600   vl_api_app_namespace_add_del_t *mp;
22601   unformat_input_t *i = vam->input;
22602   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
22603   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
22604   u64 secret;
22605   int ret;
22606
22607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22608     {
22609       if (unformat (i, "id %_%v%_", &ns_id))
22610         ;
22611       else if (unformat (i, "secret %lu", &secret))
22612         secret_set = 1;
22613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
22614         sw_if_index_set = 1;
22615       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
22616         ;
22617       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
22618         ;
22619       else
22620         break;
22621     }
22622   if (!ns_id || !secret_set || !sw_if_index_set)
22623     {
22624       errmsg ("namespace id, secret and sw_if_index must be set");
22625       return -99;
22626     }
22627   if (vec_len (ns_id) > 64)
22628     {
22629       errmsg ("namespace id too long");
22630       return -99;
22631     }
22632   M (APP_NAMESPACE_ADD_DEL, mp);
22633
22634   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
22635   mp->namespace_id_len = vec_len (ns_id);
22636   mp->secret = clib_host_to_net_u64 (secret);
22637   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
22638   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
22639   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
22640   vec_free (ns_id);
22641   S (mp);
22642   W (ret);
22643   return ret;
22644 }
22645
22646 static int
22647 api_sock_init_shm (vat_main_t * vam)
22648 {
22649 #if VPP_API_TEST_BUILTIN == 0
22650   unformat_input_t *i = vam->input;
22651   vl_api_shm_elem_config_t *config = 0;
22652   u64 size = 64 << 20;
22653   int rv;
22654
22655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22656     {
22657       if (unformat (i, "size %U", unformat_memory_size, &size))
22658         ;
22659       else
22660         break;
22661     }
22662
22663   /*
22664    * Canned custom ring allocator config.
22665    * Should probably parse all of this
22666    */
22667   vec_validate (config, 6);
22668   config[0].type = VL_API_VLIB_RING;
22669   config[0].size = 256;
22670   config[0].count = 32;
22671
22672   config[1].type = VL_API_VLIB_RING;
22673   config[1].size = 1024;
22674   config[1].count = 16;
22675
22676   config[2].type = VL_API_VLIB_RING;
22677   config[2].size = 4096;
22678   config[2].count = 2;
22679
22680   config[3].type = VL_API_CLIENT_RING;
22681   config[3].size = 256;
22682   config[3].count = 32;
22683
22684   config[4].type = VL_API_CLIENT_RING;
22685   config[4].size = 1024;
22686   config[4].count = 16;
22687
22688   config[5].type = VL_API_CLIENT_RING;
22689   config[5].size = 4096;
22690   config[5].count = 2;
22691
22692   config[6].type = VL_API_QUEUE;
22693   config[6].count = 128;
22694   config[6].size = sizeof (uword);
22695
22696   rv = vl_socket_client_init_shm (config);
22697   if (!rv)
22698     vam->client_index_invalid = 1;
22699   return rv;
22700 #else
22701   return -99;
22702 #endif
22703 }
22704
22705 static int
22706 api_dns_enable_disable (vat_main_t * vam)
22707 {
22708   unformat_input_t *line_input = vam->input;
22709   vl_api_dns_enable_disable_t *mp;
22710   u8 enable_disable = 1;
22711   int ret;
22712
22713   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22714     {
22715       if (unformat (line_input, "disable"))
22716         enable_disable = 0;
22717       if (unformat (line_input, "enable"))
22718         enable_disable = 1;
22719       else
22720         break;
22721     }
22722
22723   /* Construct the API message */
22724   M (DNS_ENABLE_DISABLE, mp);
22725   mp->enable = enable_disable;
22726
22727   /* send it... */
22728   S (mp);
22729   /* Wait for the reply */
22730   W (ret);
22731   return ret;
22732 }
22733
22734 static int
22735 api_dns_resolve_name (vat_main_t * vam)
22736 {
22737   unformat_input_t *line_input = vam->input;
22738   vl_api_dns_resolve_name_t *mp;
22739   u8 *name = 0;
22740   int ret;
22741
22742   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22743     {
22744       if (unformat (line_input, "%s", &name))
22745         ;
22746       else
22747         break;
22748     }
22749
22750   if (vec_len (name) > 127)
22751     {
22752       errmsg ("name too long");
22753       return -99;
22754     }
22755
22756   /* Construct the API message */
22757   M (DNS_RESOLVE_NAME, mp);
22758   memcpy (mp->name, name, vec_len (name));
22759   vec_free (name);
22760
22761   /* send it... */
22762   S (mp);
22763   /* Wait for the reply */
22764   W (ret);
22765   return ret;
22766 }
22767
22768 static int
22769 api_dns_resolve_ip (vat_main_t * vam)
22770 {
22771   unformat_input_t *line_input = vam->input;
22772   vl_api_dns_resolve_ip_t *mp;
22773   int is_ip6 = -1;
22774   ip4_address_t addr4;
22775   ip6_address_t addr6;
22776   int ret;
22777
22778   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22779     {
22780       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
22781         is_ip6 = 1;
22782       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
22783         is_ip6 = 0;
22784       else
22785         break;
22786     }
22787
22788   if (is_ip6 == -1)
22789     {
22790       errmsg ("missing address");
22791       return -99;
22792     }
22793
22794   /* Construct the API message */
22795   M (DNS_RESOLVE_IP, mp);
22796   mp->is_ip6 = is_ip6;
22797   if (is_ip6)
22798     memcpy (mp->address, &addr6, sizeof (addr6));
22799   else
22800     memcpy (mp->address, &addr4, sizeof (addr4));
22801
22802   /* send it... */
22803   S (mp);
22804   /* Wait for the reply */
22805   W (ret);
22806   return ret;
22807 }
22808
22809 static int
22810 api_dns_name_server_add_del (vat_main_t * vam)
22811 {
22812   unformat_input_t *i = vam->input;
22813   vl_api_dns_name_server_add_del_t *mp;
22814   u8 is_add = 1;
22815   ip6_address_t ip6_server;
22816   ip4_address_t ip4_server;
22817   int ip6_set = 0;
22818   int ip4_set = 0;
22819   int ret = 0;
22820
22821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22822     {
22823       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
22824         ip6_set = 1;
22825       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
22826         ip4_set = 1;
22827       else if (unformat (i, "del"))
22828         is_add = 0;
22829       else
22830         {
22831           clib_warning ("parse error '%U'", format_unformat_error, i);
22832           return -99;
22833         }
22834     }
22835
22836   if (ip4_set && ip6_set)
22837     {
22838       errmsg ("Only one server address allowed per message");
22839       return -99;
22840     }
22841   if ((ip4_set + ip6_set) == 0)
22842     {
22843       errmsg ("Server address required");
22844       return -99;
22845     }
22846
22847   /* Construct the API message */
22848   M (DNS_NAME_SERVER_ADD_DEL, mp);
22849
22850   if (ip6_set)
22851     {
22852       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
22853       mp->is_ip6 = 1;
22854     }
22855   else
22856     {
22857       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
22858       mp->is_ip6 = 0;
22859     }
22860
22861   mp->is_add = is_add;
22862
22863   /* send it... */
22864   S (mp);
22865
22866   /* Wait for a reply, return good/bad news  */
22867   W (ret);
22868   return ret;
22869 }
22870
22871 static void
22872 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
22873 {
22874   vat_main_t *vam = &vat_main;
22875
22876   if (mp->is_ip4)
22877     {
22878       print (vam->ofp,
22879              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22880              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22881              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
22882              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
22883              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22884              clib_net_to_host_u32 (mp->action_index), mp->tag);
22885     }
22886   else
22887     {
22888       print (vam->ofp,
22889              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
22890              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
22891              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
22892              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
22893              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
22894              clib_net_to_host_u32 (mp->action_index), mp->tag);
22895     }
22896 }
22897
22898 static void
22899 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
22900                                              mp)
22901 {
22902   vat_main_t *vam = &vat_main;
22903   vat_json_node_t *node = NULL;
22904   struct in6_addr ip6;
22905   struct in_addr ip4;
22906
22907   if (VAT_JSON_ARRAY != vam->json_tree.type)
22908     {
22909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
22910       vat_json_init_array (&vam->json_tree);
22911     }
22912   node = vat_json_array_add (&vam->json_tree);
22913   vat_json_init_object (node);
22914
22915   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
22916   vat_json_object_add_uint (node, "appns_index",
22917                             clib_net_to_host_u32 (mp->appns_index));
22918   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
22919   vat_json_object_add_uint (node, "scope", mp->scope);
22920   vat_json_object_add_uint (node, "action_index",
22921                             clib_net_to_host_u32 (mp->action_index));
22922   vat_json_object_add_uint (node, "lcl_port",
22923                             clib_net_to_host_u16 (mp->lcl_port));
22924   vat_json_object_add_uint (node, "rmt_port",
22925                             clib_net_to_host_u16 (mp->rmt_port));
22926   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
22927   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
22928   vat_json_object_add_string_copy (node, "tag", mp->tag);
22929   if (mp->is_ip4)
22930     {
22931       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
22932       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
22933       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
22934       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
22935     }
22936   else
22937     {
22938       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
22939       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
22940       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
22941       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
22942     }
22943 }
22944
22945 static int
22946 api_session_rule_add_del (vat_main_t * vam)
22947 {
22948   vl_api_session_rule_add_del_t *mp;
22949   unformat_input_t *i = vam->input;
22950   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
22951   u32 appns_index = 0, scope = 0;
22952   ip4_address_t lcl_ip4, rmt_ip4;
22953   ip6_address_t lcl_ip6, rmt_ip6;
22954   u8 is_ip4 = 1, conn_set = 0;
22955   u8 is_add = 1, *tag = 0;
22956   int ret;
22957
22958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
22959     {
22960       if (unformat (i, "del"))
22961         is_add = 0;
22962       else if (unformat (i, "add"))
22963         ;
22964       else if (unformat (i, "proto tcp"))
22965         proto = 0;
22966       else if (unformat (i, "proto udp"))
22967         proto = 1;
22968       else if (unformat (i, "appns %d", &appns_index))
22969         ;
22970       else if (unformat (i, "scope %d", &scope))
22971         ;
22972       else if (unformat (i, "tag %_%v%_", &tag))
22973         ;
22974       else
22975         if (unformat
22976             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
22977              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
22978              &rmt_port))
22979         {
22980           is_ip4 = 1;
22981           conn_set = 1;
22982         }
22983       else
22984         if (unformat
22985             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
22986              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
22987              &rmt_port))
22988         {
22989           is_ip4 = 0;
22990           conn_set = 1;
22991         }
22992       else if (unformat (i, "action %d", &action))
22993         ;
22994       else
22995         break;
22996     }
22997   if (proto == ~0 || !conn_set || action == ~0)
22998     {
22999       errmsg ("transport proto, connection and action must be set");
23000       return -99;
23001     }
23002
23003   if (scope > 3)
23004     {
23005       errmsg ("scope should be 0-3");
23006       return -99;
23007     }
23008
23009   M (SESSION_RULE_ADD_DEL, mp);
23010
23011   mp->is_ip4 = is_ip4;
23012   mp->transport_proto = proto;
23013   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
23014   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
23015   mp->lcl_plen = lcl_plen;
23016   mp->rmt_plen = rmt_plen;
23017   mp->action_index = clib_host_to_net_u32 (action);
23018   mp->appns_index = clib_host_to_net_u32 (appns_index);
23019   mp->scope = scope;
23020   mp->is_add = is_add;
23021   if (is_ip4)
23022     {
23023       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
23024       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
23025     }
23026   else
23027     {
23028       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
23029       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
23030     }
23031   if (tag)
23032     {
23033       clib_memcpy (mp->tag, tag, vec_len (tag));
23034       vec_free (tag);
23035     }
23036
23037   S (mp);
23038   W (ret);
23039   return ret;
23040 }
23041
23042 static int
23043 api_session_rules_dump (vat_main_t * vam)
23044 {
23045   vl_api_session_rules_dump_t *mp;
23046   vl_api_control_ping_t *mp_ping;
23047   int ret;
23048
23049   if (!vam->json_output)
23050     {
23051       print (vam->ofp, "%=20s", "Session Rules");
23052     }
23053
23054   M (SESSION_RULES_DUMP, mp);
23055   /* send it... */
23056   S (mp);
23057
23058   /* Use a control ping for synchronization */
23059   MPING (CONTROL_PING, mp_ping);
23060   S (mp_ping);
23061
23062   /* Wait for a reply... */
23063   W (ret);
23064   return ret;
23065 }
23066
23067 static int
23068 api_ip_container_proxy_add_del (vat_main_t * vam)
23069 {
23070   vl_api_ip_container_proxy_add_del_t *mp;
23071   unformat_input_t *i = vam->input;
23072   u32 plen = ~0, sw_if_index = ~0;
23073   ip4_address_t ip4;
23074   ip6_address_t ip6;
23075   u8 is_ip4 = 1;
23076   u8 is_add = 1;
23077   int ret;
23078
23079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23080     {
23081       if (unformat (i, "del"))
23082         is_add = 0;
23083       else if (unformat (i, "add"))
23084         ;
23085       if (unformat (i, "%U", unformat_ip4_address, &ip4))
23086         {
23087           is_ip4 = 1;
23088           plen = 32;
23089         }
23090       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
23091         {
23092           is_ip4 = 0;
23093           plen = 128;
23094         }
23095       else if (unformat (i, "sw_if_index %u", &sw_if_index))
23096         ;
23097       else
23098         break;
23099     }
23100   if (sw_if_index == ~0 || plen == ~0)
23101     {
23102       errmsg ("address and sw_if_index must be set");
23103       return -99;
23104     }
23105
23106   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
23107
23108   mp->is_ip4 = is_ip4;
23109   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
23110   mp->plen = plen;
23111   mp->is_add = is_add;
23112   if (is_ip4)
23113     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
23114   else
23115     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
23116
23117   S (mp);
23118   W (ret);
23119   return ret;
23120 }
23121
23122 static int
23123 api_qos_record_enable_disable (vat_main_t * vam)
23124 {
23125   unformat_input_t *i = vam->input;
23126   vl_api_qos_record_enable_disable_t *mp;
23127   u32 sw_if_index, qs = 0xff;
23128   u8 sw_if_index_set = 0;
23129   u8 enable = 1;
23130   int ret;
23131
23132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
23133     {
23134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
23135         sw_if_index_set = 1;
23136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
23137         sw_if_index_set = 1;
23138       else if (unformat (i, "%U", unformat_qos_source, &qs))
23139         ;
23140       else if (unformat (i, "disable"))
23141         enable = 0;
23142       else
23143         {
23144           clib_warning ("parse error '%U'", format_unformat_error, i);
23145           return -99;
23146         }
23147     }
23148
23149   if (sw_if_index_set == 0)
23150     {
23151       errmsg ("missing interface name or sw_if_index");
23152       return -99;
23153     }
23154   if (qs == 0xff)
23155     {
23156       errmsg ("input location must be specified");
23157       return -99;
23158     }
23159
23160   M (QOS_RECORD_ENABLE_DISABLE, mp);
23161
23162   mp->sw_if_index = ntohl (sw_if_index);
23163   mp->input_source = qs;
23164   mp->enable = enable;
23165
23166   S (mp);
23167   W (ret);
23168   return ret;
23169 }
23170
23171
23172 static int
23173 q_or_quit (vat_main_t * vam)
23174 {
23175 #if VPP_API_TEST_BUILTIN == 0
23176   longjmp (vam->jump_buf, 1);
23177 #endif
23178   return 0;                     /* not so much */
23179 }
23180
23181 static int
23182 q (vat_main_t * vam)
23183 {
23184   return q_or_quit (vam);
23185 }
23186
23187 static int
23188 quit (vat_main_t * vam)
23189 {
23190   return q_or_quit (vam);
23191 }
23192
23193 static int
23194 comment (vat_main_t * vam)
23195 {
23196   return 0;
23197 }
23198
23199 static int
23200 statseg (vat_main_t * vam)
23201 {
23202   ssvm_private_t *ssvmp = &vam->stat_segment;
23203   ssvm_shared_header_t *shared_header = ssvmp->sh;
23204   vlib_counter_t **counters;
23205   u64 thread0_index1_packets;
23206   u64 thread0_index1_bytes;
23207   f64 vector_rate, input_rate;
23208   uword *p;
23209
23210   uword *counter_vector_by_name;
23211   if (vam->stat_segment_lockp == 0)
23212     {
23213       errmsg ("Stat segment not mapped...");
23214       return -99;
23215     }
23216
23217   /* look up "/if/rx for sw_if_index 1 as a test */
23218
23219   clib_spinlock_lock (vam->stat_segment_lockp);
23220
23221   counter_vector_by_name = (uword *) shared_header->opaque[1];
23222
23223   p = hash_get_mem (counter_vector_by_name, "/if/rx");
23224   if (p == 0)
23225     {
23226       clib_spinlock_unlock (vam->stat_segment_lockp);
23227       errmsg ("/if/tx not found?");
23228       return -99;
23229     }
23230
23231   /* Fish per-thread vector of combined counters from shared memory */
23232   counters = (vlib_counter_t **) p[0];
23233
23234   if (vec_len (counters[0]) < 2)
23235     {
23236       clib_spinlock_unlock (vam->stat_segment_lockp);
23237       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
23238       return -99;
23239     }
23240
23241   /* Read thread 0 sw_if_index 1 counter */
23242   thread0_index1_packets = counters[0][1].packets;
23243   thread0_index1_bytes = counters[0][1].bytes;
23244
23245   p = hash_get_mem (counter_vector_by_name, "vector_rate");
23246   if (p == 0)
23247     {
23248       clib_spinlock_unlock (vam->stat_segment_lockp);
23249       errmsg ("vector_rate not found?");
23250       return -99;
23251     }
23252
23253   vector_rate = *(f64 *) (p[0]);
23254   p = hash_get_mem (counter_vector_by_name, "input_rate");
23255   if (p == 0)
23256     {
23257       clib_spinlock_unlock (vam->stat_segment_lockp);
23258       errmsg ("input_rate not found?");
23259       return -99;
23260     }
23261   input_rate = *(f64 *) (p[0]);
23262
23263   clib_spinlock_unlock (vam->stat_segment_lockp);
23264
23265   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
23266          vector_rate, input_rate);
23267   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
23268          thread0_index1_packets, thread0_index1_bytes);
23269
23270   return 0;
23271 }
23272
23273 static int
23274 cmd_cmp (void *a1, void *a2)
23275 {
23276   u8 **c1 = a1;
23277   u8 **c2 = a2;
23278
23279   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
23280 }
23281
23282 static int
23283 help (vat_main_t * vam)
23284 {
23285   u8 **cmds = 0;
23286   u8 *name = 0;
23287   hash_pair_t *p;
23288   unformat_input_t *i = vam->input;
23289   int j;
23290
23291   if (unformat (i, "%s", &name))
23292     {
23293       uword *hs;
23294
23295       vec_add1 (name, 0);
23296
23297       hs = hash_get_mem (vam->help_by_name, name);
23298       if (hs)
23299         print (vam->ofp, "usage: %s %s", name, hs[0]);
23300       else
23301         print (vam->ofp, "No such msg / command '%s'", name);
23302       vec_free (name);
23303       return 0;
23304     }
23305
23306   print (vam->ofp, "Help is available for the following:");
23307
23308     /* *INDENT-OFF* */
23309     hash_foreach_pair (p, vam->function_by_name,
23310     ({
23311       vec_add1 (cmds, (u8 *)(p->key));
23312     }));
23313     /* *INDENT-ON* */
23314
23315   vec_sort_with_function (cmds, cmd_cmp);
23316
23317   for (j = 0; j < vec_len (cmds); j++)
23318     print (vam->ofp, "%s", cmds[j]);
23319
23320   vec_free (cmds);
23321   return 0;
23322 }
23323
23324 static int
23325 set (vat_main_t * vam)
23326 {
23327   u8 *name = 0, *value = 0;
23328   unformat_input_t *i = vam->input;
23329
23330   if (unformat (i, "%s", &name))
23331     {
23332       /* The input buffer is a vector, not a string. */
23333       value = vec_dup (i->buffer);
23334       vec_delete (value, i->index, 0);
23335       /* Almost certainly has a trailing newline */
23336       if (value[vec_len (value) - 1] == '\n')
23337         value[vec_len (value) - 1] = 0;
23338       /* Make sure it's a proper string, one way or the other */
23339       vec_add1 (value, 0);
23340       (void) clib_macro_set_value (&vam->macro_main,
23341                                    (char *) name, (char *) value);
23342     }
23343   else
23344     errmsg ("usage: set <name> <value>");
23345
23346   vec_free (name);
23347   vec_free (value);
23348   return 0;
23349 }
23350
23351 static int
23352 unset (vat_main_t * vam)
23353 {
23354   u8 *name = 0;
23355
23356   if (unformat (vam->input, "%s", &name))
23357     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
23358       errmsg ("unset: %s wasn't set", name);
23359   vec_free (name);
23360   return 0;
23361 }
23362
23363 typedef struct
23364 {
23365   u8 *name;
23366   u8 *value;
23367 } macro_sort_t;
23368
23369
23370 static int
23371 macro_sort_cmp (void *a1, void *a2)
23372 {
23373   macro_sort_t *s1 = a1;
23374   macro_sort_t *s2 = a2;
23375
23376   return strcmp ((char *) (s1->name), (char *) (s2->name));
23377 }
23378
23379 static int
23380 dump_macro_table (vat_main_t * vam)
23381 {
23382   macro_sort_t *sort_me = 0, *sm;
23383   int i;
23384   hash_pair_t *p;
23385
23386     /* *INDENT-OFF* */
23387     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
23388     ({
23389       vec_add2 (sort_me, sm, 1);
23390       sm->name = (u8 *)(p->key);
23391       sm->value = (u8 *) (p->value[0]);
23392     }));
23393     /* *INDENT-ON* */
23394
23395   vec_sort_with_function (sort_me, macro_sort_cmp);
23396
23397   if (vec_len (sort_me))
23398     print (vam->ofp, "%-15s%s", "Name", "Value");
23399   else
23400     print (vam->ofp, "The macro table is empty...");
23401
23402   for (i = 0; i < vec_len (sort_me); i++)
23403     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
23404   return 0;
23405 }
23406
23407 static int
23408 dump_node_table (vat_main_t * vam)
23409 {
23410   int i, j;
23411   vlib_node_t *node, *next_node;
23412
23413   if (vec_len (vam->graph_nodes) == 0)
23414     {
23415       print (vam->ofp, "Node table empty, issue get_node_graph...");
23416       return 0;
23417     }
23418
23419   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
23420     {
23421       node = vam->graph_nodes[0][i];
23422       print (vam->ofp, "[%d] %s", i, node->name);
23423       for (j = 0; j < vec_len (node->next_nodes); j++)
23424         {
23425           if (node->next_nodes[j] != ~0)
23426             {
23427               next_node = vam->graph_nodes[0][node->next_nodes[j]];
23428               print (vam->ofp, "  [%d] %s", j, next_node->name);
23429             }
23430         }
23431     }
23432   return 0;
23433 }
23434
23435 static int
23436 value_sort_cmp (void *a1, void *a2)
23437 {
23438   name_sort_t *n1 = a1;
23439   name_sort_t *n2 = a2;
23440
23441   if (n1->value < n2->value)
23442     return -1;
23443   if (n1->value > n2->value)
23444     return 1;
23445   return 0;
23446 }
23447
23448
23449 static int
23450 dump_msg_api_table (vat_main_t * vam)
23451 {
23452   api_main_t *am = &api_main;
23453   name_sort_t *nses = 0, *ns;
23454   hash_pair_t *hp;
23455   int i;
23456
23457   /* *INDENT-OFF* */
23458   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
23459   ({
23460     vec_add2 (nses, ns, 1);
23461     ns->name = (u8 *)(hp->key);
23462     ns->value = (u32) hp->value[0];
23463   }));
23464   /* *INDENT-ON* */
23465
23466   vec_sort_with_function (nses, value_sort_cmp);
23467
23468   for (i = 0; i < vec_len (nses); i++)
23469     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
23470   vec_free (nses);
23471   return 0;
23472 }
23473
23474 static int
23475 get_msg_id (vat_main_t * vam)
23476 {
23477   u8 *name_and_crc;
23478   u32 message_index;
23479
23480   if (unformat (vam->input, "%s", &name_and_crc))
23481     {
23482       message_index = vl_msg_api_get_msg_index (name_and_crc);
23483       if (message_index == ~0)
23484         {
23485           print (vam->ofp, " '%s' not found", name_and_crc);
23486           return 0;
23487         }
23488       print (vam->ofp, " '%s' has message index %d",
23489              name_and_crc, message_index);
23490       return 0;
23491     }
23492   errmsg ("name_and_crc required...");
23493   return 0;
23494 }
23495
23496 static int
23497 search_node_table (vat_main_t * vam)
23498 {
23499   unformat_input_t *line_input = vam->input;
23500   u8 *node_to_find;
23501   int j;
23502   vlib_node_t *node, *next_node;
23503   uword *p;
23504
23505   if (vam->graph_node_index_by_name == 0)
23506     {
23507       print (vam->ofp, "Node table empty, issue get_node_graph...");
23508       return 0;
23509     }
23510
23511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
23512     {
23513       if (unformat (line_input, "%s", &node_to_find))
23514         {
23515           vec_add1 (node_to_find, 0);
23516           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
23517           if (p == 0)
23518             {
23519               print (vam->ofp, "%s not found...", node_to_find);
23520               goto out;
23521             }
23522           node = vam->graph_nodes[0][p[0]];
23523           print (vam->ofp, "[%d] %s", p[0], node->name);
23524           for (j = 0; j < vec_len (node->next_nodes); j++)
23525             {
23526               if (node->next_nodes[j] != ~0)
23527                 {
23528                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
23529                   print (vam->ofp, "  [%d] %s", j, next_node->name);
23530                 }
23531             }
23532         }
23533
23534       else
23535         {
23536           clib_warning ("parse error '%U'", format_unformat_error,
23537                         line_input);
23538           return -99;
23539         }
23540
23541     out:
23542       vec_free (node_to_find);
23543
23544     }
23545
23546   return 0;
23547 }
23548
23549
23550 static int
23551 script (vat_main_t * vam)
23552 {
23553 #if (VPP_API_TEST_BUILTIN==0)
23554   u8 *s = 0;
23555   char *save_current_file;
23556   unformat_input_t save_input;
23557   jmp_buf save_jump_buf;
23558   u32 save_line_number;
23559
23560   FILE *new_fp, *save_ifp;
23561
23562   if (unformat (vam->input, "%s", &s))
23563     {
23564       new_fp = fopen ((char *) s, "r");
23565       if (new_fp == 0)
23566         {
23567           errmsg ("Couldn't open script file %s", s);
23568           vec_free (s);
23569           return -99;
23570         }
23571     }
23572   else
23573     {
23574       errmsg ("Missing script name");
23575       return -99;
23576     }
23577
23578   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
23579   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
23580   save_ifp = vam->ifp;
23581   save_line_number = vam->input_line_number;
23582   save_current_file = (char *) vam->current_file;
23583
23584   vam->input_line_number = 0;
23585   vam->ifp = new_fp;
23586   vam->current_file = s;
23587   do_one_file (vam);
23588
23589   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
23590   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
23591   vam->ifp = save_ifp;
23592   vam->input_line_number = save_line_number;
23593   vam->current_file = (u8 *) save_current_file;
23594   vec_free (s);
23595
23596   return 0;
23597 #else
23598   clib_warning ("use the exec command...");
23599   return -99;
23600 #endif
23601 }
23602
23603 static int
23604 echo (vat_main_t * vam)
23605 {
23606   print (vam->ofp, "%v", vam->input->buffer);
23607   return 0;
23608 }
23609
23610 /* List of API message constructors, CLI names map to api_xxx */
23611 #define foreach_vpe_api_msg                                             \
23612 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
23613 _(sw_interface_dump,"")                                                 \
23614 _(sw_interface_set_flags,                                               \
23615   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
23616 _(sw_interface_add_del_address,                                         \
23617   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
23618 _(sw_interface_set_rx_mode,                                             \
23619   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
23620 _(sw_interface_set_rx_placement,                                        \
23621   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
23622 _(sw_interface_rx_placement_dump,                                       \
23623   "[<intfc> | sw_if_index <id>]")                                         \
23624 _(sw_interface_set_table,                                               \
23625   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
23626 _(sw_interface_set_mpls_enable,                                         \
23627   "<intfc> | sw_if_index [disable | dis]")                              \
23628 _(sw_interface_set_vpath,                                               \
23629   "<intfc> | sw_if_index <id> enable | disable")                        \
23630 _(sw_interface_set_vxlan_bypass,                                        \
23631   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23632 _(sw_interface_set_geneve_bypass,                                       \
23633   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
23634 _(sw_interface_set_l2_xconnect,                                         \
23635   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23636   "enable | disable")                                                   \
23637 _(sw_interface_set_l2_bridge,                                           \
23638   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
23639   "[shg <split-horizon-group>] [bvi]\n"                                 \
23640   "enable | disable")                                                   \
23641 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
23642 _(bridge_domain_add_del,                                                \
23643   "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") \
23644 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
23645 _(l2fib_add_del,                                                        \
23646   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
23647 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
23648 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
23649 _(l2_flags,                                                             \
23650   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23651 _(bridge_flags,                                                         \
23652   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
23653 _(tap_connect,                                                          \
23654   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
23655 _(tap_modify,                                                           \
23656   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
23657 _(tap_delete,                                                           \
23658   "<vpp-if-name> | sw_if_index <id>")                                   \
23659 _(sw_interface_tap_dump, "")                                            \
23660 _(tap_create_v2,                                                        \
23661   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>]") \
23662 _(tap_delete_v2,                                                        \
23663   "<vpp-if-name> | sw_if_index <id>")                                   \
23664 _(sw_interface_tap_v2_dump, "")                                         \
23665 _(bond_create,                                                          \
23666   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
23667   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]}")        \
23668 _(bond_delete,                                                          \
23669   "<vpp-if-name> | sw_if_index <id>")                                   \
23670 _(bond_enslave,                                                         \
23671   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
23672 _(bond_detach_slave,                                                    \
23673   "sw_if_index <n>")                                                    \
23674 _(sw_interface_bond_dump, "")                                           \
23675 _(sw_interface_slave_dump,                                              \
23676   "<vpp-if-name> | sw_if_index <id>")                                   \
23677 _(ip_table_add_del,                                                     \
23678   "table <n> [ipv6] [add | del]\n")                                     \
23679 _(ip_add_del_route,                                                     \
23680   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
23681   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
23682   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
23683   "[multipath] [count <n>]")                                            \
23684 _(ip_mroute_add_del,                                                    \
23685   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
23686   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
23687 _(mpls_table_add_del,                                                   \
23688   "table <n> [add | del]\n")                                            \
23689 _(mpls_route_add_del,                                                   \
23690   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
23691   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
23692   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
23693   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
23694   "[drop] [local] [classify <n>] [multipath] [count <n>] [del]")        \
23695 _(mpls_ip_bind_unbind,                                                  \
23696   "<label> <addr/len>")                                                 \
23697 _(mpls_tunnel_add_del,                                                  \
23698   " via <addr> [table-id <n>]\n"                                        \
23699   "sw_if_index <id>] [l2]  [del]")                                      \
23700 _(sr_mpls_policy_add,                                                   \
23701   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
23702 _(sr_mpls_policy_del,                                                   \
23703   "bsid <id>")                                                          \
23704 _(bier_table_add_del,                                                   \
23705   "<label> <sub-domain> <set> <bsl> [del]")                             \
23706 _(bier_route_add_del,                                                   \
23707   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
23708   "[<intfc> | sw_if_index <id>]"                                        \
23709   "[weight <n>] [del] [multipath]")                                     \
23710 _(proxy_arp_add_del,                                                    \
23711   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
23712 _(proxy_arp_intfc_enable_disable,                                       \
23713   "<intfc> | sw_if_index <id> enable | disable")                        \
23714 _(sw_interface_set_unnumbered,                                          \
23715   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
23716 _(ip_neighbor_add_del,                                                  \
23717   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
23718   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
23719 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
23720 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
23721   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
23722   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
23723   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
23724 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
23725 _(reset_fib, "vrf <n> [ipv6]")                                          \
23726 _(dhcp_proxy_config,                                                    \
23727   "svr <v46-address> src <v46-address>\n"                               \
23728    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
23729 _(dhcp_proxy_set_vss,                                                   \
23730   "tbl_id <n> [fib_id <n> oui <n> | vpn_ascii_id <text>] [ipv6] [del]") \
23731 _(dhcp_proxy_dump, "ip6")                                               \
23732 _(dhcp_client_config,                                                   \
23733   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
23734 _(set_ip_flow_hash,                                                     \
23735   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
23736 _(sw_interface_ip6_enable_disable,                                      \
23737   "<intfc> | sw_if_index <id> enable | disable")                        \
23738 _(sw_interface_ip6_set_link_local_address,                              \
23739   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
23740 _(ip6nd_proxy_add_del,                                                  \
23741   "<intfc> | sw_if_index <id> <ip6-address>")                           \
23742 _(ip6nd_proxy_dump, "")                                                 \
23743 _(sw_interface_ip6nd_ra_prefix,                                         \
23744   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
23745   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
23746   "[nolink] [isno]")                                                    \
23747 _(sw_interface_ip6nd_ra_config,                                         \
23748   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
23749   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
23750   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
23751 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
23752 _(l2_patch_add_del,                                                     \
23753   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
23754   "enable | disable")                                                   \
23755 _(sr_localsid_add_del,                                                  \
23756   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
23757   "fib-table <num> (end.psp) sw_if_index <num>")                        \
23758 _(classify_add_del_table,                                               \
23759   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
23760   " [del] [del-chain] mask <mask-value>\n"                              \
23761   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
23762   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
23763 _(classify_add_del_session,                                             \
23764   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
23765   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
23766   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
23767   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
23768 _(classify_set_interface_ip_table,                                      \
23769   "<intfc> | sw_if_index <nn> table <nn>")                              \
23770 _(classify_set_interface_l2_tables,                                     \
23771   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23772   "  [other-table <nn>]")                                               \
23773 _(get_node_index, "node <node-name")                                    \
23774 _(add_node_next, "node <node-name> next <next-node-name>")              \
23775 _(l2tpv3_create_tunnel,                                                 \
23776   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
23777   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
23778   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
23779 _(l2tpv3_set_tunnel_cookies,                                            \
23780   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
23781   "[new_remote_cookie <nn>]\n")                                         \
23782 _(l2tpv3_interface_enable_disable,                                      \
23783   "<intfc> | sw_if_index <nn> enable | disable")                        \
23784 _(l2tpv3_set_lookup_key,                                                \
23785   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
23786 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
23787 _(vxlan_offload_rx,                                                     \
23788   "hw { <interface name> | hw_if_index <nn>} "                          \
23789   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
23790 _(vxlan_add_del_tunnel,                                                 \
23791   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23792   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
23793   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23794 _(geneve_add_del_tunnel,                                                \
23795   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
23796   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23797   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
23798 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
23799 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
23800 _(gre_add_del_tunnel,                                                   \
23801   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
23802   "[teb | erspan <session-id>] [del]")                                  \
23803 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
23804 _(l2_fib_clear_table, "")                                               \
23805 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
23806 _(l2_interface_vlan_tag_rewrite,                                        \
23807   "<intfc> | sw_if_index <nn> \n"                                       \
23808   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
23809   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
23810 _(create_vhost_user_if,                                                 \
23811         "socket <filename> [server] [renumber <dev_instance>] "         \
23812         "[disable_mrg_rxbuf] [disable_indirect_desc] "                  \
23813         "[mac <mac_address>]")                                          \
23814 _(modify_vhost_user_if,                                                 \
23815         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
23816         "[server] [renumber <dev_instance>]")                           \
23817 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
23818 _(sw_interface_vhost_user_dump, "")                                     \
23819 _(show_version, "")                                                     \
23820 _(show_threads, "")                                                     \
23821 _(vxlan_gpe_add_del_tunnel,                                             \
23822   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
23823   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
23824   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
23825   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
23826 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
23827 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
23828 _(interface_name_renumber,                                              \
23829   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
23830 _(input_acl_set_interface,                                              \
23831   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
23832   "  [l2-table <nn>] [del]")                                            \
23833 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
23834 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
23835   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
23836 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
23837 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
23838 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
23839 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
23840 _(ip_dump, "ipv4 | ipv6")                                               \
23841 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
23842 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
23843   "  spid_id <n> ")                                                     \
23844 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
23845   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
23846   "  integ_alg <alg> integ_key <hex>")                                  \
23847 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
23848   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
23849   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
23850   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
23851 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
23852 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
23853   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
23854   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
23855   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
23856   "  [instance <n>]")     \
23857 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
23858 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
23859   "  <alg> <hex>\n")                                                    \
23860 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
23861 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
23862 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
23863   "(auth_data 0x<data> | auth_data <data>)")                            \
23864 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
23865   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
23866 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
23867   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
23868   "(local|remote)")                                                     \
23869 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
23870 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
23871 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23872 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
23873 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
23874 _(ikev2_initiate_sa_init, "<profile_name>")                             \
23875 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
23876 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
23877 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
23878 _(delete_loopback,"sw_if_index <nn>")                                   \
23879 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
23880 _(bd_ip_mac_dump, "[bd_id] <id>")                                       \
23881 _(want_interface_events,  "enable|disable")                             \
23882 _(want_stats,"enable|disable")                                          \
23883 _(get_first_msg_id, "client <name>")                                    \
23884 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
23885 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
23886   "fib-id <nn> [ip4][ip6][default]")                                    \
23887 _(get_node_graph, " ")                                                  \
23888 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
23889 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
23890 _(ioam_disable, "")                                                     \
23891 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
23892                             " sw_if_index <sw_if_index> p <priority> "  \
23893                             "w <weight>] [del]")                        \
23894 _(one_add_del_locator, "locator-set <locator_name> "                    \
23895                         "iface <intf> | sw_if_index <sw_if_index> "     \
23896                         "p <priority> w <weight> [del]")                \
23897 _(one_add_del_local_eid,"vni <vni> eid "                                \
23898                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23899                          "locator-set <locator_name> [del]"             \
23900                          "[key-id sha1|sha256 secret-key <secret-key>]")\
23901 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
23902 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
23903 _(one_enable_disable, "enable|disable")                                 \
23904 _(one_map_register_enable_disable, "enable|disable")                    \
23905 _(one_map_register_fallback_threshold, "<value>")                       \
23906 _(one_rloc_probe_enable_disable, "enable|disable")                      \
23907 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
23908                                "[seid <seid>] "                         \
23909                                "rloc <locator> p <prio> "               \
23910                                "w <weight> [rloc <loc> ... ] "          \
23911                                "action <action> [del-all]")             \
23912 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
23913                           "<local-eid>")                                \
23914 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
23915 _(one_use_petr, "ip-address> | disable")                                \
23916 _(one_map_request_mode, "src-dst|dst-only")                             \
23917 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
23918 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
23919 _(one_locator_set_dump, "[local | remote]")                             \
23920 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
23921 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
23922                        "[local] | [remote]")                            \
23923 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
23924 _(one_ndp_bd_get, "")                                                   \
23925 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
23926 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
23927 _(one_l2_arp_bd_get, "")                                                \
23928 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
23929 _(one_stats_enable_disable, "enable|disable")                           \
23930 _(show_one_stats_enable_disable, "")                                    \
23931 _(one_eid_table_vni_dump, "")                                           \
23932 _(one_eid_table_map_dump, "l2|l3")                                      \
23933 _(one_map_resolver_dump, "")                                            \
23934 _(one_map_server_dump, "")                                              \
23935 _(one_adjacencies_get, "vni <vni>")                                     \
23936 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
23937 _(show_one_rloc_probe_state, "")                                        \
23938 _(show_one_map_register_state, "")                                      \
23939 _(show_one_status, "")                                                  \
23940 _(one_stats_dump, "")                                                   \
23941 _(one_stats_flush, "")                                                  \
23942 _(one_get_map_request_itr_rlocs, "")                                    \
23943 _(one_map_register_set_ttl, "<ttl>")                                    \
23944 _(one_set_transport_protocol, "udp|api")                                \
23945 _(one_get_transport_protocol, "")                                       \
23946 _(one_enable_disable_xtr_mode, "enable|disable")                        \
23947 _(one_show_xtr_mode, "")                                                \
23948 _(one_enable_disable_pitr_mode, "enable|disable")                       \
23949 _(one_show_pitr_mode, "")                                               \
23950 _(one_enable_disable_petr_mode, "enable|disable")                       \
23951 _(one_show_petr_mode, "")                                               \
23952 _(show_one_nsh_mapping, "")                                             \
23953 _(show_one_pitr, "")                                                    \
23954 _(show_one_use_petr, "")                                                \
23955 _(show_one_map_request_mode, "")                                        \
23956 _(show_one_map_register_ttl, "")                                        \
23957 _(show_one_map_register_fallback_threshold, "")                         \
23958 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
23959                             " sw_if_index <sw_if_index> p <priority> "  \
23960                             "w <weight>] [del]")                        \
23961 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
23962                         "iface <intf> | sw_if_index <sw_if_index> "     \
23963                         "p <priority> w <weight> [del]")                \
23964 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
23965                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
23966                          "locator-set <locator_name> [del]"             \
23967                          "[key-id sha1|sha256 secret-key <secret-key>]") \
23968 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
23969 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
23970 _(lisp_enable_disable, "enable|disable")                                \
23971 _(lisp_map_register_enable_disable, "enable|disable")                   \
23972 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
23973 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
23974                                "[seid <seid>] "                         \
23975                                "rloc <locator> p <prio> "               \
23976                                "w <weight> [rloc <loc> ... ] "          \
23977                                "action <action> [del-all]")             \
23978 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
23979                           "<local-eid>")                                \
23980 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
23981 _(lisp_use_petr, "<ip-address> | disable")                              \
23982 _(lisp_map_request_mode, "src-dst|dst-only")                            \
23983 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
23984 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
23985 _(lisp_locator_set_dump, "[local | remote]")                            \
23986 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
23987 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
23988                        "[local] | [remote]")                            \
23989 _(lisp_eid_table_vni_dump, "")                                          \
23990 _(lisp_eid_table_map_dump, "l2|l3")                                     \
23991 _(lisp_map_resolver_dump, "")                                           \
23992 _(lisp_map_server_dump, "")                                             \
23993 _(lisp_adjacencies_get, "vni <vni>")                                    \
23994 _(gpe_fwd_entry_vnis_get, "")                                           \
23995 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
23996 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
23997                                 "[table <table-id>]")                   \
23998 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
23999 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
24000 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
24001 _(gpe_get_encap_mode, "")                                               \
24002 _(lisp_gpe_add_del_iface, "up|down")                                    \
24003 _(lisp_gpe_enable_disable, "enable|disable")                            \
24004 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
24005   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
24006 _(show_lisp_rloc_probe_state, "")                                       \
24007 _(show_lisp_map_register_state, "")                                     \
24008 _(show_lisp_status, "")                                                 \
24009 _(lisp_get_map_request_itr_rlocs, "")                                   \
24010 _(show_lisp_pitr, "")                                                   \
24011 _(show_lisp_use_petr, "")                                               \
24012 _(show_lisp_map_request_mode, "")                                       \
24013 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
24014 _(af_packet_delete, "name <host interface name>")                       \
24015 _(af_packet_dump, "")                                                   \
24016 _(policer_add_del, "name <policer name> <params> [del]")                \
24017 _(policer_dump, "[name <policer name>]")                                \
24018 _(policer_classify_set_interface,                                       \
24019   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24020   "  [l2-table <nn>] [del]")                                            \
24021 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
24022 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
24023     "[master|slave]")                                                   \
24024 _(netmap_delete, "name <interface name>")                               \
24025 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
24026 _(mpls_fib_dump, "")                                                    \
24027 _(classify_table_ids, "")                                               \
24028 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
24029 _(classify_table_info, "table_id <nn>")                                 \
24030 _(classify_session_dump, "table_id <nn>")                               \
24031 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
24032     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
24033     "[template_interval <nn>] [udp_checksum]")                          \
24034 _(ipfix_exporter_dump, "")                                              \
24035 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
24036 _(ipfix_classify_stream_dump, "")                                       \
24037 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
24038 _(ipfix_classify_table_dump, "")                                        \
24039 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
24040 _(sw_interface_span_dump, "[l2]")                                           \
24041 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
24042 _(pg_create_interface, "if_id <nn>")                                    \
24043 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
24044 _(pg_enable_disable, "[stream <id>] disable")                           \
24045 _(ip_source_and_port_range_check_add_del,                               \
24046   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
24047 _(ip_source_and_port_range_check_interface_add_del,                     \
24048   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
24049   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
24050 _(ipsec_gre_add_del_tunnel,                                             \
24051   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
24052 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
24053 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
24054 _(l2_interface_pbb_tag_rewrite,                                         \
24055   "<intfc> | sw_if_index <nn> \n"                                       \
24056   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
24057   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
24058 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
24059 _(flow_classify_set_interface,                                          \
24060   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
24061 _(flow_classify_dump, "type [ip4|ip6]")                                 \
24062 _(ip_fib_dump, "")                                                      \
24063 _(ip_mfib_dump, "")                                                     \
24064 _(ip6_fib_dump, "")                                                     \
24065 _(ip6_mfib_dump, "")                                                    \
24066 _(feature_enable_disable, "arc_name <arc_name> "                        \
24067   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
24068 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
24069 "[disable]")                                                            \
24070 _(l2_xconnect_dump, "")                                                 \
24071 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
24072 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
24073 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
24074 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
24075 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
24076 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
24077 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
24078   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
24079 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
24080 _(sock_init_shm, "size <nnn>")                                          \
24081 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
24082 _(dns_enable_disable, "[enable][disable]")                              \
24083 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24084 _(dns_resolve_name, "<hostname>")                                       \
24085 _(dns_resolve_ip, "<ip4|ip6>")                                          \
24086 _(dns_name_server_add_del, "<ip-address> [del]")                        \
24087 _(dns_resolve_name, "<hostname>")                                       \
24088 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
24089   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
24090 _(session_rules_dump, "")                                               \
24091 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
24092 _(output_acl_set_interface,                                             \
24093   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
24094   "  [l2-table <nn>] [del]")                                            \
24095 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
24096
24097 /* List of command functions, CLI names map directly to functions */
24098 #define foreach_cli_function                                    \
24099 _(comment, "usage: comment <ignore-rest-of-line>")              \
24100 _(dump_interface_table, "usage: dump_interface_table")          \
24101 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
24102 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
24103 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
24104 _(dump_stats_table, "usage: dump_stats_table")                  \
24105 _(dump_macro_table, "usage: dump_macro_table ")                 \
24106 _(dump_node_table, "usage: dump_node_table")                    \
24107 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
24108 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
24109 _(echo, "usage: echo <message>")                                \
24110 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
24111 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
24112 _(help, "usage: help")                                          \
24113 _(q, "usage: quit")                                             \
24114 _(quit, "usage: quit")                                          \
24115 _(search_node_table, "usage: search_node_table <name>...")      \
24116 _(set, "usage: set <variable-name> <value>")                    \
24117 _(script, "usage: script <file-name>")                          \
24118 _(statseg, "usage: statseg");                                   \
24119 _(unset, "usage: unset <variable-name>")
24120
24121 #define _(N,n)                                  \
24122     static void vl_api_##n##_t_handler_uni      \
24123     (vl_api_##n##_t * mp)                       \
24124     {                                           \
24125         vat_main_t * vam = &vat_main;           \
24126         if (vam->json_output) {                 \
24127             vl_api_##n##_t_handler_json(mp);    \
24128         } else {                                \
24129             vl_api_##n##_t_handler(mp);         \
24130         }                                       \
24131     }
24132 foreach_vpe_api_reply_msg;
24133 #if VPP_API_TEST_BUILTIN == 0
24134 foreach_standalone_reply_msg;
24135 #endif
24136 #undef _
24137
24138 void
24139 vat_api_hookup (vat_main_t * vam)
24140 {
24141 #define _(N,n)                                                  \
24142     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
24143                            vl_api_##n##_t_handler_uni,          \
24144                            vl_noop_handler,                     \
24145                            vl_api_##n##_t_endian,               \
24146                            vl_api_##n##_t_print,                \
24147                            sizeof(vl_api_##n##_t), 1);
24148   foreach_vpe_api_reply_msg;
24149 #if VPP_API_TEST_BUILTIN == 0
24150   foreach_standalone_reply_msg;
24151 #endif
24152 #undef _
24153
24154 #if (VPP_API_TEST_BUILTIN==0)
24155   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
24156
24157   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
24158
24159   vam->function_by_name = hash_create_string (0, sizeof (uword));
24160
24161   vam->help_by_name = hash_create_string (0, sizeof (uword));
24162 #endif
24163
24164   /* API messages we can send */
24165 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
24166   foreach_vpe_api_msg;
24167 #undef _
24168
24169   /* Help strings */
24170 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24171   foreach_vpe_api_msg;
24172 #undef _
24173
24174   /* CLI functions */
24175 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
24176   foreach_cli_function;
24177 #undef _
24178
24179   /* Help strings */
24180 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
24181   foreach_cli_function;
24182 #undef _
24183 }
24184
24185 #if VPP_API_TEST_BUILTIN
24186 static clib_error_t *
24187 vat_api_hookup_shim (vlib_main_t * vm)
24188 {
24189   vat_api_hookup (&vat_main);
24190   return 0;
24191 }
24192
24193 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
24194 #endif
24195
24196 /*
24197  * fd.io coding-style-patch-verification: ON
24198  *
24199  * Local Variables:
24200  * eval: (c-set-style "gnu")
24201  * End:
24202  */